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

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

作者: BlueFishMan | 来源:发表于2018-07-11 09:54 被阅读0次
    #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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/viwcpftx.html