本博客主要为代码实现的小伙伴提供模板,具体的原理已经有好多文章啦,所以在这里我也就不啰嗦啦,只作简单介绍!
1.残差结构
1.1 残差单元
与普通网络的串行结构相比,残差单元增加了跳跃映射,将输入与输出直接进行相加,补充卷积过程中损失的特征信息,这点与U-net的跳跃连接结构有点类似,不过Res中的跳跃连接做的是Add操作,而U-net的跳跃连接做的是Concatenate操作,还是有本质的不同,残差单元如图所示:
1.2 残差家族
根据层数的不同ResNet有以下的伐木累
由图中可以看出ResNet18和ResNet34的残差单元只有两层,而ResNet50、ResNet101、ResNet152的残差单元有三层。本文使用的是ResNet50所以主要讲解ResNet50。
1.3 Resnet50
ResNet50由两个基本结构组成,一个为Conv_block,一个为Identity_block。如图所示:
Conv_block用于放在第一个位置调整通道以及特征图大小,Identity_block用于加深网络。
2.U-net
自己看吧…
3.Res-Unet
本文讲的Res-Unet主要是将U-net特征提取层的普通卷积用ResNet50代替,以达到加深网络的目的,直接上代码吧!
import keras
from keras.models import *
from keras.layers import *
from keras import layers
import keras.backend as K
IMAGE_ORDERING = 'channels_last'
def identity_block(input_tensor, kernel_size, filters, stage, block):
filters1, filters2, filters3 = filters
if IMAGE_ORDERING == 'channels_last':
bn_axis = 3
else:
bn_axis = 1
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'
x = Conv2D(filters1, (1, 1), data_format=IMAGE_ORDERING, name=conv_name_base + '2a')(input_tensor)
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
x = Activation('relu')(x)
x = Conv2D(filters2, kernel_size, data_format=IMAGE_ORDERING,
padding='same', name=conv_name_base + '2b')(x)
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
x = Activation('relu')(x)
x = Conv2D(filters3, (1, 1), data_format=IMAGE_ORDERING, name=conv_name_base + '2c')(x)
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
x = layers.add([x, input_tensor])
x = Activation('relu')(x)
return x
def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):
filters1, filters2, filters3 = filters
if IMAGE_ORDERING == 'channels_last':
bn_axis = 3
else:
bn_axis = 1
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'
x = Conv2D(filters1, (1, 1), data_format=IMAGE_ORDERING, strides=strides,
name=conv_name_base + '2a')(input_tensor)
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
x = Activation('relu')(x)
x = Conv2D(filters2, kernel_size, data_format=IMAGE_ORDERING, padding='same',
name=conv_name_base + '2b')(x)
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
x = Activation('relu')(x)
x = Conv2D(filters3, (1, 1), data_format=IMAGE_ORDERING, name=conv_name_base + '2c')(x)
x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
shortcut = Conv2D(filters3, (1, 1), data_format=IMAGE_ORDERING, strides=strides,
name=conv_name_base + '1')(input_tensor)
shortcut = BatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut)
x = layers.add([x, shortcut])
x = Activation('relu')(x)
return x
def get_resnet50_encoder(input_height=256, input_width=256, pretrained='imagenet',
include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None,
classes=1000):
assert input_height % 32 == 0
assert input_width % 32 == 0
if IMAGE_ORDERING == 'channels_first':
img_input = Input(shape=(6, input_height, input_width))
elif IMAGE_ORDERING == 'channels_last':
img_input = Input(shape=(input_height, input_width, 6))
if IMAGE_ORDERING == 'channels_last':
bn_axis = 3
else:
bn_axis = 1
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(img_input)
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)
f1 = x
x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x)
x = Activation('relu')(x)
x = MaxPooling2D((2, 2), data_format=IMAGE_ORDERING, strides=(2, 2))(x)
x = conv_block(x, 3, [32, 32, 128], stage=2, block='a', strides=(1, 1))
x = identity_block(x, 3, [32, 32, 128], stage=2, block='b')
x = identity_block(x, 3, [32, 32, 128], stage=2, block='c')
f2 = x
x = conv_block(x, 3, [64, 64, 256], stage=3, block='a')
x = identity_block(x, 3, [64, 64, 256], stage=3, block='b')
x = identity_block(x, 3, [64, 64, 256], stage=3, block='c')
x = identity_block(x, 3, [64, 64, 256], stage=3, block='d')
f3 = x
x = conv_block(x, 3, [128, 128, 512], stage=4, block='a')
x = identity_block(x, 3, [128, 128, 512], stage=4, block='b')
x = identity_block(x, 3, [128, 128, 512], stage=4, block='c')
x = identity_block(x, 3, [128, 128, 512], stage=4, block='d')
x = identity_block(x, 3, [128, 128, 512], stage=4, block='e')
x = identity_block(x, 3, [128, 128, 512], stage=4, block='f')
f4 = x
x = conv_block(x, 3, [256, 256, 1024], stage=5, block='a')
x = identity_block(x, 3, [256, 256, 1024], stage=5, block='b')
x = identity_block(x, 3, [256, 256, 1024], stage=5, block='c')
f5 = x
return img_input, [f1, f2, f3, f4, f5]
def _unet(n_classes , encoder , input_height = 256, input_width = 256):
img_input , levels = encoder(input_height=input_height,input_width=input_width)
[f1 , f2 , f3 , f4 , f5] = levels
o = f5
o = UpSampling2D((2, 2), data_format=IMAGE_ORDERING)(o)
# o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(512, (2, 2), padding='same', data_format=IMAGE_ORDERING)(o)
o = Activation('relu')(o)
o = BatchNormalization()(o)
o = concatenate([o,f4],axis=3)
o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(512, (3, 3), padding='valid', data_format=IMAGE_ORDERING)(o)
o = Activation('relu')(o)
o = BatchNormalization()(o)
o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(512, (3, 3), padding='valid', data_format=IMAGE_ORDERING)(o)
o = Activation('relu')(o)
o = BatchNormalization()(o)
o = UpSampling2D((2, 2), data_format=IMAGE_ORDERING)(o)
# o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(256, (2, 2), padding='same', data_format=IMAGE_ORDERING)(o)
o = Activation('relu')(o)
o = BatchNormalization()(o)
o = concatenate([o,f3],axis=3)
o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(256, (3, 3), padding='valid', data_format=IMAGE_ORDERING)(o)
o = BatchNormalization()(o)
o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(256, (3, 3), padding='valid', data_format=IMAGE_ORDERING)(o)
o = BatchNormalization()(o)
o = UpSampling2D((2, 2), data_format=IMAGE_ORDERING)(o)
# o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(128, (2, 2), padding='same', data_format=IMAGE_ORDERING)(o)
o = BatchNormalization()(o)
o = concatenate([o,f2],axis=3)
o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(128, (3, 3), padding='valid', data_format=IMAGE_ORDERING)(o)
o = Activation('relu')(o)
o = BatchNormalization()(o)
o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(128, (3, 3), padding='valid', data_format=IMAGE_ORDERING)(o)
o = Activation('relu')(o)
o = BatchNormalization()(o)
o = UpSampling2D((2, 2), data_format=IMAGE_ORDERING)(o)
# o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(64, (2, 2), padding='same', data_format=IMAGE_ORDERING)(o)
o = Activation('relu')(o)
o = BatchNormalization()(o)
o = concatenate([o,f1],axis=3)
o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(64, (3, 3), padding='valid', data_format=IMAGE_ORDERING)(o)
o = Activation('relu')(o)
o = BatchNormalization()(o)
o = ZeroPadding2D((1, 1) , data_format=IMAGE_ORDERING)(o)
o = Conv2D(64, (3, 3), padding='valid', data_format=IMAGE_ORDERING)(o)
o = Activation('relu')(o)
o = BatchNormalization()(o)
o = Conv2D(n_classes, (3,3) ,padding='same',data_format=IMAGE_ORDERING)(o)
o = Reshape((int(input_height)*int(input_width),-1))(o)
o = Softmax()(o)
model = Model(img_input,o)
return model
def conv_unet(n_classes , input_height=256, input_width=256):
model = _unet(n_classes,get_resnet50_encoder,input_height=input_height,input_width=input_width)
model.model_name = 'conv_unet'
return model
model = conv_unet(2)
model.summary()
什么?你用的不是Keras?
什么?你用的Pytroch?