我的反向传播算法实现有什么问题?



我尝试实现一个无隐藏的神经网络来用MNIST数据集进行入侵。

我将sigmoid用作激活函数和跨肠道函数。

为简单起见,我的网络没有隐藏的层,只有输入和输出。

X = trainImage
label = trainLabel
w1 = np.random.normal(np.zeros([28 * 28, 10]))
b1 = np.random.normal(np.zeros([10]))
def sigm(x):
    return 1 / (1 + np.exp(-x))
def acc():
    y = sigm(np.matmul(X, w1))
    return sum(np.argmax(label, 1) == np.argmax(y, 1)) / y.shape[0]
def loss():
    y = sigm(np.matmul(X, w1))
    return sum((-label * np.log(y)).flatten())
a = np.matmul(X[0:1], w1)
y = sigm(a)
dy = - label[0:1] / y
ds = dy * y * (1 - y)
dw = np.matmul(X[0:1].transpose(), ds)
db = ds
def bp(lr, i):
    global w1, b1, a, y, dy, ds, dw, db
    a = np.matmul(X[i:i+1], w1)
    y = sigm(a)
    dy = - label[0:1] / y
    ds = dy * y * (1 - y)
    dw = np.matmul(X[i:i+1].transpose(), ds)
    db = ds
    w1 = w1 - lr * dw
    b1 = b1 - lr * db
for i in range(100 * 60000):
    bp(1, i % 60000)
    if i % 60000 == 0:
        print("#", int(i / 60000), "loss:", loss(), "acc:", acc())

这是我实施反向传播算法的一部分,但它无法正常工作。损失功能的下降非常慢(我尝试使用0.001到1的学习率变化),并且准确性永远不超过0.1。

输出就是这样:

# 0 loss: 279788.368245 acc: 0.0903333333333
# 1 loss: 279788.355211 acc: 0.09035
# 2 loss: 279788.350629 acc: 0.09035
# 3 loss: 279788.348228 acc: 0.09035
# 4 loss: 279788.346736 acc: 0.09035
# 5 loss: 279788.345715 acc: 0.09035
# 6 loss: 279788.344969 acc: 0.09035
# 7 loss: 279788.3444 acc: 0.09035
# 8 loss: 279788.343951 acc: 0.09035
# 9 loss: 279788.343587 acc: 0.09035
# 10 loss: 279788.343286 acc: 0.09035
# 11 loss: 279788.343033 acc: 0.09035

从我在这里看到的,有一些可能阻止此功能的因素。

首先,您必须随机初始化体重和偏见。据我所知,您正在尝试更改一个尚未有切实价值的值(ex: w1 = 0)。

其次,您的优化器不适用于MNIST数据集。优化器是根据反向传播更改值的原因,因此选择正确的优化器非常重要。梯度下降更适合该数据集,从我所看到的,您不使用梯度下降。如果您试图使用代码进行梯度下降优化器,那么您很可能做错了。梯度下降涉及SSE的部分导数(平方错误之和),我在此代码中看不到。

如果您想使用梯度下降优化器,则除了实现梯度下降背后的数学外,还必须对代码进行一些更改。您将必须使用Relu激活功能(我建议您无论如何都可以这样做),而不是Sigmoid函数。这将确保不会发生消失的梯度问题。另外,您应该使您的损失功能减少横熵的平均值。这样的优化器将更加有效。

希望这会有所帮助。

最新更新