Pytorch 之神经网络

目录

  • 第1关:加载数据——Data Loader
  • 第2关:建立模型,定义损失和优化函数
  • 第3关:训练模型
  • 第4关:测试保存模型

第1关:加载数据——Data Loader

本关要求掌握 Pytorch 中加载和处理数据的方法。

本关任务:本关要求下载训练集 MNIST,创建符合要求的DataLoader变量data_loader,同时按要求输出特定数据的维度大小和类别。


import torch
import torchvision.datasets as dsets
import torchvision.transforms as transforms
import os
import sys
import torch
import torchvision.datasets as dsets
import torchvision.transforms as transforms
import os
import sys
path = os.path.split(os.path.abspath(os.path.realpath(sys.argv[0])))[0] + os.path.sep

path = path[:-10] + '/data/'


#/********** Begin *********/
# 下载训练集 MNIST 训练集,设置 root = path,train=False ,download=False,赋值给变量train_dataset
train_dataset = dsets.MNIST(root= path,
                            train=False,
                            transform=transforms.ToTensor(),
                            download=False)



# 创建batch_size=100, shuffle=True的DataLoader变量data_loader
data_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                           batch_size=100,
                                           shuffle=True)

# 获取数据集中的第四个元素的图片信息和类别
print('Number of samples: ', len(train_dataset))
img, target = train_dataset[3] # load 4th sample

#按照格式“Image Size: ...”输出该图片大小
print("Image Size: ", img.size())

#按照格式“Image Target: ...”输出该图片的类别
print("Image Target: ",target)
#/********** End *********/

path = os.path.split(os.path.abspath(os.path.realpath(sys.argv[0])))[0] + os.path.sep

path = path[:-10] + '/data/'


#/********** Begin *********/
# 下载训练集 MNIST 训练集,设置 root = path,train=False ,download=False,赋值给变量train_dataset


# 创建dataset=train_dataset,batch_size=100, shuffle=True的DataLoader变量data_loader


# 获取数据集中的第四个元素的图片信息和类别


#按照格式“Image Size: ...”输出该图片大小


#按照格式“Image Target: ...”输出该图片的类别

#/********** End *********/

第2关:建立模型,定义损失和优化函数

本关创建的为前馈传播网络(feedforward neural network),即将每一层的输出直接作为下一层的输入。

本关任务:本关声明了一个模型CNN,它是一个卷积神经网络,一共有三层,要求同学们仿照layer1声明layer2,并定义全连接层。同时,按照代码中的提示补充填写forward()函数。

import torch 
import torch.nn as nn
import torchvision.datasets as dsets
import torchvision.transforms as transforms
from torch.autograd import Variable

# CNN Model (2 conv layer)
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(1, 16, kernel_size=5, padding=2),
            nn.BatchNorm2d(16),
            nn.ReLU(),
            nn.MaxPool2d(2))
        #/********** Begin *********/

        self.layer2 = nn.Sequential(
            #定义卷积层Conv2d:输入16张特征图,输出32张特征图,卷积核5x5,padding为2
            nn.Conv2d(16, 32, kernel_size=5, padding=2),

            #定义BatchNorm2d层,参数为32
            nn.BatchNorm2d(32),
            #定义非线性层ReLU
            nn.ReLU(),
            #定义2x2窗口的最大池化层MaxPool2d
            nn.MaxPool2d(2))

        # 定义全连接层:线性连接(y = Wx + b),7*7*32个节点连接到10个节点上
        self.fc = nn.Linear(7*7*32, 10)
        
    def forward(self, x):
  
        out = self.layer1(x)
        # 输入out->layer2->更新到out
        out = self.layer2(out)
        #view函数将张量x变形成一维向量形式,总特征数不变,为全连接层做准备
        out = out.view(out.size(0), -1)
        # 输入out->fc,更新到out
        out = self.fc(out)
        return out
    #/********** End *********/
        
cnn = CNN()


params = list(cnn.parameters())
print(len(params))

for name, parameters in cnn.named_parameters():
    print(name, ":", parameters.size())


第3关:训练模型

本关任务:本关利用上一节构造的模型进行训练,并创建一个交叉熵损失函数,创建类型为Adam的优化算子,补充梯度归零、反馈求导、优化等语句,根据num_epochs的设定共训练60次,分10次输出一回loss的数值信息。

import torch
import torch.nn as nn
import torchvision.datasets as dsets
import torchvision.transforms as transforms
from torch.autograd import Variable
import os
import sys
path = os.path.split(os.path.abspath(os.path.realpath(sys.argv[0])))[0] + os.path.sep
#rootpath = path[:10] + '/data/'
#print(path)
# Hyper Parameters
batch_size = 100
learning_rate = 0.001
num_epochs = 1
# MNIST Dataset
train_dataset = dsets.MNIST(root='./data/',
                            train=True,
                            transform=transforms.ToTensor(),
                            download=False)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                           batch_size=batch_size,
                                           shuffle=True)

# CNN Model (2 conv layer)
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.layer1 = nn.Sequential(
                                    nn.Conv2d(1, 16, kernel_size=5, padding=2),
                                    nn.BatchNorm2d(16),
                                    nn.ReLU(),
                                    nn.MaxPool2d(2))
        self.layer2 = nn.Sequential(
                                    nn.Conv2d(16, 32, kernel_size=5, padding=2),
                                    nn.BatchNorm2d(32),
                                    nn.ReLU(),
                                    nn.MaxPool2d(2))
        self.fc = nn.Linear(7*7*32, 10)
    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.view(out.size(0), -1)
        out = self.fc(out)
        return out
cnnmodel = CNN()
#创建输出文件 output.txt
f = open(path + 'output.txt', 'w')
f.seek(0)
f.truncate()   #清空文件
#/********** Begin *********/
# 声明一个为交叉熵损失函数的变量criterion
criterion = nn.CrossEntropyLoss()
# 声明一个为Adam优化函数的变量optimizer,传入 cnn的参数,并使学习率lr为0.001
optimizer = torch.optim.Adam(cnnmodel.parameters(), lr=learning_rate)
# 训练模型
for i, (images, labels) in enumerate(train_loader):
    # 将images,labels数据转换为Variable类型
    images = Variable(images)
    labels = Variable(labels)
    
    # optimizer梯度归零
    optimizer.zero_grad()
    # 对 images 应用 cnnmodel 模型并赋值给变量 outputs
    outputs = cnnmodel(images)
    loss = criterion(outputs, labels)
    #Backward
    loss.backward()
    #Optimize
    optimizer.step()
    #共训练60次,分别100次输出一回loss信息,并将输出信息存到文件中
    if (i+1) % 10 == 0:
        f.writelines('Epoch [%d/%d], Iter [%d/%d] Loss: %.4f \n'
                     %(1, num_epochs, i+1, len(train_dataset)//1000, loss.data[0]))
        print ('Epoch [%d/%d], Iter [%d/%d] Loss: %.4f'
            %(1, num_epochs, i+1, len(train_dataset)//1000, loss.data[0]))
    if i > 60:
        break
f.close()
#/********** End *********/



第4关:测试保存模型

本关任务:本关提供了数据集MNIST中的测试数据test_dataset,并加载之前所训练的模型 cnnmodel,要求同学们将模型转化为测试模式,利用 cnnmodel计算预测值,输出预测精度。

import torch
import torch.nn as nn
import torchvision.datasets as dsets
from torch.utils.data import Dataset, DataLoader
import torchvision.transforms as transforms
from torch.autograd import Variable
import warnings
from PIL import Image
warnings.filterwarnings('ignore')
import os,sys
path = os.path.split(os.path.abspath(os.path.realpath(sys.argv[0])))[0] + os.path.sep
root = path[:-10]
#print("validation path:" ,root)
# MNIST Dataset
test_dataset = dsets.MNIST(root='./data/',
                           train=False,
                           transform=transforms.ToTensor(),
                           download=False)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                          batch_size=100,
                                          shuffle=True)
# CNN Model (2 conv layer)
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.layer1 = nn.Sequential(
                                    nn.Conv2d(1, 16, kernel_size=5, padding=2),
                                    nn.BatchNorm2d(16),
                                    nn.ReLU(),
                                    nn.MaxPool2d(2))
        self.layer2 = nn.Sequential(
                                    nn.Conv2d(16, 32, kernel_size=5, padding=2),
                                    nn.BatchNorm2d(32),
                                    nn.ReLU(),
                                    nn.MaxPool2d(2))
        self.fc = nn.Linear(7*7*32, 10)
    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.view(out.size(0), -1)
        out = self.fc(out)
        return out
cnnmodel = CNN()
#加载整个模型
cnnmodel = torch.load( root + 'src/step3/cnnModel.pkl')
#/********** Begin *********/
# Change model to 'eval' mode
cnnmodel.eval()
correct = 0
total = 0
i = 0
for images, labels in test_loader:
    images = Variable(images)
    #对images 应用cnn模型,将结果赋值给 outputs
    outputs = cnnmodel(images)
    _, predicted = torch.max(outputs.data, 1)
    total += labels.size(0)
    correct += (predicted == labels).sum()
    i += 1
    # 为了节约时间, 我们测试时只测试前10个
    if  i> 10 :
        break
#输出正确率correct/total 的百分比
print('Test Accuracy of the model on the 200 test images: %d %%' % (100 * correct / total))
#/********** End *********/

你可能感兴趣的:(深度学习框架,pytorch,神经网络,深度学习)