我的Backpropagation算法实现有什么问题?

时间:2017-12-19 07:45:00

标签: machine-learning neural-network backpropagation

我尝试使用无隐藏层神经网络来破解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

1 个答案:

答案 0 :(得分:0)

从我在这里看到的,有一些可能的因素妨碍了它的运作。

首先,您必须随机初始化您的权重和偏差。从我所看到的,你正试图改变一个尚未具有实际价值的价值(例如:w1 = 0)。

其次,您的优化器不适合MNIST数据集。优化器根据反向传播更改值,因此选择正确的优化器非常重要。渐变下降更适合此数据集,从我可以看到,您没有使用渐变下降。如果您尝试使用代码制作渐变下降优化器,则最有可能做错了。梯度下降涉及SSE(平方误差之和)的偏导数,我在此代码中没有看到。

如果您想使用Gradient Descent优化器,除了实现Gradient Descent背后的数学之外,您还必须对代码进行一些更改。您将不得不使用ReLU激活功能(我建议您不要这样做)而不是sigmoid功能。这将确保消失梯度问题不会发生。此外,你应该使你的损失函数减少交叉熵的平均值。优化器将以这种方式更加有效。

希望这有帮助。