尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

GoolgeNet实战

GoolgeNet实战
📅 发布时间:2026/7/8 14:00:00

1.GoolgeNet代码分析

1.1Inception模块

class Inception(nn.Module): def __init__(self, in_channels, c1, c2, c3, c4): super(Inception, self).__init__() self.ReLU = nn.ReLU() # 路线1,单1×1卷积层 self.p1_1 = nn.Conv2d(in_channels=in_channels, out_channels=c1, kernel_size=1) # 路线2,1×1卷积层, 3×3的卷积 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,1×1卷积层, 5×5的卷积 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,3×3的最大池化, 1×1的卷积 self.p4_1 = nn.MaxPool2d(kernel_size=3, padding=1, stride=1) self.p4_2 = nn.Conv2d(in_channels=in_channels, out_channels=c4, kernel_size=1) def forward(self, x): p1 = self.ReLU(self.p1_1(x)) p2 = self.ReLU(self.p2_2(self.ReLU(self.p2_1(x)))) p3 = self.ReLU(self.p3_2(self.ReLU(self.p3_1(x)))) p4 = self.ReLU(self.p4_2(self.p4_1(x))) return torch.cat((p1, p2, p3, p4), dim=1)

这里Inception模块包含四条并行路径:

路径1:1×1卷积 (降维)路径2:1×1卷积 → 3×3卷积 (提取中等特征)

路径3:1×1卷积 → 5×5卷积 (提取大范围特征)

路径4:3×3最大池化 → 1×1卷积 (保留空间信息)

1.2GoogLeNet主体结构

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)) 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, (128, 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

其中这段是网络的参数初始化代码:

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)

这段代码就是遍历所有模块,判断是卷积层还是全连接层,然后进行相应的操作。

代码保证了卷积层使用适合ReLU的Kaiming初始化,所有偏置置于0,全连接层使用小标准差的正态分布初始化。

2.代码

#model 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,单1×1卷积层 self.p1_1 = nn.Conv2d(in_channels=in_channels, out_channels=c1, kernel_size=1) # 路线2,1×1卷积层, 3×3的卷积 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,1×1卷积层, 5×5的卷积 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,3×3的最大池化, 1×1的卷积 self.p4_1 = nn.MaxPool2d(kernel_size=3, padding=1, stride=1) self.p4_2 = nn.Conv2d(in_channels=in_channels, out_channels=c4, kernel_size=1) def forward(self, x): p1 = self.ReLU(self.p1_1(x)) p2 = self.ReLU(self.p2_2(self.ReLU(self.p2_1(x)))) p3 = self.ReLU(self.p3_2(self.ReLU(self.p3_1(x)))) p4 = self.ReLU(self.p4_2(self.p4_1(x))) return torch.cat((p1, p2, p3, p4), dim=1) 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)) 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, (128, 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 import copy import time import torch from torchvision.datasets import FashionMNIST from torchvision import transforms import torch.utils.data as Data import numpy as np import matplotlib.pyplot as plt from model import GoogLeNet, Inception import torch.nn as nn import pandas as pd def train_val_data_process(): train_data = FashionMNIST(root='./data', train=True, transform=transforms.Compose([transforms.Resize(size=224), transforms.ToTensor()]), download=True) 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): # 设定训练所用到的设备,有GPU用GPU没有GPU用CPU device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 使用Adam优化器,学习率为0.001 optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 损失函数为交叉熵函数 criterion = 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) # 初始化参数 # 训练集损失函数 train_loss = 0.0 # 训练集准确度 train_corrects = 0 # 验证集损失函数 val_loss = 0.0 # 验证集准确度 val_corrects = 0 # 训练集样本数量 train_num = 0 # 验证集样本数量 val_num = 0 # 对每一个mini-batch训练和计算 for step, (b_x, b_y) in enumerate(train_dataloader): # 将特征放入到训练设备中 b_x = b_x.to(device) # 将标签放入到训练设备中 b_y = b_y.to(device) # 设置模型为训练模式 model.train() # 前向传播过程,输入为一个batch,输出为一个batch中对应的预测 output = model(b_x) # 查找每一行中最大值对应的行标 pre_lab = torch.argmax(output, dim=1) # 计算每一个batch的损失函数 loss = criterion(output, b_y) # 将梯度初始化为0 optimizer.zero_grad() # 反向传播计算 loss.backward() # 根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值的作用 optimizer.step() # 对损失函数进行累加 train_loss += loss.item() * b_x.size(0) # 如果预测正确,则准确度train_corrects加1 train_corrects += torch.sum(pre_lab == b_y.data) # 当前用于训练的样本数量 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,输出为一个batch中对应的预测 output = model(b_x) # 查找每一行中最大值对应的行标 pre_lab = torch.argmax(output, dim=1) # 计算每一个batch的损失函数 loss = criterion(output, b_y) # 对损失函数进行累加 val_loss += loss.item() * b_x.size(0) # 如果预测正确,则准确度train_corrects加1 val_corrects += torch.sum(pre_lab == b_y.data) # 当前用于验证的样本数量 val_num += b_x.size(0) # 计算并保存每一次迭代的loss值和准确率 # 计算并保存训练集的loss值 train_loss_all.append(train_loss / train_num) # 计算并保存训练集的准确率 train_acc_all.append(train_corrects.double().item() / train_num) # 计算并保存验证集的loss值 val_loss_all.append(val_loss / val_num) # 计算并保存验证集的准确率 val_acc_all.append(val_corrects.double().item() / val_num) print("{} train loss:{:.4f} train acc: {:.4f}".format(epoch, train_loss_all[-1], train_acc_all[-1])) print("{} val loss:{:.4f} val acc: {:.4f}".format(epoch, 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), "C:/Users/86159/Desktop/LeNet/best_model.pth") torch.save(best_model_wts, "C:/Users/12072/Desktop/TEST/GoogLeNet/best_model.pth") train_process = pd.DataFrame(data={"epoch":range(num_epochs), "train_loss_all":train_loss_all, "val_loss_all":val_loss_all, "train_acc_all":train_acc_all, "val_acc_all":val_acc_all,}) return train_process 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, "bs-", label="Val loss") plt.legend() plt.xlabel("epoch") plt.ylabel("Loss") plt.subplot(1, 2, 2) plt.plot(train_process['epoch'], train_process.train_acc_all, "ro-", label="Train acc") plt.plot(train_process['epoch'], train_process.val_acc_all, "bs-", label="Val acc") plt.xlabel("epoch") plt.ylabel("acc") plt.legend() plt.show() if __name__ == '__main__': # 加载需要的模型 GoogLeNet = GoogLeNet(Inception) # 加载数据集 train_data, val_data = train_val_data_process() # 利用现有的模型进行模型的训练 train_process = train_model_process(GoogLeNet, train_data, val_data, num_epochs=20) matplot_acc_loss(train_process)
#model-test import torch import torch.utils.data as Data from torchvision import transforms from torchvision.datasets import FashionMNIST from model import GoogLeNet, Inception def test_data_process(): test_data = FashionMNIST(root='./data', train=False, transform=transforms.Compose([transforms.Resize(size=224), transforms.ToTensor()]), download=True) test_dataloader = Data.DataLoader(dataset=test_data, batch_size=1, shuffle=True, num_workers=0) return test_dataloader def test_model_process(model, test_dataloader): # 设定测试所用到的设备,有GPU用GPU没有GPU用CPU device = "cuda" if torch.cuda.is_available() else 'cpu' # 讲模型放入到训练设备中 model = model.to(device) # 初始化参数 test_corrects = 0.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() # 前向传播过程,输入为测试数据集,输出为对每个样本的预测值 output= model(test_data_x) # 查找每一行中最大值对应的行标 pre_lab = torch.argmax(output, dim=1) # 如果预测正确,则准确度test_corrects加1 test_corrects += torch.sum(pre_lab == test_data_y.data) # 将所有的测试样本进行累加 test_num += test_data_x.size(0) # 计算测试准确率 test_acc = test_corrects.double().item() / test_num print("测试的准确率为:", 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) # 设定测试所用到的设备,有GPU用GPU没有GPU用CPU device = "cuda" if torch.cuda.is_available() else 'cpu' model = model.to(device) classes = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot'] 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("预测值:", classes[result], "------", "真实值:", classes[label])

3.结果展示

model-train运行结果:

model-test运行结果:

相关新闻

  • AI助手系统架构设计:从自然语言处理到个性化对话管理
  • 又一个AI视频神器爆火!日更百条短视频不是梦
  • VLM增强的语义蒙特卡洛定位:让机器人真正看懂环境

最新新闻

  • 如何用ncmdump解锁网易云音乐加密文件?三步实现NCM文件解密
  • 后端Agent框架选型:LangChain、Spring AI与自研方案的工程对比
  • Python scikit-learn 1.4 实战:3种判别分析算法(距离/Fisher/贝叶斯)核心差异与代码对比
  • Mask R-CNN 与 YOLOv8-Seg 对比:实例分割掩模生成速度与mAP实测分析
  • 大疆智图 4.0 重建报告解读:5 个关键指标与 3 类精度问题排查
  • 机器学习实验报告的标准结构:从假设到结论的逻辑链条设计

日新闻

  • PROPKA 3深度解析:蛋白质pKa预测的实战指南与算法原理
  • 微信小程序 globalData 监听:基于 Object.defineProperty 的 3 种实现方案对比
  • MySQL 8.0 数据清洗实战:3类异常值识别与 UPDATE/DELETE 批量处理

周新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号