从零自建pytorch GPU训练的vgg16 resnet50 inceptionv1的分别识别,训练自己的数据集

应付深度学习期末三级项目,突发奇想从0构建模型,花费四天写训练,测试。由于基本是纯手写调试打印搭建出来,所以未必代码写的很流畅,欢迎大家改进完善。

一、Vgg16搭建

首先写的第一个网络是VGG16,按照书上的定义手写网络,下图是官方定义

        可以看出Vgg16的网络结构非常简单,由13个卷积层加3个全连接层组成,输入224*224的三通道图片。非常纯的网络,卷积->激活函数->池化。最后拉成一维排列以进行全连接输出。其中一定要加入BN!!!!,否则模型训练效果极差且不收敛,BN为批归一化将图像数值压缩至0-1之间,BN的作用是加速训练,提升模型泛化能力,实际测试是必不可少的模块。

代码如下

from torch import nn
# -----------------------------------------------#
#  2024.10.14
#  自建base VGG16
# -----------------------------------------------#
class VGG16(nn.Module):
    def __init__(self, num_classes):
        super(VGG16, self).__init__()

        self.conv = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 128, kernel_size=3, padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            nn.Conv2d(128, 256, kernel_size=3, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            nn.Conv2d(256, 512, kernel_size=3, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
        )

        self.dense = nn.Sequential(
            nn.Flatten(),
            nn.Linear(512 * 7 * 7, 4096),
            nn.Dropout(0.4),
            nn.ReLU(inplace=True),
            nn.Linear(4096, 4096),
            nn.Dropout(0.4),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes)

        )

    def forward(self, x):
        x = self.conv(x)
        x = self.dense(x)

        return x
################################################################################
# 测试模型
# model = VGG16(num_classes=2)
# input_tensor = torch.randn(1, 3, 224, 224)  # 假设输入为一张 224x224 的 RGB 图像
# output = model(input_tensor)
# print(output.shape)  # 输出的形状应为 (1, 2)
# print(output)
################################################################################

二、Resnet50

resnet精髓在于引入了残差连接,缓解了梯度消失的问题,通过坐“电梯”连接输入输出联动

在层数逐层加深的情况反向传播时梯度会无线趋近于0,比如第一层0.1,第二层0.01,以此类推趋近0梯度消失,但是如果此时将输入1加入,1+趋向0,此时梯度不为0。这块可以看下反向传播,推导下。

书上定义如下

两种残差连接结构图

模型参数的计算=3*3*64*64+3*3*64*64

模型参数的计算=1*1*256*64+3*3*64*64+1*1*64*256

import torch
import torch.nn as nn

# -----------------------------------------------#
#   2024.10.22
#   resnet50                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
# -----------------------------------------------#

# 定义Residual Block
class ResidualBlock(nn.Module):
    def __init__(self, in_channels, out_channels, stride=1, downsample=None):
        super(R
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值