目的:使模型(e.g., MLP)不會(huì)退化成線性模型
ReLu
修正線性單元(Rectified linear unit,ReLu)
實(shí)現(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))
當(dāng)輸入為負(fù)時(shí),ReLU函數(shù)的導(dǎo)數(shù)為0佑吝,而當(dāng)輸入為正時(shí)疫剃,ReLU函數(shù)的導(dǎo)數(shù)為1田篇。 注意峦椰,當(dāng)輸入值精確等于0時(shí)徒扶,ReLU函數(shù)不可導(dǎo)趣席。 在此時(shí)兵志,我們默認(rèn)使用左側(cè)的導(dǎo)數(shù),即當(dāng)輸入為0時(shí)導(dǎo)數(shù)為0宣肚。 我們可以忽略這種情況想罕,因?yàn)檩斎肟赡苡肋h(yuǎn)都不會(huì)是0。
y.backward(torch.ones_like(x), retain_graph = True) #返回一個(gè)用1填充的張量霉涨,其大小與輸入相同按价。
# 進(jìn)行一次backward之后,各個(gè)節(jié)點(diǎn)的值會(huì)清除笙瑟,這樣進(jìn)行第二次backward會(huì)報(bào)錯(cuò)楼镐,如果加上retain_graph==True后,計(jì)算節(jié)點(diǎn)中間值不會(huì)被釋放,可以再來(lái)一次backward往枷。
d2l.plot(x.detach(), x.grad, 'x','grad of relu', figsize=(5,2.5))
PReLU
y = torch.prelu(x, torch.tensor([0.25]))
d2l.plot(x.detach(), y.detach(), 'x', 'prelu(x)', figsize = (5, 2.5))
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))
sigmoid
y = torch.sigmoid(x)
d2l.plot(x.detach(), y.detach(), 'x', 'sigmoid(x)', figsize = (5, 2.5))
sigmoid函數(shù)的導(dǎo)數(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))
tanh函數(shù)
注意框产,當(dāng)輸入在0附近時(shí),tanh函數(shù)接近線性變換师溅。 函數(shù)的形狀類似于sigmoid函數(shù)茅信, 不同的是tanh函數(shù)關(guān)于坐標(biāo)系原點(diǎn)中心對(duì)稱。
y = torch.tanh(x)
d2l.plot(x.detach(), y.detach(), 'x', 'tanh(x)', figsize = (5, 2.5))
tanh函數(shù)的導(dǎo)數(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))