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

为何np.shape未返回维度元组,反而输出完整列表?

为什么np.shape输出整个列表而非维度?

我在编写简单神经网络的反向传播函数时,为了调试最后一层偏置项偏导数的索引错误,插入了print(np.shape(dz[len(dz)-1]))语句,想对比变量维度与预期是否一致。但实际输出不是整数维度列表,而是整个长列表的内容:

array([None, None,
list([-178817.32020913006, 115656.44251148969, -410256.53703781555, -44727.1419577356, ...])

反向传播函数代码

def neural_network_backward(X,Y,Z,W,b,z,a):
    da=[0 for i in range(len(a))]
    dz=[0 for i in range(len(z))]
    dW=[0 for i in range(len(W))]
    db=[0 for i in range(len(b))]
    da[len(da)-1]=[(-Z[k]/a[len(a)-1][k]*len(Z))+((1-Z[k])/(1-a[len(a)-1][k])*len(Z)) for k in range(len(Z))]
    dz[len(dz)-1]=[[(Z[k]-a[len(a)-1][k])/len(Z) for k in range(len(Z))],[(a[len(a)-1][k]-Z[k])/len(Z) for k in range(len(Z))]]
    dW[len(dW)-1]=np.matmul(dz[len(dz)-1],np.transpose(a[len(a)-2]))
    print(np.shape(dz[len(dz)-1]))
    db[len(db)-1]=[[np.sum([dz[len(dz)-1][i][j] for i in range(np.shape(dz[len(dz)-1])[1])])] for j in range(len(b[len(b)-1]))]
    return da,dz,dW,db

变量说明

  • X、Y:输入数值列表,长度40000
  • Z:类别标签列表(元素为0或1),长度40000
  • W:权重列表,每个元素为数值矩阵,长度等于网络层数
  • b:偏置项列表,每个元素为列向量,长度等于网络层数
  • z:存储各层非线性函数输入值的列表
  • a:存储各层非线性函数输出值的列表

X、Y、Z、W、b为给定值,z和a由前向传播函数生成。

前向传播函数代码

def neural_network_forward(X,Y,W,b):
    depth=len(W)
    z=[]
    a=[]
    for i in range(depth):
        weights=np.array(W[i])
        biases=np.array([[b[i][j] for k in range(len(X))] for j in range(len(b[i]))])
        if i==0:
            inputs=np.array([X,Y])
            z.append(np.matmul(weights,inputs)+biases)
        else:
            inputs=a[len(a)-1]
            z.append(np.matmul(weights,inputs)+biases)
        if i<depth-1:
            a.append([[np.amax(z[len(z)-1][j][k],0) for k in range(len(X))] for j in range(len(z[len(z)-1]))])
        else:
            z_final=[[z[len(z)-1][j][k] for k in range(len(X))] for j in range(2)]
            a.append([np.exp(z_final[1][k])/(np.exp(z_final[0][k])+np.exp(z_final[1][k])) for k in range(len(X))])
            loga_final=[z_final[1][k]-logadd([z_final[0][k],z_final[1][k]]) for k in range(len(X))]
    return z,a,loga_final

问题原因与解决办法

核心原因

dz[len(dz)-1]是纯Python嵌套列表,而非numpy数组。numpy的np.shape函数处理纯Python列表时,若列表结构不规则(或未转为数组),不会返回标准的维度元组,反而会输出包含list/array的混合结构,看起来像是直接输出了列表内容。

看反向传播代码里的赋值:

dz[len(dz)-1]=[[(Z[k]-a[len(a)-1][k])/len(Z) for k in range(len(Z))],[(a[len(a)-1][k]-Z[k])/len(Z) for k in range(len(Z))]]

这里直接生成了嵌套Python列表,没有转为numpy数组。

解决办法

  1. 将dz最后一层转为numpy数组:
    修改赋值语句,用np.array()包裹列表生成式:
dz[len(dz)-1] = np.array([[(Z[k]-a[len(a)-1][k])/len(Z) for k in range(len(Z))],[(a[len(a)-1][k]-Z[k])/len(Z) for k in range(len(Z))]])

之后再调用np.shape(dz[-1])就会返回标准维度元组,比如(2, 40000)。

  1. 简化索引写法:
    代码中大量使用的len(dz)-1可以直接用-1替代,即dz[-1]表示列表最后一个元素,更简洁且不易出错。

  2. 统一用numpy数组处理张量:
    神经网络运算推荐全程使用numpy数组,避免混合Python列表和numpy数组,减少维度解析和运算错误。

内容的提问来源于stack exchange,提问作者J.D.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 23:44:58