从Keras神经网络中间层提取嵌入时遇TypeError错误求助
Keras提取中间层输出报错的解决方法
问题场景
构建了包含预训练Word2Vec嵌入的Keras模型,尝试提取Embedding层的输出时触发TypeError,核心代码与错误信息如下:
核心代码片段
words_input = Input(shape=(500,),dtype='int32',name='words_input') words = Embedding(input_dim=wordEmbeddings.shape[0], output_dim=wordEmbeddings.shape[1], weights=[wordEmbeddings], trainable=False)(words_input) # ... 其余层定义省略 model = Model(inputs=words_input, outputs=dense_2) # 出错的代码行 extractor = Model(inputs=model.inputs, outputs=model.get_layer(words).output)
错误信息
TypeError Traceback (most recent call last) /tmp/ipykernel_6732/2108362002.py in <module> 11 sgd = keras.optimizers.Adam(lr=0.0001) 12 model = Model(inputs=words_input, outputs=dense_2) ---> 13 extractor = Model(inputs=model.inputs, outputs=model.get_layer(words).output) 14 model.compile(loss='mean_squared_error', optimizer='adam', metrics=['acc']) 15 model.summary() ~/.local/lib/python3.8/site-packages/keras/engine/training.py in get_layer(self, name, index) 3271 if name is not None: 3272 for layer in self.layers: -> 3273 if layer.name == name: 3274 return layer 3275 raise ValueError( TypeError: Exception encountered when calling layer "tf.__operators__.eq" (type TFOpLambda). Expected float32 passed to parameter 'y' of op 'Equal', got 'words_input' of type 'str' instead. Error: Expected float32, but got words_input of type 'str'.
错误原因
model.get_layer()方法的参数要求是层的名称字符串或者层的索引值,而你传入的是words这个Embedding层的对象本身。Keras内部会尝试将这个层对象的张量值与各层的名称字符串做比较,导致类型不匹配,触发上述错误。
解决方案
提供两种简单可行的修复方式:
方式1:通过层名称获取输出
先给Embedding层指定明确的名称,再通过名称提取输出:
# 修改Embedding层定义,添加name参数 words = Embedding(input_dim=wordEmbeddings.shape[0], output_dim=wordEmbeddings.shape[1], weights=[wordEmbeddings], trainable=False, name='pre_trained_embedding')(words_input) # 提取层输出时使用名称 extractor = Model(inputs=model.inputs, outputs=model.get_layer('pre_trained_embedding').output)
方式2:直接使用层对象获取输出
既然已经持有words层的引用,无需调用get_layer(),直接访问其output属性即可:
extractor = Model(inputs=model.inputs, outputs=words.output)
额外提示
你的代码中定义了sgd = keras.optimizers.Adam(lr=0.0001)但后续model.compile()时使用的是optimizer='adam',这行定义并未生效,若要使用自定义学习率的Adam,需改为optimizer=sgd。
内容的提问来源于stack exchange,提问作者Atirag
相关产品推荐
相关产品推荐

