如何为单层感知器的 tanh() 激活函数实现梯度下降?

数据挖掘 神经网络 梯度下降 感知器
2022-02-24 17:53:16

我需要为图像分类任务实现一个简单的基于感知器的神经网络,具有二进制输出和单层,但是我遇到了困难。我有几个问题:

  1. 我需要使用范围为 [-1, 1] 的 tanh() 激活函数,但是,我的训练标签是 1 和 0。我应该缩放激活函数,还是简单地将 0 标签更改为 -1?

  2. 所以梯度下降规则要求我根据规则移动权重:

Δω=ηδEδω

我对我的错误使用均方误差:

E=(outputlabel)2

考虑到我的输出是o=tanh(ω.x), x 是我的输入向量和yi是这里对应的标签。

δEδω=δ(yitanh(wx))2δω=2(yitanh(wx))(1tanh2(wx))δwxδw=2(yitanh(wx))(1tanh2(wx))x=2(yio)(1o2)x

我实现这是python,输入向量与权重的点积结果太大,这使得tanh(x)=11o2=0,所以我学不会。我该如何规避这个问题?

感谢您的回复。

实施:

def perc_nnet(X, y, iter = 10000, eta=0.0001):
    a, b, c = X.shape
    W_aug = np.random.normal(0, 0.01, a*b+1)
    errors = []

    for i in range(iter):
        selector = rd.randint(0,c-1)
        x_n = X[:,:,selector].ravel() #.append(1) #has the bias as well
        x_n = np.append(x_n, 1)
        v = x_n.dot(W_aug)
        o = np.tanh(v)
        y_i = y[:,selector] if y[:,selector]==1 else -1
        MSE = 0.5*(o - y_i)**2
        errors.append(MSE)
        delta = - eta * (o - y_i) * (1 - o**2) * x_n
        W_aug = W_aug + delta

    return W_aug, errors
1个回答

我该如何规避这个问题?

TLDR:规范化您的输入数据。

为什么?

注意 tanh 是如何处理输入数据的:

>>> np.tanh(np.asarray([-1000, -100, -10, -1, 0, 1, 10, 100, 1000])) array([-1. , -1., -1. , -0.76159416, 0.,0.76159416, 1. ,1. , 1])

如果您输入到 tanh 的数据的大小为 10 或更大,则 tanh 产生的输出为 1。这意味着它对 10、50、100、1000 的处理相同。我们不希望那样。

这可以解释

带权重的输入向量结果太大,这使得 tanh(x)=1tanh(x)=1 和 1−o2=01−o2=0,所以我无法学习。

相反,我们对数据进行归一化(通过将输入数据除以 1000(还有其他方法)):

>>> np.tanh(np.asarray([-1000, -100, -10, -1, 0, 1, 10, 100, 1000]) / 1000) array([-0.76159416, -0.09966799, -0.00999967, -0.001, 0. ,0.001, 0.00999967, 0.09966799, 0.76159416])

现在,tanh 以不同的方式对待它们。

注意 您正在执行分类任务。使用均方误差作为成本函数在这里不会产生最好的结果。您应该改为使用带有 One Hot Vectors 和 softmax 的交叉熵损失。

至于为什么应该是一个完全不同的答案。 是相同的链接。