zoukankan      html  css  js  c++  java
  • 【653】FCN——全卷积网络详解

    [1] 语义分割--全卷积网络FCN详解【解释详细】

    [2] 四、全卷积网络FCN详细讲解(超级详细哦)

    [3] github - FCN32、FCN8

    [4] keras.applications【VGG16】

    [5] keras—VGG16

    [6] 五、VGG、AlexNet、ResNet网络(超详细哦)

    一、总体说明

      FCN = CNN(VGG16) + UpSampling

    • FCN-32s: conv7 直接上采样 32 倍到原来的尺寸

    • FCN-16s: 

      • conv7 上采样 2 倍 (/16)

      • pool4 (/16)  

      • 两者 add 之后,上采样 16 倍到原来的尺寸

    • FCN-8s:

      • conv7 上采样 2 倍 (/16)

      • pool4 (/16)  

      • 两者 add 之后,上采样 2 倍 (/8)

      • pool3 (/8)

      • 上面两者 add 之后,上采样 8 倍到原来的尺寸

    二、结构图示

      图示如下所示:

      第1阶段

    这里写图片描述 
      以经典的分类网络为初始化。最后两级是全连接(红色),参数弃去不用。

      第2阶段

    这里写图片描述 
      从特征小图(16*16*4096)预测分割小图(16*16*21),之后直接升采样为大图。 
      反卷积(橙色)的步长为32,这个网络称为FCN-32s。 
      这一阶段使用单GPU训练约需3天。

      第3阶段

    这里写图片描述 
      升采样分为两次完成(橙色×2)。 
      在第二次升采样前,把第4个pooling层(绿色)的预测结果(蓝色)融合进来。使用跳级结构提升精确性。 
      第二次反卷积步长为16,这个网络称为FCN-16s。 
      这一阶段使用单GPU训练约需1天。

      第4阶段

    这里写图片描述 
      升采样分为三次完成(橙色×3)。 
      进一步融合了第3个pooling层的预测结果。 
      第三次反卷积步长为8,记为FCN-8s。 

    三、代码实现

      FCN-32s

    from keras.applications import vgg16
    from keras.models import Model, Sequential
    from keras.layers import Conv2D, Conv2DTranspose, Input, Cropping2D, add, Dropout, Reshape, Activation
    from keras.utils.vis_utils import plot_model
    
    def FCN32(nClasses, input_height, input_width):
    
        assert input_height % 32 == 0
        assert input_width % 32 == 0
    
        img_input = Input(shape=(input_height, input_width, 3))
        
        # VGG16 structrue
        # 2conv + 1pool -> block1_pool
        # 2conv + 1pool -> block2_pool
        # 3conv + 1pool -> block3_pool
        # 3conv + 1pool -> block4_pool
        # 3conv + 1pool -> block5_pool
        model = vgg16.VGG16(include_top=False, weights='imagenet', input_tensor=img_input)
        assert isinstance(model, Model)
    
        o = Conv2D(4096, 7, padding="same", activation="relu", name="fc6")(model.output)
        o = Dropout(rate=0.5)(o)
        o = Conv2D(4096, 1, padding="same", activation="relu", name="fc7")(o)
        o = Dropout(rate=0.5)(o)
    
        o = Conv2D(nClasses, 1, padding="same", activation="relu", kernel_initializer="he_normal", name="score_fr")(o)
    
        o = Conv2DTranspose(nClasses, 32, strides=(32, 32), padding="valid", activation=None, name="score2")(o)
    
        #o = Reshape((-1, nClasses))(o)
        o = Activation("softmax")(o)
    
        fcn8 = Model(inputs=img_input, outputs=o)
        # mymodel.summary()
        return fcn8
    
    
    if __name__ == '__main__':
        m = FCN32(2, 512, 512)
        m.summary()
        plot_model(m, show_shapes=True, to_file='model_fcn32.png')
        print(len(m.layers)) 
    

      FCN-16s

    from keras.applications import vgg16
    from keras.models import Model, Sequential
    from keras.layers import Conv2D, Conv2DTranspose, Input, Cropping2D, add, Dropout, Reshape, Activation
    
    
    def FCN16_helper(nClasses, input_height, input_width):
    
        assert input_height % 32 == 0
        assert input_width % 32 == 0
    
        img_input = Input(shape=(input_height, input_width, 3))
    
        model = vgg16.VGG16(include_top=False,weights='imagenet', input_tensor=img_input)
        assert isinstance(model, Model)
    
        o = Conv2D(4096,7,padding="same",activation="relu",name="fc6")(model.output)
        o = Dropout(rate=0.5)(o)
        o = Conv2D(4096,1,padding="same",activation="relu",name="fc7")(o)
        o = Dropout(rate=0.5)(o)
        
        # /32
        o = Conv2D(nClasses, 1, padding="same", activation="relu", kernel_initializer="he_normal",name="score_fr")(o)
        
        # 用于与 block4_pool合并
        # /32 * 2 = /16
        o = Conv2DTranspose(nClasses, 2, strides=(2, 2), padding="valid", activation=None, name="score2")(o)
    
        fcn16 = Model(inputs=img_input, outputs=o)
    
        return fcn16
    
    def FCN16(nClasses, input_height, input_width):
    
        fcn16 = FCN16_helper(nClasses, input_height, input_width)
    
        # Conv to be applied on Pool4
        # 这些 layer 的名字也可以通过后面的 summary 显示查看
        # /16
        skip_con1 = Conv2D(nClasses, 1, padding="same", activation=None, kernel_initializer="he_normal",
                           name="score_pool4")(fcn16.get_layer("block4_pool").output)
        Summed = add(inputs=[skip_con1, fcn16.output])
        
        # /16 * 16 = /1
        Up = Conv2DTranspose(nClasses, 16, strides=(16, 16), padding="valid", activation=None,name="upsample")(Summed)
    
        #Up = Reshape((-1, nClasses))(Up)
        Up = Activation("softmax")(Up)
    
        mymodel = Model(inputs=fcn16.input, outputs=Up)
    
        return mymodel
    
    
    if __name__ == '__main__':
        m16 = FCN16(2, 512, 512)
        #plot_model(m, show_shapes=True, to_file='model_fcn8.png')
        m16.summary() 
        print(len(m.layers))
    

      FCN-8s

    from keras.applications import vgg16
    from keras.models import Model, Sequential
    from keras.layers import Conv2D, Conv2DTranspose, Input, Cropping2D, add, Dropout, Reshape, Activation
    
    
    def FCN8_helper(nClasses, input_height, input_width):
    
        assert input_height % 32 == 0
        assert input_width % 32 == 0
    
        img_input = Input(shape=(input_height, input_width, 3))
    
        model = vgg16.VGG16(include_top=False,weights='imagenet', input_tensor=img_input)
        assert isinstance(model, Model)
    
        o = Conv2D(4096,7,padding="same",activation="relu",name="fc6")(model.output)
        o = Dropout(rate=0.5)(o)
        o = Conv2D(4096,1,padding="same",activation="relu",name="fc7")(o)
        o = Dropout(rate=0.5)(o)
        
        # /32
        o = Conv2D(nClasses, 1, padding="same", activation="relu", kernel_initializer="he_normal",name="score_fr")(o)
        
        # 用于与 block4_pool合并
        # /32 * 2 = /16
        o = Conv2DTranspose(nClasses, 2, strides=(2, 2), padding="valid", activation=None, name="score2")(o)
    
        fcn8 = Model(inputs=img_input, outputs=o)
    
        return fcn8
    
    def FCN8(nClasses, input_height, input_width):
    
        fcn8 = FCN8_helper(nClasses, input_height, input_width)
    
        # Conv to be applied on Pool4
        # 这些 layer 的名字也可以通过后面的 summary 显示查看
        # /16
        skip_con1 = Conv2D(nClasses, 1, padding="same", activation=None, kernel_initializer="he_normal",
                           name="score_pool4")(fcn8.get_layer("block4_pool").output)
        Summed = add(inputs=[skip_con1, fcn8.output])
        
        # /16 * 2 = /8
        x = Conv2DTranspose(nClasses, 2, strides=(2, 2), padding="valid", activation=None,name="score4")(Summed)
    
        ###
        # /8
        skip_con2 = Conv2D(nClasses, 1, padding="same", activation=None, kernel_initializer="he_normal",
                           name="score_pool3")(fcn8.get_layer("block3_pool").output)
        Summed2 = add(inputs=[skip_con2, x])
    
        #####
        # /8 * 8 = /1
        Up = Conv2DTranspose(nClasses, 8, strides=(8, 8),padding="valid", activation=None, name="upsample")(Summed2)
    
        #Up = Reshape((-1, nClasses))(Up)
        Up = Activation("softmax")(Up)
    
        mymodel = Model(inputs=fcn8.input, outputs=Up)
    
        return mymodel
    
    
    if __name__ == '__main__':
        m = FCN8(2, 512, 512)
        #plot_model(m, show_shapes=True, to_file='model_fcn8.png')
        m.summary() 
        print(len(m.layers))
    

    四、模型网络图

      FCN-32s

      FCN-16s

      FCN-8s

  • 相关阅读:
    dnc开源梦之队2018 开源项目精选集
    2018年4月更新70多个公司dnc招聘职位
    首届.NET Core开源峰会
    回顾Google IO 2016 -Keynote【图解】
    SharedPreferences实现记住密码功能
    Android 五大布局
    Visual Studio Code 编辑器相关
    你好!2015!
    Get Start StrangeIOC for Unity3D
    Unity3d Web Player 的server端联网配置
  • 原文地址:https://www.cnblogs.com/alex-bn-lee/p/15223376.html
Copyright © 2011-2022 走看看