zoukankan      html  css  js  c++  java
  • LeNet详解

       LeNet-5是一个较简单的卷积神经网络。下图显示了其结构:输入的二维图像,先经过两次卷积层到池化层,再经过全连接层,最后使用softmax分类作为输出层。关于CNN参见:https://blog.csdn.net/qq_42570457/article/details/81458077

    网络解析(一):LeNet-5详解

           LeNet-5 这个网络虽然很小,但是它包含了深度学习的基本模块:卷积层,池化层,全连接层。是其他深度学习模型的基础, 这里我们对LeNet-5进行深入分析。同时,通过实例分析,加深对与卷积层和池化层的理解。

    网络解析(一):LeNet-5详解

           LeNet-5共有7层,不包含输入,每层都包含可训练参数;每个层有多个Feature Map,每个FeatureMap通过一种卷积滤波器提取输入的一种特征,然后每个FeatureMap有多个神经元。

    各层参数详解:

    1、INPUT层-输入层

           首先是数据 INPUT 层,输入图像的尺寸统一归一化为32*32。

           注意:本层不算LeNet-5的网络结构,传统上,不将输入层视为网络层次结构之一。

    2、C1层-卷积层

          输入图片:32*32

          卷积核大小:5*5

          卷积核种类:6

          输出featuremap大小:28*28 (32-5+1)=28

          神经元数量:28*28*6

          可训练参数:(5*5+1) * 6(每个滤波器5*5=25个unit参数和一个bias参数,一共6个滤波器)

          连接数:(5*5+1)*6*28*28=122304

         详细说明:对输入图像进行第一次卷积运算(使用 6 个大小为 5*5 的卷积核),得到6个C1特征图(6个大小为28*28的 feature maps, 32-5+1=28)。我们再来看看需要多少个参数,卷积核的大小为5*5,总共就有6*(5*5+1)=156个参数,其中+1是表示一个核有一个bias。对于卷积层C1,C1内的每个像素都与输入图像中的5*5个像素和1个bias有连接,所以总共有156*28*28=122304个连接(connection)。有122304个连接,但是我们只需要学习156个参数,主要是通过权值共享实现的。

    3、S2层-池化层(下采样层)

          输入:28*28

          采样区域:2*2

          采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid

          采样种类:6

          输出featureMap大小:14*14(28/2)

          神经元数量:14*14*6

          可训练参数:2*6(和的权+偏置)

          连接数:(2*2+1)*6*14*14

          S2中每个特征图的大小是C1中特征图大小的1/4。

           详细说明:第一次卷积之后紧接着就是池化运算,使用 2*2核 进行池化,于是得到了S2,6个14*14的 特征图(28/2=14)。S2这个pooling层是对C1中的2*2区域内的像素求和乘以一个权值系数再加上一个偏置,然后将这个结果再做一次映射。于是每个池化核有两个训练参数,所以共有2x6=12个训练参数,但是有5x14x14x6=5880个连接。

    4、C3层-卷积层

           输入:S2中所有6个或者几个特征map组合

          卷积核大小:5*5

          卷积核种类:16

          输出featureMap大小:10*10 (14-5+1)=10

          C3中的每个特征map是连接到S2中的所有6个或者几个特征map的,表示本层的特征map是上一层提取到的特征map的不同组合。

           存在的一个方式是:C3的前6个特征图以S2中3个相邻的特征图子集为输入。接下来6个特征图以S2中4个相邻特征图子集为输入。然后的3个以不相邻的4个特征图子集为输入。最后一个将S2中所有特征图为输入。则:可训练参数:6*(3*5*5+1)+6*(4*5*5+1)+3*(4*5*5+1)+1*(6*5*5+1)=1516

           连接数:10*10*1516=151600

           详细说明:第一次池化之后是第二次卷积,第二次卷积的输出是C3,16个10x10的特征图,卷积核大小是 5*5. 我们知道S2 有6个 14*14 的特征图,怎么从6 个特征图得到 16个特征图了? 这里是通过对S2 的特征图特殊组合计算得到的16个特征图。具体如下:

    网络解析(一):LeNet-5详解

           C3的前6个feature map(对应上图第一个红框的6列)与S2层相连的3个feature map相连接(上图第一个红框),后面6个feature map与S2层相连的4个feature map相连接(上图第二个红框),后面3个feature map与S2层部分不相连的4个feature map相连接,最后一个与S2层的所有feature map相连。卷积核大小依然为5*5,所以总共有6*(3*5*5+1)+6*(4*5*5+1)+3*(4*5*5+1)+1*(6*5*5+1)=1516个参数。而图像大小为10*10,所以共有151600个连接。

    网络解析(一):LeNet-5详解

            C3与S2中前3个图相连的卷积结构如下图所示:

    网络解析(一):LeNet-5详解

           上图对应的参数为 3*5*5+1,一共进行6次卷积得到6个特征图,所以有6*(3*5*5+1)参数。 为什么采用上述这样的组合了?论文中说有两个原因:1)减少参数,2)这种不对称的组合连接的方式有利于提取多种组合特征。

    5、S4层-池化层(下采样层)

           输入:10*10

           采样区域:2*2

          采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid

          采样种类:16

          输出featureMap大小:5*5(10/2)

          神经元数量:5*5*16=400

          可训练参数:2*16=32(和的权+偏置)

          连接数:16*(2*2+1)*5*5=2000

          S4中每个特征图的大小是C3中特征图大小的1/4

          详细说明:S4是pooling层,窗口大小仍然是2*2,共计16个feature map,C3层的16个10x10的图分别进行以2x2为单位的池化得到16个5x5的特征图。这一层有2x16共32个训练参数,5x5x5x16=2000个连接。连接的方式与S2层类似。

    6、C5层-卷积层

         输入:S4层的全部16个单元特征map(与s4全相连)

         卷积核大小:5*5

         卷积核种类:120

         输出featureMap大小:1*1(5-5+1)

         可训练参数/连接:120*(16*5*5+1)=48120

         详细说明:C5层是一个卷积层。由于S4层的16个图的大小为5x5,与卷积核的大小相同,所以卷积后形成的图的大小为1x1。这里形成120个卷积结果。每个都与上一层的16个图相连。所以共有(5x5x16+1)x120 = 48120个参数,同样有48120个连接。C5层的网络结构如下:

    网络解析(一):LeNet-5详解

    7、F6层-全连接层

          输入:c5 120维向量

          计算方式:计算输入向量和权重向量之间的点积,再加上一个偏置,结果通过sigmoid函数输出。

          可训练参数:84*(120+1)=10164

          详细说明:6层是全连接层。F6层有84个节点,对应于一个7x12的比特图,-1表示白色,1表示黑色,这样每个符号的比特图的黑白色就对应于一个编码。该层的训练参数和连接数是(120 + 1)x84=10164。ASCII编码图如下:

    网络解析(一):LeNet-5详解

         F6层的连接方式如下:

    网络解析(一):LeNet-5详解

    8、Output层-全连接层

           Output层也是全连接层,共有10个节点,分别代表数字0到9,且如果节点i的值为0,则网络识别的结果是数字i。采用的是径向基函数(RBF)的网络连接方式。假设x是上一层的输入,y是RBF的输出,则RBF输出的计算方式是:

    网络解析(一):LeNet-5详解

         上式w_ij 的值由i的比特图编码确定,i从0到9,j取值从0到7*12-1。RBF输出的值越接近于0,则越接近于i,即越接近于i的ASCII编码图,表示当前网络输入的识别结果是字符i。该层有84x10=840个参数和连接。

    网络解析(一):LeNet-5详解

    上图是LeNet-5识别数字3的过程。

    总结

    • LeNet-5是一种用于手写体字符识别的非常高效的卷积神经网络。
    • 卷积神经网络能够很好的利用图像的结构信息。
    • 卷积层的参数较少,这也是由卷积层的主要特性即局部连接和共享权重所决定。

     参考:http://cuijiahua.com/blog/2018/01/dl_3.html

    理解keras中的sequential模型

    keras中的主要数据结构是model(模型),它提供定义完整计算图的方法。通过将图层添加到现有模型/计算图,我们可以构建出复杂的神经网络。

    Keras有两种不同的构建模型的方法:

    1. Sequential models
    2. Functional API

    本文将要讨论的就是keras中的Sequential模型。

    理解Sequential模型

    Sequential模型字面上的翻译是顺序模型,给人的第一感觉是那种简单的线性模型,但实际上Sequential模型可以构建非常复杂的神经网络,包括全连接神经网络、卷积神经网络(CNN)、循环神经网络(RNN)、等等。这里的Sequential更准确的应该理解为堆叠,通过堆叠许多层,构建出深度神经网络。

    如下代码向模型添加一个带有64个大小为3 * 3的过滤器的卷积层:

    from keras.models import Sequential
    from keras.layers import Dense, Activation,Conv2D,MaxPooling2D,Flatten,Dropout
    
    model = Sequential()
    model.add(Conv2D(64, (3, 3), activation='relu'))

    Sequential模型的核心操作是添加layers(图层),以下展示如何将一些最流行的图层添加到模型中:

    • 卷积层
    model.add(Conv2D(64, (3, 3), activation='relu'))
    • 最大池化层
    model.add(MaxPooling2D(pool_size=(2, 2)))
    • 全连接层
    model.add(Dense(256, activation='relu'))
    • dropout
    model.add(Dropout(0.5))
    • Flattening layer(展平层)
    model.add(Flatten())

    基本的Sequential模型开发流程

    从我们所学习到的机器学习知识可以知道,机器学习通常包括定义模型、定义优化目标、输入数据、训练模型,最后通常还需要使用测试数据评估模型的性能。keras中的Sequential模型构建也包含这些步骤。

    首先,网络的第一层是输入层,读取训练数据。为此,我们需要指定为网络提供的训练数据的大小,这里input_shape参数用于指定输入数据的形状:

    model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)))

    上面的代码中,输入层是卷积层,其获取224 * 224 * 3的输入图像。

    接下来就是为模型添加中间层和输出层,请参考上面一节的内容,这里不赘述。

    然后,进入最重要的部分: 选择优化器(如rmsprop或adagrad)并指定损失函数(如categorical_crossentropy)来指定反向传播的计算方法。在keras中,Sequential模型的compile方法用来完成这一操作。例如,在下面的这一行代码中,我们使用’rmsprop’优化器,损失函数为’binary_crossentropy’。

    model.compile(loss='binary_crossentropy',
                  optimizer='rmsprop')

    到这一步,我们创建了模型,接下来就是调用fit函数将数据提供给模型。这里还可以指定批次大小(batch size)、迭代次数、验证数据集等等。其中批次大小、迭代次数需要根据数据规模来确定,并没有一个固定的最优值。

    model.fit(x_train, y_train, batch_size=32, epochs=10,validation_data=(x_val, y_val))

    最后,使用evaluate方法来评估模型:

    score = model.evaluate(x_test,y_test,batch_size = 32)

    以上就是在Keras中使用Sequential模型的基本构建块,相对于tensorflow,keras的代码更少,接口更加清晰,更重要的是,keras的后端框架切(比如从tensorflow切换到Theano)换后,我们的代码不需要做任何修改。

    使用Sequential模型解决线性回归问题

    谈到tensorflow、keras之类的框架,我们的第一反应通常是深度学习,其实大部分的问题并不需要深度学习,特别是在数据规模较小的情况下,一些机器学习算法就可以解决问题。除了构建深度神经网络,keras也可以构建一些简单的算法模型,下面以线性学习为例,说明使用keras解决线性回归问题。

    线性回归中,我们根据一些数据点,试图找出最拟合各数据点的直线。为了说明这一问题,我们创建100个数据点,然后通过回归找出拟合这100个数据点的直线。

    1. 创建训练数据
    import keras
    from keras.models import Sequential
    from keras.layers import Dense
    import numpy as np
    
    trX = np.linspace(-1, 1, 101)
    trY = 3 * trX + np.random.randn(*trX.shape) * 0.33

    上面这段代码创中,TrainX的值在-1和1之间均匀分布,而TrainY的值为TrainX的三倍,但增加了一些随机扰动。

    1. 创建模型
    model = Sequential()
    model.add(Dense(input_dim=1, output_dim=1, init='uniform', activation='linear'))

    代码创建一个Sequential模型,这里使用了一个采用线性激活的全连接(Dense)层。它实际上封装了输入值x乘以权重w,加上偏置(bias)b,然后进行线性激活以产生输出。

    我们可以查看默认初始化的权重和偏置值:

    weights = model.layers[0].get_weights()
    w_init = weights[0][0][0]
    b_init = weights[1][0]
    print('Linear regression model is initialized with weights w: %.2f, b: %.2f' % (w_init, b_init))
    1. 选择优化器和损失函数
    model.compile(optimizer='sgd', loss='mse')

    选择简单的梯度递减优化算法,损失函数选择均方差(mean squared error, mse)。

    1. 训练模型
    model.fit(trX, trY, nb_epoch=200, verbose=1)

    训练完毕之后,我们可以再看看权重值和偏置值

    weights = model.layers[0].get_weights()
    w_final = weights[0][0][0]
    b_final = weights[1][0]
    print('Linear regression model is trained to have weight w: %.2f, b: %.2f' % (w_final, b_final))

    最后的结果为

    Linear regression model is trained to have weight w: 2.94, b: 0.08

    可以看到,进行200次迭代之后,权重值现在非常接近3。我们可以尝试修改迭代次数,看看不同迭代次数下得到的权重值。

    这段例子仅仅作为一个简单的示例,所以没有做模型评估,有兴趣的同学可以构建测试数据自己尝试一下。

    总结

    keras中的Sequential模型其实非常强大,而且接口简单易懂,大部分情况下,我们只需要使用Sequential模型即可满足需求。在某些特别的场合,可能需要更复杂的模型结构,这时就需要Functional API,在后面的教程中,我将探讨Functional API。

    参考

    1. Keras tutorial: Practical guide from getting started to developing complex deep neural network
    2. Getting started with the Keras Sequential model

    =========================

    工作机会(内部推荐):发送邮件至gaoyabing@126.com,看到会帮转内部HR。

    邮件标题:X姓名X_X公司X_简历(如:张三_东方财富_简历),否则一律垃圾邮件!

    公司信息:

    1. 1.东方财富|上海徐汇、南京|微信客户端查看职位(可自助提交信息,微信打开);
  • 相关阅读:
    循环神经网络
    相似度计算(余弦距离/欧式距离)
    最常见Linux操作
    注意力机制总结
    随机打乱数组算法、蓄水池算法
    6.1 数据结构---树(遍历)
    Node.js调用C/C++
    linux中nmcli命令详解
    stylus入门使用方法
    webpack CommonsChunkPlugin详细教程
  • 原文地址:https://www.cnblogs.com/Chary/p/15080966.html
Copyright © 2011-2022 走看看