首页 > 解决方案 > 如何使用 Keras 中的功能 API 在快捷连接中添加卷积层?

问题描述

定制模型

我正在尝试使用 Keras 中的功能 API 实现一个自定义 CNN 模型,如附图所示。我已经编写了实现主分支的代码,但是在添加 1x1 卷积作为快捷连接时遇到了问题。为每对卷积块添加快捷卷积,就在最大池化层之前。代码如下:

input_shape = (256,256,3)
model_input = Input(shape=input_shape)
print(model_input) 

def custom_cnn(model_input):
    x = Conv2D(16, (3, 3), strides = (2,2), padding = 'same')(model_input)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(16, (3, 3), strides = (2,2), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
    
    x = Conv2D(32, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(32, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
    
    x = Conv2D(48, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(48, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
    
    x = Conv2D(64, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(64, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
    
    x = Conv2D(80, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(80, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
            
    x = GlobalAveragePooling2D()(x)
    x = Dense(num_classes, activation='softmax')(x)
    model = Model(inputs=model_input, outputs=x, name='custom_cnn')
    return model

#instantiate the model
custom_model = custom_cnn(model_input)

#display model summary
custom_model.summary() 

标签: tensorflowkerasdeep-learningconv-neural-network

解决方案


这里是按照模式在网络内实现残差块:

在此处输入图像描述

num_classes = 3
input_shape = (256,256,3)
model_input = Input(shape=input_shape)

def custom_cnn(model_input):
    
    x = Conv2D(16, (3, 3), strides = (2,2), padding = 'same')(model_input)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(16, (3, 3), strides = (2,2), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    xx = Conv2D(16, (1,1), strides= (4,4), padding = 'same')(model_input)
    x = Add()([x,xx])
    xx = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
    
    x = Conv2D(32, (3, 3), strides = (1,1), padding = 'same')(xx)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(32, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    xx = Conv2D(32, (1,1), strides= (1,1), padding = 'same')(xx)
    x = Add()([x,xx])
    xx = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
    
    x = Conv2D(48, (3, 3), strides = (1,1), padding = 'same')(xx)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(48, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    xx = Conv2D(48, (1,1), strides= (1,1), padding = 'same')(xx)
    x = Add()([x,xx])
    xx = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
    
    x = Conv2D(64, (3, 3), strides = (1,1), padding = 'same')(xx)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(64, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    xx = Conv2D(64, (1,1), strides= (1,1), padding = 'same')(xx)
    x = Add()([x,xx])
    xx = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
    
    x = Conv2D(80, (3, 3), strides = (1,1), padding = 'same')(xx)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(80, (3, 3), strides = (1,1), padding = 'same')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    xx = Conv2D(80, (1,1), strides= (1,1), padding = 'same')(xx)
    x = Add()([x,xx])
    xx = MaxPooling2D(pool_size=(3, 3), strides=(2,2))(x)
            
    x = GlobalAveragePooling2D()(xx)
    x = Dense(num_classes, activation='softmax')(x)
    model = Model(inputs=model_input, outputs=x, name='custom_cnn')
    return model

#instantiate the model
custom_model = custom_cnn(model_input)

#display model summary
custom_model.summary() 

推荐阅读