目的:使模型(e.g., MLP)不會退化成線性模型
ReLu
修正線性單元(Rectified linear unit,ReLu)

relu公式
實現(xiàn):
%matplotlib inline
import torch
from d2l import torch as d2l
# ReLu函數(shù)圖
x = torch.arange(-8.0, 8.0, 0.1, requires_grad= True)
y = torch.relu(x)
d2l.plot(x.detach(), y.detach(), 'x', 'relu(x)', figsize = (5, 2.5))

relu函數(shù)圖
當輸入為負時,ReLU函數(shù)的導數(shù)為0,而當輸入為正時,ReLU函數(shù)的導數(shù)為1。 注意,當輸入值精確等于0時,ReLU函數(shù)不可導。 在此時,我們默認使用左側(cè)的導數(shù),即當輸入為0時導數(shù)為0。 我們可以忽略這種情況,因為輸入可能永遠都不會是0。
y.backward(torch.ones_like(x), retain_graph = True) #返回一個用1填充的張量,其大小與輸入相同。
# 進行一次backward之后,各個節(jié)點的值會清除,這樣進行第二次backward會報錯,如果加上retain_graph==True后,計算節(jié)點中間值不會被釋放,可以再來一次backward。
d2l.plot(x.detach(), x.grad, 'x','grad of relu', figsize=(5,2.5))

relu函數(shù)導數(shù)圖
PReLU
y = torch.prelu(x, torch.tensor([0.25]))
d2l.plot(x.detach(), y.detach(), 'x', 'prelu(x)', figsize = (5, 2.5))

PReLU函數(shù)圖
PReLU函數(shù)梯度圖
x.grad.data.zero_()
y.backward(torch.ones_like(x), retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of prelu', figsize = (5, 2.5))

PReLU函數(shù)梯度圖
sigmoid

sigmoid公式
y = torch.sigmoid(x)
d2l.plot(x.detach(), y.detach(), 'x', 'sigmoid(x)', figsize = (5, 2.5))

sigmoid函數(shù)圖
sigmoid函數(shù)的導數(shù)
# 清除以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x), retain_graph = True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of sigmoid', figsize = (5,2.5))

sigmoid函數(shù)導數(shù)公式

sigmoid函數(shù)導數(shù)圖
tanh函數(shù)

tanh函數(shù)公式
注意,當輸入在0附近時,tanh函數(shù)接近線性變換。 函數(shù)的形狀類似于sigmoid函數(shù), 不同的是tanh函數(shù)關(guān)于坐標系原點中心對稱。
y = torch.tanh(x)
d2l.plot(x.detach(), y.detach(), 'x', 'tanh(x)', figsize = (5, 2.5))

tanh函數(shù)圖
tanh函數(shù)的導數(shù):
# 清楚以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x), retain_graph = True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of tanh', figsize = (5, 2.5))

tanh函數(shù)的導數(shù)

tanh函數(shù)導數(shù)圖