简单记录GoogLeNet网络,pytorch+GoogLeNet+CIFAR10

目录

数据集

Net

uilt

train

 总结


数据集

数据集使用的是CIFAR10,cifar 10 这个数据集一共有 50000 张训练集,10000 张测试集,两个数据集里面的图片都是 png 彩色图片,图片大小是 32 x 32 x 3,一共是 10 分类问题,分别为飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船和卡车。这个数据集是对网络性能测试一个非常重要的指标,可以说如果一个网络在这个数据集上超过另外一个网络,那么这个网络性能上一定要比另外一个网络好,目前这个数据集最好的结果是 95% 左右的测试集准确率。
 

from torchvision.datasets import CIFAR10
import torch
import cv2
import numpy as np

def data_tf(x):
    x = np.array(x, dtype='float32') / 255
    x = (x - 0.5) / 0.5  # 标准化,这个技巧之后会讲到
    x = cv2.resize(x, (224, 224))
    x = x.transpose((2, 0, 1))  # 将 channel 放到第一维,只是 pytorch 要求的输入方式
    x = torch.from_numpy(x)
    return x

##下载数据集
train_set = CIFAR10('./data', train=True, transform=data_tf, download=False)
test_set = CIFAR10('./data', train=False,  transform=data_tf, download=False)

Net

这是GoogLeNet的网络结构

class BasicConv2d(nn.Module):
    def __init__(self,in_channels, out_channels, kernel, stride=1, padding=0):
        super(BasicConv2d, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels,
                              kernel_size=kernel, stride=stride, padding=padding,
                              bias=False)
        self.bn = nn.BatchNorm2d(out_channels, eps=0.001)

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        return F.relu(x, inplace=True)

'''
in_channels         输入数据的通道
out_channels_1x1    1*1卷积深度
out_channels_1x1_3  3*3前面的1*1卷积深度
out_channels_3x3    3*3卷积深度
out_channels_1x1_5  5*5前面的1*1卷积深度
out_channels_5x5    5*5卷积深度
out_channels_pool   池化后面的1*1卷积深度
'''
class Inception(nn.Module):
    def __init__(self, in_channels, out_channels_1x1,
                 out_channels_1x1_3,  out_channels_3x3,
                 out_channels_1x1_5, out_channels_5x5,
                 out_channels_pool ):
        super(Inception, self).__init__()
        ##第一条线
        self.branch1x1 = BasicConv2d(in_channels, out_channels_1x1, 1)

        ##第二条线
        self.branch3x3 = nn.Sequential(
            BasicConv2d(in_channels, out_channels_1x1_3, 1),
            BasicConv2d(out_channels_1x1_3, out_channels_3x3, 3, 1, 1)
        )

        ##第三条线
        self.branch5x5 = nn.Sequential(
            BasicConv2d(in_channels, out_channels_1x1_5, 1),
            BasicConv2d(out_channels_1x1_5, out_channels_5x5, 5, 1, 2)
        )

        ##第四条线
        self.branch_pool = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
            BasicConv2d(in_channels, out_channels_pool, 1)
        )

    def forward(self, x):
        branch1x1 = self.branch1x1(x)

        branch3x3 = self.branch3x3(x)

        branch5x5 = self.branch5x5(x)

        branch_pool = self.branch_pool(x)

        output = [branch1x1, branch3x3, branch5x5, branch_pool]
        return torch.cat(output, 1)
    
class GoogLeNet(nn.Module):
    def __init__(self, in_channels, num_class):
        super(GoogLeNet, self).__init__()
        ##第 1 个模块
        self.block1 = nn.Sequential(
            nn.Conv2d(in_channels, 64, 7, 2, 3),
            nn.MaxPool2d(3, 2, 1)
        )
        ##第 2 个模块
        self.block2 = nn.Sequential(
            nn.Conv2d(64, 192, 3, 1, 1),
            nn.Conv2d(192, 192, 3, 1, 1),
            nn.MaxPool2d(3, 2, 1)
        )
        ##第 3 个模块
        self.block3 = nn.Sequential(
            Inception(192, 64, 96, 128, 16, 32, 32),
            Inception(256, 128, 128, 192, 32, 96, 64),
            nn.MaxPool2d(3, 2, 1)
        )
        ##第 4 个模块
        self.block4 = 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(3, 2, 1)
        )
        ##第 4 个模块
        self.block5 = nn.Sequential(
            Inception(832, 256, 160, 320, 32, 128, 128),
            Inception(832, 384, 192, 384, 48, 128, 128),
            nn.AvgPool2d(7, 1)
        )
        self.classifier = nn.Sequential(
            nn.Dropout(0.4),
            nn.Linear(1024, num_class),
            # nn.Sigmoid(1024,out_channels)
        )

    def forward(self, x):
        x = self.block1(x)
        x = self.block2(x)
        x = self.block3(x)
        x = self.block4(x)
        x = self.block5(x)

        x = torch.reshape(x, (x.shape[0], -1))
        x = self.classifier(x)

        return x

详细内容可以查看我这篇博客

简单记录一下,几个经典的网络结构_子根的博客-CSDN博客

 接下来是把训练的代码模块化在uilt中

uilt

#  开发人员:    骆根强
#  开发时间:    2022/7/30 10:50
#  功能作用:    未知

import torch
import time
import tqdm

from torch.autograd import Variable

'''
参数介绍:
epoches, 训练几轮
train_data, 训练的数据
model, 训练模型
device, 使用的设备是
criterion, 损失函数
optimizer, 优化函数
pth_name    参数文件的名字
'''

def train(epoches, train_data, model, device, criterion, optimizer, pth_name):
    # 开始训练
    losses_men = []
    acces_men = []

    start = time.time()
    for epoche in range(epoches):
        train_loss = 0
        train_acc = 0
        time1 = time.time()
        print()
        print(f'开始,第 {epoche + 1} / {epoches} 个Epoche中:')
        for image_data, image_label in tqdm.tqdm(train_data):
            image_data = Variable(image_data.to(device))
            image_label = Variable(image_label.to(device))

            ##前向传播
            out = model(image_data)
            loss = criterion(out, image_label)
            # print(out.shape)
            ##反向传播
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            ##记录误差
            train_loss += loss.item()

            ##记录准确率
            _, pred_label = out.max(1)
            num_correct = (pred_label == image_label).sum().item()  ##计算每次batch_size正确的个数
            acc = num_correct / out.shape[0]
            train_acc += acc

        losses_men.append(train_loss / len(train_data))
        acces_men.append(train_acc / len(train_data))
        time2 = time.time()

        torch.save(model.state_dict(), f'./params/{pth_name}_{epoches}.pth')

        print(f'Epoch_time : ', time2 - time1)
        print()
        print('train_loss : ', losses_men)
        print()
        print('train_acc : ', acces_men)

    print(f'All time : {int((time.time() - start) / 3600)} H '
          f'{int((time.time() - start) / 60)} m {int((time.time() - start) % 60)} s  ')

然后就进行完整的训练过程

train

import torch
import cv2
import numpy as np
import torch.nn as nn

import four_net
import uilt

from torchvision.datasets import CIFAR10
from torch.utils.data import DataLoader
from torch import optim

##定义一些参数
epoches = 1
batch_size = 3
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

def data_tf(x):
    x = np.array(x, dtype='float32') / 255
    x = (x - 0.5) / 0.5  # 标准化,这个技巧之后会讲到
    x = cv2.resize(x, (224, 224))
    x = x.transpose((2, 0, 1))  # 将 channel 放到第一维,只是 pytorch 要求的输入方式
    x = torch.from_numpy(x)
    return x

##下载数据集
train_set = CIFAR10('./data', train=True, transform=data_tf, download=False)
test_set = CIFAR10('./data', train=False,  transform=data_tf, download=False)

train_data = DataLoader(train_set, batch_size=batch_size, shuffle=True)
test_data = DataLoader(test_set, batch_size=batch_size, shuffle=False)

model = four_net.GoogLeNet(3,10).to(device)

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=1e-1)

print()
print('目前使用的是: ', device)
uilt.train(epoches, train_data, model, device, criterion, optimizer, pth_name='googlenet'

 总结

****************************************************************************************************************************************************************************************************************************

train_acc :  [0.4877117966751918, 0.7165121483375959, 0.8027293797953964, 0.8466272378516624, 0.8776974104859335, 0.9011149296675192, 0.9178388746803069, 0.9341432225063938, 0.9479699488491049, 0.9559223145780051, 0.9642543158567775, 0.9674312659846548, 0.9730458759590793, 0.9789402173913043, 0.9809782608695652, 0.984934462915601, 0.9881713554987213, 0.9888507033248082, 0.9883112212276215, 0.9879515664961637, 0.9934063299232737, 0.9944453324808185, 0.9930466751918159, 0.9949048913043478, 0.9937859654731458, 0.9963834718670077, 0.9977221867007673, 0.998321611253197, 0.9973025895140665, 0.9927070012787724]

画出准确度曲线:
 

import matplotlib.pyplot as plt
acces_men = [0.4877117966751918, 0.7165121483375959, 0.8027293797953964, 
             0.8466272378516624, 0.8776974104859335, 0.9011149296675192, 
             0.9178388746803069, 0.9341432225063938, 0.9479699488491049, 
             0.9559223145780051, 0.9642543158567775, 0.9674312659846548, 
             0.9730458759590793, 0.9789402173913043, 0.9809782608695652, 
             0.984934462915601, 0.9881713554987213, 0.9888507033248082, 
             0.9883112212276215, 0.9879515664961637, 0.9934063299232737, 
             0.9944453324808185, 0.9930466751918159, 0.9949048913043478, 
             0.9937859654731458, 0.9963834718670077, 0.9977221867007673, 
             0.998321611253197, 0.9973025895140665, 0.9927070012787724]

###画出LOSS曲线和准确率曲线
plt.plot(np.arange(len(acces_men)), acces_men, label ='train acc')
plt.show()

 

GoogLeNet模型训练的收敛速度比VGG还快,光是第一个epoch,准确率就达到了0.3,要知道VGG(经过BatchNorm1d)是经过了第三个epoch才超过0.3的,如果Vgg没有BatchNorm1d那就是个弟弟,经过20轮的训练精确度连0.1都达不到

GoogLeNet经过20轮精确度高到99%

最后,老婆压场

喜欢的话,给我老婆点个赞吧☺

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于GoogLeNet的CIFAR-10数据集的网络结构示例代码,使用PyTorch实现: ```python import torch.nn as nn import torch.nn.functional as F class Inception(nn.Module): def __init__(self, in_channels, ch1x1, ch3x3red, ch3x3, ch5x5red, ch5x5, pool_proj): super(Inception, self).__init__() # 1x1 conv branch self.branch1 = nn.Sequential( nn.Conv2d(in_channels, ch1x1, kernel_size=1), nn.BatchNorm2d(ch1x1), nn.ReLU(inplace=True) ) # 1x1 conv -> 3x3 conv branch self.branch2 = nn.Sequential( nn.Conv2d(in_channels, ch3x3red, kernel_size=1), nn.BatchNorm2d(ch3x3red), nn.ReLU(inplace=True), nn.Conv2d(ch3x3red, ch3x3, kernel_size=3, padding=1), nn.BatchNorm2d(ch3x3), nn.ReLU(inplace=True) ) # 1x1 conv -> 5x5 conv branch self.branch3 = nn.Sequential( nn.Conv2d(in_channels, ch5x5red, kernel_size=1), nn.BatchNorm2d(ch5x5red), nn.ReLU(inplace=True), nn.Conv2d(ch5x5red, ch5x5, kernel_size=5, padding=2), nn.BatchNorm2d(ch5x5), nn.ReLU(inplace=True) ) # 3x3 pool -> 1x1 conv branch self.branch4 = nn.Sequential( nn.MaxPool2d(kernel_size=3, stride=1, padding=1), nn.Conv2d(in_channels, pool_proj, kernel_size=1), nn.BatchNorm2d(pool_proj), nn.ReLU(inplace=True) ) def forward(self, x): branch1 = self.branch1(x) branch2 = self.branch2(x) branch3 = self.branch3(x) branch4 = self.branch4(x) outputs = [branch1, branch2, branch3, branch4] return torch.cat(outputs, 1) class GoogLeNet(nn.Module): def __init__(self): super(GoogLeNet, self).__init__() self.conv1 = nn.Conv2d(3, 64, kernel_size=3, padding=1) self.bn1 = nn.BatchNorm2d(64) self.inception1 = Inception(64, 64, 96, 128, 16, 32, 32) self.inception2 = Inception(256, 128, 128, 192, 32, 96, 64) self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) self.inception3 = Inception(480, 192, 96, 208, 16, 48, 64) self.inception4 = Inception(512, 160, 112, 224, 24, 64, 64) self.inception5 = Inception(512, 128, 128, 256, 24, 64, 64) self.inception6 = Inception(512, 112, 144, 288, 32, 64, 64) self.inception7 = Inception(528, 256, 160, 320, 32, 128, 128) self.avgpool = nn.AdaptiveAvgPool2d((1,1)) self.dropout = nn.Dropout(p=0.4) self.fc = nn.Linear(832, 10) def forward(self, x): x = F.relu(self.bn1(self.conv1(x))) x = self.maxpool(x) x = self.inception1(x) x = self.inception2(x) x = self.maxpool(x) x = self.inception3(x) x = self.inception4(x) x = self.inception5(x) x = self.inception6(x) x = self.inception7(x) x = self.avgpool(x) x = x.view(x.size(0), -1) x = self.dropout(x) x = self.fc(x) return x ``` 这里使用了Inception模块和多个Inception模块的堆叠,与GoogLeNet的结构类似。同时,也使用了BatchNorm和Dropout等技术来提高模型的性能和泛化能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值