Keras合并两个CNN模型时出现Graph disconnected错误求助
解决Keras多输入模型图断开问题
问题场景
尝试用Keras合并两个CNN模型,实现代码如下:
import keras from keras import Model from keras.layers.core import Dense, Activation from keras.layers import Conv2D, Conv1D, MaxPooling2D, Reshape, Concatenate, Dropout , MaxPooling1D, Flatten from keras.layers import Dense, Input, LeakyReLU from keras.utils.vis_utils import plot_model input_p=Input(shape=(2001,1),name='in_p') input_sp=Input(shape=(25,2),name='in_sp') ###CNN for P wave model_p_in = Input((2001,1)) #1 2001 to 1000 model_p = Conv1D(filters=64, kernel_size=3, strides=2)(model_p_in) model_p = LeakyReLU(alpha=0.05)(model_p) #2 1000 to 500 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #3 500 to 250 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #4 250 to 125 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #5 125 to 62 model_p = Conv1D(filters=64, kernel_size=3, strides=2)(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #6 62 to 31 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #7 31 to 15 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #8 15 to 7 model_p = Conv1D(filters=64, kernel_size=3, strides=2)(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #9 7 to 3 model_p = Conv1D(filters=64, kernel_size=3, strides=2)(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) model_p = Flatten()(model_p) model_p = Dense(64)(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) ###CNN for spectrums model_sp_in = Input((25,2)) #1 25 to 25 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp_in) model_sp = LeakyReLU(alpha=0.05)(model_sp) #2 25 to 25 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #3 25 to 12 model_sp = Conv1D(filters=64, kernel_size=3, strides=2)(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #4 12 to 12 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #5 12 to 12 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #6 12 to 6 model_sp = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #7 6 to 6 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #8 6 to 6 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #9 6 to 3 model_sp = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) model_sp = Flatten()(model_sp) model_sp = Dense(64)(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) ###Combine two CNNs model_merged = Concatenate()([model_p, model_sp]) model_merged = Dense(128)(model_merged) output = Dense(2, activation='softmax')(model_merged) model_final = Model(inputs=[input_p, input_sp], outputs=[output],name='model_p_sp') plot_model(model_final, to_file='model_final.png')
运行时出现错误:
model_final = Model(inputs=[input_p, input_sp], outputs=[output],name='model_p_sp') ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_20:0", shape=(?, 25, 2), dtype=float32) at layer "input_20". The following previous layers were accessed without issue: []
错误原因
你定义了两组完全独立的Input层:
- 全局的
input_p和input_sp(最终用来构建模型的输入) - 分支内部的
model_p_in和model_sp_in(实际连接CNN层的输入)
这两组Input没有任何关联,导致input_p/input_sp无法连接到后续的CNN分支,计算图断裂,因此报错。
修正方案
直接用一开始定义的input_p和input_sp作为两个CNN分支的输入,删除分支内部多余的model_p_in和model_sp_in定义。
修正后的完整代码:
import keras from keras import Model from keras.layers.core import Dense, Activation from keras.layers import Conv2D, Conv1D, MaxPooling2D, Reshape, Concatenate, Dropout , MaxPooling1D, Flatten from keras.layers import Dense, Input, LeakyReLU from keras.utils.vis_utils import plot_model input_p=Input(shape=(2001,1),name='in_p') input_sp=Input(shape=(25,2),name='in_sp') ###CNN for P wave # 直接用input_p作为分支输入,删除多余的model_p_in model_p = Conv1D(filters=64, kernel_size=3, strides=2)(input_p) model_p = LeakyReLU(alpha=0.05)(model_p) #2 1000 to 500 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #3 500 to 250 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #4 250 to 125 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #5 125 to 62 model_p = Conv1D(filters=64, kernel_size=3, strides=2)(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #6 62 to 31 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #7 31 to 15 model_p = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #8 15 to 7 model_p = Conv1D(filters=64, kernel_size=3, strides=2)(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) #9 7 to 3 model_p = Conv1D(filters=64, kernel_size=3, strides=2)(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) model_p = Flatten()(model_p) model_p = Dense(64)(model_p) model_p = LeakyReLU(alpha=0.05)(model_p) ###CNN for spectrums # 直接用input_sp作为分支输入,删除多余的model_sp_in model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(input_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #2 25 to 25 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #3 25 to 12 model_sp = Conv1D(filters=64, kernel_size=3, strides=2)(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #4 12 to 12 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #5 12 to 12 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #6 12 to 6 model_sp = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #7 6 to 6 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #8 6 to 6 model_sp = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) #9 6 to 3 model_sp = Conv1D(filters=64, kernel_size=3, strides=2, padding='same')(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) model_sp = Flatten()(model_sp) model_sp = Dense(64)(model_sp) model_sp = LeakyReLU(alpha=0.05)(model_sp) ###Combine two CNNs model_merged = Concatenate()([model_p, model_sp]) model_merged = Dense(128)(model_merged) output = Dense(2, activation='softmax')(model_merged) model_final = Model(inputs=[input_p, input_sp], outputs=[output],name='model_p_sp') plot_model(model_final, to_file='model_final.png')
说明
修正后,input_p和input_sp直接连接到各自的CNN分支,计算图完整,不会再出现断开的问题。运行代码后,就能正常生成模型结构并保存为图片。
内容的提问来源于stack exchange,提问作者user20436147
相关产品推荐
相关产品推荐

