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

Jer*_*meK 3 python theano conv-neural-network keras tensorflow

我正致力于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
Run Code Online (Sandbox Code Playgroud)

然后,我调用两个不同的模型来预测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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

非常感谢您的帮助.

Par*_*kar 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'])
Run Code Online (Sandbox Code Playgroud)

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