#关于CNN学习后 对pytorch的理解
#导入相应模块
import torch
import torch.nn as nn
import torchvision
import torch.utils.data as Data
# Hyper Parameters 超参数
EPOCH = 1 # 训练整批数据多少次, 为了节约时间, 我们只训练一次
BATCH_SIZE = 50
LR = 0.001 # 学习率
DOWNLOAD_MNIST = True # 已经下载好的话,会自动跳过的
# Mnist 手写数字集的设置
train_data = torchvision.datasets.MNIST(
root='./mnist/', # 保存或者提取位置
train=True, # this is training data
transform=torchvision.transforms.ToTensor(), # 转换 PIL.Image or numpy.ndarray 成
# torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间
download=DOWNLOAD_MNIST, # 没下载就下载, 下载了就不用再下了
)
#关于train_data 里面的transform=torchvision.transforms.ToTensor(),是将图片改成C*H*W在这里为1*28*28
#而train_data.train data 为60000*28*28
test_data = torchvision.datasets.MNIST(
root='./mnist/',
train=False,
)
#print(test_data.test_data) 为10000*28*28
# 训练集丢BATCH_SIZE个, 图片大小为28*28
train_loader = Data.DataLoader( #数据加载器。组合数据集和采样器,并在数据集上提供单进程或多进程迭代器
dataset=train_data, #数据加载器的作用是将数据存进去,组合数据集,对其进行采用,提供迭代器
batch_size=BATCH_SIZE, #这里将数据组合和采用成大小为50*1*28*28的张量,同时迭代器次数为1200
shuffle=True # 是否打乱顺序 #我的理解是为1200次的每次为一个50*1*28*28的迭代器
)
# test_data为 [10000, 28, 28]这样的一个数组,这里就只截取一段就好了
test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)
test_y = test_data.test_labels
# cnn
class CNN(nn.Module):
def __init__(self): #卷积核的大小为16*1*5*5既16个通道,1个通道的5*5的卷积核
super(CNN, self).__init__() #因此可以与dataloader50*1*28*28 里面的数据进行运算
self.layer1 = nn.Sequential( #由于有第一维度有50个数据 因此不需要设置多少输入输出大小,只需要设置卷基层大小就行
# (1, 28, 28) #既设置好layer的参数以后,就可以输入层 隐藏层输出层的个数就确定下来了
nn.Conv2d(
in_channels=1,
out_channels=16,
kernel_size=5, # 卷积filter, 移动块长
stride=1, # filter的每次移动步长
padding=2,
groups=1
),
# (16, 28, 38)
nn.ReLU(),
nn.MaxPool2d(kernel_size=2)
# (16, 14, 14)
)
self.layer2 = nn.Sequential(
nn.Conv2d(
in_channels=16,
out_channels=32,
kernel_size=5,
stride=1,
padding=2
),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2)
)
self.layer3 = nn.Linear(32 * 7 * 7, 10)
def forward(self, x):
# print(x.shape)
x = self.layer1(x)
# print(x.shape)
x = self.layer2(x)
# print(x.shape)
x = x.view(x.size(0), -1)
# print(x.shape)
x = self.layer3(x)
# print(x.shape)
return x
cnn = CNN()
optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)
loss_function = nn.CrossEntropyLoss()
for epoch in range(EPOCH):
for step, (b_x, b_y) in enumerate(train_loader):
output = cnn(b_x)
loss = loss_function(output, b_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if step%10==0:
print(step)
print('finished training')
test_out = cnn(test_x)
predict_y = torch.argmax(test_out, 1).data.numpy() #取输出的10个神经元中最大的数的序号
print('Accuracy in Test : %.4f%%' % (sum(predict_y == test_y.data.numpy()) * 100/ len(predict_y)))
print(predict_y[:20],'preditiocn')
print(test_y.data.numpy()[:20])