TensorFlow中predict_on_batch重复输出首个结果的问题求助
颜色分类模型predict_on_batch输出重复结果的问题
在用TensorFlow构建颜色分类模型时,调用predict_on_batch方法对输入样本集进行预测时,模型始终重复输出首个样本的预测结果,而非为每个输入生成对应结果。
原代码
import tensorflow as tf import numpy as np x = np.array([[1, 0, 0], #x1 [1, 0.5, 0], #x2 [1, 1, 0], #x3 [0.5, 1, 0], #x4 [0, 1, 0], #x5 [0, 1, 0.5], #x6 [0, 1, 1], #x7 [0, 0.5, 1], #x8 [0, 0, 1], #x9 [0.5, 0, 1], #x10 [1, 0, 1], #x11 [1, 0, 1]]) #x12 #Key: #[red, orange, yellow, green, blue, purple] y = np.array([[1,0,0,0,0,0], #y1 [0,1,0,0,0,0], #y2 [0,0,1,0,0,0], #y3 [0,0,0,1,0,0], #y4 [0,0,0,1,0,0], #y5 [0,0,0,1,0,0], #y6 [0,0,0,0,1,0], #y7 [0,0,0,0,1,0], #y8 [0,0,0,0,1,0], #y9 [0,0,0,0,0,1], #y10 [0,0,0,0,0,1], #y11 [1,0,0,0,0,0]]) #y12 # Define the model model = tf.keras.models.Sequential() model.add(tf.keras.Input(shape=(3))) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(10, activation=tf.keras.activations.sigmoid)) model.add(tf.keras.layers.Dense(6, activation=tf.keras.activations.sigmoid)) # Compile the model model.compile(tf.keras.optimizers.Adam(learning_rate=0.1), "BinaryCrossentropy", metrics=[ 'binary_accuracy']) model.summary() history = model.fit(x, y, batch_size=1, epochs=500) predictions = model.predict_on_batch(x) print(predictions)
原预测输出
[[0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773] [0.16287932 0.07145664 0.08749434 0.26094046 0.25779992 0.16714773]]
问题原因及修复方案
核心问题
- 梯度消失:堆叠10层全连接层+sigmoid激活,sigmoid的梯度在输入远离0时趋近于0,多层叠加后梯度几乎消失,模型参数无法有效更新,最终所有输出趋于一致。
- 损失函数与激活不匹配:这是多分类任务(每个样本属于唯一类别),应使用
CategoricalCrossentropy损失函数,且最后一层激活用softmax(输出和为1,代表类别概率),而非BinaryCrossentropy+sigmoid(适用于多标签任务)。 - 学习率过高:Adam优化器默认学习率为0.001,设置0.1会导致训练过程震荡,无法收敛。
修复后的代码
import tensorflow as tf import numpy as np x = np.array([[1, 0, 0], #x1 [1, 0.5, 0], #x2 [1, 1, 0], #x3 [0.5, 1, 0], #x4 [0, 1, 0], #x5 [0, 1, 0.5], #x6 [0, 1, 1], #x7 [0, 0.5, 1], #x8 [0, 0, 1], #x9 [0.5, 0, 1], #x10 [1, 0, 1], #x11 [1, 0, 1]]) #x12 #Key: #[red, orange, yellow, green, blue, purple] y = np.array([[1,0,0,0,0,0], #y1 [0,1,0,0,0,0], #y2 [0,0,1,0,0,0], #y3 [0,0,0,1,0,0], #y4 [0,0,0,1,0,0], #y5 [0,0,0,1,0,0], #y6 [0,0,0,0,1,0], #y7 [0,0,0,0,1,0], #y8 [0,0,0,0,1,0], #y9 [0,0,0,0,0,1], #y10 [0,0,0,0,0,1], #y11 [1,0,0,0,0,0]]) #y12 # 简化模型结构,改用ReLU避免梯度消失 model = tf.keras.models.Sequential() model.add(tf.keras.Input(shape=(3))) model.add(tf.keras.layers.Dense(32, activation='relu')) model.add(tf.keras.layers.Dense(16, activation='relu')) model.add(tf.keras.layers.Dense(6, activation='softmax')) # 多分类用softmax # 多分类任务使用CategoricalCrossentropy,调整学习率 model.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss=tf.keras.losses.CategoricalCrossentropy(), metrics=['categorical_accuracy'] ) model.summary() history = model.fit(x, y, batch_size=4, epochs=200) predictions = model.predict_on_batch(x) # 打印每个样本的预测类别(概率最大的索引) print("预测类别索引:", np.argmax(predictions, axis=1)) print("预测概率矩阵:") print(predictions)
修复效果
修复后,模型会输出每个样本对应的不同预测结果,np.argmax(predictions, axis=1)会输出与样本匹配的类别索引,概率矩阵每行结果不再重复。
内容的提问来源于stack exchange,提问作者John Justininininininininings
相关产品推荐
相关产品推荐

