【PyTorch】高级神经网络结构

本文是PyTorch学习笔记,深入探讨卷积神经网络(CNN)和循环神经网络(RNN),包括CNN的卷积、池化、结构,RNN的LSTM模型以及在序列数据上的应用。通过实例展示了CNN和RNN在图像识别和序列预测中的应用。
摘要由CSDN通过智能技术生成

本文为 PyTorch 学习笔记,讲解高级神经网络结构。欢迎在评论区与我交流 😀

CNN

简介

卷积神经网络简写为 CNN。卷积的意思是不再对每个像素的信息做处理,而是对一小块像素区域的信息做处理。这种做法加强了图片信息的连续性,使得神经网络能够看到图形而非一个点,也加深了神经网络对图片的理解。

在这里插入图片描述

具体来说,如上图,神经网络的批量过滤器在图片上滚动收集信息,每次只收集一小块像素区域,然后进行整理,此时神经网络能看到边缘的图片信息,继续扫过边缘信息总结更高层的信息结构,可以画出眼睛鼻子等,再经过一次过滤,脸部信息从这些信息中被总结出来。最后放入全连接神经网络进行分类。

在每次卷积时,神经层会无意中丢失一些信息(角上的信息),池化可以解决这个问题。在每次卷积时不进行压缩,尽量保留更多的信息,把压缩的任务交给池化。能有效地提高准确性。

比较经典的结构是,输入图片,经过一层卷积层,再用最大池化处理卷积信息。然后经过一次同样的处理,将这次的信息传入两层全连接的神经层。最后再接一个分类器进行分类预测。

关于卷积神经网络的详细内容见【卷积神经网络】。

实践

我们使用 MNIST 上的数据集进行训练,构建卷积神经网络对手写数字进行识别。

首先引入我们需要的模块:

pimport os
import torch
import torch.nn as nn # 简化书写格式
import torch.utils.data as Data
import torchvision      # 数据库模块
import matplotlib.pyplot as plt

然后进行超参数的设置:

EPOCH = 1 # 训练整批数据多少次, 为了节约时间只训练一次
BATCH_SIZE = 50 # mini-batch
LR = 0.001          # 学习率
DOWNLOAD_MNIST = True  # 如果你已经下载好了mnist数据就写上False

从 MNIST 上下载手写数据集:

# Mnist digits dataset
if not(os.path.exists('./mnist/')) or not os.listdir('./mnist/'):
    # not mnist dir or mnist is empyt dir
    DOWNLOAD_MNIST = True

train_data = torchvision.datasets.MNIST(
    root='./mnist/',    # 保存或者提取位置
    train=True,  # True返回6w个训练集。如果是False则返回test_data,有1w个
    # 转换PIL.Image或numpy.ndarray成orch.FloatTensor(C x H x W)
    # 训练的时候归一化成[0.0, 1.0]区间,彩色图像为0-255,这里使用灰度图
    transform=torchvision.transforms.ToTensor(),
    download=DOWNLOAD_MNIST,# 没下载就下载, 下载了就不用再下了
)

运行程序后,可以看到正在下载数据:

ahBqiR.png

可以看到数据成功下载到当前目录下:

在这里插入图片描述

我们绘制出 train_data

print(train_data.data.size()) # (60000, 28, 28)
print(train_data.targets.size()) # (60000)
# 画出train_data第一张图片
plt.imshow(train_data.data[0].numpy(), cmap='gray')
plt.title('%i' % train_data.targets[0])
plt.show()

得到第一张图片为:

在这里插入图片描述

使训练变成小批,图像维度为 (50, 1, 28, 28)

train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)

创建测试数据集,为了节约时间, 我们测试时只测试前 2000 个,手动将深度压缩成 0-1 之间:

test_data = torchvision.datasets.MNIST(root='./mnist/', train=False)
test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_y = test_data.test_labels[:2000]

建立 CNN 网络,定义 2 个卷积层和 1 个全连接层:

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Sequential(  # 输入维度(1, 28, 28),第一维为通道
            nn.Conv2d(
                in_channels=1,      # 输入图像的高度,灰度图为1
                out_channels=16,    # 输出图像的深度,即过滤器的个数
                kernel_size=5,      # 过滤器size为5×5
                stride=1,           # 步幅
                padding=2,      # 设置padding,使得长宽不变
            ),      # 输出维度(16, 28, 28)
            nn.ReLU(),    # 激活函数
            nn.MaxPool2d(kernel_size=2), # 输出维度(16, 14, 14),长宽减小1倍
        )
        self.conv2 = nn.Sequential(  # 输入维度(16, 14, 14)
            nn.Conv2d(16, 32, 5, 1, 2),  # 输出维度(32, 14, 14)
            nn.ReLU(),  # 激活函数
            nn.MaxPool2d(2),  # 输出维度(32, 7, 7),减小了1倍
        )
        self.out = nn.Linear(32 * 7 * 7, 10)   # 全连接层, 10类

将神经网络输出的数据展开,并输出结果:

class CNN(nn.Module):
    ...
	def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x) # (batch, 32, 7, 7)
        x = x.view(x.size(0), -1) # 展平多维的卷积图成 (batch_size, 32 * 7 * 7)
        output = self.out(x)
        return output

cnn = CNN()
print(cnn)

得到的神经网络结构为:

在这里插入图片描述

用优化器进行优化,这里使用 Adam 优化器:

optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)   # optimize all cnn parameters
loss_func = nn.CrossEntropyLoss()   # the target label is not one-hotted

使用 sklearn 进行可视化(可选):

# following function (plot_with_labels) is for visualization, can be ignored if not interested
from matplotlib import cm
try: from sklearn.manifold import TSNE; HAS_SK = True
except: HAS_SK = False; print('Please install sklearn for layer visualization')
def plot_with_labels(lowDWeights, labels):
    plt.cla()
    X, Y = lowDWeights[:, 0], lowDWeights[:, 1]
    for x, y, s in zip(X, Y, labels):
        c = cm.rainbow(int(255 * s / 9)); plt.text(x, y, s, backgroundcolor=c, fontsize=9)
    plt.xlim(
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值