学习神经网络:搭建一个vgg-11模型在FashionMNIST训练

本文介绍了如何使用VGG-11的vgg_block函数设计和实现一个深度卷积神经网络,通过模块化结构展示其简洁性,并详细阐述了网络结构的调整和FashionMNIST数据集的应用。

 VGG-11 的模型如下:

根据上图设计vgg_block:

代码如下:

def vgg_block(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
    layers.append(nn.MaxPool2d(kernel_size=2,stride=2))
    return nn.Sequential(*layers)

 args:

1.num_convs:vgg块中的卷积层数

2.in_channels:卷积层输入通道数

3.out_channesl:卷积层输出通道数(即:卷积层中卷积核的个数)

返回一个nn.Sequential

根据vgg_block 实现vgg网络搭建:

代码如下:

def vgg (conv_arch):
    '''通过块嵌套块的形式搭建vgg网络'''
    vgg_blks=[]
    in_channels=1
    for num_conv,out_channels in conv_arch:
        vgg_blks.append(vgg_block(num_conv,in_channels,out_channels))
        in_channels=out_channels

    return nn.Sequential(*vgg_blks,#进入全连接层之前要展开tensor
                         nn.Flatten(),
                         nn.Linear(out_channels*7*7,4096),nn.ReLU(),nn.Dropout(0.5),
                         nn.Linear(4096,4096),nn.ReLU(),nn.Dropout(0.5),
                         nn.Linear(4096,10)
                         )

args:

conv_arch:整个vgg网络的vgg_block骨架,其中元素含有num_conv 和 out_channels

整体代码:

'''自定义一个vgg块'''
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torchvision import transforms



def try_gpu(i=0):
    '''尽量使用gpu提速'''
    if torch.cuda.device_count()>=i+1:
        return torch.device(f"cuda:{i}")
    else:
        return torch.device('cpu')

def vgg_block(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
    layers.append(nn.MaxPool2d(kernel_size=2,stride=2))
    return nn.Sequential(*layers)

'''原始vgg网络有5个卷积块,其中前两个各有一个卷积层,后三个块各包含两个卷积层。第一个模块有64个通道,
每个后续模块将输出通道数量翻倍,知道数字达到512.由于该网络使用8个卷积层和3个全连接层,因此它通常被称为vgg-11'''

conv_arch=((1,64),(1,128),(2,256),(2,512),(2,512))

#实现vgg-11。
def vgg (conv_arch):
    '''通过块嵌套块的形式搭建vgg网络'''
    vgg_blks=[]
    in_channels=1
    for num_conv,out_channels in conv_arch:
        vgg_blks.append(vgg_block(num_conv,in_channels,out_channels))
        in_channels=out_channels

    return nn.Sequential(*vgg_blks,#进入全连接层之前要展开tensor
                         nn.Flatten(),
                         nn.Linear(out_channels*7*7,4096),nn.ReLU(),nn.Dropout(0.5),
                         nn.Linear(4096,4096),nn.ReLU(),nn.Dropout(0.5),
                         nn.Linear(4096,10)
                         )

'''训练模型'''
ratio=4
#运用列表解析
small_conv_arch=[(pair[0],pair[1]//ratio)for pair in conv_arch]
net=vgg(small_conv_arch).to(try_gpu())

#下载数据集
train_data=torchvision.datasets.FashionMNIST('FashionMNIST',train=True,transform=torchvision.
                                             transforms.Compose([transforms.ToTensor(),transforms.Resize(224)]),
                                             download=True)
test_data=torchvision.datasets.FashionMNIST('FashionMNIST',train=False,transform=torchvision.
                                             transforms.Compose([transforms.ToTensor(),transforms.Resize(224)]),
                                             download=True)

#加载数据集
batch_size=128
train_loader=DataLoader(train_data,batch_size=batch_size)
test_loader=DataLoader(test_data,batch_size=batch_size)


#损失函数
loss_fn=nn.CrossEntropyLoss()

#优化器
lr=0.05
optimizer=torch.optim.SGD(net.parameters(),lr=lr)

#训练次数
epoch=10
total_train_step=0
total_test_step=0

#训练
for i in range(epoch):
    print(f"第{i}轮训练开始了")
    for data in train_loader:
        imgs , targets=data
        imgs=imgs.to(try_gpu())
        targets=targets.to(try_gpu())
        outputs=net(imgs)
        loss=loss_fn(outputs,targets)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        total_train_step=total_train_step+1
        if total_train_step%100==0:
            print(f"训练次数:{total_train_step},loss:{loss.item()}")

    #测试步骤
    total_test_loss=0
    total_accuracy=0
    with torch.no_grad():
        for data in test_loader:
            imgs,targets=data
            imgs=imgs.to(try_gpu())
            targets=targets.to(try_gpu())
            outputs=net(imgs)
            loss=loss_fn(outputs,targets)
            total_test_loss=total_test_loss+loss
            accuracy=(outputs.argmax(1)==targets).sum()
            total_accuracy=accuracy+total_accuracy

    print(f"整体测试集上的Loss:{total_test_loss}")
    print(f"整体测试集上的测试率:{total_accuracy/len(test_data)}")
    total_test_step=total_test_step+1




 小结:

1.VGG-11使用可复用的卷积块构造网络。不同的VGG模型可通过每个块中卷积层数量和输出通道数量的差异来定义

2.块的使用导致网络定义的非常简洁。使用块可以有效地设计复杂的网络。

3.在VGG论文中,Simonyan和iserman尝试了各种架构。特别是他们发现深层且窄的卷积(即3x3)比较浅层且宽的卷积更有效

### 如何使用卷积神经网络 (CNN) 搭建 VGG 模型 #### 架构详解 VGG 是一种经典的卷积神经网络结构,其核心思想是通过堆叠多层小尺寸的卷积核(通常是 \(3 \times 3\) 的卷积核),逐步加深网络层次来提升模型性能。这种设计不仅简化了网络参数的数量,还使得深层网络更容易实现和优化。 VGG 模型的主要特点包括: - 使用连续的小卷积核代替较大的卷积核,例如两个 \(3 \times 3\) 卷积核等效于一个 \(5 \times 5\) 卷积核的效果[^2]。 - 网络由多个卷积层组成,每组卷积层后面接有一个最大池化层用于降维。 - 后续连接全连接层以及 Softmax 输出层完成分类任务。 以下是基于 PyTorch 实现的一个简单 VGG-16 模型: ```python import torch.nn as nn import torch class VGG(nn.Module): def __init__(self, num_classes=10): # 默认设置为 FashionMNIST 数据集的类别数 super(VGG, self).__init__() # 定义卷积部分 self.features = nn.Sequential( # 第一层:两层卷积 + 最大池化 nn.Conv2d(1, 64, kernel_size=3, padding=1), nn.ReLU(True), nn.Conv2d(64, 64, kernel_size=3, padding=1), nn.ReLU(True), nn.MaxPool2d(kernel_size=2, stride=2), # 第二层:两层卷积 + 最大池化 nn.Conv2d(64, 128, kernel_size=3, padding=1), nn.ReLU(True), nn.Conv2d(128, 128, kernel_size=3, padding=1), nn.ReLU(True), nn.MaxPool2d(kernel_size=2, stride=2), # 第三层:四层卷积 + 最大池化 nn.Conv2d(128, 256, kernel_size=3, padding=1), nn.ReLU(True), nn.Conv2d(256, 256, kernel_size=3, padding=1), nn.ReLU(True), nn.Conv2d(256, 256, kernel_size=3, padding=1), nn.ReLU(True), nn.MaxPool2d(kernel_size=2, stride=2), # 第四层:四层卷积 + 最大池化 nn.Conv2d(256, 512, kernel_size=3, padding=1), nn.ReLU(True), nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(True), nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(True), nn.MaxPool2d(kernel_size=2, stride=2), # 第五层:四层卷积 + 最大池化 nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(True), nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(True), nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(True), nn.MaxPool2d(kernel_size=2, stride=2) ) # 定义全连接层部分 self.classifier = nn.Sequential( nn.Linear(512 * 1 * 1, 4096), # 输入大小取决于输入图片分辨率 nn.ReLU(True), nn.Dropout(), nn.Linear(4096, 4096), nn.ReLU(True), nn.Dropout(), nn.Linear(4096, num_classes) ) def forward(self, x): x = self.features(x) x = x.view(x.size(0), -1) # 展平操作 x = self.classifier(x) return x # 创建模型实例并打印结构 model = VGG(num_classes=10) print(model) ``` 上述代码定义了一个适用于 FashionMNIST 数据集的简化版 VGG-16 模型。该模型保留了原版 VGG 的主要特性,同时调整了一些超参以适应较小规模的数据集[^1]。 #### 示例代码说明 1. **卷积层**:每一组卷积层之后都跟有一个 `MaxPool2d` 进行下采样,减少计算量的同时保持重要特征。 2. **激活函数**:采用 ReLU 函数作为非线性变换单元,加速收敛过程。 3. **全连接层**:最后三个全连接层负责将高层抽象特征映射到具体的类标签上。 4. **Dropout**:防止过拟合,在训练阶段随机丢弃一部分神经元。 此代码可以根据实际需求进一步扩展或修改,比如支持更大的数据集或者更高的分辨率图像[^3]。 --- ####
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值