CNN典型模型及pytorch实现 —— AlexNet

AlexNet是2012年ImageNet比赛的冠军model,以第一作者alex命名;(关于ImageNet:超过1400万的图像URL被ImageNet手动注释,以指示图片中的对象;在至少一百万个图像中,提供了边界框,ImageNet包含2万多个类别,ImageNet挑战使用了一个“修剪”的1000个非重叠类的列表【参考百度百科】)

AlexNet用于解决图像分类问题;
它证明了CNN在复杂模型下的有效性,使用GPU实现使得训练在可接受的时间内得到结果;

AlexNet模型结构图

在这里插入图片描述
输入: 256 * 256的3通道(RGB)彩色图片;

使用随机位置采点的方法做数据增强,增强了图像的泛化能力;

AlexNet的创新点 / 特点:

  • 卷积部分采用分组的方法(因当时GPU显卡还不够强大)分成上下两块进行计算;
    分通道学习降低了卷积核学习维度(卷积核维度越高,学习难度越高);
  • AlexNet有一个特殊的计算层 —— LRN层(局部响应归一化),对输出结果做平滑处理(在某一层得到多个通道响应图后,对响应图的某一位置和相邻通道值做归一化处理);(后来在VGG中发现局部归一化处理并没有作用)
  • AlexNet最后一个全连接层是上一个全连接层进行ReLU及dropout后,再进行全连接的结果;
  • 使用softmax作为输出层的激活函数;
  • 最后输出融合label和softmax loss;

注释

dropout: 前向传播时,让某个神经元的激活值以一定的概率p停止工作(后层神经元只与前一层的部分神经元进行连接),通过阻止特征检测器的共同作用来提高神经网络的性能,防止过拟合;

AlexNet模型代码(pytorch)

模型部分:

import numpy as np
import torch
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
from torch import nn
from PIL import Image
from torch.autograd import Variable
from torchvision import transforms


# AlexNet模型
class AlexNet(nn.Module):
    def __init__(self):
        super(AlexNet, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(3, 96, 11, 4),
            nn.ReLU(),
            nn.MaxPool2d(3, 2)
        )
        self.layer2 = nn.Sequential(
            nn.Conv2d(96, 256, 5, padding=2, groups=2),
            nn.ReLU(),
            nn.MaxPool2d(3, 2)
        )
        self.layer3 = nn.Sequential(
            nn.Conv2d(256, 384, 3, padding=1),
            nn.ReLU()
        )
        self.layer4 = nn.Sequential(
            nn.Conv2d(384, 256, 3, padding=1),
            nn.ReLU(),
        )
        self.layer5 = nn.Sequential(
            nn.Conv2d(384, 256, 3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(3, 2)
        )
        self.layer6 = nn.Sequential(
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(),
            nn.Dropout()
        )
        self.layer7 = nn.Sequential(
            nn.Linear(4096, 4096),
            nn.ReLU(),
            nn.Dropout()
        )
        self.layer8 = nn.Linear(4096, 1000)

    def forward(self, x):
        x = self.layer5(self.layer4(self.layer3(self.layer2(self.layer1(x)))))
        x = x.view(x.size(0), -1)
        x = self.layere8(self.layer7(self.layer6(x)))
        output = F.softmax(x, dim=1)
        return output

超参数:

# 定义超参数
LR = 0.001
EPOCH = 20
BATCH_SIZE = 50
LOAD_DOWN = True

数据加载部分:
图片路径与标签信息已保存在txt文件中(路径与标签用空格分隔);
加载自己的数据集详解【点击此处】

# 数据预处理
def pre_loader(path):
    im = Image.open(path).convert('RGB')
    im = np.asarray(im.resize((227, 227)))
    return im


class MyDataset(Dataset):
    def __init__(self, txt, transform=None, target_transform=None, loader=pre_loader):
        f = open(txt, 'r')
        self.folder = txt.split('/')[-1].split('.')[0]
        img = []
        for line in f.readlines():
            img_name = line.split()[0]
            label = line.split()[1]
            img.append((img_name, int(label)))
        self.img = img
        self.transform = transform
        self.target_transform = target_transform
        self.loader = loader

    def __getitem__(self, index):
        img_name, label = self.img[index]
        img = self.loader('./data/' + self.folder + '/' + img_name)
        if self.transform is not None:
            img = self.transform(img)
        return img, label

    def __len__(self):
        return len(self.img)

训练 & 测试部分:

# 模型加载
alexnet = AlexNet().cuda()

optimizer = torch.optim.Adam(alexnet.parameters(), lr=LR)
loss_func = nn.CrossEntropyLoss()

for epoch in range(EPOCH):
    # 训练
    for x, y in train_loader:
        x, y = Variable(x).cuda(), Variable(y).cuda()
        pred_out = alexnet(x)
        loss = loss_func(pred_out, y)

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

    # 测试
    alexnet.eval()
    for b_x, b_y in test_loader:
        b_x = Variable(b_x, volatile=True).cuda()
        b_y = Variable(b_y, volatile=True).cuda()
        output = torch.max(alexnet(b_x), 1)[1]
        loss = loss_func(output, b_y)
        accuracy = sum(output == b_y) / b_y.size
        print('loss:', loss.data.numpy(), '| accuracy:', accuracy)

保存模型参数:

torch.save(alexnet.state_dict(), 'alexnet_parameters.pkl')

保存模型:

torch.save(alexnet, 'alexnet.pkl')

加载模型参数:
须先搭建一个相同的模型,再加载参数:

model.load_state_dict(torch.load('alexnet_parameters.pkl'))

加载模型:

model = torch.load('alexnet.pkl')
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值