首页 文章

Keras - 如何与2个独立的FullyConnected层共享CNN的卷积部分

提问于
浏览
3

我正致力于CNN,旨在从一组心脏MRI图像中预测2种不同的体积(收缩压和舒张压) .

我做的第一件事就是实现2个独立的“顺序”CNN,每个CNN预测一个音量 .

首先定义模型:

def get_model():
    dim_img = 64
    model = Sequential()
    model.add(Activation(activation=center_normalize, input_shape=(30, dim_img, dim_img)))

    # CONVOLUTIONAL LAYERS
    model.add(Convolution2D(32, 3, 3, border_mode='same'))
    model.add(Activation('relu'))
    model.add(Convolution2D(32, 3, 3,border_mode='same'))
    model.add(Activation('relu'))
    model.add(Dropout(0.25))

    model.add(Convolution2D(64, 3, 3, border_mode='same'))
    model.add(Activation('relu'))
    model.add(Convolution2D(64, 3, 3, border_mode='same'))
    model.add(Activation('relu'))
    model.add(ZeroPadding2D(padding=(1, 1)))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
    model.add(Dropout(0.25))

    # FULLY CONNECTED LAYERS
    model.add(Flatten())
    model.add(Dense(512, W_regularizer=l2(1e-3)))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    model.add(Dense(1))

    adam = Adam(lr=0.0001)
    model.compile(optimizer=adam, loss=root_mean_squared_error)
    return model

然后,我调用两个不同的模型来预测2个不同的卷:

model_systole= get_model()
model_diastole= get_model()
print('Fitting systole model...')
hist_systole = model_systole.fit_generator(generator_train_sys, nb_epoch = 1,samples_per_epoch=N_train,validation_data=generator_validate_sys,nb_val_samples=N_validate)

print('Fitting Diastole model...')
hist_diastole = model_diastole.fit_generator(generator_train_dia,nb_epoch = 1,samples_per_epoch=N_train,validation_data=generator_validate_dia, nb_val_samples=N_validate)

但是,我必须训练两个不同的模型,有2个卷积部分 .

===>我想我的网络,并添加2个不同的FC层来预测我的卷(1个独特的卷积部分和两个独立的FC层共享卷积部分)

你知道如何用Keras做到这一点吗?我是否必须切换到Keras图形模式?

非常感谢您的帮助 .

1 回答

  • 5

    当您两次调用 get_model() 时,它会创建两个不同的实例 . 这意味着它们将使用两个不同的初始权重集进行初始化 . 此外,它们是不同的模型,因此它们在反向传播期间没有任何关联 .

    您必须切换到 Model 类 . 我强烈建议您更新Keras,以便获得 Model 类而不是 Graph .

    input1 = Input(30 ,64, 64)
    input2 = Input(30 ,64, 64)
    conv1 = Conv2D(32, (3,3), padding='same', activation='relu') # shared
    
    model1 = conv1(input1)
    model2 = conv1(input2)
    model1 = Flatten()(model1)
    model2 = Flatten()(model2)
    
    # following dense layers do not share the weight
    model1 = Dense(512, activation='relu', kernel_regularizer=l2(1e-3))(model1)
    model2 = Dense(512, activation='relu', kernel_regularizer=l2(1e-3))(model2)
    model1 = Dense(1)(model1)
    model2 = Dense(1)(model2)
    
    model = Model(inputs=[input1, input2], outputs=[model1, model2])
    model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
    

    基本上,图层现在可以调用 . 所以我首先创建了一个卷积层并用两个不同的输入调用它,因此它的权重是共享的 . 但是,我通过两次实例化它们来调用两个密集层(如 Dense(512) ),因此它们不会被共享 .

相关问题