基于PaddlePaddle实现AlexNet在Cifar10上的训练全过程

AlexNet是ILSVRC 2012的图像分类项目的第一名, 它具有6000万个参数和65万个神经元,基于两块GTX 580 3GB GPU,花了五到六天的时间来训练。本文基于一块GTX-1080Ti GPU,在Cifar10数据集上实现并训练AlexNet,大约只需要30分钟,大家可以感受到技术的进步。

AlexNet的结构图如下所示:
From https://learnopencv.com/understanding-alexnet/

根据上述结构图,用PaddlePaddle实现其网络范例如下:

import paddle 
import paddle.nn.functional as F # 组网相关的函数,如conv2d, relu...
import numpy as np
from paddle.nn.layer.common import Dropout 
from paddle.vision.transforms import Compose, Resize, Transpose, Normalize, ToTensor
from paddle.vision.datasets import Cifar10

# 构建AlexNet 网络
# Sequential:顺序容器,子Layer将按构造函数参数的顺序添加到此容器中,传递给构造函数的参数可以Layers或可迭代的name Layer元组
from paddle.nn import Sequential, Conv2D, ReLU, MaxPool2D, Linear, Dropout, Flatten

class AlexNet(paddle.nn.Layer):
    def __init__(self, num_classes=10):
        super().__init__()

        self.conv_relu_pool1 = Sequential(
            Conv2D(3,96,11,4,0),
            ReLU(),
            MaxPool2D(3,2))

        self.conv_relu_pool2 = Sequential(
            Conv2D(96,256,5,1,2),
            ReLU(),
            MaxPool2D(3,2))
        
        self.conv_relu3 = Sequential(
            Conv2D(256,384,3,1,1),
            ReLU())
        
        self.conv_relu4 = Sequential(
            Conv2D(384,384,3,1,1),
            ReLU())
        
        self.conv_relu_pool5 = Sequential(
            Conv2D(384,256,3,1,1),
            ReLU(),
            MaxPool2D(3,2))
        
        self.fc = Sequential(
            Linear(256*6*6, 4096),
            ReLU(),
            Dropout(0.5),
            Linear(4096,4096),
            ReLU(),
            Dropout(0.5),
            Linear(4096,num_classes))

        self.flatten = Flatten()

    def forward(self,x):
        x = self.conv_relu_pool1(x)
        x = self.conv_relu_pool2(x)
        x = self.conv_relu3(x)
        x = self.conv_relu4(x)
        x = self.conv_relu_pool5(x)
        x = self.flatten(x)
        x = self.fc(x)
        return x

alex_net = AlexNet(num_classes=10)
model = paddle.Model(alex_net)
from paddle.static import InputSpec
input = InputSpec([None, 3, 227, 227], 'float32', 'image')
label = InputSpec([None, 1], 'int64', 'label')
model = paddle.Model(alex_net, input, label)
model.summary()

Layer (type) Input Shape Output Shape Param #
Conv2D-1 [[1, 3, 227, 227]] [1, 96, 55, 55] 34,944
ReLU-1 [[1, 96, 55, 55]] [1, 96, 55, 55] 0
MaxPool2D-1 [[1, 96, 55, 55]] [1, 96, 27, 27] 0
Conv2D-2 [[1, 96, 27, 27]] [1, 256, 27, 27] 614,656
ReLU-2 [[1, 256, 27, 27]] [1, 256, 27, 27] 0
MaxPool2D-2 [[1, 256, 27, 27]] [1, 256, 13, 13] 0
Conv2D-3 [[1, 256, 13, 13]] [1, 384, 13, 13] 885,120
ReLU-3 [[1, 384, 13, 13]] [1, 384, 13, 13] 0
Conv2D-4 [[1, 384, 13, 13]] [1, 384, 13, 13] 1,327,488
ReLU-4 [[1, 384, 13, 13]] [1, 384, 13, 13] 0
Conv2D-5 [[1, 384, 13, 13]] [1, 256, 13, 13] 884,992
ReLU-5 [[1, 256, 13, 13]] [1, 256, 13, 13] 0
MaxPool2D-3 [[1, 256, 13, 13]] [1, 256, 6, 6] 0
Flatten-1 [[1, 256, 6, 6]] [1, 9216] 0
Linear-1 [[1, 9216]] [1, 4096] 37,752,832
ReLU-6 [[1, 4096]] [1, 4096] 0
Dropout-1 [[1, 4096]] [1, 4096] 0
Linear-2 [[1, 4096]] [1, 4096] 16,781,312
ReLU-7 [[1, 4096]] [1, 4096] 0
Dropout-2 [[1, 4096]] [1, 4096] 0
Linear-3 [[1, 4096]] [1, 10] 40,970
===========================================
Total params: 58,322,314
Trainable params: 58,322,314
Non-trainable params: 0
===========================================
Input size (MB): 0.59
Forward/backward pass size (MB): 11.11
Params size (MB): 222.48
Estimated Total Size (MB): 234.18
============================================

训练代码如下:

# Compose: 以列表的方式组合数据集预处理功能
# Resize: 调整图像大小
# Transpose: 调整通道顺序, eg, HWC(img) -> CHW(NN)
# Normalize: 对图像数据归一化
# ToTensor: 将 PIL.Image 或 numpy.ndarray 转换成 paddle.Tensor
# cifar10 手动计算均值和标准差:mean = [125.31, 122.95, 113.86] 和 std = [62.99, 62.08, 66.7] link:https://www.jianshu.com/p/a3f3ffc3cac1

t = Compose([Resize(size=227), 
             Normalize(mean=[125.31, 122.95, 113.86], std=[62.99, 62.08, 66.7], data_format='HWC'), 
             Transpose(order=(2,0,1)), 
             ToTensor(data_format='HWC')])

train_dataset = Cifar10(mode='train', transform=t, backend='cv2') 
test_dataset  = Cifar10(mode='test', transform=t, backend='cv2')
BATCH_SIZE = 256
train_loader = paddle.io.DataLoader(train_dataset, shuffle=True, batch_size=BATCH_SIZE)
test_loader = paddle.io.DataLoader(test_dataset, batch_size=BATCH_SIZE)

# 为模型训练做准备,设置优化器,损失函数和精度计算方式
learning_rate = 0.0001
loss_fn = paddle.nn.CrossEntropyLoss()
opt = paddle.optimizer.Adam(learning_rate=learning_rate, parameters=model.parameters())
model.prepare(optimizer=opt, loss=loss_fn, metrics=paddle.metric.Accuracy())

# 启动模型训练,指定训练数据集,设置训练轮次,设置每次数据集计算的批次大小,设置日志格式
model.fit(train_loader, batch_size=256, epochs=20, verbose=1)
model.evaluate(test_loader, verbose=1)

训练结果:在测试数据集上,精度可以达到78.79%

Epoch 20/20
step 196/196 [==============================] - loss: 0.0318 - acc: 0.9822 - 748ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 40/40 [==============================] - loss: 0.9298 - acc: 0.7879 - 641ms/step

心得:深度学习图像分类技术已经非常成熟,直接用PaddlePaddle框架的高层API实现即可。目标检测网络,由于需要合并Loss函数,训练过程需要动手实现,所以使用普通API函数。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 226,097评论 6 523
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,198评论 3 410
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 173,602评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,750评论 1 304
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,684评论 6 404
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,151评论 1 317
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,349评论 3 433
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,430评论 0 282
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,986评论 1 328
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,969评论 3 351
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,071评论 1 359
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,667评论 5 352
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,358评论 3 342
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,757评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,944评论 1 278
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,684评论 3 384
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,123评论 2 368

推荐阅读更多精彩内容