代码的基本结构还是延续我通过深度学习神经网络,基于MNIST实现手写数字识别 的结构,只是神经网络部分使用了Pytorch的API。
有一些地方要多说一点,但是不展开:
1、激活函数选用了ReLU,而非之前的sigmoid,二者的不同,网上文章很多,有机会总结一下。
2、可以跟前文的代码进行比较看,主要看train、query两个方法,感受一下Pytorch的封装。
3、用Pytorch构建的神经网络,在训练、测试时采用对应的模式train()、eval(),主要是对BN、Dropout层进行设置,具体的情况有机会详细说一下。
4、本次还是使用了200个隐藏层节点,学习率0.1,使用了6W+条数据用以训练,1W+条数据用以测试,激活函数分别用ReLU,Sigmoid训练了7个世代,结果如下:
Sigmoid 7世代
准确率=94.21%
该循环程序运行时间: 404.66520285606384
Relu 7世代
准确率=98.15%
该循环程序运行时间: 396.1038899421692
之前代码,7个世代结果:
准确率=97.26%
该循环程序运行时间: 314.45252776145935
代码如下:
# -*- coding: utf-8 -*-
#!/usr/bin/Python3import numpyimport torchimport torch.optim as optim
from torch import nn
from time import *
class NNW(torch.nn.Module):
def __init__(self): super(NNW, self).__init__()
self.inputLinear=torch.nn.Linear(784,200)
self.hidden1Linear=torch.nn.Linear(200,200)
self.outLinear=torch.nn.Linear(200,10)
def forward(self,x): #relu激活函数 x=torch.nn.functional.relu(self.inputLinear(x)) x=torch.nn.functional.relu(self.hidden1Linear(x)) return self.outLinear(x)
#sigmoid激活函数 #x=torch.sigmoid(self.inputLinear(x)) #x=torch.sigmoid(self.hidden1Linear(x)) #return torch.sigmoid(self.outLinear(x))
begin_time = time()nnw=NNW()#损失函数loss=torch.nn.MSELoss()#随机梯度下降optimizer=optim.SGD(nnw.parameters(),0.1)
def train(inputs,targets): #前向传播 output = nnw(inputs) loss_result=loss(output,targets) #反向传播 optimizer.zero_grad() loss_result.backward() optimizer.step()def query(inputs): out=nnw(inputs)
return out
#从文件取出训练数据trainFile=open("mnist_train.csv","r")
trains=trainFile.readlines()trainFile.close#从文件取出测试数据testFile=open("mnist_test.csv","r")
tests=testFile.readlines()testFile.close#训练模式,启用BN层、Dropout层nnw.train()for size in range(1):
print("第{}次训练".format(size+1))
for data in trains:
allVals=data.split(",")
inputs_list=numpy.asfarray(allVals[1:])/255.0*0.99+0.01
targets_list=numpy.zeros(10)+0.01
targets_list[int(allVals[0])]=0.99
inputs=torch.autograd.Variable(torch.tensor(inputs_list)) targets=torch.autograd.Variable(torch.tensor(targets_list)) train(inputs.float(),targets.float())score=[]#测试模式,固定住BN层和Dropout层,使用已经训练好的值nnw.eval()for data in tests:
allVals=data.split(",")
realNum=int(allVals[0])
inputs_list=numpy.asfarray(allVals[1:])/255.0*0.99+0.01
inputs = torch.autograd.Variable(torch.tensor(inputs_list)) result=query(inputs.float()) outNum=numpy.argmax(result.cpu().detach().numpy()) #print("真实值{},结果值{}".format(realNum,outNum))
if(outNum==realNum):
score.Append(1)
else:
score.append(0)
scoreArr=numpy.asarray(score)print("准确率={}%".format(scoreArr.sum()/scoreArr.size*100))
end_time = time()run_time = end_time-begin_timeprint ('该循环程序运行时间:',run_time)