经典CNN识别MINIST数据集代码的理解

#关于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])

你可能感兴趣的:(经典CNN识别MINIST数据集代码的理解)