# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
# N is batch size(sample size); D_in is input dimension;
# H is hidden dimension; D_out is output dimension.
N, D_in, H, D_out = 4, 2, 30, 1
# Create random input and output data
x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])
# Randomly initialize weights
w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)
learning_rate = 0.002
loss_col = []
for t in range(200):
# Forward pass: compute predicted y
h = x.dot(w1)
h_relu = np.maximum(h, 0) # using ReLU as activate function
y_pred = h_relu.dot(w2)
# Compute and print loss
loss = np.square(y_pred - y).sum() # loss function
loss_col.append(loss)
print(t, loss, y_pred)
# Backprop to compute gradients of w1 and w2 with respect to loss
grad_y_pred = 2.0 * (y_pred - y) # the last layer's error
grad_w2 = h_relu.T.dot(grad_y_pred)
grad_h_relu = grad_y_pred.dot(w2.T) # the second laye's error
grad_h = grad_h_relu.copy()
grad_h[h < 0] = 0 # the derivate of ReLU
grad_w1 = x.T.dot(grad_h)
# Update weights
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
plt.plot(loss_col)
plt.show()
5 回答
如果你有一个由单个ReLU构成的图层,就像你的架构所暗示的那样,那么是的,你会在
0
处杀死渐变 . 在训练期间,ReLU将0
返回到您的输出图层,如果您使用的是后勤单位,它将返回0
或0.5
,而softmax将会压缩它们 . 因此,当前架构下的0
值对于前向传播部分也没有多大意义 .参见例如this . 你可以做的是使用"leaky ReLU",它是
0
的一个小值,例如0.01
.我会重新考虑这个架构,然而,将单个ReLU馈送到一堆其他单元然后应用softmax对我来说没有多大意义 .
ReLU函数定义为:对于x> 0,输出为x,即 f(x) = max(0,x)
因此,对于导数f'(x),它实际上是:
如果x <0,则输出为0.如果x> 0,则输出为1 .
导数f'(0)未定义 . 所以它通常设置为0或者你将激活函数修改为小e的f(x)= max(e,x) .
通常:ReLU是使用整流器激活功能的单元 . 这意味着它的工作原理与任何其他隐藏层完全相同,但除了tanh(x),sigmoid(x)或您使用的任何激活之外,您将使用f(x)= max(0,x) .
如果你已经为使用sigmoid激活的工作多层网络编写了代码,那么它实际上只有一行变化 . 关于前向或后向传播的任何内容都不会在算法上发生变化 . 如果你还没有更简单的模型工作,那就回过头来开始吧 . 否则你的问题不是关于ReLUs,而是关于整体实施NN .
这是一个很好的例子,使用ReLU实现XOR:reference,http://pytorch.org/tutorials/beginner/pytorch_with_examples.html
更多关于ReLU的衍生物,你可以在这里看到:http://kawahara.ca/what-is-the-derivative-of-relu/
是的,原始的Relu功能有你描述的问题 . 所以他们后来改变了公式,并将其称为泄漏Relu本质上Leaky Relu将函数的水平部分略微倾斜了一小部分 . 欲了解更多信息,请观看:
An explantion of activation methods, and a improved Relu on youtube
另外,在这里你可以找到caffe框架中的一个实现:https://github.com/BVLC/caffe/blob/master/src/caffe/layers/relu_layer.cpp
negative_slope指定是否通过将其与斜率值相乘而不是将其设置为0来“泄漏”负部分 . 当然,您应将此参数设置为零以具有经典版本 .