基于神经网络的双输入XOR门权重赋值异常求助
解决手动设置权重实现XOR门的问题
我来帮你梳理下代码里的问题,以及如何修正得到正确的XOR输出:
核心问题分析
- 无效的
__init__方法:你写了__init__但没有定义类,这在当前代码里完全不起作用,权重设置逻辑根本没执行。而且你试图用输入样本的x1/x2来动态设置权重,但手动设置权重应该是固定的,和输入样本无关——我们需要的是一组通用权重,能处理所有XOR的输入组合。 - 激活函数选择错误:
softmax用于多分类任务,单神经元用softmax会强制输出为1,这就是你得到全1的原因;- 之前用
sigmoid/linear输出不对,是因为权重设置逻辑错误,不是激活函数本身的问题。
- 权重逻辑不符合XOR的计算规则:你原来的权重设置没有正确构建XOR所需的中间逻辑(XOR等价于
(x1 AND NOT x2) OR (NOT x1 AND x2))。
修正后的代码
import numpy as np import keras # 构建模型:隐藏层2个神经元(relu激活),输出层1个神经元(linear激活) model = keras.models.Sequential() model.add(keras.layers.Dense(2, activation='relu', input_shape=(2,), use_bias=False)) # 隐藏层 model.add(keras.layers.Dense(1, activation='linear', use_bias=False)) # 输出层用linear,直接输出数值 # 手动设置权重:符合XOR的逻辑 # w1: 输入层(2个神经元) → 隐藏层(2个神经元)的权重 w1 = np.array([ [1, -1], # 第一个隐藏神经元:计算x1 - x2 → 对应x1 AND NOT x2的逻辑(relu后只有x1=1,x2=0时输出1) [-1, 1] # 第二个隐藏神经元:计算-x1 + x2 → 对应NOT x1 AND x2的逻辑(relu后只有x1=0,x2=1时输出1) ]) # w2: 隐藏层(2个神经元) → 输出层(1个神经元)的权重 w2 = np.array([[1], [1]]) # 把两个隐藏神经元的输出相加,得到XOR结果 # 加载权重到模型 model.set_weights([w1, w2]) # 测试XOR的所有输入组合 x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) predictions = model.predict(x) print("XOR输出结果:") for input_val, pred in zip(x, predictions): print(f"输入{input_val} → 输出{round(pred[0])}")
代码解释
- 模型结构:
- 隐藏层用
relu激活,因为我们需要把负数输出置0,只保留符合条件的正输出; - 输出层用
linear激活,直接输出隐藏层结果的和,正好对应XOR的0/1输出。
- 隐藏层用
- 权重逻辑:
- 第一个隐藏神经元:
x1*1 + x2*(-1),当x1=1,x2=0时结果为1(relu后保留1),其他情况结果≤0(relu后变为0); - 第二个隐藏神经元:
x1*(-1) + x2*1,当x1=0,x2=1时结果为1(relu后保留1),其他情况结果≤0(relu后变为0); - 输出层把两个隐藏神经元的输出相加:只有当其中一个隐藏神经元输出1时,结果为1(对应XOR的真),否则为0(对应XOR的假)。
- 第一个隐藏神经元:
- 测试结果:运行代码后会输出:
完全符合XOR门的预期结果。XOR输出结果: 输入[0 0] → 输出0 输入[0 1] → 输出1 输入[1 0] → 输出1 输入[1 1] → 输出0
如果你想改用sigmoid作为输出层激活函数,只需要把输出层的activation='linear'改成activation='sigmoid',然后权重可以保持不变,此时输出会是接近0或1的概率值,你可以用round(pred[0])来得到0/1的结果。
内容的提问来源于stack exchange,提问作者Lavanya
相关产品推荐
相关产品推荐

