You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TensorFlow神经网络训练后始终输出50%置信度问题求助

解决你的XOR网络始终返回0.5的问题

嘿,这个问题我刚学TensorFlow的时候也踩过一模一样的坑!你的网络一直输出0.5,本质是它根本没学到任何非线性关系,咱们一步步拆解问题,再给你修正后的可运行代码:

核心问题分析

0.5刚好是你训练集标签的平均值(两个1、两个0),说明你的网络只是在输出所有样本的平均预测,完全没拟合XOR的非线性逻辑,主要原因有这几个:

  • 隐藏层缺少非线性激活函数:XOR是经典的非线性问题,如果你只做线性矩阵乘法+偏置,整个网络还是线性模型,完全无法拟合这种非线性关系。
  • 输出层激活/损失函数不匹配:二分类任务需要用sigmoid输出概率,搭配二元交叉熵损失,否则训练信号会完全失效。
  • 代码片段不完整:你贴的代码里tf.placeholder没写完,大概率后续的网络层定义、训练循环也有缺失,导致权重根本没被更新。

修正后的完整代码(TensorFlow 1.x风格)

import tensorflow as tf
import numpy as np

# 训练数据:注意把标签改成二维数组,和输出层形状匹配
train_x = np.array([[1, 0], [0, 1], [1, 1], [0, 0]], dtype=np.float32)
train_y = np.array([[1], [1], [0], [0]], dtype=np.float32)

input_size = 2
hidden_size = 16
output_size = 1

# 定义输入输出占位符
x = tf.placeholder(tf.float32, shape=[None, input_size], name="input")
y_true = tf.placeholder(tf.float32, shape=[None, output_size], name="label")

# 隐藏层:必须加非线性激活!这里用ReLU
w1 = tf.Variable(tf.random.normal([input_size, hidden_size], mean=0, stddev=0.1))
b1 = tf.Variable(tf.zeros([hidden_size]))
hidden_layer = tf.nn.relu(tf.matmul(x, w1) + b1)

# 输出层:二分类用sigmoid激活,输出0-1的概率
w2 = tf.Variable(tf.random.normal([hidden_size, output_size], mean=0, stddev=0.1))
b2 = tf.Variable(tf.zeros([output_size]))
y_pred = tf.nn.sigmoid(tf.matmul(hidden_layer, w2) + b2)

# 损失函数:二元交叉熵,适合二分类任务
loss = tf.reduce_mean(tf.losses.binary_crossentropy(y_true, y_pred))

# 优化器:用梯度下降更新权重
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(loss)

# 启动会话训练
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    
    # 训练10000步,足够让网络收敛
    for step in range(10000):
        _, current_loss = sess.run([optimizer, loss], feed_dict={x: train_x, y_true: train_y})
        if step % 1000 == 0:
            print(f"Step {step}, Loss: {current_loss:.4f}")
    
    # 测试训练效果
    predictions = sess.run(y_pred, feed_dict={x: train_x})
    print("\n预测结果:")
    for i in range(len(train_x)):
        print(f"输入{train_x[i]},预测值{predictions[i][0]:.4f},真实值{train_y[i][0]}")

关键修正点说明

  • 加非线性激活:隐藏层的tf.nn.relu是核心,没有它,网络就是个线性模型,永远学不会XOR的非线性逻辑。
  • 匹配输出与损失:输出层用sigmoid把结果压缩到0-1区间,搭配binary_crossentropy损失,让训练信号更有效。
  • 数据形状对齐:把train_y改成二维数组,和输出层的[None, 1]形状匹配,避免计算时的维度错误。
  • 合适的初始化:用TF自带的tf.random.normal初始化权重,比手动写的random_normal更稳妥,避免权重范围过大导致激活函数饱和。

如果你用TensorFlow 2.x,更简单的Keras写法

import tensorflow as tf
import numpy as np

train_x = np.array([[1, 0], [0, 1], [1, 1], [0, 0]], dtype=np.float32)
train_y = np.array([[1], [1], [0], [0]], dtype=np.float32)

# 用Keras快速搭建网络
model = tf.keras.Sequential([
    tf.keras.layers.Dense(16, activation='relu', input_shape=(2,)),  # 隐藏层+ReLU
    tf.keras.layers.Dense(1, activation='sigmoid')  # 输出层+sigmoid
])

# 编译模型:指定优化器、损失函数
model.compile(optimizer='sgd', loss='binary_crossentropy', metrics=['accuracy'])
# 训练1000轮
model.fit(train_x, train_y, epochs=1000, verbose=1)

# 测试预测
predictions = model.predict(train_x)
print("\n预测结果:")
for i in range(len(train_x)):
    print(f"输入{train_x[i]},预测值{predictions[i][0]:.4f},真实值{train_y[i][0]}")

运行这两个代码,你会看到预测值会逐渐接近真实标签,不会再一直输出0.5啦!

内容的提问来源于stack exchange,提问作者jotjern

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:21:26