精华内容
参与话题
问答
  • 包含fcn8s-heavy-pascal.caffemodel、fcn8s-heavy-pascal.prototxt、pascal-classes.txt文件 和FCN模型实现图像分割源码、配套图片素材 具体实现效果见CSDN博客“DNN系列5_FCN模型实现图像分割”查看效果
  • FCN 模型简单建立

    2020-04-20 22:58:44
    Fully Convolutional Networks(FCN) 图片均来自论文:Fully Convolutional Networks for Semantic Segmentation 上图简单解释: 若image为:224×224的图片,通过pool1后,为112×112,通过pool2后,为56×6,通过...

    Fully Convolutional Networks(FCN)

    图片均来自论文:Fully Convolutional Networks for Semantic Segmentation
    在这里插入图片描述
    上图简单解释:
    若image为:224×224的图片,通过pool1后,为112×112,通过pool2后,为56×6,通过pool3后,为28×28,通过pool4后,为14×14,通过pool5后,为7×7

    FCN-32s:7 × 7 直接32倍上采样变成 224 × 224
    FCN-16s:7×7 两倍上采样变成 14 × 14, 和pool4后的14 ×14相加,16倍上采样变成224×224
    FCN-8s: FCN-16s 上采样前矩阵 进行2倍上采样变成28 × 28,和 pool3后的 28 × 28相加,8倍上采样为224 × 224

    FCN-VGG16

    下采样的工作利用VGG16来完成
    在这里插入图片描述
    先利用pytorch简单的实现一下

    class VGG(torch.nn.Module):
        def __init__(self, n_class=10):
            super().__init__()
            # stage = 1
            self.conv1_1 = torch.nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1)
            self.relu1_1 = torch.nn.ReLU(inplace=True)
            self.conv1_2 = torch.nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding=1)
            self.relu1_2 = torch.nn.ReLU(inplace=True)
            self.pool1 = torch.nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)
            
            # stage = 2
            self.conv2_1 = torch.nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=1)
            self.relu2_1 = torch.nn.ReLU(inplace=True)
            self.conv2_2 = torch.nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, padding=1)
            self.relu2_2 = torch.nn.ReLU(inplace=True)
            self.pool2 = torch.nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)
            
            # stage = 3
            self.conv3_1 = torch.nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, padding=1)
            self.relu3_1 = torch.nn.ReLU(inplace=True)
            self.conv3_2 = torch.nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, padding=1)
            self.relu3_2 = torch.nn.ReLU(inplace=True)
            self.conv3_3 = torch.nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, padding=1)
            self.relu3_3 = torch.nn.ReLU(inplace=True)
            self.pool3 = torch.nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)
            
            # stage = 4
            self.conv4_1 = torch.nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, padding=1)
            self.relu4_1 = torch.nn.ReLU(inplace=True)
            self.conv4_2 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1)
            self.relu4_2 = torch.nn.ReLU(inplace=True)
            self.conv4_3 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1)
            self.relu4_3 = torch.nn.ReLU(inplace=True)
            self.pool4 = torch.nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)
            
            # stage = 5
            self.conv5_1 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1)
            self.relu5_1 = torch.nn.ReLU(inplace=True)
            self.conv5_2 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1)
            self.relu5_2 = torch.nn.ReLU(inplace=True)
            self.conv5_3 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1)
            self.relu5_3 = torch.nn.ReLU(inplace=True)
            self.pool5 = torch.nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)
            
            ## fully connection。这里利用了全卷积替代了全连接层
            self.fc_6 = torch.nn.Conv2d(in_channels=512, out_channels=4096, kernel_size=7)
            
            self.fc_7 = torch.nn.Conv2d(in_channels=4096, out_channels=4096, kernel_size=1)
            
            self.fc_8 = torch.nn.Conv2d(in_channels=4096, out_channels=1000, kernel_size=1)
        
        def forward(self, x):
            print(x.shape)
            h = self.pool1(self.conv1_2(self.conv1_1(x)))
            print(h.shape)
            h = self.pool1(self.conv2_2(self.conv2_1(h)))
            print(h.shape)
            h = self.pool1(self.conv3_2(self.conv3_1(h)))
            print(h.shape)
            h = self.pool1(self.conv4_2(self.conv4_1(h)))
            print(h.shape)
            h = self.pool1(self.conv5_2(self.conv5_1(h)))
            print(h.shape)
            h = self.fc_8(self.fc_7(self.fc_6(h)))
            print(h.shape)
            
            return h
    

    做一个简单的测验

    h = torch.randn(1,3,224,224)
    model = VGG()
    

    其结果就如上图所示一致

    torch.Size([1, 3, 224, 224])
    torch.Size([1, 64, 112, 112])
    torch.Size([1, 128, 56, 56])
    torch.Size([1, 256, 28, 28])
    torch.Size([1, 512, 14, 14])
    torch.Size([1, 512, 7, 7])
    torch.Size([1, 1000, 1, 1])
    
    展开全文
  • RESNet50+FCN模型文件

    2019-03-06 16:34:58
    RESNet50+FCN train模型文件
  • fcn模型训练问题

    2017-07-01 14:48:10
    FCN模型训练问题
  • fcn模型训练及测试

    2019-10-07 00:38:20
    1.模型下载 1)下载新版caffe: https://github.com/BVLC/caffe 2)下载fcn代码: ...3)将下载得到的fcn模型代码解压到caffe-master目录下 4)下载vgg16预训练好的模型和参数:http://dl.caffe.berkeleyvisi...

    1.模型下载

    1)下载新版caffe: https://github.com/BVLC/caffe
    2)下载fcn代码: https://github.com/shelhamer/fcn.berkeleyvision.org

    3)将下载得到的fcn模型代码解压到caffe-master目录下
    4)下载vgg16预训练好的模型和参数:http://dl.caffe.berkeleyvision.org/siftflow-fcn32s-heavy.caffemodel
    放置在fcn.berkeleyvision.org/ilsvrc-nets/目录下

    2.选择模型

    选择siftflow-fcn32s:

    1)下载siftflow数据集:http://www.cs.unc.edu/~jtighe/Papers/ECCV10/siftflow/SiftFlowDataset.zip
    并解压至/fcn.berkeleyvision.org/siftflow-fcn32s/data/下,并将文件夹名重命名为sift-flow

    2)cd进入fcn源码路径
    以个人路径为例:/home/zzq/caffe-master/fcn.berkeleyvision.org-master/
    将其中所有的py文件,例如surgery.py等等,全部复制到siftflow-fcn32s文件夹中

    3) cd 进入siftflow-fcn32s文件夹,运行python solve.py进行训练,
    注意修改solver.prototxt文件,保存快照。
    个人solver.prototxt文件参考:

    train_net: "trainval.prototxt"
    test_net: "test.prototxt"
    test_iter: 200
    # make test net, but don't invoke it from the solver itself
    test_interval: 999999999
    display: 20
    average_loss: 20
    lr_policy: "fixed"
    # lr for unnormalized softmax
    base_lr: 1e-10
    # high momentum
    momentum: 0.99
    # no gradient accumulation
    iter_size: 1
    max_iter: 100000
    weight_decay: 0.0005
    snapshot: 4000
    snapshot_prefix: "/home/zzq/caffe-master/fcn.berkeleyvision.org/siftflow-fcn32s/snapshot/train"  //快照保存路径
    test_initialization: false

    4)训练大概到40000次左右时,loss从十几万下降到1000左右,可以做测试啦
    5)修改fcn文件夹下的infer文件
    测试单张图片。
    在fcn源码文件夹,找到infer.py
    以个人路径示例:/home/zzq/caffe-master/fcn.berkeleyvision.org-master/
    打开infer.py 在第一行加上
    import sys
    sys.path.append('/home/zzq/caffe-master//python')
    其中/home/zzq/caffe-master/python为自己所下载的caffe源码包中的python所在路径
    其中,net = caffe.Net('deploy.prototxt', 'siftflow-fcn32s/train_iter_36000.caffemodel', caffe.TEST)
    中,train_iter_136000.caffemodel为训练得到的模型

    其中,im = Image.open('test.jpg')为 测试的图片名,
    plt.savefig('test_out.png')为将测试结果保存为test_output.png
    此外
    out = net.blobs['score'].data[0].argmax(axis=0)
    改成
    out = net.blobs['score_sem'].data[0].argmax(axis=0)
    最终修改结果如下:

         import numpy as np  
    from PIL import Image  
    import matplotlib.pyplot as plt  
    import sys    
    sys.path.append('/home/zzq/caffe-master/python')  
    import caffe  
    import cv2  
          
    # load image, switch to BGR, subtract mean, and make dims C x H x W for Caffe  
    im = Image.open('/home/zzq/caffe-master/fcn.berkeleyvision.org/data/sift-flow/Images/spatial_envelope_256x256_static_8outdoorcategories/coast_n243003.jpg')  
    in_ = np.array(im, dtype=np.float32)  
    in_ = in_[:,:,::-1]  
    #in_ -= np.array((104.00698793,116.66876762,122.67891434))  
    #in_ -= np.array((111.67446899,109.91841125,105.24302673))  
    in_ -= np.array((105.24302673,109.91841125,111.67446899))  
    in_ = in_.transpose((2,0,1))  
          
    # load net  
    #net = caffe.Net('deploy.prototxt', 'siftflow-fcn32s-heavy.caffemodel', caffe.TEST)  
    net = caffe.Net('/home/zzq/caffe-master/fcn.berkeleyvision.org/siftflow-fcn32s/deploy.prototxt', '/home/zzq/caffe-master/fcn.berkeleyvision.org/siftflow-fcn32s/snapshot/train_iter_36000.caffemodel', caffe.TEST)  
     
        # shape for input (data blob is N x C x H x W), set data  
    net.blobs['data'].reshape(1, *in_.shape)  
    net.blobs['data'].data[...] = in_  
    # run net and take argmax for prediction  
    net.forward()  
    out = net.blobs['score_sem'].data[0].argmax(axis=0)   
        #out = net.blobs['score_geo'].data[0].argmax(axis=0)   
        #print type(out)  
        #print out, out.shape  
        #cv2.imwrite("output.png", out)  
    plt.imshow(out,cmap='gray');  
    plt.imshow(out);  
    plt.axis('off')  
    plt.savefig('test_3_out.png')  
    plt.show()
    注意:

    如果没有deploy文件,可以参考如下方法:

    deploy文件如果没有 可以参照一下方法

    首先,根据你利用的模型,例如模型是siftflow32s的,那么你就去siftflow32s的文件夹,

    里面有train.prototxt文件,将文件打开,全选,复制,新建一个名为deploy.prototxt文件,粘贴进去,

    然后ctrl+F 寻找所有名为loss的layer 只要有loss 无论是loss还是geo_loss 将这个layer统统删除,然后删除第一层data layer
    在文件顶部加上

    layer {
    name: "input"
    type: "Input"
    top: "data"
    input_param {
    # These dimensions are purely for sake of example;
    # see infer.py for how to reshape the net to the given input size.
    shape { dim: 1 dim: 3 dim: 256 dim: 256 }
    }
    }

    其中shape{dim:1 dim:3 dim:256 dim:256}这两个256,是由于我的测试图片是256X256 如果你的是500X500 那你就将最后两个dim改为500 500

    需要注意的是 如果你执行的是siftflow32s,你没有deploy,你需要加入inputdata layer,你如果执行sififlow16s的model 那么是不需要加inputdata layer的

    因为他们的train.prototxt文件里已经有了inputdata layer

    此外,关于siftflow-fcn32s需要的deploy文件,我在这里附上一个下载地址,如果不愿意自己制作可以下载这个:

    http://pan.baidu.com/s/1dFCHWf3

    其中 deploy是fcn32的

    deploy16是fcn16的

    deploy8是fcn8的

    6) 测试结果:
    809232-20171007100810708-74485993.png

    (原图)
    809232-20171007100851411-1109756349.jpg

    9) 如果想下载官方的训练好的model 试试结果可以在这里下载到

    http://dl.caffe.berkeleyvision.org/

    转载于:https://www.cnblogs.com/zzq-123456/p/7634215.html

    展开全文
  • tensorflow2.0入门实例四(FCN模型建立)

    万次阅读 热门讨论 2019-10-21 14:35:22
    做东西,最重要的就是动手了,所以这篇文章主要教...文章使用的是tensorflow2.0框架,该框架集成了keras,在模型的训练方面极其简洁,不像tf1.x那么复杂,综合其他深度学习框架,发现这个是最适合新手使用的一种。 ...

      做东西,最重要的就是动手了,所以这篇文章动手跑了一个fcn32s和fcn8s以及deeplab v3+的例子,这个例子的数据集选用自动驾驶相关竞赛的kitti数据集, FCN8s在训练过程中用tensorflow2.0自带的评估能达到91%精确率, deeplab v3+能达到97%的准确率。这篇文章适合入门级选手,在文章中不再讲述fcn的结构,直接百度就可以搜到。
      文章使用的是tensorflow2.0框架,该框架集成了keras,在模型的训练方面极其简洁,不像tf1.x那么复杂,综合其他深度学习框架,发现这个是最适合新手使用的一种。
      文章中用到的库函数,参数等均可在tensorflow2.0 api中查找到。
      文章的代码在github可以获取,地址:https://github.com/fengshilin/tf2.0-FCN

    文章的结构如下:

    1. 数据下载与分析
    2. 数据预处理(重点在label的预处理)
    3. 模型加载
    4. 模型建立(FCN与Deeplab)
    5. 模型训练与测试

    4.模型建立

      这里会给出三个模型的框架,FCN32S,FCN8S, DeepLabV3+,精确度依次递增,训练时间也依次递增。
      建议初学者先复制模型代码跑一遍,再打印关键层的输出shape,然后再对模型做研究。

    FCN32S

      FCN32s的模型相对简单,在VGG16的模型基础上加上分类层即可。
    在这里插入图片描述

    # model
    import numpy as np
    import tensorflow as tf
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Conv2D, Conv2DTranspose, UpSampling2D
    from tensorflow.keras.layers import Dropout, Input
    from tensorflow.keras.initializers import Constant
    # from tensorflow.nn import conv2d_transpose
    
    image_shape = (160, 576)
    def bilinear_upsample_weights(factor, number_of_classes):
    	"""初始化权重参数"""
        filter_size = factor*2 - factor%2
        factor = (filter_size + 1) // 2
        if filter_size % 2 == 1:
            center = factor - 1
        else:
            center = factor - 0.5
        og = np.ogrid[:filter_size, :filter_size]
        upsample_kernel = (1 - abs(og[0] - center) / factor) * (1 - abs(og[1] - center) / factor)
        weights = np.zeros((filter_size, filter_size, number_of_classes, number_of_classes),
                           dtype=np.float32)
        for i in range(number_of_classes):
            weights[:, :, i, i] = upsample_kernel
        return weights
      
    
    class MyModel(tf.keras.Model):
        def __init__(self, n_class):
            super().__init__()
            self.vgg16_model = self.load_vgg()
            
            self.conv_test = Conv2D(filters=n_class, kernel_size=(1, 1))  # 分类层
            self.deconv_test = Conv2DTranspose(filters=n_class, 
                            kernel_size=(64, 64),
                            strides=(32, 32),
                            padding='same',
                            activation='sigmoid',
                            kernel_initializer=Constant(bilinear_upsample_weights(32, n_class)))  # 上采样层
    
        def call(self, input):
          x = self.vgg16_model(input)
          x = self.conv_test(x)
          x = self.deconv_test(x)
          return x
    
        def load_vgg(self):
            # 加载vgg16模型,其中注意input_tensor,include_top
            vgg16_model = tf.keras.applications.vgg16.VGG16(weights='imagenet', include_top=False, input_tensor=Input(shape=(image_shape[0], image_shape[1], 3)))
            for layer in vgg16_model.layers[:15]:
              layer.trainable = False  # 不训练前15层模型
            return vgg16_model
    

    FCN8s

      fcn8s在fcn32s的基础上还要再加上vgg16第四次pool的输出的分类结果,以此结果再与第三次pool的输出分类后的结果。

    # model
    import numpy as np
    import tensorflow as tf
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Conv2D, Conv2DTranspose, UpSampling2D, Add, BatchNormalization, MaxPooling2D
    from tensorflow.keras.layers import Dropout, Input
    from tensorflow.keras.initializers import Constant
    # from tensorflow.nn import conv2d_transpose
    
    def bilinear_upsample_weights(factor, number_of_classes):
        filter_size = factor*2 - factor%2
        factor = (filter_size + 1) // 2
        if filter_size % 2 == 1:
            center = factor - 1
        else:
            center = factor - 0.5
        og = np.ogrid[:filter_size, :filter_size]
        upsample_kernel = (1 - abs(og[0] - center) / factor) * (1 - abs(og[1] - center) / factor)
        weights = np.zeros((filter_size, filter_size, number_of_classes, number_of_classes),
                           dtype=np.float32)
        for i in range(number_of_classes):
            weights[:, :, i, i] = upsample_kernel
        return weights
      
    
    class MyModel(tf.keras.Model):
        def __init__(self, NUM_OF_CLASSESS):
            super().__init__()
            vgg16_model = self.load_vgg()
            self.conv1_1 = vgg16_model.layers[1]
            self.conv1_2 = vgg16_model.layers[2]
            self.pool1 = vgg16_model.layers[3]
            #(128,128)
            self.conv2_1 = vgg16_model.layers[4]
            self.conv2_2 = vgg16_model.layers[5]
            self.pool2 = vgg16_model.layers[6]
            #(64,64)
            self.conv3_1 = vgg16_model.layers[7]
            self.conv3_2 = vgg16_model.layers[8]
            self.conv3_3 = vgg16_model.layers[9]
            self.pool3 =  vgg16_model.layers[10]
            #(32,32)
            self.conv4_1 = vgg16_model.layers[11]
            self.conv4_2 = vgg16_model.layers[12]
            self.conv4_3 = vgg16_model.layers[13]
            self.pool4 =  vgg16_model.layers[14]
            #(16,16)
            self.conv5_1 = vgg16_model.layers[15]
            self.conv5_2 =  vgg16_model.layers[16]
            self.conv5_3 = vgg16_model.layers[17]
            self.pool5 = vgg16_model.layers[18]
            self.conv6 = Conv2D(4096,(7,7),(1,1),padding="same",activation="relu")
            self.drop6 = Dropout(0.5)
            self.conv7 = Conv2D(4096,(1,1),(1,1),padding="same",activation="relu")
            self.drop7 = Dropout(0.5)
            self.score_fr = Conv2D(NUM_OF_CLASSESS,(1,1),(1,1),padding="valid",activation="relu")
            self.score_pool4 = Conv2D(NUM_OF_CLASSESS,(1,1),(1,1),padding="valid",activation="relu")
            self.conv_t1 = Conv2DTranspose(NUM_OF_CLASSESS,(4,4),(2,2),padding="same")
            self.fuse_1 = Add()
            self.conv_t2 = Conv2DTranspose(NUM_OF_CLASSESS,(4,4),(2,2),padding="same")
            self.score_pool3 = Conv2D(NUM_OF_CLASSESS,(1,1),(1,1),padding="valid",activation="relu")
            self.fuse_2 = Add()
            self.conv_t3 = Conv2DTranspose(NUM_OF_CLASSESS,(16,16),(8,8),padding="same", activation="sigmoid", kernel_initializer=Constant(bilinear_upsample_weights(8, NUM_OF_CLASSESS)))
            
    
        def call(self, input):
          x = self.conv1_1(input)
          x = self.conv1_2(x)
          x = self.pool1(x)
          x = self.conv2_1(x)
          x = self.conv2_2(x)
          x = self.pool2(x)
          x = self.conv3_1(x)
          x = self.conv3_2(x)
          x = self.conv3_3(x)
          x_3 = self.pool3(x)
          x = self.conv4_1(x_3)
          x = self.conv4_2(x)
          x = self.conv4_3(x)
          x_4 = self.pool4(x)
          x = self.conv5_1(x_4)
          x = self.conv5_2(x)
          x = self.conv5_3(x)
          x = self.pool5(x)
          x = self.conv6(x)
          x = self.drop6(x)
          x = self.conv7(x)
          x = self.drop7(x)
          x = self.score_fr(x)  # 第5层pool分类结果
          x_score4 = self.score_pool4(x_4) # 第4层pool分类结果
          x_dconv1 = self.conv_t1(x)  # 第5层pool分类结果上采样
          x = self.fuse_1([x_dconv1,x_score4])  # 第4层pool分类结果+第5层pool分类结果上采样
          x_dconv2 = self.conv_t2(x)  # 第一次融合后上采样
          x_score3 = self.score_pool3(x_3)  # 第三次pool分类
          x = self.fuse_2([x_dconv2,x_score3])  #  第一次融合后上采样+第三次pool分类
          x = self.conv_t3(x)  # 上采样
          return x
    
        def load_vgg(self):
            # 加载vgg16模型,其中注意input_tensor,include_top
            vgg16_model = tf.keras.applications.vgg16.VGG16(weights='imagenet', include_top=False, input_tensor=Input(shape=(image_shape[0], image_shape[1], 3)))
            for layer in vgg16_model.layers[:18]:
              layer.trainable = False
            return vgg16_model
    

    DeepLab V3+模型的建立

    import tensorflow as tf
    from tensorflow.keras import backend as K
    from tensorflow.keras.models import Model
    from tensorflow.keras.layers import AveragePooling2D, Lambda, Conv2D, Conv2DTranspose, Activation, Reshape, concatenate, Concatenate, BatchNormalization, ZeroPadding2D
    
    from tensorflow.keras.applications import ResNet50
    
    
    def Upsample(tensor, size):
        '''bilinear upsampling'''
        name = tensor.name.split('/')[0] + '_upsample'
    
        def bilinear_upsample(x, size):
            resized = tf.image.resize(
                images=x, size=size)
            return resized
        y = Lambda(lambda x: bilinear_upsample(x, size),
                   output_shape=size, name=name)(tensor)
        return y
    
    
    def ASPP(tensor):
        '''atrous spatial pyramid pooling'''
        dims = K.int_shape(tensor)
    
        y_pool = AveragePooling2D(pool_size=(
            dims[1], dims[2]), name='average_pooling')(tensor)
        y_pool = Conv2D(filters=256, kernel_size=1, padding='same',
                        kernel_initializer='he_normal', name='pool_1x1conv2d', use_bias=False)(y_pool)
        y_pool = BatchNormalization(name=f'bn_1')(y_pool)
        y_pool = Activation('relu', name=f'relu_1')(y_pool)
    
        y_pool = Upsample(tensor=y_pool, size=[dims[1], dims[2]])
    
        y_1 = Conv2D(filters=256, kernel_size=1, dilation_rate=1, padding='same',
                     kernel_initializer='he_normal', name='ASPP_conv2d_d1', use_bias=False)(tensor)
        y_1 = BatchNormalization(name=f'bn_2')(y_1)
        y_1 = Activation('relu', name=f'relu_2')(y_1)
    
        y_6 = Conv2D(filters=256, kernel_size=3, dilation_rate=6, padding='same',
                     kernel_initializer='he_normal', name='ASPP_conv2d_d6', use_bias=False)(tensor)
        y_6 = BatchNormalization(name=f'bn_3')(y_6)
        y_6 = Activation('relu', name=f'relu_3')(y_6)
    
        y_12 = Conv2D(filters=256, kernel_size=3, dilation_rate=12, padding='same',
                      kernel_initializer='he_normal', name='ASPP_conv2d_d12', use_bias=False)(tensor)
        y_12 = BatchNormalization(name=f'bn_4')(y_12)
        y_12 = Activation('relu', name=f'relu_4')(y_12)
    
        y_18 = Conv2D(filters=256, kernel_size=3, dilation_rate=18, padding='same',
                      kernel_initializer='he_normal', name='ASPP_conv2d_d18', use_bias=False)(tensor)
        y_18 = BatchNormalization(name=f'bn_5')(y_18)
        y_18 = Activation('relu', name=f'relu_5')(y_18)
    
        y = concatenate([y_pool, y_1, y_6, y_12, y_18], name='ASPP_concat')
    
        y = Conv2D(filters=256, kernel_size=1, dilation_rate=1, padding='same',
                   kernel_initializer='he_normal', name='ASPP_conv2d_final', use_bias=False)(y)
        y = BatchNormalization(name=f'bn_final')(y)
        y = Activation('relu', name=f'relu_final')(y)
        return y
    
    
    def DeepLabV3Plus(img_height, img_width, nclasses=2):
        print('*** Building DeepLabv3Plus Network ***')
        
    	# 这里加载ResNet50模型,并且使用其两个模块的结果。
        base_model = ResNet50(input_shape=(
            img_height, img_width, 3), weights='imagenet', include_top=False)
        
        # 可以像模型加载章节的加载部分打印ResNet50模型,查看结构,“conv4_block6_2_relu”为层的名字, 加上.output表示这一层的输出。
        image_features = base_model.get_layer('conv4_block6_2_relu').output
        x_a = ASPP(image_features)
        x_a = Upsample(tensor=x_a, size=[img_height // 4, img_width // 4])
    
        x_b = base_model.get_layer('conv2_block3_2_relu').output
        x_b = Conv2D(filters=48, kernel_size=1, padding='same',
                     kernel_initializer='he_normal', name='low_level_projection', use_bias=False)(x_b)
        x_b = BatchNormalization(name=f'bn_low_level_projection')(x_b)
        x_b = Activation('relu', name='low_level_activation')(x_b)
    
        x = concatenate([x_a, x_b], name='decoder_concat')
    
        x = Conv2D(filters=256, kernel_size=3, padding='same', activation='relu',
                   kernel_initializer='he_normal', name='decoder_conv2d_1', use_bias=False)(x)
        x = BatchNormalization(name=f'bn_decoder_1')(x)
        x = Activation('relu', name='activation_decoder_1')(x)
    
        x = Conv2D(filters=256, kernel_size=3, padding='same', activation='relu',
                   kernel_initializer='he_normal', name='decoder_conv2d_2', use_bias=False)(x)
        x = BatchNormalization(name=f'bn_decoder_2')(x)
        x = Activation('relu', name='activation_decoder_2')(x)
        x = Upsample(x, [img_height, img_width])
    
        x = Conv2D(nclasses, (1, 1), name='output_layer')(x)
        '''
        x = Activation('softmax')(x) 
        tf.losses.SparseCategoricalCrossentropy(from_logits=True)
        Args:
            from_logits: Whether `y_pred` is expected to be a logits tensor. By default,
            we assume that `y_pred` encodes a probability distribution.
        '''     
        model = Model(inputs=base_model.input, outputs=x, name='DeepLabV3_Plus')
        print(f'*** Output_Shape => {model.output_shape} ***')
        return model
    
    展开全文
  • 5 FCN模型图像分割 5.1 FCN模型模型与数据介绍 FCN模型 支持20个分割标签  使用模型实现图像分割 5.2 模型文件  二进制模型 - fcn8s-heavy-pascal.caffemodel 官网下载  网络描述 - fcn8s-heavy-pascal....

    本例程用到的模型文件、源码和图片素材

    贾志刚OpenCV3.3深度神经网络DNN模块系列学习资料整理

    5 FCN模型图像分割

    5.1 FCN模型模型与数据介绍

    FCN模型
    支持20个分割标签


     使用模型实现图像分割

    5.2 模型文件

     二进制模型
    - fcn8s-heavy-pascal.caffemodel   官网下载
     网络描述
    - fcn8s-heavy-pascal.prototxt
     分割信息
    - pascal-classes.txt
    - 20个分类

    5.3 使用模型实现图像分割

     编码处理
    - 加载Caffem模型
    - 使用模型预测

    实例5:FCN模型实现图像分割

    #include <opencv2/opencv.hpp>
    #include <opencv2/dnn.hpp>
    #include <iostream>
    
    using namespace cv;
    using namespace cv::dnn;
    using namespace std;
    
    const size_t width = 300;
    const size_t height = 300;
    String labelFile = "D:/opencv3.3/opencv/sources/samples/data/dnn/pascal-classes.txt";
    String modelFile = "D:/opencv3.3/opencv/sources/samples/data/dnn/fcn8s-heavy-pascal.caffemodel";
    String model_text_file = "D:/opencv3.3/opencv/sources/samples/data/dnn/fcn8s-heavy-pascal.prototxt";
    
    vector<Vec3b> readColors();
    int main(int argc, char** argv) {
    	Mat frame = imread("rgb.jpg");
    	if (frame.empty()) {
    		printf("could not load image...\n");
    		return -1;
    	}
    	namedWindow("input image", CV_WINDOW_AUTOSIZE);
    	imshow("input image", frame);
    	resize(frame, frame, Size(500, 500));//改变尺寸
    	vector<Vec3b> colors = readColors();
    //
    	// init net  初始化网络
    	Net net = readNetFromCaffe(model_text_file, modelFile);
    	Mat blobImage = blobFromImage(frame);
    
    	// use net   使用网络
    	float time = getTickCount();
    	net.setInput(blobImage, "data");
    	Mat score = net.forward("score");
    	float tt = getTickCount() - time;
    	printf("time consume: %.2f ms \n", (tt / getTickFrequency()) * 1000);
    	
    	// segmentation and display   分割并显示
    	const int rows = score.size[2];
    	const int cols = score.size[3];
    	const int chns = score.size[1];
    	Mat maxCl(rows, cols, CV_8UC1);
    	Mat maxVal(rows, cols, CV_32FC1);
    
    	// setup LUT  LUT查找
    	for (int c = 0; c < chns; c++) {
    		for (int row = 0; row < rows; row++) {
    			const float *ptrScore = score.ptr<float>(0, c, row);
    			uchar *ptrMaxCl = maxCl.ptr<uchar>(row);
    			float *ptrMaxVal = maxVal.ptr<float>(row);
    			for (int col = 0; col < cols; col++) {
    				if(ptrScore[col] > ptrMaxVal[col]) {
    					ptrMaxVal[col] = ptrScore[col];
    					ptrMaxCl[col] = (uchar)c;
    				}
    			}
    		}
    	}
    
    	// look up colors 找到对应颜色
    	Mat result = Mat::zeros(rows, cols, CV_8UC3);
    	for (int row = 0; row < rows; row++) {
    		const uchar *ptrMaxCl = maxCl.ptr<uchar>(row);
    		Vec3b *ptrColor = result.ptr<Vec3b>(row);
    		for (int col = 0; col < cols; col++) {
    			ptrColor[col] = colors[ptrMaxCl[col]];
    		}
    	}
    	Mat dst;
    	imshow("FCN-demo1", result);
    	addWeighted(frame, 0.3, result, 0.7, 0, dst);//增加宽度
    	imshow("FCN-demo", dst);
    
    	waitKey(0);
    	return 0;
    }
    
    vector<Vec3b> readColors() {
    	vector<Vec3b> colors;
    	ifstream fp(labelFile);
    	if (!fp.is_open()) {
    		printf("could not open the file...\n");
    		exit(-1);
    	}
    	string line;
    	while (!fp.eof()) {
    		getline(fp, line);
    		if (line.length()) {
    			stringstream ss(line);
    			string name;
    			ss >> name;
    			int temp;
    			Vec3b color;
    			ss >> temp;
    			color[0] = (uchar)temp;
    			ss >> temp;
    			color[1] = (uchar)temp;
    			ss >> temp;
    			color[2] = (uchar)temp;
    			colors.push_back(color);
    		}
    	}
    	return colors;
    }

                                       

     

     pascal可实现分割的种类和显示颜色(BGR)可见 pascal-classes.txt文件

                           

    展开全文
  • 全卷积神经网络FCN模型Unet 图像分割项目实践

    千次阅读 多人点赞 2019-05-15 01:40:30
    本文基于下面链接的项目, 实践一次基于Unet模型的图像分割. 个人在实现时遇到很多问题, 许多问题在网上并没有找到解答, 所以写下本文, 记录了在实现过程中遇到的问题和大部分代码的注解, 主要从代码逻辑入手, 分析...
  • FCN模型实现-Pytorch+预训练VGG16

    千次阅读 2020-03-17 14:57:53
    FCN模型的网络与VGG16类似,之后后边将全连接层换成了卷基层,具体的网络结构与细节可以去看论文: https://people.eecs.berkeley.edu/~jonlong/long_shelhamer_fcn.pdf 下边详细讲一下用Pytorch对FCN的实现: ...
  • FCN模型的理解

    千次阅读 2017-05-09 20:47:50
    FCN模型的理解
  • FCN是先通过5层缩小2的5次方,然后通过反卷积扩大2的5次方,期间采用了残差模型 数据集是自己使用labelme标注的,只标注了40个数据,代码可运行,如下: import numpy as np import torch import cv2 import torch....
  • FCN FCN论文下载地址: link. 原作者的代码: link 备注:此文的FCN特指《Fully Convolutional Networks for Semantic Segmentation》论文中提出的结构,并非是广义的全卷机网络。 一、介绍 1.1 FCN 关于图像分割...
  • FCN模型结构往简答说,就是先用VGG类似的卷积网络进行特征提取,然后再对特征图进行反卷积(deconvolution)来将其投影到像素空间从而实现逐个逐个像素的分类。 结合代码分析模型结构 说起来简单,不过还是需要结合...
  • fcn模型精调

    2019-10-07 00:38:19
    http://www.cnblogs.com/JZ-Ser/p/7248316.html http://blog.csdn.net/Scythe666/article/details/77963586 转载于:https://www.cnblogs.com/zzq-123456/p/7634224.html
  • [深度学习] TensorFlow上FCN模型验证

    千次阅读 2018-10-30 17:44:44
    针对 https://blog.csdn.net/weixin_41028208/article/details/81568310 中好多留言,不知道如何用自己的数据验证模型结果,我特意从原程序中摘出来了一个程序,用来验证data_dir中的图片 一个简单的办法,把图片...
  • 由于系列(五)中提到的github开源项目只针对VOC2012格式数据集进行FCN模型训练,所以为了方便起见,我们在对自己数据集进行标注完成后,需要先转换成VOC格式再来用该项目代码训练我们自己的FCN模型。 数据格式转换...

空空如也

1 2 3 4 5 ... 20
收藏数 572
精华内容 228
关键字:

fcn模型