代码如下,U我认为对于新手来说最重要的是学会rnn读取数据的格式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# -*- coding: utf-8 -*-
"""
Created on Tue Oct 9 08:53:25 2018
@author: www
"""
import sys
sys.path.append( '..' )
import torch
import datetime
from torch.autograd import Variable
from torch import nn
from torch.utils.data import DataLoader
from torchvision import transforms as tfs
from torchvision.datasets import MNIST
#定义数据
data_tf = tfs.Compose([
tfs.ToTensor(),
tfs.Normalize([ 0.5 ], [ 0.5 ])
])
train_set = MNIST( 'E:/data' , train = True , transform = data_tf, download = True )
test_set = MNIST( 'E:/data' , train = False , transform = data_tf, download = True )
train_data = DataLoader(train_set, 64 , True , num_workers = 4 )
test_data = DataLoader(test_set, 128 , False , num_workers = 4 )
#定义模型
class rnn_classify(nn.Module):
def __init__( self , in_feature = 28 , hidden_feature = 100 , num_class = 10 , num_layers = 2 ):
super (rnn_classify, self ).__init__()
self .classifier = nn.Linear(hidden_feature, num_class) #将最后一个的rnn使用全连接的到最后的输出结果
def forward( self , x):
#x的大小为(batch,1,28,28),所以我们需要将其转化为rnn的输入格式(28,batch,28)
x = x.squeeze() #去掉(batch,1,28,28)中的1,变成(batch, 28,28)
x = x.permute( 2 , 0 , 1 ) #将最后一维放到第一维,变成(batch,28,28)
out, _ = self .rnn(x) #使用默认的隐藏状态,得到的out是(28, batch, hidden_feature)
out = out[ - 1 ,:,:] #取序列中的最后一个,大小是(batch, hidden_feature)
out = self .classifier(out) #得到分类结果
return out
net = rnn_classify()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adadelta(net.parameters(), 1e - 1 )
#定义训练过程
def get_acc(output, label):
total = output.shape[ 0 ]
_, pred_label = output. max ( 1 )
num_correct = (pred_label = = label). sum ().item()
return num_correct / total
def train(net, train_data, valid_data, num_epochs, optimizer, criterion):
if torch.cuda.is_available():
net = net.cuda()
prev_time = datetime.datetime.now()
for epoch in range (num_epochs):
train_loss = 0
train_acc = 0
net = net.train()
for im, label in train_data:
if torch.cuda.is_available():
im = Variable(im.cuda()) # (bs, 3, h, w)
label = Variable(label.cuda()) # (bs, h, w)
else :
im = Variable(im)
label = Variable(label)
# forward
output = net(im)
loss = criterion(output, label)
# backward
optimizer.zero_grad()
loss.backward()
optimizer.step()
train_loss + = loss.item()
train_acc + = get_acc(output, label)
cur_time = datetime.datetime.now()
h, remainder = divmod ((cur_time - prev_time).seconds, 3600 )
m, s = divmod (remainder, 60 )
time_str = "Time %02d:%02d:%02d" % (h, m, s)
if valid_data is not None :
valid_loss = 0
valid_acc = 0
net = net. eval ()
for im, label in valid_data:
if torch.cuda.is_available():
im = Variable(im.cuda())
label = Variable(label.cuda())
else :
im = Variable(im)
label = Variable(label)
output = net(im)
loss = criterion(output, label)
valid_loss + = loss.item()
valid_acc + = get_acc(output, label)
epoch_str = (
"Epoch %d. Train Loss: %f, Train Acc: %f, Valid Loss: %f, Valid Acc: %f, "
% (epoch, train_loss / len (train_data),
train_acc / len (train_data), valid_loss / len (valid_data),
valid_acc / len (valid_data)))
else :
epoch_str = ( "Epoch %d. Train Loss: %f, Train Acc: %f, " %
(epoch, train_loss / len (train_data),
train_acc / len (train_data)))
prev_time = cur_time
print (epoch_str + time_str)
train(net, train_data, test_data, 10 , optimizer, criterion)
|
以上这篇pytorch 利用lstm做mnist手写数字识别分类的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/xckkcxxck/article/details/82978942