TensorFlow预测报错:仅整数标量数组可转换为标量索引
错误原因
触发TypeError: only integer scalar arrays can be converted to a scalar index的核心原因是索引类型不匹配:
- 你代码里
pred.argmax(axis=1)返回的是形状为(1,)的一维numpy数组(即你排查到的array([3], dtype=int64)),不是整数标量。 class_names是普通Python列表,Python列表仅支持整数标量做索引,不支持一维numpy数组作为索引,因此报错。
你之前的判断有误:带维度的单元素数组不是标量,标量是0维数组/原生Python整数,例如直接输出3而非array([3])。
修复方法
只需要把argmax返回的一维数组转为整数标量即可,两种写法都可以:
- 对单样本预测的结果,直接调用
pred.argmax()不传axis参数,会全局查找最大值索引,直接返回整数标量 - 保留
argmax(axis=1)的写法,后续取[0]拿到第一个元素,即pred.argmax(axis=1)[0]
另外原函数还有几个不影响运行但体验较差的小问题,一并修复:
- 子图网格计算逻辑会生成多余空位,优化为自适应行列数
model.predict默认会打印进度条,加verbose=0屏蔽冗余日志- 显式传入
class_names参数,避免依赖全局变量 - 增加
tight_layout()自动调整布局,避免标题、子图重叠 - 置信度保留2位小数,可读性更强
修复后的完整函数代码如下:
import random import numpy as np import matplotlib.pyplot as plt def show_image_labels(num_pred=1, model=None, data=None, labels=None, class_names=None, figsize=(12, 12)): plt.figure(figsize=figsize) # 自适应计算子图行列数 col_count = int(np.ceil(np.sqrt(num_pred))) row_count = int(np.ceil(num_pred / col_count)) for i in range(num_pred): plt.subplot(row_count, col_count, i+1) random_index = random.choice(range(len(data))) plt.imshow(data[random_index], cmap=plt.cm.binary) # 单样本预测,屏蔽日志输出 pred = model.predict(data[random_index].reshape(1, 28, 28), verbose=0) # 修复索引问题,获取整数标量索引 pred_label = class_names[pred.argmax()] true_label = class_names[labels[random_index]] confidence = np.max(pred) plt.title(f'Prediction: {pred_label}\nTrue label: {true_label}\nConfidence: {confidence:.2f}') plt.axis(False) plt.tight_layout() plt.show()
调用时把class_names参数传入即可正常运行,示例调用:
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot'] show_image_labels(num_pred=16, model=model_8, data=test_data_norm, labels=test_labels, class_names=class_names, figsize=(20, 20))
内容的提问来源于stack exchange,提问作者Andrzej Olejniczak
相关产品推荐
相关产品推荐

