Keras模型用于具有不同通道数的多个输入

时间:2020-06-14 05:41:47

标签: python keras

我正在尝试使用Keras创建卷积神经网络。我想要两个采用不同输入但共享相同架构和权重的模型-所需的架构如下所示。我将如何使用Keras定义这样的模型?

Classifier 1 takes only input a whereas classifier 2 takes both a and b inputs. SO they can be concatenated to increase the depth to

我尝试如下实现此目标:

from keras.layers import Input,Conv2D,Activation,Flatten,Concatenate, MaxPooling2D, Dense
from keras.models import Model

def combined_model():

    a = Input(shape=(100,100,None))   ## should not change this
    fe = Conv2D(3, (1,1), strides=(2,2), padding='same', kernel_initializer=initl)(a) 
    fe = MaxPooling2D()(fe)
    fe = Flatten()(fe)
    fe = Dense(3)(fe)
    class1 = Activation('sigmoid')(fe)
    c_model = Model(a, class1, name = "c_model")
    c_model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    fe = Dense(1)(fe)
    class2 = Activation('sigmoid')(fe)
    d_model = Model(a, class2, name = "d_model")
    d_model.compile(loss= 'binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    return c_model, d_model

c,d = combined_model()

但是,它导致错误:

ValueError: The channel dimension of the inputs should be defined. Found `None`

1 个答案:

答案 0 :(得分:2)

简单答案: 只需如下定义输入形状并显式设置通道形状即可:

a = Input(shape=(100, 100, 3))

如果您要具有多个输入(具有不同的通道形状),则可以简单地创建多个输入:

a = Input(shape=(100, 100, 3))
b = Input(shape=(100, 100, 3)) # or Input(shape=(100, 100, 1))

在示例中,您还错误地将一个密集层的输出连接到另一层。但是基于提供的模型架构图,您想要将平坦层的输出连接到每个密集层(您可以在下面看到实现细节)。

实施:

在下面的代码中,我正确设置了输入形状,还将平坦层的输出传递到每个密集(3和1)层(您错误地将一个密集的输出传递给了另一层)。

重要说明::您要将两个输入图像传递给“分类器2”,但不能将两个图像直接传递给CNN层,而是可以对每个输入使用单独的CNN,然后连接它们的结果,如以下代码所示:

from keras.layers import Input,Conv2D,Activation,Flatten,Concatenate, MaxPooling2D, Dense, concatenate
from keras.models import Model

def combined_model():
    a = Input(shape=(100, 100, 3))
    b = Input(shape=(100, 100, 3))
    fe = Conv2D(3, (1,1), strides=(2,2), padding='same', kernel_initializer=initl)(a) 
    fe = MaxPooling2D()(fe)
    flattened1 = Flatten()(fe)

    fe = Conv2D(3, (1,1), strides=(2,2), padding='same')(b) 
    fe = MaxPooling2D()(fe)
    flattened2 = Flatten()(fe)

    fe = Dense(3)(flattened1)
    class1 = Activation('sigmoid')(fe)
    c_model = Model(a, class1, name = "c_model")
    c_model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

    fe = Dense(1)(concatenate([flattened1, flattened2]))
    class2 = Activation('sigmoid')(fe)
    d_model = Model([a, b], class2, name = "d_model")
    d_model.compile(loss= 'binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    return c_model, d_model

c,d = combined_model()
from keras.utils import plot_model
plot_model(c, 'c.png')
plot_model(d, 'd.png')

模型架构(我已经一起展示了两个模型,因为它们具有共享的层): enter image description here