卷积神经网络CNN学习记录-CNN实现语义分割(Encoder-Decoder结构)

1.Encoder

from keras.layers import *


def Conv_Encoder( input_height=416 ,  input_width=416 ):

	Img_In = Input(shape=(input_height,input_width , 3 ))

	# 416,416,3 -> 208,208,64
	Img_Conv = Conv2D(64, (3, 3), activation='relu', padding='same', name='Conv1_layer1')(Img_In)
	Img_Conv = Conv2D(64, (3, 3), activation='relu', padding='same', name='Conv1_layer2')(Img_Conv)
	Img_Conv = MaxPooling2D((2, 2), strides=(2, 2), name='MaxPooling_layer1')(Img_Conv)
	layers1 = Img_Conv

	# 208,208,64 -> 128,128,128
	Img_Conv = Conv2D(128, (3, 3), activation='relu', padding='same', name='Conv2_layer1')(Img_Conv)
	Img_Conv = Conv2D(128, (3, 3), activation='relu', padding='same', name='Conv2_layer2')(Img_Conv)
	Img_Conv = MaxPooling2D((2, 2), strides=(2, 2), name='MaxPooling_layer2')(Img_Conv)
	layers2 = Img_Conv

	# 104,104,128 -> 52,52,256
	Img_Conv = Conv2D(256, (3, 3), activation='relu', padding='same', name='Conv3_layer1')(Img_Conv)
	Img_Conv = Conv2D(256, (3, 3), activation='relu', padding='same', name='Conv3_layer2')(Img_Conv)
	Img_Conv = Conv2D(256, (3, 3), activation='relu', padding='same', name='Conv3_layer3')(Img_Conv)
	Img_Conv = MaxPooling2D((2, 2), strides=(2, 2), name='MaxPooling_layer3')(Img_Conv)
	layers3 = Img_Conv

	# 52,52,256 -> 26,26,512
	Img_Conv = Conv2D(512, (3, 3), activation='relu', padding='same', name='Conv4_layer1')(Img_Conv)
	Img_Conv = Conv2D(512, (3, 3), activation='relu', padding='same', name='Conv4_layer2')(Img_Conv)
	Img_Conv = Conv2D(512, (3, 3), activation='relu', padding='same', name='Conv4_layer3')(Img_Conv)
	Img_Conv = MaxPooling2D((2, 2), strides=(2, 2), name='MaxPooling_layer4')(Img_Conv)
	layers4 = Img_Conv 

	# 26,26,512 -> 13,13,1024
	Img_Conv = Conv2D(512, (3, 3), activation='relu', padding='same', name='Conv5_layer1')(Img_Conv)
	Img_Conv = Conv2D(512, (3, 3), activation='relu', padding='same', name='Conv5_layer2')(Img_Conv)
	Img_Conv = Conv2D(512, (3, 3), activation='relu', padding='same', name='Conv5_layer3')(Img_Conv)
	Img_Conv = MaxPooling2D((2, 2), strides=(2, 2), name='MaxPooling_layer5')(Img_Conv)
	layers5 = Img_Conv 

	#经过五次压缩后,图片被压缩至13*13*512,将最后压缩后的结果与每一层压缩后的结果一起返回给解码器
	return Img_In , [layers1 , layers2 , layers3 , layers4 , layers5 ]

2.Decoder

from keras.models import *
from keras.layers import *
from nets.convnet import Conv_Encoder


def Conv_Decoder(  layer , classNum , Top=3 ):
	#数据格式
	IMAGE_ORDERING = 'channels_last'

	assert Top >= 3

	Get_Layer = layer
	# 13*13*1024
	# 上采样,长宽变为原来的1/16
	# 26*26*512
	Get_Layer = ( ZeroPadding2D( (1,1) , data_format=IMAGE_ORDERING ))(Get_Layer)
	Get_Layer = ( Conv2D(512, (3, 3), padding='valid', data_format=IMAGE_ORDERING))(Get_Layer)
	Get_Layer = ( BatchNormalization())(Get_Layer)

	# 长宽变为原来的1/16
	# 52*52*256
	Get_Layer = ( UpSampling2D( (2,2), data_format=IMAGE_ORDERING))(Get_Layer)
	Get_Layer = ( ZeroPadding2D( (1,1), data_format=IMAGE_ORDERING))(Get_Layer)
	Get_Layer = ( Conv2D( 256, (3, 3), padding='valid', data_format=IMAGE_ORDERING))(Get_Layer)
	Get_Layer = ( BatchNormalization())(Get_Layer)


	# 长宽变为原来的1/4
	# 104,104,128
	Get_Layer = ( UpSampling2D((2,2)  , data_format=IMAGE_ORDERING ) )(Get_Layer)
	Get_Layer = ( ZeroPadding2D((1,1) , data_format=IMAGE_ORDERING ))(Get_Layer)
	Get_Layer = ( Conv2D( 128 , (3, 3), padding='valid' , data_format=IMAGE_ORDERING ))(Get_Layer)
	Get_Layer = ( BatchNormalization())(Get_Layer)

	# 上采样,此时hw变为原来的1/2
	# 208,208,64
	Get_Layer = ( UpSampling2D((2,2)  , data_format=IMAGE_ORDERING ))(Get_Layer)
	Get_Layer = ( ZeroPadding2D((1,1)  , data_format=IMAGE_ORDERING ))(Get_Layer)
	Get_Layer = ( Conv2D( 64 , (3, 3), padding='valid'  , data_format=IMAGE_ORDERING ))(Get_Layer)
	Get_Layer = ( BatchNormalization())(Get_Layer)


	# 最后通过卷积调整通道数为类别数 即208,208,2
	Result =  Conv2D( classNum , (3, 3) , padding='same', data_format=IMAGE_ORDERING )( Get_Layer )
	
	return Result

def Get_Conv( classNum , Conv  ,  input_height=416, input_width=416 , Conv_Level=3):
	#获取shape
	Img_In , levels = Conv( input_height=input_height ,  input_width=input_width )

	# 获取卷积压缩后的特征层
	Conv_Result = levels[Conv_Level]

	# 将特征传入解码函数
	temp = Conv_Decoder(Conv_Result, classNum, Top=4 )

	# 将结果进行reshape,经过softmax最后输出model
	temp = Reshape((int(input_height/2)*int(input_width/2), -1))(temp)
	temp = Softmax()(temp)
	model = Model(Img_In,temp)

	return model

def convnet_segnet( classNum ,  input_height=224, input_width=224 , Conv_Level=4):
	#五次压缩,有五个特征层,Conv_Level设为4
	model = Get_Conv( classNum , Conv_Encoder ,  input_height=input_height, input_width=input_width , encoder_level=Conv_Level)
	model.model_name = "Conv_Model"
	return model

3.分割效果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值