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

Python无隐藏层双输出XOR神经网络权重矩阵收缩问题求助

问题修复:双输出XOR神经网络权重矩阵收缩问题

错误原因

核心问题出在权重更新的代码行:

w = w[:, i]-np.transpose(dw)

这行代码直接将整个权重矩阵w替换成了第i列的向量减去dw,导致原本(3,2)的矩阵变成一维数组,后续迭代自然无法正常进行。正确的做法应该是只更新权重矩阵的第i列,而不是替换整个矩阵。

此外还有两处次要问题:

  • sigmoid函数的导数计算重复计算了sigmoid(x),可以直接用已计算的结果简化。
  • 训练循环中的前向传播和误差计算维度需要调整,确保和目标值维度匹配。

修复后的完整代码

import numpy as np

data = np.array([[0, 0],
                [0, 1],
                [1, 0],
                [1, 1]])
data = np.transpose(data)
print("Data:")
print(data)

# 双输出XOR目标:[第一个输出, 第二个输出]
target = np.array([[0, 1],
                   [1, 0],
                   [1, 0],
                   [0, 1]])
print("Targets:")
print(target)

numberOfColumns = data.shape[1]
print('Number of columns', numberOfColumns)

inputSize = data.shape[0]
print('Number of rows', inputSize)

# 添加偏置项(全1行)
data = np.r_[data, np.ones((1, numberOfColumns), int)]

# 修正后的sigmoid函数,导数计算更高效
def sigmoid(x, derivative=False):
    v = 1 / (1 + np.exp(-x))
    if derivative:
        # 直接用已计算的v,避免重复计算sigmoid
        v = v * (1 - v)
    return v

def linear(x, derivative=False):
    v = x
    if derivative:
        v = np.ones(x.shape)
    return v

eta = 0.1  # 学习率
epochs = 10000  # 增加迭代次数,确保收敛
afun = sigmoid
# 初始权重矩阵(3,2):3个输入(含偏置),2个输出
w = np.array([[0.01, 0.2],
              [0.1, 0.1],
              [0.2, 0.01]])

# 训练前的预测与误差计算
y = afun(np.dot(w.T, data)).T
e = np.mean(0.5 * np.power(y - target, 2))

print("\nBefore training")
print("Weights:")
print(w)
print("Y:")
print(y)
print("Error:")
print(e)

print("\nData after polarization:")
print(data)

print("\nLearning")

for epoch in range(epochs):
    total_error = 0
    for j in range(numberOfColumns):
        # 当前样本:(3,) 维度
        x_sample = data[:, j]
        # 前向传播:计算两个输出值,(2,) 维度
        y_pred = afun(np.dot(x_sample, w))
        # 计算误差:(2,) 维度
        error = y_pred - target[j]
        total_error += np.sum(0.5 * np.power(error, 2))
        
        # 遍历每个输出,更新对应权重列
        for i in range(error.shape[0]):
            # 计算梯度:(3,) 维度
            dw = eta * error[i] * afun(np.dot(x_sample, w[:, i]), derivative=True) * x_sample
            # 关键修复:只更新第i列权重,不替换整个矩阵
            w[:, i] -= dw

    # 每1000轮打印一次误差,监控训练进度
    if epoch % 1000 == 0:
        print(f"Epoch {epoch}, Mean Error: {total_error / numberOfColumns:.4f}")

# 训练后的预测与误差计算
y = afun(np.dot(w.T, data)).T
e = np.mean(0.5 * np.power(y - target, 2))

print("\nAfter training")
print("Weights:")
print(w)
print("Net output:")
print(y)
print("Error:")
print(e)

关键修改点说明

  • 权重更新逻辑:将w = w[:, i]-np.transpose(dw)改为w[:, i] -= dw,确保只修改权重矩阵的指定列,保留矩阵结构。
  • sigmoid导数优化:直接使用已计算的sigmoid(x)值计算导数,避免重复计算提升效率。
  • 训练监控:添加每1000轮打印一次误差的逻辑,方便观察训练收敛情况。
  • 迭代次数调整:将epochs从1000增加到10000,确保双输出XOR任务的收敛。
  • 代码简化:合并训练前的预测循环,用矩阵运算替代逐样本循环,提升可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 16:30:09