Pytorch-激活函数及梯度

1.激活函数

1 #激活函数
2 z1=torch.linspace(-100,100,10)      
3 print(z1)                     #tensor([-100.0000, -77.7778, -55.5556, -33.3333, -11.1111, 11.1111, 33.3333, 55.5556, 77.7778, 100.0000])
4 print(torch.sigmoid(z1))      #tensor([0.0000e+00, 1.6655e-34, 7.4564e-25, 3.3382e-15, 1.4945e-05, 9.9999e-01, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00])
5 
6 z2=torch.linspace(-1,1,10)
7 print(torch.tanh(z2))         #tensor([-0.7616, -0.6514, -0.5047, -0.3215, -0.1107, 0.1107, 0.3215, 0.5047, 0.6514, 0.7616])
8 
9 print(torch.relu(z2))         #tensor([0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1111, 0.3333, 0.5556, 0.7778, 1.0000])

2.loss及其梯度

2.1均方差(MSE)

均方损失函数torch.nn.mse_loss(pred, target)

 1 import torch
 2 from torch.nn import functional as F
 3 
 4 #y=x*w(b取0)
 5 x=torch.ones(1)
 6 w=torch.full([1],2)
 7 
 8 #计算均方差
 9 #法一
10 mse1=torch.norm(torch.ones(1)-x*w, 2)**2
11 print(mse1)                             #tensor(1.)
12 #法二
13 mse2=F.mse_loss(torch.ones(1), x*w)
14 print(mse2)                             #tensor(1.)

2.2梯度计算

torch.autograd.grad(loss, [w1, w2,...])

  1. 第一个参数是损失函数,第二个参数是该损失函数要求梯度的参数列表
  2. 返回结果grad_val是梯度列表,列表记录了每一个Tensor的grade信息

    $[\frac{\alpha Loss}{\alpha w1}, \frac{\alpha Loss}{\alpha w2},...]$

1 #对w求导,需要先指明w需要梯度信息
2 w.requires_grad_()
3 print(w)                                #tensor([2.], requires_grad=True)   
4 mse=F.mse_loss(torch.ones(1), x*w)
5 print(torch.autograd.grad(mse, [w]))    #(tensor([2.]),)

loss.backward()

图的反向传播,自动求出该图上所有的需要计算梯度的参数相对于这个MSE的梯度,梯度信息附加到每个Tensor的成员变量grad中,不会额外返回。w1.grad,w2.grad...

1 w.requires_grad_()
2 print(w)                                #tensor([2.], requires_grad=True)   
3 mse=F.mse_loss(torch.ones(1), x*w)
4 
5 mse.backward()              
6 print(w.grad)                           #tensor([2.])    

Tip:这个方法会将之前的梯度信息覆盖掉,所以多次调用这个loss对象的.backward()方法时会报错,如果要再次调用以生成新的梯度信息,要给它一个参数.backward(retain_graph=True)。

3.softmax

可以用于将多个输出值转换成多个概率值,使每个值都符合概率的定义,范围在[0, 1],且概率相加和为1,非常适合多分类问题。

1 import torch
2 from torch.nn import functional as F
3 
4 a=torch.rand(3)
5 a.requires_grad_()
6 print(a)                                                  #tensor([0.4580, 0.6305, 0.0915], requires_grad=True)             
7 
8 p=F.softmax(a, dim=0)
9 print(p)                                                  #tensor([0.3471, 0.4124, 0.2406], grad_fn=<SoftmaxBackward>) 相加为1

1 print(torch.autograd.grad(p[0], [a], retain_graph=True))  #(tensor([ 0.2266, -0.1431, -0.0835]),)                                  
2 print(torch.autograd.grad(p[1], [a], retain_graph=True))  #(tensor([-0.1431,  0.2423, -0.0992]),)
3 print(torch.autograd.grad(p[2], [a]))                     #(tensor([-0.0835, -0.0992,  0.1827]),)

上面的第一行相当于:

1 p[0].backward(retain_graph=True)
2 print(a.grad)

Tip:

  1. 计算导数时,loss只能是一个值,不能多个分量,所以分别对p[0],p[1],p[2]对应的loss求导
  2. loss可以对多个参数求偏导,eg.p0对a0,a1,a2求偏导
  3. i==j时,偏导为正,i!=j时偏导为负
posted @ 2020-07-09 23:29  最咸的鱼  阅读(779)  评论(0编辑  收藏  举报