激活函数
激活函数用来加入非线性因素,解决线性模型所不能解决的问题
原始激活函数:阈值函数(大于0为1,小于0为0)
缺点不可导
改进激活函数:
- sigmoid(0~1之间)
f ( x ) = σ ( x ) = 1 1 + e − x f(x)=\sigma(x)=\frac{1}{1+e^{-x}} f(x)=σ(x)=1+e−x1
优点是可导且易导:
σ ′ = σ ( 1 − σ ) \sigma^{\prime}=\sigma(1-\sigma) σ′=σ(1−σ)
缺点是会在两端会出现长时间loss保持不变
torch.sigmoid(a)
- Tanh
f ( x ) = tanh ( x ) = ( e x − e − x ) ( e x + e − x ) = 2 sigmoid ( 2 x ) − 1 \begin{aligned} f(x) &=\tanh (x)=\frac{\left(e^{x}-e^{-x}\right)}{\left(e^{x}+e^{-x}\right)} \\ &=2 \operatorname{sigmoid}(2 x)-1 \end{aligned} f(x)=tanh(x)=(ex+e−x)(ex−e−x)=2sigmoid(2x)−1
常用于RNN - ReLU
目前使用最多,起到奠基作用的激活函数,一般做研究优先使用ReLU激活函数
f ( x ) = { 0 for x < 0 x for x ≥ 0 f(x)=\left\{\begin{array}{ll} {0} & {\text { for } x<0} \\ {x} & {\text { for } x \geq 0} \end{array}\right. f(x)={0x for x<0 for x≥0
优点:减少了梯度爆炸和梯度离散的情况
torch.relu(a)
- Softmax
用预测分类,每个值都在0~1之间,且和为1
S ( y i ) = e y i ∑ j e y j S\left(y_{i}\right)=\frac{e^{y_{i}}}{\sum_{j} e^{y_{j}}} S(yi)=∑jeyjeyi
求导:
∂ p i ∂ a j = { p i ( 1 − p j ) if i = j − p j ⋅ p i if i ≠ j \frac{\partial p_{i}}{\partial a_{j}}=\left\{\begin{array}{ll} {p_{i}\left(1-p_{j}\right)} & {\text { if } i=j} \\ {-p_{j} \cdot p_{i}} & {\text { if } i \neq j} \end{array}\right. ∂aj∂pi={pi(1−pj)−pj⋅pi if i=j if i=j
i=j是正的,其它时是负的
p=F.softmax(a,dim=0)
torch.autograd.grad(p[1],[a],retain_graph=True)
Loss及其梯度
MSE:均方误差
Cross Entropy Loss:交叉熵
loss求导:
- torch.autograd.grad(loss,[w1,w2,…]
In [55]: x=torch.ones(1)
In [56]: w=torch.full([1],2)
In [57]: w.requires_grad_()
Out[57]: tensor([2.], requires_grad=True)
In [63]: mse=F.mse_loss(torch.ones(1),x*w)
In [64]: torch.autograd.grad(mse,[w])
Out[64]: (tensor([2.]),)
- loss.backward()
mse=F.mse_loss(torch.ones(1),x*w)
mse.backward()
w.grad