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

关于softmax反向传播适配MNIST神经网络的技术咨询

问题分析与解决方案

首先,你的softmax反向传播实现是错误的,这才是导致维度不匹配报错的核心原因,而非linear_backward方法本身不兼容。让我一步步拆解问题:

问题1:当前softmax_backward的核心问题

你现在的softmax_backward函数返回的是softmax输出的雅各比矩阵(形状为(m*n, m*n),其中m是样本数,n是类别数),但linear_backward期望接收的是和Z同形状的dZ张量(形状为(n_classes, m),对应每个样本每个类别的梯度)。这直接导致了报错里的维度不匹配:(10000,10000) 的dZ和 (20,1000) 的A_prev.T无法进行矩阵乘法。

另外,你调用softmax时还犯了一个低级错误:x, _ =softmax(dA) 这里应该传入的是Z,而非dA,但即便修正这个问题,返回雅各比矩阵的思路依然不适合你的反向传播流程。

问题2:正确的softmax反向传播实现(结合交叉熵损失)

在实际神经网络开发中,我们几乎不会单独计算softmax的导数——因为softmax通常和交叉熵损失搭配使用,两者结合后的导数会极大简化:

假设最后一层输出Al是softmax的结果,损失函数为交叉熵损失,那么损失对Z的梯度dZ可以直接计算为:

dZ = Al - y

这里的Al是形状为(n_classes, m)的softmax输出,y是one-hot编码的标签(同样是(n_classes, m)形状)。

你需要修改反向传播流程,具体示例如下:

  1. 先确认你的损失函数是交叉熵损失(这是分类任务搭配softmax的标准选择)
  2. 替换原有的softmax_backward逻辑,直接在liner_activ_backward中计算简化后的dZ:
def liner_activ_backward(dA, zCache, linCache, activation, y=None):
    Z = zCache
    A_prev, W, b = linCache
    m = A_prev.shape[1]
    
    if activation == "softmax":
        # 结合交叉熵损失后,无需单独计算softmax的雅各比矩阵,直接用Al和y得到dZ
        Al = softmax(Z)
        dZ = Al - y
    elif activation == "relu":
        # 保留你的relu反向传播逻辑
        dZ = dA * (Z > 0).astype(float)
    else:
        raise ValueError("Unknown activation function")
    
    # 以下linear_backward的逻辑完全可以正常复用
    dA_prev = np.dot(W.T, dZ)
    dW = (1/m) * np.dot(dZ, A_prev.T)
    db = (1/m) * np.sum(dZ, axis=1, keepdims=True)
    
    return dA_prev, dW, db

额外优化提示

  • 你的softmax实现可以简化,不需要返回z:
    def softmax(z):
        exps = np.exp(z - z.max())  # 减去max防止数值溢出,这个逻辑是对的
        return exps / np.sum(exps, axis=0, keepdims=True)  # 按axis=0求和,确保每个样本的类别概率和为1
    
  • 确保数据维度规范:通常我们会把特征放在行、样本放在列,即Z的形状为(n_classes, m),m为样本数。

这样修改后,dZ的形状会和Z完全一致,linear_backward就能正常执行矩阵运算了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:22:47