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

基于Numpy/Pandas的MNIST分类神经网络gradient_descent参数报错排查

问题原因与解决方法

核心错误:实例方法缺少self参数

你定义的gradient_descent是类的实例方法,但没有在参数列表里添加第一个必选的self参数。当你用nn.gradient_descent(...)调用时,Python会自动把nn这个实例作为第一个参数传入方法,加上你手动传入的4个参数,总共就有5个参数,和方法定义的4个参数不匹配,因此触发报错。

修复方法

修改gradient_descent的定义,将self作为第一个参数:

def gradient_descent(self, x, y, alpha, iterations):

代码中其他需修复的问题

除核心错误外,代码还有多处语法和逻辑问题,修复后才能正常运行:

  • 类内部方法调用未加self:类里调用自身方法(如ReLU、softmax、forward等)必须用self.方法名()的形式,否则会被当作全局函数处理。例如a1 = ReLU(z1)要改成a1 = self.ReLU(z1)。
  • 方法名不匹配:代码里存在方法名调用错误,比如定义的是forward却写成forward_prop,backward写成backward_prop,需统一方法名。
  • 参数初始化错误:gradient_descent里的w1, b1, w2, b2 = __init__()完全错误,应直接使用实例初始化的属性:w1, b1, w2, b2 = self.w1, self.b1, self.w2, self.b2。
  • get_preds方法缺少self:该方法是实例方法,必须添加self参数:def get_preds(self, a2):。
  • ReLU导数方法拼写错误:RelU_deriv应改为ReLU_deriv(第二个字母为e)。
  • softmax维度错误:原实现未考虑批量数据,需指定维度求和:return np.exp(z) / np.sum(np.exp(z), axis=0, keepdims=True)。
  • backward中m未定义:应使用训练集样本数,可替换为1 / x.shape[1](x的列数为样本数)。
  • return位置错误:原代码将return写在for循环内部,会导致第一次循环就返回,需移到循环外部。

修复后的核心代码示例

import numpy as np

# 假设data为已加载的MNIST数据集
data = np.array(data)
m, n = data.shape
np.random.shuffle(data) # 拆分前打乱数据
data_dev = data[0:1000].T
y_dev = data_dev[0]
x_dev = data_dev[1:n]
x_dev = x_dev / 255.
data_train = data[1000:m].T
y_train = data_train[0]
x_train = data_train[1:n]
x_train = x_train / 255.
_, m_train = x_train.shape

class NeuralNet():

    def __init__(self, i_lay, h_lay, o_lay):
        self.i_lay = i_lay
        self.h_lay = h_lay
        self.o_lay = o_lay

        # 修正权重矩阵维度,确保矩阵乘法合法
        self.w1 = np.random.rand(self.h_lay, self.i_lay)/np.sqrt(self.i_lay)
        self.b1 = np.zeros((self.h_lay, 1))
        self.w2 = np.random.rand(self.o_lay, self.h_lay)/np.sqrt(self.h_lay)
        self.b2 = np.zeros((self.o_lay, 1))
    
    def ReLU(self, z):
        return np.maximum(z, 0)

    def softmax(self, z):
        return np.exp(z) / np.sum(np.exp(z), axis=0, keepdims=True)
    
    def forward(self, x):
        z1 = self.w1.dot(x) + self.b1
        a1 = self.ReLU(z1)
        z2 = self.w2.dot(a1) + self.b2
        a2 = self.softmax(z2)
        return z1, a1, z2, a2
    
    def ReLU_deriv(self, z):
        return z > 0

    def one_hot(self, y):
        one_hot_y = np.zeros((y.size, y.max() + 1))
        one_hot_y[np.arange(y.size), y] = 1
        one_hot_y = one_hot_y.T
        return one_hot_y
    
    def backward(self, z1, a1, z2, a2, x, y):
        m = x.shape[1]
        one_hot_y = self.one_hot(y)
        dz2 = a2 - one_hot_y
        dw2 = 1 / m * dz2.dot(a1.T)
        db2 = 1 / m * np.sum(dz2, axis=1, keepdims=True)
        dz1 = self.w2.T.dot(dz2) * self.ReLU_deriv(z1)
        dw1 = 1 / m * dz1.dot(x.T)
        db1 = 1 / m * np.sum(dz1, axis=1, keepdims=True)
        return dw1, db1, dw2, db2
    
    def update_parameters(self, dw1, db1, dw2, db2, alpha):
        self.w1 -= alpha * dw1
        self.b1 -= alpha * db1
        self.w2 -= alpha * dw2
        self.b2 -= alpha * db2
    
    def get_preds(self, a2):
        return np.argmax(a2, 0)

    def get_acc(self, preds, y):
        return np.sum(preds == y) / y.size
    
    def gradient_descent(self, x, y, alpha, iterations):
        for i in range(iterations):
            z1, a1, z2, a2 = self.forward(x)
            dw1, db1, dw2, db2 = self.backward(z1, a1, z2, a2, x, y)
            self.update_parameters(dw1, db1, dw2, db2, alpha)
            if i % 10 == 0:
                print("Iteration: ", i)
                predictions = self.get_preds(a2)
                print(f"Accuracy: {self.get_acc(predictions, y):.4f}")
        return self.w1, self.b1, self.w2, self.b2

nn = NeuralNet(784, 10, 10)
nn.gradient_descent(x_train, y_train, 0.1, 500)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 15:10:16