3.8.多层全连接神经网络实现MNIST手写数字分类

2018-07-11  本文已影响0人  BlueFishMan
#talk is cheap, show me the code
#MNIST数据集是一个手写字体数据集,包含0到9这10个数字,其中55000张训练集,10000张测试集,5000张验证集,图片大小是28X28的灰度图
import torch
from torch import nn,optim
from torch.autograd import Variable
from torch.utils.data import DataLoader
from torchvision import datasets,transforms

#超参数(Hyperparameters)
batch_size=32
learning_rate=1e-2
num_epochs=1000

#将各种预处理操作组合在一起{(0,1)->(-1,1)}
data_tf=transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5],[0.5])])
#下载训练集MNIST手写数字训练集
train_dataset=datasets.MNIST(root='./data',train=True,transform=data_tf,download=True)
test_dataset=datasets.MNIST(root='./data',train=False,transform=data_tf,download=True)
train_loader=DataLoader(train_dataset,batch_size=batch_size,shuffle=True)
test_loader=DataLoader(test_dataset,batch_size=batch_size,shuffle=False)

class MyNet(nn.Module):
    #输入的纬度,第一、二、三(输出层)层网络的神经元的个数
    def __init__(self,in_dim,n_hidden_1,n_hidden_2,out_dim):
        super(MyNet,self).__init__()
        #添加激活函数增加网络的非线性,添加批标准化加快收敛速度
        #将网络的层组合在一起
        self.layer1=nn.Sequential(nn.Linear(in_dim,n_hidden_1),nn.BatchNorm1d(n_hidden_1),nn.ReLU(True))
        #批标准化一般放在全连接层的后面、非线性层(激活函数)的前面
        self.layer2=nn.Sequential(nn.Linear(n_hidden_1,n_hidden_2),nn.BatchNorm1d(n_hidden_2),nn.ReLU(True))
        #最后一个输出层不能添加激活函数,因为输出结果表示的是实际的得分
        self.layer3=nn.Sequential(nn.Linear(n_hidden_2,out_dim))
        
    def forward(self,x):
        x=self.layer1(x)
        x=self.layer2(x)
        x=self.layer3(x)
        return x
if torch.cuda.is_available():
    model=MyNet(28*28,300,100,10).cuda()
else:
    model=MyNet(28*28,300,100,10)
    
#定义损失函数和优化方法
criterion=nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=learning_rate)

for epoch in range(num_epochs):
    image,label=iter(train_loader).next()
    if torch.cuda.is_available():
        image=Variable(image.view(image.size(0),-1)).cuda()
        label=Variable(label).cuda()
    else:
        image=Variable(image.view(image.size(0),-1))
        label=Variable(label)  
    out=model(image)
    loss=criterion(out,label)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

model.eval()
eval_loss=0
eval_acc=0
for data in test_loader:
    image,label=data
    if torch.cuda.is_available():
        image=Variable(image.view(image.size(0),-1),volatile=True).cuda()
        label=Variable(label,volatile=True).cuda()
    else:
        image=Variable(image.view(image.size(0),-1),volatile=True)
        label=Variable(label,volatile=True)
    out=model(image)
    loss=criterion(out,label)
    eval_loss+=loss.data[0]*label.size(0)
    _,pred=torch.max(out,1)
    num_correct=(pred==label).sum()
    eval_acc+=num_correct.data[0]
print('Test Loss:{:.6f},Acc:{:.6f}'.format(eval_loss/len(test_dataset),eval_acc/(len(test_dataset))))
Test Loss:0.269822,Acc:0.939300
上一篇 下一篇

猜你喜欢

热点阅读