经典卷积网络的发展

LeNet-5网络: 

 

LeNet-5手写数字识别,con卷积层,Subsampling下采样,俩个卷积层和3个全连接层组成,是5层。数字识别直接垄断了美国50%的市场。后来成了facebook的技术层。

AlexNet开启了卷及网络的征程: 

 2010年开始shallow网络,2-4层的网络,Alexnet在2012年ImageNet挑战赛上,准确率一下提高了10个百分点,2013年ZFNet准确率进一步提升,网络层数没有增加,2014年19层的VGG,GoogleNet是22层的,VGG只是网络深度发生变化,但是宽度没啥变化,
GoogleNet网络深度发生变化,inception网络结构,允许在同一层输入不同的卷积核,(1*1,3*3,5*5,7*7)。ResNet的作者何恺明也因此摘得CVPR2016最佳论文奖,华人学者,结合了VGG的深度和Google的宽度inception。目前使用非常广泛。

8层网络,网络新加入了Max Pooling和ReLU,因为性能问题加入Dropout,准确率提高了10%

在这基础上牛津大学的团队发明了VGGNet网络

 

 

VGG是牛津大学发明的,vgg-11,vgg-16,vgg-19,VGG重大创新,AlexNet是11x11的窗口。VGG提出3x3和1x1,并不损失准确度,还提高了运算速度。拿了2014年Imagenet的亚军,冠GoogleNet 

 

GoogleNet在VGG19层基础上加了三层,inception是googleNet的加深版本 (inception-v1(google-net),inceptio-v2,inception-v3,inceptio-v4),GoogLeNet CNN由9个Inception module组成,V2\V3分解尺寸较大的卷积核,Iception-V4是将Inception结构和残余连接相结合,通过残余连接加速Inception网络的训练。提出了两个Inception残余网络:Inception-ResNet-v1、Inception-ResNet-v2网络;一个Inception网络Inception-v4,证明了在算法开销相近时,残余Inception网络比没有残余连接的Inception网络的性能稍稍好一些。

赫布认为“两个神经元或者神经元系统,如果总是同时兴奋,就会形成一种‘组合’,其中一个神经元的兴奋会促进另一个的兴奋”。

ResNet(深度残差网络)

 

设计的初衷:

更深层次的网络,会带来更好的效果。但是却相反,更深的网络效果却并不好,会出现梯度弥散(计算梯度的时候梯度逐渐趋近于0)和梯度爆炸。咋样才能使得深层网络最差也不会比22层的网络差。这就是resNet最初的设想,增加一个shortcut连接,如果梯度效果不好,直接跳过这8层,从22层开始,但是每个shortcut是一个小单元,有可能是一层或者多层。


 

 

Resnet可以做物体检测,实例分割准确度上都有所提高 

 

 

一个Basic Block的实现:

import tensorflow as tf

class BasicBlock(layers.Layer):
    def __init__(self,filter_num,stride=1):
        super(BasicBlock,self).__init__()

        self.conv1 = layers.Conv2D(filter_num,(3,3),strides=stride,padding='same')
        self.bn1=layers.BatchNormalization()
        self.relu = layers.Activation('relu')
        self.conv2 = layers.Conv2D(filter_num,(3,3),strides=1,padding='same')
        self.bn2 = layers.BatchNormalization()
        if stride != 1:
            self.dowmsample = Sequential()
            self.downsample.add(layers.Conv2D(filter_num,(1,1),strides=stride))
            self.downsample.add(layers.BatchNormalization())
        else:
            self.dowmsample = lambda x:x

        self.stride = stride
    def call(selfself,inputs,training=None):
        residual = self.downsample(inputs)

        conv1 = self.conv1(inputs)
        bn1 = self.bn1(conv1)
        relu1 = self.relu(bn1)
        conv2 = self.conv2(relu1)
        bn2 = self.bn2(conv2)

        add = layers.add([bn2,residual])
        out = self.relu(add)
        return out

一个Res Block由 多个basic block组成:

    def _build_resblock(self,block,filter_num,blocks,stride=1):

        res_blocks = keras.Sequential()
        res_blocks.add(block(filter_num,stride))

        for _ in range(1,blocks):
            res_blocks.add(block(filter_num,stride=1))

        return res_blocks

一个完整过程: 


 

 

其实resNet每个节点都总结了前面所有层的信息。 

猜你喜欢

转载自blog.csdn.net/chehec2010/article/details/127057680