LeNet网络PaddlePaddle实现1

LeNet神经网络由深度学习三巨头之一的Yan LeCun于1998年提出,解决手写字符的识别与分类的神经网络。详细信息参考:http://yann.lecun.com/exdb/lenet/index.html

LeNet在深度学习发展史上之所以特别重要是因为:在LeNet被发明之前,字符识别是由手工设计提取特征的算法,然后把提取的特征输入传统的机器学习模型。机器学习模型分类的是手动提取的特征,而不是原始图像数据。LeNet证明了,可以由模型自动提取特征,特征在模型中的内部表达,比人工手动提取的特征更优秀,更有利于提高分类的精准度,从而实现直接读入原始数据到模型完成分类的工作,LeNet分类的是原始数据(raw image data)
传统方法需要手动设计特征提取器

LeNet-5总共有7层
LeNet构架

LeNet-5第一层:卷积层C1
C1层是卷积层,6个滤波器(num_filters),执行1输入6输出的卷积计算,每个滤波器大小(filter_size)是5x5,卷积区域每次滑动一个像素(stride=1),这样卷积层形成的每个特征图谱大小是(32-5)/1+1=28x28。C1层共有(5x5+1)x6=156个训练参数

LeNet-5第二层:池化层S2
S2层是一个下采样层,即池化层(Pool),池化层大小为2x2,用于降低数据量

LeNet-5第三层:卷积层C3
C3层是一个卷积层,10个滤波器,执行6输入10输出的卷积计算,意思是每个滤波器有6个输入通道,一共10个滤波器。每个滤波器大小(filter_size)是5x5,卷积区域每次滑动一个像素(stride=1)

LeNet-5第四层:池化层S4
S4是一个下采样层,即池化层(Pool),池化层大小为2x2,用于降低数据量

LeNet-5第五层:卷积层C5
C5层是一个卷积层,由于输入的数据是5x5,卷积核是5x5,最终输出的特征图大小为1x1,相当于卷积层展开了。

LeNet-5第六层:全连接层F6
F6层是全连接层,输入120,输出84。

LeNet-5第七层:全连接层Output
输入84,输出10。

由此,用PaddlePaddle实现其LeNet网络结构定义,代码如下所示:

import numpy as np 
import paddle
import paddle.fluid as fluid 
from paddle.fluid.dygraph.nn import Conv2D, Pool2D, Linear

# 定义LeNet网络结构
class LeNet(fluid.dygraph.Layer):
    def __init__(self, num_classes=1):
        super().__init__()

        # C1: feature maps 6@28x28
        self.conv1 = Conv2D(1, 6, 5, act='sigmoid')
        # S2:6@Maxpool 6@14x14
        self.maxpool1 = Pool2D(pool_size=2, pool_type='max', pool_stride=2)
        # C3: f.maps 16@10x10
        self.conv2 = Conv2D(6, 16, 5, act='sigmoid')
        # S4: 16@maxpool 16@5x5
        self.maxpool2 = Pool2D(pool_size=2, pool_type='max', pool_stride=2)
        # C5: f.maps 16@5x5 -> 120@1x1
        self.conv3 = Conv2D(16, 120, 5, act='sigmoid')
        # F6: FC 120 -> 84
        self.fc1 = Linear(120, 84, act='sigmoid')
        # output: 10
        self.fc2 = Linear(84, output_dim=num_classes)

    # 定义网络前向计算
    def forward(self, x):
        x = self.conv1(x)
        x = self.maxpool1(x)
        x = self.conv2(x)
        x = self.maxpool2(x)
        x = self.conv3(x)
        x = fluid.layers.reshape(x, (x.shape[0],-1))
        x = self.fc1(x)
        x = self.fc2(x)
        return x

神经网络计算对数据的形状非常敏感,LeNet处理的是32x32的输入数据,构建测试数据,打印神经网络各层的信息,代码如下:

# 查看LeNet-5 每一层输出数据形状
x = np.random.randn(*[20,1,32,32]).astype('float32')
with fluid.dygraph.guard():
    model =LeNet(num_classes=10)
    print(model.sublayers())
    x = fluid.dygraph.to_variable(x)
    for item in model.sublayers():
        try:
            x = item(x)
        except:
            print(x.shape)
            x = fluid.layers.reshape(x, (x.shape[0],-1))
            print(x.shape)
            x = item(x)
            print(x.shape)
        if len(item.parameters()) == 2 :
            print(item.full_name(), x.shape, item.parameters()[0].shape, item.parameters()[1].shape)
        else:
            print(item.full_name(), x.shape)

运行结果:

W0113 16:56:11.127960  4340 device_context.cc:252] Please NOTE: device: 0, CUDA Capability: 61, Driver API Version: 11.1, Runtime API Version: 10.0
W0113 16:56:11.134941  4340 device_context.cc:260] device: 0, cuDNN Version: 7.6.
[<paddle.fluid.dygraph.nn.Conv2D object at 0x00000199026A6108>, <paddle.fluid.dygraph.nn.Pool2D object at 0x00000199026A6228>, <paddle.fluid.dygraph.nn.Conv2D object at 0x00000199026A6288>, <paddle.fluid.dygraph.nn.Pool2D object at 0x00000199026A63A8>, <paddle.fluid.dygraph.nn.Conv2D object at 0x00000199026A6408>, <paddle.fluid.dygraph.nn.Linear object at 0x00000199026A6528>, <paddle.fluid.dygraph.nn.Linear object at 0x00000199026A6648>]
conv2d_0 [20, 6, 28, 28] [6, 1, 5, 5] [6]
pool2d_0 [20, 6, 14, 14]
conv2d_1 [20, 16, 10, 10] [16, 6, 5, 5] [16]
pool2d_1 [20, 16, 5, 5]
conv2d_2 [20, 120, 1, 1] [120, 16, 5, 5] [120]
[20, 120, 1, 1]
[20, 120]
[20, 84]
linear_0 [20, 84] [120, 84] [84]
linear_1 [20, 10] [84, 10] [10]

当把测试数据改为:

x = np.random.randn(*[20,1,28,28]).astype('float32')

运行会报错,指出数据形状不匹配。

----------------------
Error Message Summary:
----------------------
InvalidArgumentError: The input of Op(Conv) should be a 4-D or 5-D Tensor. But received: input's dimension is 2, input's shape is [20, 256].
  [Hint: Expected in_dims.size() == 4 || in_dims.size() == 5 == true, but received in_dims.size() == 4 || in_dims.size() == 5:0 != true:1.] at (D:\1.8.5\paddle\paddle\fluid\operators\conv_op.cc:59)
  [operator < conv2d > error]

下一篇《LeNet网络PaddlePaddle实现2》

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

推荐阅读更多精彩内容