卷积神经网络(Convolutional Network)

卷积神经网络(Convolutional Network)

目录:

  • 卷积神经网络的发展与优势
  • 什么是卷积
  • 卷积神经网络的结构
  • 经典的卷积网络结构
  • 代码实现

卷积神经网络的发展与优势

卷积层第一次被提出是在1998年,由Yann LeCun,Leon Bottou,Yoshua Bengio,Patrick Haffner等人发表的论文(http://goo.gl/A347S4)提出。该论文除了提出著名的LeNet架构,还第一次提出了卷积层(convolutional layers)和池化层(pooling layers)的概念。在二十多年前,Yann LeCun等人的LeNet-5就对手写数字识别达到非常好的效果。

卷积网络诞生之后,越来越多人意识到它在图像处理领域的优势。直到今天,CNN依然主要应用于图像领域。
CNN的优势:

  • 减少参数。
    普通的DNN(全连接的深度网络)在处理图像时,由于是把像素作为特征输入,假设一张100x100的彩色图像,输入层就需要100x100x3个神经元。假设第二层有1000个神经元(1000个真的不多,已经减少了大量传入到后面网络的数据量),则输入层与第一个隐藏层之间就有100x100x3x1000=30,000,000个参数,这还没算后面的网络呢。如此大的参数量对硬件要求很高。

    而CNN由于每两层之间只连接一部分,而且高度重复使用权重,所以,蚕食要比DNN少很多。训练速度更快。
    CNN
    图1:CNN后面的神经元只连接前面的一部分

  • 保留了图像的结构化信息
    普通的DNN把像素作为输入,像素彼此之间的结构化信息就这样被破坏了。
    而CNN低层网络可以保留一些小的结构化信息,高层可以保留一些大的结构化信息。这样,就不会破坏图像的结构特征。这也是为什么CNN尤其适合图像处理的原因。

  • 当CNN学会检测图像某个特征时,它可以在图像任何区域检测到该特征,因为一个特征图(feature map)上的权重是一样的。而DNN只能检测到该位置的特征。

什么是卷积

卷积在信号处理,复变函数等课程里都有介绍。书上介绍的卷积主要分为连续型和离散型两种。
***在这里插入图片描述
连续型卷积
连续型卷积主要是积分,两个函数在(-∞,+∞)的域内做积分。

在这里插入图片描述
离散型卷积
对于离散型函数,积分肯定是不行的了。所以,就在(-∞,+∞)内进行相乘再相加的运算。

演示:
在这里插入图片描述

在这里插入图片描述
在深度学习中的卷积不再是一维的了,但是原理不变。
在这里插入图片描述
像这样,卷积的两个函数都是二维的,只不过一个大,一个小。小的叫做filter(上图中那个不断滑动的3x3阴影),filter不断在大的上面滑动,每次向左向下滑动多少叫做strides,上图中大的外面一层白色边框是加上去的全0的像素,如果不加,那么卷积之后生成的新图叫特征图(feature map)就比原来的每个边少一个像素(strides=1),加边框的这个过程角做zero padding。filetr每经过大的图像的一个区域,就把对应的元素相乘,再相加得到新的特征图的一个像素。

下图是一个卷积的计算过程:
在这里插入图片描述
对于CNN,同一个卷积层不是只有一个特征图,而是很多。

卷积神经网络的结构

卷积神经网络最主要的就是卷积层,除此之外,还有一个叫做池化层的东西。理解了卷积层之后,池化层就简单了,因为池化层除了把卷积的相乘再求和改为直接求最大值或者均值外,其他都一样。
池化可以降低数据的大小,从而达到减小计算负载,内存利用率和参数数量,降低过拟合的风险等。
在这里插入图片描述
卷积和池化二者构成了CNN的基本结构。但是,作为图像分类的话,一般,最后还需要添加全连接层。

举一个例子来介绍CNN的基本结构:
在这里插入图片描述
首先,输入一个32x32的图像,通过卷积得到6个特征图,再通过池化,把特征图大小减小到一半。然后再通过卷积,池化。之后,通过全连接层得到输出。

经典卷积网络

LeNet-5
在这里插入图片描述
AlexNet
在这里插入图片描述

GoogLeNet
在这里插入图片描述
Google就喜欢整深层网络(有钱就是任性)

ResNet(残差网络)
这个才是可怕,152层
在这里插入图片描述
ResNet的创造性不在于它的卷积结构,而在于它的残差学习:
在这里插入图片描述
如图,普通的神经网络(CNN也好,DNN也好)都是一层连一层,而resnet除了相邻层之间有连接,隔一层的不相邻层还有连接,相当于添加了一个捷径。

VGG
我个人很喜欢VGG,网络简单,效果还不错。
在这里插入图片描述

代码实现

LeNet:

from keras import backend as K
from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dense
from keras.datasets import mnist
from keras.utils import np_utils
from keras.optimizers import SGD, RMSprop, Adam


class LeNet(object):
    @staticmethod
    def build(input_shape, classes):
        model = Sequential()
        
        model.add(Conv2D(20, kernel_size=5, padding='same', input_shape=input_shape))
        model.add(Activation('relu'))
        model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
        model.add(Conv2D(50, kernel_size=5, border_mode='same'))
        model.add(Activation('relu'))
        model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
        
        # flatten
        model.add(Flatten())
        model.add(Dense(500))
        model.add(Activation('relu'))
        model.add(Dense(classes))
        model.add(Activation('softmax'))
        
        return model

VGG-16:

import pandas as pd
from keras.models import Sequential
from keras.layers import Dense,Activation,Flatten, Dropout
from keras.layers.convolutional import Conv2D, MaxPooling2D, ZeroPadding2D
from keras.optimizers import SGD
from keras.utils import np_utils

def myModel(weights_path = None):
    model = Sequential()
    
    model.add(ZeroPadding2D((1,1), input_shape=(28,28,1)))
    model.add(Conv2D(64, (3,3),padding='same', activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(64, (3,3),padding='same', activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))
    
    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(128, kernel_size=3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(128, kernel_size=3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))
    
    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(256, kernel_size=3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(256, kernel_size=3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(256, kernel_size=3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))
    
    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(512, kernel_size=3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(512, kernel_size=3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(512, kernel_size=3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))
    
    model.add(Flatten())
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(10, activation='softmax'))
    
    return model
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值