多输出 Keras 模型中消失的维度
Disappearing Dimensions in Multi-Output Keras Model
当我尝试训练下面描述的自动编码器时,我收到一个错误 ' 形状为 (256, 28, 28, 1) 的目标数组被传递用于形状输出 (None, 0, 28, 1) 作为损失`binary_crossentropy。此损失预计目标与输出具有相同的形状。' 输入和输出维度应均为 (28,28,1),其中 256 为批量大小。 运行.summary() 确认解码器模型的输出是正确的 (28,28,1),但是当编码器和解码器一起编译时,这似乎发生了变化。知道这里发生了什么吗?三个函数在生成网络的时候依次调用。
def buildEncoder():
input1 = Input(shape=(28,28,1))
input2 = Input(shape=(28,28,1))
merge = concatenate([input1,input2])
convEncode1 = Conv2D(16, (3,3), activation = 'relu', padding = 'same')(merge)
maxPoolEncode1 = MaxPooling2D(pool_size=(2, 1))(convEncode1)
convEncode2 = Conv2D(16, (3,3), activation = 'sigmoid', padding = 'same')(maxPoolEncode1)
convEncode3 = Conv2D(1, (3,3), activation = 'sigmoid', padding = 'same')(convEncode2)
model = Model(inputs = [input1,input2], outputs = convEncode3)
model.compile(loss='binary_crossentropy', optimizer=adam)
return model
def buildDecoder():
input1 = Input(shape=(28,28,1))
upsample1 = UpSampling2D((2,1))(input1)
convDecode1 = Conv2D(16, (3,3), activation = 'relu', padding = 'same')(upsample1)
crop1 = Cropping2D(cropping = ((0,28),(0,0)))(convDecode1)
crop2 = Cropping2D(cropping = ((28,0),(0,0)))(convDecode1)
convDecode2_1 = Conv2D(16, (3,3), activation = 'relu', padding = 'same')(crop1)
convDecode3_1 = Conv2D(16, (3,3), activation = 'relu', padding = 'same')(crop2)
convDecode2_2 = Conv2D(1, (3,3), activation = 'sigmoid', padding = 'same')(convDecode2_1)
convDecode3_2 = Conv2D(1, (3,3), activation = 'sigmoid', padding = 'same')(convDecode3_1)
model = Model(inputs=input1, outputs=[convDecode2_2,convDecode3_2])
model.compile(loss='binary_crossentropy', optimizer=adam)
return model
def buildAutoencoder():
autoInput1 = Input(shape=(28,28,1))
autoInput2 = Input(shape=(28,28,1))
encode = encoder([autoInput1,autoInput2])
decode = decoder(encode)
model = Model(inputs=[autoInput1,autoInput2], outputs=[decode[0],decode[1]])
model.compile(loss='binary_crossentropy', optimizer=adam)
return model
运行 model.summary() 函数确认了这个
的最终输出维度
看来您的编码器形状计算有误。您假设解码器将获得 (None, 28, 28, 1) 但您的编码器实际上输出 (None, 14, 28, 28, 1).
print(encoder) # Tensor("model_1/conv2d_3/Sigmoid:0", shape=(?, 14, 28, 1), dtype=float32)
现在在你的解码器中你正在裁剪等,假设你有 (28, 28, 1),这可能会把它切成 0。模型自己工作,当你连接它们时会发生不匹配。
当我尝试训练下面描述的自动编码器时,我收到一个错误 ' 形状为 (256, 28, 28, 1) 的目标数组被传递用于形状输出 (None, 0, 28, 1) 作为损失`binary_crossentropy。此损失预计目标与输出具有相同的形状。' 输入和输出维度应均为 (28,28,1),其中 256 为批量大小。 运行.summary() 确认解码器模型的输出是正确的 (28,28,1),但是当编码器和解码器一起编译时,这似乎发生了变化。知道这里发生了什么吗?三个函数在生成网络的时候依次调用。
def buildEncoder():
input1 = Input(shape=(28,28,1))
input2 = Input(shape=(28,28,1))
merge = concatenate([input1,input2])
convEncode1 = Conv2D(16, (3,3), activation = 'relu', padding = 'same')(merge)
maxPoolEncode1 = MaxPooling2D(pool_size=(2, 1))(convEncode1)
convEncode2 = Conv2D(16, (3,3), activation = 'sigmoid', padding = 'same')(maxPoolEncode1)
convEncode3 = Conv2D(1, (3,3), activation = 'sigmoid', padding = 'same')(convEncode2)
model = Model(inputs = [input1,input2], outputs = convEncode3)
model.compile(loss='binary_crossentropy', optimizer=adam)
return model
def buildDecoder():
input1 = Input(shape=(28,28,1))
upsample1 = UpSampling2D((2,1))(input1)
convDecode1 = Conv2D(16, (3,3), activation = 'relu', padding = 'same')(upsample1)
crop1 = Cropping2D(cropping = ((0,28),(0,0)))(convDecode1)
crop2 = Cropping2D(cropping = ((28,0),(0,0)))(convDecode1)
convDecode2_1 = Conv2D(16, (3,3), activation = 'relu', padding = 'same')(crop1)
convDecode3_1 = Conv2D(16, (3,3), activation = 'relu', padding = 'same')(crop2)
convDecode2_2 = Conv2D(1, (3,3), activation = 'sigmoid', padding = 'same')(convDecode2_1)
convDecode3_2 = Conv2D(1, (3,3), activation = 'sigmoid', padding = 'same')(convDecode3_1)
model = Model(inputs=input1, outputs=[convDecode2_2,convDecode3_2])
model.compile(loss='binary_crossentropy', optimizer=adam)
return model
def buildAutoencoder():
autoInput1 = Input(shape=(28,28,1))
autoInput2 = Input(shape=(28,28,1))
encode = encoder([autoInput1,autoInput2])
decode = decoder(encode)
model = Model(inputs=[autoInput1,autoInput2], outputs=[decode[0],decode[1]])
model.compile(loss='binary_crossentropy', optimizer=adam)
return model
运行 model.summary() 函数确认了这个
的最终输出维度看来您的编码器形状计算有误。您假设解码器将获得 (None, 28, 28, 1) 但您的编码器实际上输出 (None, 14, 28, 28, 1).
print(encoder) # Tensor("model_1/conv2d_3/Sigmoid:0", shape=(?, 14, 28, 1), dtype=float32)
现在在你的解码器中你正在裁剪等,假设你有 (28, 28, 1),这可能会把它切成 0。模型自己工作,当你连接它们时会发生不匹配。