#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