pytorch学习笔记(12)

# VGG  Nin


def vgg_block(num_convs, in_channels, out_channels):  # num_convs 是卷积层的数量,指定了该卷积块中包含多少个卷积层,in_channels 是输入通道数,指定了输入数据的通道数。out_channels 是输出通道数,指定了输出数据的通道数。
    layers = []  # 创建一个空列表,用于存储卷积块中的不同层。
    for _ in range(num_convs):
        layers.append(nn.Conv2d(in_channels, out_channels,
                                kernel_size=3, padding=1))
        layers.append(nn.ReLU())
        in_channels = out_channels  # 在每次循环结束后,将 in_channels 更新为 out_channels,以便下一个卷积层使用正确的输入通道数。
    layers.append(nn.MaxPool2d(kernel_size=2,stride=2))  # 最后,向 layers 列表中添加一个最大池化层
    return nn.Sequential(*layers)  # 最后,将创建的卷积块的各个层打包成一个 nn.Sequential 容器,以便将其作为一个整体使用。

与AlexNet、LeNet一样,VGG网络可以分为两部分:第一部分主要由卷积层和池化层组成,第二部分由全连接层组成。

下面的代码实现了VGG-11。

def vgg(conv_arch):  #conv_arch 是一个包含卷积块配置的列表。每个元素都是一个元组,包含两个值:
                                                      #num_convs 是卷积块中的卷积层数量。
                                                      #out_channels 是卷积块的输出通道数。
    conv_blks = []  # 创建一个空列表 conv_blks,用于存储VGG网络中的卷积块。
    in_channels = 1  # 初始化输入通道数为1,这适用于灰度图像输入。
    # 卷积层部分
    for (num_convs, out_channels) in conv_arch:
        conv_blks.append(vgg_block(num_convs, in_channels, out_channels))  # 调用 vgg_block 函数,根据卷积块配置创建一个卷积块,并将其添加到 conv_blks 列表中。
        in_channels = out_channels  # 更新 in_channels 为当前卷积块的输出通道数,以便将其作为下一个卷积块的输入通道数。

    return nn.Sequential(
        *conv_blks, nn.Flatten(),  # 卷积层输出的特征图展平成一维向量。
        # 全连接层部分
        nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5),  # 一个具有4096个隐藏单元的全连接层。
        nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),
        nn.Linear(4096, 10))  # 表示输出层,输出10个类别的分类结果。

net = vgg(conv_arch)

import torch
from torch import nn
from d2l import torch as d2l


def nin_block(in_channels, out_channels, kernel_size, strides, padding):
    return nn.Sequential(  # 创建了一个 nn.Sequential 容器,其中包含了一系列的卷积层和ReLU激活函数。
        nn.Conv2d(in_channels, out_channels, kernel_size, strides, padding),  # 卷积层
        nn.ReLU(),  # Relu激活函数
        nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU(),  # 卷积核大小为1的卷积层+激活函数
        nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU())  # 卷积核大小为1的卷积层+激活函数

NiN和AlexNet之间的一个显著区别是NiN完全取消了全连接层。NiN设计的一个优点是,它显著减少了模型所需参数的数量。然而,在实践中,这种设计有时会增加训练模型的时间。

Nin模型

net = nn.Sequential(
    nin_block(1, 96, kernel_size=11, strides=4, padding=0),  # 第一层NiN块,输入通道数为1,输出通道数为96,卷积核大小为11x11,步幅为4,没有填充。
    nn.MaxPool2d(3, stride=2),  # 第一个最大池化层,池化窗口大小为3x3,步幅为2。它用于降低特征图的空间维度。
    nin_block(96, 256, kernel_size=5, strides=1, padding=2),  # 第二层NiN块,输入通道数为96,输出通道数为256,卷积核大小为5x5,步幅为1,填充为2
    nn.MaxPool2d(3, stride=2),  # 第二个最大池化层,池化窗口大小为3x3,步幅为2。
    nin_block(256, 384, kernel_size=3, strides=1, padding=1),
    nn.MaxPool2d(3, stride=2),
    nn.Dropout(0.5),  # Dropout层,用于随机丢弃一部分神经元,以减少过拟合。
    # 标签类别数是10
    nin_block(384, 10, kernel_size=3, strides=1, padding=1),
    nn.AdaptiveAvgPool2d((1, 1)),  # 自适应平均池化层,用于将特征图的大小调整为1x1。
    # 将四维的输出转成二维的输出,其形状为(批量大小,10)
    nn.Flatten())  # 将四维的输出展平成二维的输出,其形状为(批量大小,10),其中10是标签类别数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值