DenseNet

DenseNet的几个优点:

1、减轻了vanishing-gradient(梯度消失) (每一层都直接连接input和loss,因此就可以减轻梯度消失现象
2、加强了feature的传递 
3、更有效地利用了feature 
4、一定程度上较少了参数数量

1)密集连接:

这里写图片描述

若你有L层,那么就会有L个连接,但是在DenseNet中,会有L(L+1)/2个连接。简单讲,就是每一层的输入来自前面所有层的输出。(这里不同于resnet中的权值和操作,采用了concat操作)

一个局域block(前向特征融合):

def conv_block(x, growth_rate, name):       #一个局部的特征融合,将block输入与block输出进行concat
    
    bn_axis = 3 if K.image_data_format() == 'channels_last' else 1
    x1 = layers.BatchNormalization(axis=bn_axis,
                                   epsilon=1.001e-5,
                                   name=name + '_0_bn')(x)
    x1 = layers.Activation('relu', name=name + '_0_relu')(x1)
    x1 = layers.Conv2D(2 * growth_rate, 1,
                       use_bias=False,
                       name=name + '_1_conv')(x1)
    x1 = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
                                   name=name + '_1_bn')(x1)
    x1 = layers.Activation('relu', name=name + '_1_relu')(x1)
    x1 = layers.Conv2D(growth_rate, 3,
                       padding='same',
                       use_bias=False,
                       name=name + '_2_conv')(x1)
    x = layers.Concatenate(axis=bn_axis, name=name + '_concat')([x, x1])

2)

bottleneck layer的提出:也就是每个dense block的3*3卷积前面都包含了一个1*1的卷积操作(降维,减少参数~)+ 密集连接= 减少参数量且通道融合

 

3)DenseNet-C的提出,新增加了Translation layer,该层的1*1这里写图片描述卷积的输出channel默认是输入channel的一半

 

 

附上所有代码:

# -*- coding: utf-8 -*-

from __future__ import print_function

import numpy as np
import warnings
from keras.models import Model
from keras import layers
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Input
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import GlobalMaxPooling2D
from keras.layers import GlobalAveragePooling2D
from keras.preprocessing import image
from keras.utils import layer_utils
from keras import backend as K
from keras.engine.topology import get_source_inputs

import cfg


def basemodel(input_tensor=None, input_shape=None,
          pooling=None):

    if input_tensor is None:
        img_input = Input(shape=input_shape)
    else:
        if not K.is_keras_tensor(input_tensor):
            img_input = Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor

    bn_axis = 3 if K.image_data_format() == 'channels_last' else 1

    x = layers.ZeroPadding2D(padding=((1, 1), (1, 1)))(img_input)
    x = layers.Conv2D(64, 3, strides=2, use_bias=False, name='conv1/conv')(x)
    x = layers.BatchNormalization(
        axis=bn_axis, epsilon=1.001e-5, name='conv1/bn')(x)
    x = layers.Activation('relu', name='conv1/relu')(x)
    x = layers.ZeroPadding2D(padding=((1, 1), (1, 1)))(x)
    x = layers.MaxPooling2D(3, strides=2, name='pool1')(x)   #128


    x = dense_block(x, 3, name='conv2')      #密集连接
    x = transition_block(x, 0.5, name='pool2')  #池化
    x = dense_block(x, 6, name='conv3')
    x = transition_block(x, 0.5, name='pool3')
    x = dense_block(x, 12, name='conv4')
    x = transition_block(x, 0.5, name='pool4')
   # x = dense_block(x, 4, name='conv5')


    x = layers.BatchNormalization(
        axis=bn_axis, epsilon=1.001e-5, name='bn')(x)
    x = layers.Activation('relu', name='relu')(x)


    if input_tensor is not None:
        inputs = get_source_inputs(input_tensor)
    else:
        inputs = img_input
    model = Model(inputs, x, name='basemodel_dense')

    return model


def dense_block(x, blocks, name):
    """A dense block.

    # Arguments
        x: input tensor.
        blocks: integer, the number of building blocks.
        name: string, block label.

    # Returns
        output tensor for the block.
    """
    for i in range(blocks):
        x = conv_block(x, 16, name=name + '_block' + str(i + 1))
    return x

def transition_block(x, reduction, name):   #等同于进行一次池化,减少通道数
    """A transition block.

    # Arguments
        x: input tensor.
        reduction: float, compression rate at transition layers.
        name: string, block label.

    # Returns
        output tensor for the block.
    """
    bn_axis = 3 if K.image_data_format() == 'channels_last' else 1
    x = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
                                  name=name + '_bn')(x)
    x = layers.Activation('relu', name=name + '_relu')(x)
    x = layers.Conv2D(int(K.int_shape(x)[bn_axis] * reduction), 1,
                      use_bias=False,
                      name=name + '_conv')(x)
    x = layers.AveragePooling2D(2, strides=2, name=name + '_pool')(x)
    return x


def conv_block(x, growth_rate, name):       #一个局部的特征融合,将block输入与block输出进行concat

    bn_axis = 3 if K.image_data_format() == 'channels_last' else 1
    x1 = layers.BatchNormalization(axis=bn_axis,
                                   epsilon=1.001e-5,
                                   name=name + '_0_bn')(x)
    x1 = layers.Activation('relu', name=name + '_0_relu')(x1)
    x1 = layers.Conv2D(2 * growth_rate, 1,
                       use_bias=False,
                       name=name + '_1_conv')(x1)
    x1 = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
                                   name=name + '_1_bn')(x1)
    x1 = layers.Activation('relu', name=name + '_1_relu')(x1)
    x1 = layers.Conv2D(growth_rate, 3,
                       padding='same',
                       use_bias=False,
                       name=name + '_2_conv')(x1)
    x = layers.Concatenate(axis=bn_axis, name=name + '_concat')([x, x1])
    return x

if __name__ == '__main__':
    input_img = Input(name='input_img',
                           shape=(cfg.max_train_img_size, cfg.max_train_img_size, cfg.num_channels),
                           dtype='float32')
    basemodel = basemodel(input_tensor=input_img)
    basemodel.summary()

 

 

 

 

 

Resnet和densenet的区别:

 

 

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值