我的 python MNIST 数据集代码显示了巨大的错误值,我错过了什么?

My python code for MNIST dataset shows gigantic error values, what I am missing?

您可以在下面找到我的代码,这是我自学机器学习的第一个正式代码 Python。我试图在不使用像 NumPy 这样的库的情况下从头开始编写代码。对于单个输入和输出,代码有效,但当涉及到真实数据集(在本例中是 784 个输入到 10 个输出)时,它 returns 无穷大作为错误。我检查了我认为可能是问题的任何内容,但没有成功。

该代码可能是一个肮脏的解决方案。我从研究 Trask Github 和他的多个 input/output 作品的代码开始,但是当我修改它以使用 MNIST 时,一切都变得疯狂了。 有人可以看一下并帮助我知道我缺少什么以及问题是什么吗?赞赏。

for i in range (x_train.shape[0]):
    x_labels[i,x_label[i]]=1
def w_sum(a,b):
    assert(len(a) == len(b))
    output = 0
    for i in range(len(a)):
        output += (a[i] * b[i])
    return output

def neural_network(input1, weights):
    pred = vect_mat_mul(input1,weights)
    return pred

def vect_mat_mul(vect,matrix):
    output = np.zeros(10)
    for i in range(10):

        output[i] = w_sum(vect[0],matrix[:,i])

    return output
def outer_prod(a, b):
    out = np.zeros((len(a), len(b)))
    for i in range(len(a)):
        for j in range(len(b)):
            out[i][j] = a[i] * b[j]
    return out

(x_train,x_label),(t_test,t_label)=ks.datasets.mnist.load_data()
x_train=x_train.reshape(x_train.shape[0],28*28)
weights=np.random.rand(784,10)
x_labels=np.zeros((x_train.shape[0],10))
alpha = 0.00001

for i in range(x_train.shape[0]):
    error = np.zeros(10)
    delta = np.zeros(10)
    for iter in range(50):
        x_train_to_NN = np.array([x_train[i]])
        pred = neural_network(x_train_to_NN, weights)
        for j in range(10):
            error[j] = (pred[j] - x_labels[i, j]) ** 2
            delta[j] = pred[j] - x_labels[i, j]
        weight_deltas = outer_prod(x_train[i], delta) #calculate the gradient
        for idx in range(784):
            for jdx in range(10):
                weights[idx][jdx] -= alpha * weight_deltas[idx][jdx] #update weight matrix

print('key=', i, '\n Error=', error, '\n Delta=', delta, '\n Prediction=', pred)

我看到这里有很多错误。 使用 tensorflow、pyTorch 等神经网络库的主要好处之一是它们会为您处理漂亮但令人费解的线性代数部分。 例如,神经网络的所有权重都以一种特殊的方式初始化,使它们既不大于 1,也不会小于 1,否则,梯度会消失或爆炸得太快。 此外,不清楚您在哪里计算梯度、更新成本函数等。要计算梯度,您需要转到日志 space 并返回,这样您就可以再次避免浮点错误,这将导致梯度爆炸(因此是无穷大误差)。 :) 我建议您仔细研究理论部分,然后尝试分别实现每个部分。 干杯,

我终于找到了答案,那就是“Gradient Clipping”。 问题是在计算梯度时,需要对其进行限制(归一化)以避免梯度爆炸。