【问题标题】:Relu Activation and BackpropagationRelu 激活和反向传播
【发布时间】:2021-03-24 08:41:12
【问题描述】:

我已经使用 sigmoid 激活函数为 MLP 实现了反向传播。

在前向阶段,我将每一层的输出存储在内存中。

在计算出输出误差和输出梯度向量后,我开始反向计算每一层的隐藏误差(使用当前层的输出 + 层 +1 的权重 + 层 +1 的输出误差)。然后我使用隐藏错误和层 -1 的输出来计算梯度向量。反向传播完成后,我会使用计算出的每一层的梯度向量来更新权重。

我的问题与relu激活函数的实现有关。我有以下用于应用激活函数的函数。第一个是我在初始运行时使用的,第二个是用于 relu 激活的。

def sigmoid(self, a):
    o = 1/(1+np.exp(-1*a))
    return o

def relu(self, a):
    return np.maximum(0, a)

def reluDerivative(self, x):       
    return 1. * (x > 0)

要实现 relu 激活功能,我是否需要在前向或反向传播阶段进行任何其他更改。我读到我可能需要在后向阶段计算 relu 导数并应用,但对它的应用方式感到困惑。感谢任何建议

【问题讨论】:

  • 为什么不用pytorch之类的框架呢?
  • 这是个好主意...但现在我正在尝试使用 jupyter 学习基础知识:-)
  • 对于反向传播阶段,你必须定义relu的导数函数。很难告诉你神经网络是如何进行前馈和反向传播的。首先,你可以实现导函数!
  • 我了解如何在前向阶段实现 relu,但如何在后向阶段应用它?我有计算 relu 导数的功能,但不确定在哪里应用它。def reluDerivative(self, x): return 1. * (x > 0)
  • 所以在反向传播阶段我是否必须使用 relu 导数重新计算每一层的输出?然后用它来计算隐藏的错误?

标签: python backpropagation mlp


【解决方案1】:

假设你的班级目前是这样设置的:

def logistic(z):
    return 1./(1. + np.exp(-z))


class backpropagation(object):

    ...

    def get_activation(self, a):
        return logistic(a)

    def get_delta_activation(self, a):
        y = logistic(a)
        dy = y * (1. - y)
        return dy

那么新的派生类将是

class BPwithRelu(backpropagation):
    
    def get_activation(self, a):
        return np.max(0, a)

    def get_delta_activation(self, a):
        return (x > 0).astype(np.float)


    

【讨论】:

  • 如何在反向传播过程中应用relu导数?谢谢
【解决方案2】:

在进行反向传播时,您需要使用链式法则的中间值。假设你只有一个 relu 后跟一个 sigmoid:

f(x) = relu(sigmoid(x))
relu(x) = max(0,x)
sigmoid(x) = 1/(1+exp(-1*a))

使用链式法则(拉格朗日表示法)推导f(x)

f'(x) = relu'(sigmoid(x)) * sigmoid'(x)

您会看到来自 sigmoid 的梯度与来自 relu 的梯度相乘。另请注意,relu 计算其相对于 sigmoid 输出的梯度,而 sigmoid 计算其相对于输入 (x) 的梯度。

【讨论】:

  • 我需要哪些中间值。我目前正在内存中保存每一层的权重和输出。我还需要在激活前保存值吗?
  • 是的,输入(或上一层的输出)用于反向传播。对于二元运算(即加法或乘法),您将有两个输入,这将需要您反向传播两个值。这可能会更容易解释为您的网络是什么样子的示例。
  • 我不确定如何共享我的代码,但基本上我正在使用 MNIST 数据。我的架构设置有 2 个隐藏层 (10,30) 和一个具有 10 个神经元的输出层。我已将激活从 sigmoid 更新为 relu,并且还修改了反向传播阶段,因此隐藏的错误在前向阶段应用 relu 激活之前考虑了总权重。准确性很低,我觉得需要对代码进行更多更新
  • 每个隐藏层通常会将输入与一些权重相乘,加上偏差并将其传递给激活函数,即f(Wx + b),其中f 是激活函数,W 是权重和b 是偏见。如果您了解这是一个组合函数,您就可以计算可以轻松扩展到其他隐藏层的导数。网上有很多关于这方面的资源,但是如果没有关于你想要完成的更具体的细节,很难给出任何具体的答案。
猜你喜欢
  • 2019-03-18
  • 2018-10-24
  • 2017-06-21
  • 2016-05-13
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多