【神经网络与深度学习】 Pytorch实现卷积神经网络

1、实验名称

Pytorch实现卷积神经网络

2、实验要求

用 python 的 Pytorch 模块实现卷积神经网络。网络结构为一个输入层、两个卷积层、一个全连接层、一个输出层。

3、实验目的

  • 熟悉并掌握pytorch框架
  • 掌握卷积神经网络的基本原理
  • 掌握卷积神经网络的结构
  • 掌握卷积神经网络的代码流程

4、实验过程

本次实验完全在itc的虚拟环境中操作并且运行。为了突出重点,操作流程不再赘述,对编程流程进行详细地描述。

首先是输入的图片, 经过一层卷积层, 然后在用池化方式处理卷积的信息, 然后再经过一次同样的处理, 把得到的第二次处理的信息传入全连接的神经层,最后在接上一个分类器进行分类预测。

详细流程:

  • 将图片转换为张量,并进行归一化处理。
  • 下载训练集和测试集。
  • 构建数据集和测试集的DataLoader。
  • 定义网络结构。

  • 将模型转换到device中,并将其结构显示出来。
  • 定义交叉熵损失函数。
  • 将图像和标签传输进device中。
  • 清空模型的梯度。
  • 对模型进行前向运行。
  • 计算本轮的损失。
  • 计算本轮的准确率。
  • 进行反向传播求出模型参数的梯度。
  • 使用迭代器更新模型权重。
  • 将结果进行可视化处理。
  • 重复以上7-14过程直到达到指定迭代次数。
  • 计算总测试的平均准确率。
  • 计算总测试的平均损失。

5、实验结果

6、实验总结

卷积神经网络相比与上次实验的全连接神经网络增加了卷积层和池化层,与此同时,不再是全连接,而是局部连接,并且采用了权值共享的策略。其中,局部连接和权值共享降低了参数的规模,使训练的复杂度大大下降并且减轻了过拟合,池化层的降采样则进一步降低了输出的参数规模,提高了模型的泛化能力。

入门卷积神经网络其实并不难,但是想在这个领域学深学精还是需要花费一定时间和精力的。在学习卷积神经网络时需要多了解几种网络结构,由浅入深,思考为什么这么做,这么做的好处和意义。多实践多动手,不仅可以让我们对卷积神经网络的流程有更加深刻的了解和掌握,而且可以让我们打好坚实的基础,更有基础和实力去深入钻研。

7、源码

import torch
from torch import nn
import torchvision
from tqdm import tqdm
torch.cuda.is_available()
BATCH_SIZE = 100
EPOCHS = 10

learning_rate = 1e-4
keep_prob_rate = 0.7
device = "cuda:0" if torch.cuda.is_available() else "cpu"

transform = torchvision.transforms.Compose(
    [torchvision.transforms.ToTensor(),
     torchvision.transforms.Normalize(mean = [0.5], std = [0.5])]m
)

path = './data/'
trainData =  torchvision.datasets.MNIST(
    path, train = True, transform = transform, download= True
)

testData = torchvision.datasets.MNIST(
    path, train = False, transform = transform
)

trainDataLoader = torch.utils.data.DataLoader(
    dataset = trainData, batch_size = BATCH_SIZE,shuffle = True
)

testDataLoader = torch.utils.data.DataLoader(
    dataset = testData, batch_size = BATCH_SIZE
)

class Net(torch.nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.model = torch.nn.Sequential(
            torch.nn.Conv2d(
                in_channels=1,out_channels=32,
                kernel_size=7,padding=3,stride=1
            ),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(
                kernel_size=2,stride=2
            ),
            torch.nn.Conv2d(
                in_channels=32,out_channels=64,
                kernel_size=5,stride=1,padding=2
            ),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(
                kernel_size=2,stride=2
            ),
            torch.nn.Flatten(),

            torch.nn.Linear(in_features=7*7*64, out_features= 1024),
            torch.nn.ReLU(),
            torch.nn.Dropout(1-keep_prob_rate),
            torch.nn.Linear(in_features=1024,out_features=10),
            torch.nn.Softmax(dim=1)

        )

    def forward(self, input):
        output = self.model(input)
        return output


net = Net()
print(net.to(device))
lossF = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(params=net.parameters(),lr=learning_rate)
history = {'Test Loss':[], 'Test Accuracy':[]}
for epoch in range(1,EPOCHS+1):
    processBar = tqdm(trainDataLoader,unit='step')
    net.train(True)
    for step,(trainImgs, labels) in enumerate(processBar):
        trainImgs = trainImgs.to(device)
        labels = labels.to(device)
        net.zero_grad()
        outputs = net(trainImgs)
        loss = lossF(outputs,labels)
        predictions = torch.argmax(outputs,dim=1)
        accuracy = torch.sum(predictions==labels)/labels.shape[0]
        loss.backward()
        optimizer.step()
        processBar.set_description(
            "[%d/%d] Loss: %.4f, Acc: %.4f" %(
            epoch,EPOCHS,loss.item(),accuracy.item()
            )
        )

        if step == len(processBar)-1:
            correct, totalLoss = 0,0
            net.train(False)
            for testImgs,labels in testDataLoader:
                testImgs = testImgs.to(device)
                labels = labels.to(device)
                outputs = net(testImgs)
                loss = lossF(outputs,labels)
                predicions = torch.argmax(outputs,dim=1)
                totalLoss+=loss
                correct+=torch.sum(predicions==labels)
                testAccuracy = correct/(BATCH_SIZE*len(testDataLoader))
                testLoss = totalLoss/len(testDataLoader)
                history['Test Loss'].append(testLoss.item())
                history['Test Accuracy'].append(testAccuracy.item())
                processBar.set_description(
                    "[%d/%d] Loss: %.4f, Acc: %.4f, Test Loss: %.4f, Test Acc: %.4f" % (
                        epoch,EPOCHS,loss.item(),accuracy.item(),
                        testLoss.item(),testAccuracy.item()
                    )
                )
    processBar.close()

猜你喜欢

转载自blog.csdn.net/CE00001/article/details/127813248