使用ResNet50构建图像字幕模型时调用model.predict()报ndim属性错误
问题分析与解决方案
嘿,我一眼就揪出了导致这个错误的两个关键问题,咱们一步步来修正:
核心错误点
- 直接传递字符串给模型预测:你明明已经对
inSeq做了tokenizer编码和序列填充,得到了符合模型输入要求的sequence,但调用model.predict()时却错误地传入了原始字符串inSeq——Keras模型只接受数值型张量,自然会报错说字符串没有ndim属性。 - 未正确解析模型预测结果:
model.predict()返回的是形状类似(1, vocab_size)的概率分布数组,你需要先提取概率最大的索引(用np.argmax()),再传给word_for_id,而不是直接把整个数组丢进去。另外你的word_for_id调用还漏传了tokenizer参数!
修正后的createCaptions函数
def createCaptions(tokenizer, photoData, MaxLength, model): # 可选:如果需要保存生成的字幕,初始化一个列表 captions = [] for key, feature in photoData.items(): inSeq = "START" for i in range(MaxLength): # 对输入序列做编码和填充(这部分你之前写了但没用到) sequence = tokenizer.texts_to_sequences([inSeq])[0] sequence = pad_sequences([sequence], maxlen=MaxLength) # 传入处理好的sequence,而非原始字符串inSeq # 图像特征可以用squeeze简化维度处理 pred = model.predict([feature.squeeze(), sequence]) # 取概率最大的词索引 word_id = np.argmax(pred[0]) # 正确传递tokenizer参数给word_for_id ID = word_for_id(word_id, tokenizer) if ID is None: break inSeq += " " + ID if ID == "END": break print(inSeq) captions.append(inSeq) return captions # 可选:返回生成的字幕列表
配套修正word_for_id函数
确保函数参数和调用一致:
def word_for_id(integer, tokenizer): for word, index in tokenizer.word_index.items(): if index == integer: return word return None
额外优化提示
- 图像特征处理可以用
feature.squeeze()替代feature[0][0][0],不管原始特征是(1,1,1,2048)还是其他嵌套形状,都能直接得到(2048,)的一维数组,更鲁棒。 - 原代码中
caption = createCaptions(...)不会得到有效结果,因为函数原本没有返回值,修正后的函数添加了返回字幕列表的逻辑,方便后续使用。
内容的提问来源于stack exchange,提问作者anonymous
相关产品推荐
相关产品推荐

