Keras中学习率与动量对准确率影响的3D绘图报错求解
plot_trisurf的Qhull三角化错误问题 首先,咱们来拆解你遇到的问题,这个错误本质是输入给三角化算法的数据不符合要求,结合你的代码来看,主要有两个核心问题,同时也能解释为什么示例代码可行而你的不行:
1. 数组赋值错误:np.append并没有修改你的准确率数组
你初始化了train_accuracies = np.empty([36]),但在循环里用np.append(train_accuracies, ...)的时候,numpy的append函数不会直接修改原数组——它会返回一个新的数组,而你没有把这个新数组赋值回原变量。这意味着你的train_accuracies和test_accuracies始终是初始的空数组(里面是未初始化的随机垃圾值),这肯定会让后续的绘图算法混乱。
而示例代码里的数组是直接生成的有效数据,没有赋值错误,所以能正常工作。
正确的做法是用索引来逐个填充数组:
# 初始化计数器 idx = 0 for learning_rate in learning_rates: for momentum in momentum_terms: # ... 你的模型构建、编译、训练代码 ... # 直接用索引赋值,而不是append train_accuracies[idx] = history.history['binary_accuracy'][-1] * 100 test_accuracies[idx] = history.history['val_binary_accuracy'][-1] * 100 idx += 1
2. x和y的维度与z不匹配
plot_trisurf要求x、y、z都是长度相同的一维数组,每个元素对应一个三维空间中的点(x[i], y[i], z[i])。但你现在的x是6个momentum值,y是6个learning rate值,z是36个准确率值,三者长度不一致。Qhull三角化算法无法处理这种不匹配的输入,所以抛出了"奇异输入数据"的错误。
示例代码里的x、y、z都是长度约1000的一维数组,每个点都有对应的(x,y,z),所以算法能正常处理。
你需要把x和y扩展成36个元素的数组,对应每个(learning_rate, momentum)组合:
# 生成所有(learning_rate, momentum)组合的x和y数组 x = np.repeat(momentum_terms, len(learning_rates)) # 每个momentum重复6次,对应6个learning rate y = np.tile(learning_rates, len(momentum_terms)) # 把learning rate数组重复6次,对应每个momentum z = test_accuracies
可选优化:用plot_surface替代plot_trisurf(更适合规则网格)
因为你的数据是规则的6x6网格(每个learning rate对应所有momentum),其实用plot_surface更合适——它不需要三角化,直接基于规则网格绘图,效果更规整:
# 生成二维网格 X, Y = np.meshgrid(momentum_terms, learning_rates) # 把test_accuracies转换成6x6的二维数组(对应网格的每个点) Z = test_accuracies.reshape(len(learning_rates), len(momentum_terms)) ax = plt.axes(projection='3d') ax.plot_surface(X, Y, Z, cmap='viridis', edgecolor='none') plt.show()
这样修改后,你的数据就完全符合绘图函数的要求了,应该能正常生成3D可视化图。
内容的提问来源于stack exchange,提问作者Daniel Whettam

