GooLeNet模型搭建

一、model

python 复制代码
import torch
from torch import nn
from torchsummary import summary


class Inception(nn.Module):
    def __init__(self, in_channels, c1, c2 , c3 , c4):
        super(Inception, self).__init__()
        self.ReLU = nn.ReLU()
        #路线1:1x1卷积
        self.p1_1 = nn.Conv2d(in_channels = in_channels, out_channels = c1, kernel_size = 1)
        #路线2:1x1卷积->3x3卷积
        self.p2_1 = nn.Conv2d(in_channels = in_channels, out_channels = c2[0], kernel_size = 1)
        self.p2_2 = nn.Conv2d(in_channels = c2[0], out_channels = c2[1], kernel_size = 3, padding = 1)
        #路线3:1x1卷积->5x5卷积
        self.p3_1 = nn.Conv2d(in_channels = in_channels, out_channels = c3[0], kernel_size = 1)
        self.p3_2 = nn.Conv2d(in_channels = c3[0], out_channels = c3[1], kernel_size = 5, padding = 2)
        #路线4:3x3最大池化->1x1卷积
        self.p4_1 = nn.MaxPool2d(kernel_size = 3, stride = 1, padding = 1)
        self.p4_2 = nn.Conv2d(in_channels = in_channels, out_channels = c4, kernel_size = 1)


    #前向传播
    def forward(self, x):
        #路线1
        p1 = self.ReLU(self.p1_1(x))
        #路线2
        p2 = self.ReLU(self.p2_2(self.ReLU(self.p2_1(x))))
        #路线3
        p3 = self.ReLU(self.p3_2(self.ReLU(self.p3_1(x))))
        #路线4
        p4 = self.ReLU(self.p4_2(self.p4_1(x)))
        #拼接
        out = torch.cat((p1, p2, p3, p4), dim = 1)
        return out

class GoogLeNet(nn.Module):
    def __init__(self,Inception):
        super(GoogLeNet, self).__init__()
        self.b1 = nn.Sequential(
            nn.Conv2d(in_channels = 1,out_channels = 64,kernel_size=7,stride=2,padding = 3),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size = 3, stride = 2, padding = 1))

        self.b2 = nn.Sequential(
            nn.Conv2d(in_channels=64, out_channels=64, kernel_size=1),
            nn.ReLU(),
            nn.Conv2d(in_channels=64, out_channels=192, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        )
        #Inception模块
        self.b3 = nn.Sequential(
            Inception(192,64,(96,128),(16,32),32),
            Inception(256,128,(128,192),(32,96),64),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        )

        self.b4 = nn.Sequential(
            Inception(480,192,(96,208),(16,48),64),
            Inception(512,160,(112,224),(24,64),64),
            Inception(512,128,(128,256),(24,64),64),
            Inception(512,112,(144,288),(32,64),64),
            Inception(528,256,(160,320),(32,128),128),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        )

        self.b5 = nn.Sequential(
            Inception(832, 256, (160, 320), (32, 128), 128),
            Inception(832, 384, (192, 384), (48,128), 128),
            nn.AdaptiveAvgPool2d((1,1)),
            #平展层
            nn.Flatten(),
            nn.Linear(1024,10)
        )

        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)

                elif isinstance(m, nn.Linear):
                    nn.init.normal_(m.weight, 0, 0.01)
                    if m.bias is not None:
                        nn.init.constant_(m.bias, 0)
    def forward(self, x):
        x = self.b1(x)
        x = self.b2(x)
        x = self.b3(x)
        x = self.b4(x)
        x = self.b5(x)
        return x

if __name__ == '__main__':
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    model = GoogLeNet(Inception).to(device)
    print(summary(model,(1,224,224)))

二、model_train

python 复制代码
import copy
import time
from torchvision.datasets import FashionMNIST
import numpy as np
from torchvision import transforms
import torch.utils.data as Data
import matplotlib.pyplot as plt
from model import GoogLeNet,Inception
import torch
import pandas as pd


def train_val_data_process():
     # 数据预处理
    train_data = FashionMNIST(root='./data',
                              train=True,
                              download=True,
                              transform=transforms.Compose([transforms.Resize(size=224),transforms.ToTensor()]))

    # 数据集划分
    train_data,val_data = Data.random_split(train_data,[round(0.8*len(train_data)),round(0.2*len(train_data))])
    train_dataloader = Data.DataLoader(dataset=train_data,
                                       batch_size=32,
                                       shuffle=True, #数据打乱
                                       num_workers=2)

    val_dataloader = Data.DataLoader(dataset=val_data,
                                      batch_size=32,
                                      shuffle=True,
                                      num_workers=2)

    #返回数据集
    return train_dataloader,val_dataloader

# 训练模型
def train_model_process(model,train_dataloader,val_dataloader,num_epochs):

    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    #定义优化器,
    optimizer = torch.optim.Adam(model.parameters(),lr=0.001)
    #定义损失函数(交叉熵损失函数)
    criterion = torch.nn.CrossEntropyLoss()

    model = model.to(device)
    #复制当前模型的参数
    best_model_wts = copy.deepcopy(model.state_dict())
    #初始化参数
    best_acc = 0.0
    #训练集与验证集损失函数列表
    train_loss_all = []
    val_loss_all = []
    #训练集与验证集准确率列表
    train_acc_all = []
    val_acc_all = []

    since = time.time()

    for epoch in range(num_epochs):
        print('Epoch {}/{}'.format(epoch, num_epochs - 1))
        print('-' * 10)
        # 每个epoch都有训练集训练过程和验证集评估过程
        train_loss = 0.0
        train_corrects = 0
        val_loss = 0.0
        val_corrects = 0
        # 训练集与验证集样本数量
        train_num = 0
        val_num = 0

        for step,(b_x,b_y) in enumerate(train_dataloader):
            #将特征和标签数据放入GPU中
            b_x = b_x.to(device)
            b_y = b_y.to(device)
            #设置模型为训练模式
            model.train()
            #前向传播,输入为一个batch的特征数据,输出为预测的标签
            output = model(b_x)
            #查看每一行中最大值所在的位置,即预测的类别
            pre_lab = torch.argmax(output,dim=1)
            # 计算损失函数
            loss = criterion(output,b_y)

            #将梯度置零,因为PyTorch中梯度是累加的
            optimizer.zero_grad()
            #反向传播,计算梯度
            loss.backward()
            #根据网络反向传播的梯度更新网络参数,达到降低loss的目的
            optimizer.step()
            #计算训练集的损失
            train_loss = train_loss + loss.item() * b_x.size(0)

            train_corrects = train_corrects + torch.sum(pre_lab == b_y.data)

            train_num = train_num + b_x.size(0)

        for step,(b_x,b_y) in enumerate(val_dataloader):
            # 将特征和标签数据放入验证设备中
            b_x = b_x.to(device)
            b_y = b_y.to(device)
            # 设置模型为评估模式
            model.eval()
            # 前向传播,输入为一个batch的特征数据,输出为预测的标签
            output = model(b_x)
            #查看每一行中最大值所在的位置,即预测的类别
            pre_lab = torch.argmax(output,dim=1)
            # 计算损失函数
            loss = criterion(output,b_y)
            # 计算验证集的损失
            val_loss = val_loss + loss.item() * b_x.size(0)

            val_corrects = val_corrects + torch.sum(pre_lab == b_y.data)

            val_num = val_num + b_x.size(0)

        # 计算训练集与测试集每个epoch的损失和准确率
        train_loss_all.append(train_loss / train_num)
        train_acc_all.append(train_corrects.double() / train_num)

        val_loss_all.append(val_loss / val_num)
        val_acc_all.append(val_corrects.double() / val_num)

        # 打印训练集和验证集准确率
        print('Train Loss: {:.4f} Acc: {:.4f}'.format(train_loss_all[-1], train_acc_all[-1]))
        print('Val Loss: {:.4f} Acc: {:.4f}'.format(val_loss_all[-1], val_acc_all[-1]))

        if val_acc_all[-1] > best_acc: # 保存准确率最高的模型参数
            best_acc = val_acc_all[-1]
            #保存当前的最高准确度
            best_model_wts = copy.deepcopy(model.state_dict())
        #训练耗时
        time_use = time.time() - since
        print("训练和验证耗费的时间{:.0f}m{:.0f}s".format(time_use / 60,time_use % 60))

    #选择最优的模型参数
    #加载最高准确率的模型参数
    # model.load_state_dict(best_model_wts)
    # torch.save(model.load_state_dict(best_model_wts), 'best_model.pth')

    torch.save(best_model_wts, 'best_model.pth')

    train_porcess = pd.DataFrame(data = {
        'epoch':range(num_epochs),
        'train_loss_all':train_loss_all,
        'train_acc_all':train_acc_all,
        'val_loss_all':val_loss_all,
        'val_acc_all':val_acc_all
    })

    return train_porcess

def matplot_acc_loss(train_process):
    plt.figure(figsize=(12, 4))
    plt.subplot(1,2,1)
    plt.plot(train_process["epoch"],train_process["train_loss_all"],'ro-',label="train_loss")
    plt.plot(train_process["epoch"],train_process["val_loss_all"],'bo-',label="val_loss")
    plt.legend()
    plt.xlabel("epoch")
    plt.ylabel("loss")

    plt.figure(figsize=(12, 4))
    plt.subplot(1, 2, 1)
    plt.plot(train_process["epoch"], train_process["train_acc_all"], 'ro-', label="train_loss")
    plt.plot(train_process["epoch"], train_process["val_acc_all"], 'bo-', label="val_loss")
    plt.legend()
    plt.xlabel("epoch")
    plt.ylabel("acc")
    plt.show()


if __name__=='__main__':
    #模型实例化
    GoogLeNet = GoogLeNet(Inception)
    train_dataloader,val_dataloader = train_val_data_process()
    train_porcess = train_model_process(GoogLeNet, train_dataloader,val_dataloader,num_epochs=10)
    matplot_acc_loss(train_porcess)

三、model_test

python 复制代码
import torch
import torch.utils.data as Data
from torchvision import transforms
from torchvision.datasets import FashionMNIST
from model import GoogLeNet,Inception
import matplotlib.pyplot as plt
import numpy as np
import os
import time


def test_data_process():
    # 数据预处理
    test_data = FashionMNIST(root='./data',
                              train=False,
                              download=True,
                              transform=transforms.Compose([transforms.Resize(size=224), transforms.ToTensor()]))

    test_dataloader = Data.DataLoader(dataset=test_data,
                                       batch_size=1,
                                       shuffle=True,  # 数据打乱
                                       num_workers=2)
    return test_dataloader

#测试过程
def test_model_process(model,test_dataloader):
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    #将模型放入设备中
    model = model.to(device)
    #初始化参数
    test_corrects = 0
    test_num = 0
    #只进行前向传播,不计算梯度,节省内存,提高速度
    with torch.no_grad():
        for test_data_x,test_data_y in test_dataloader:
            test_data_x = test_data_x.to(device)
            test_data_y = test_data_y.to(device)
            #设置模型为评估模式
            model.eval()
            #前向传播,输入为测试数据集,输出为每个样本的预测值
            test_output = model(test_data_x)
            #获取预测值中最大值对应的索引,即预测的类别
            pre_lab = torch.argmax(test_output, 1)  #预测标签

            test_corrects += torch.sum(pre_lab == test_data_y.data)  #预测正确的数量
            test_num = test_num + test_data_y.size(0)  #测试样本数量

            #计算测试集的准确率
    test_acc = test_corrects.double().item() / test_num
    #打印测试集的准确率
    print('Test Accuracy: {:.4f}'.format(test_acc))

if __name__ == '__main__':
    model = GoogLeNet(Inception)
    #加载训练好的模型
    model.load_state_dict(torch.load('best_model.pth'))
    test_dataloader = test_data_process() #加载测试数据
    # test_model_process(model,test_dataloader) #测试模型

    #模型推理
    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    model = model.to(device)
    #将模型设置为评估模式
    with torch.no_grad():
        for b_x,b_y in test_dataloader:
            b_x = b_x.to(device)
            b_y = b_y.to(device)
            #模型设为验证模型
            model.eval()
            output = model(b_x)
            #获取预测值中最大值对应的索引,即预测的类别
            pre_lab = torch.argmax(output, dim = 1)  #预测标签
            result = pre_lab.item()
            label = b_y.item()

            #打印预测结果
            print('预测结果:',result,"--------","真实值:",label)
相关推荐
DogDaoDao17 分钟前
NNVC-17.1 深度解析:神经网络视频编码的最新进展与性能全景
神经网络·音视频·视频编解码·h266·vvc·vtm·nnvc
hhzz1 小时前
《深度学习框架PyTorch入门与实践》系列:09-分布式与并行训练之DataParallel、DDP与Horovod
pytorch·分布式·深度学习
心运软件2 小时前
基于深度学习的宝石图像分类系统
人工智能·python·深度学习·机器学习·分类·数据挖掘
雨晨源码(同名B站)2 小时前
【2027届人工智能专业选题】基于yolov8的农业病虫害图像识别与分类系统 |深度学习 计算机视觉
人工智能·深度学习·yolo·计算机视觉·分类
OpenApi.cc2 小时前
MoCode — AI Agent Server (Docker) + macOS Desktop Client(开源项目)
数据结构·人工智能·深度学习·神经网络
一个王同学2 小时前
从零到一 | CV转多模态大模型 | week22 | 实战项目-DocuMind-VL:基于 OCR 与 Qwen-VL 的文档多模态问答系统(二)
人工智能·深度学习·机器学习·计算机视觉·ocr
美狐美颜SDK开放平台2 小时前
第三方美颜SDK接入教程:直播APP实现实时美颜、滤镜与美型效果的方法
人工智能·深度学习·音视频·sdk·美颜sdk·视频美颜sdk·直播app开发
狂奔蜗牛(bradley)14 小时前
深度学习三大基础激活函数详解:Sigmoid、Tanh、ReLU 公式、导数、图像与优缺点对比
人工智能·深度学习
船厂电气自动化ai大模型15 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法