2021-07-20 梯度下降&感知机

一、梯度下降

1、激活函数

  • sigmoid函数


    sigmoid函数
z = torch.linspace(-10,10,10)
print(z)
a = torch.sigmoid(z)
print("sigmoid激活后:",a)
tensor([-10.0000,  -7.7778,  -5.5556,  -3.3333,  -1.1111,   1.1111,   3.3333,
          5.5556,   7.7778,  10.0000])
sigmoid激活后: tensor([4.5398e-05, 4.1877e-04, 3.8510e-03, 3.4445e-02, 2.4766e-01, 7.5234e-01,
        9.6555e-01, 9.9615e-01, 9.9958e-01, 9.9995e-01])
  • tanh函数


    tanh函数
aa = torch.tanh(z)
print("tanh激活后:",aa)
tanh激活后: tensor([-1.0000, -1.0000, -1.0000, -0.9975, -0.8045,  0.8045,  0.9975,  1.0000,
         1.0000,  1.0000])
  • relu函数&leakyrelu函数


    relu函数

    leakyrelu函数
aaa = torch.relu(z)
print("relu函数激活后:",aaa)
relu函数激活后: tensor([ 0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  1.1111,  3.3333,  5.5556,
         7.7778, 10.0000])

2、其他不常用到的激活函数

  • selu函数



  • softplus函数


2、损失函数与梯度计算

  • MSE均方损失函数

其中m为样本量,y_test为正确的值,y^_test为预测的值
如何在Pytroch中使用?
①导入torch.nn里面的functionnal的包

from torch.nn import functional as F

②调用里面的mse_loss函数

loss = F.mse_loss(torch.ones(2,2),x*w)
  • 梯度计算
    梯度计算相当于计算参数的导数,如:y^ = w*x+b 中的dw,db
    ①手动计算的代码如下:
x = torch.ones(2,2)
w = torch.full([2],3,dtype=float)
#loss = F.mse_loss(torch.ones(2,2),w*x)  #MSE表示均方误差
#print(loss)
w = w.requires_grad_()  #此处表示w需要求导,不写此行代码便会默认w不需要求导
# print(w)
loss = F.mse_loss(torch.ones(2,2),x*w)  #在表示需要求导后,还需要更新一下计算图,最后才能给出求导值
w = torch.autograd.grad(loss,w)
print(w)
输出结果:(tensor([2., 2.], dtype=torch.float64),)

②自动计算的代码如下:

x = torch.ones(2,2)
w = torch.full([2],3,dtype=float)
w = w.requires_grad_()
loss = F.mse_loss(torch.ones(2,2),x*w)
#sub = torch.sub(torch.ones(2,2),x*w)
loss.backward()
print(w.grad)
输出结果:(tensor([2., 2.], dtype=torch.float64),)

二、分类器

1、softmax函数

  • 数学表达式



    其作用于多分类任务,可将多个输出值,不管是正的还是负的,我们都可以将其转换成正的且都在0~1之间,它们的和也为1.如下图:



    代码:
b = torch.rand(3,requires_grad=True)
p = F.softmax(b,dim=0)
print(b,p)
result = torch.autograd.grad(p[1],[b],retain_graph=True)  #retain_graph=True保证之后还能继续计算
print(result)
result1 = torch.autograd.grad(p[2],[b])
print(result1)
tensor([0.5857, 0.8326, 0.9944], requires_grad=True) tensor([0.2642, 0.3382, 0.3976], grad_fn=<SoftmaxBackward>)
(tensor([-0.0894,  0.2238, -0.1345]),)
(tensor([-0.1051, -0.1345,  0.2395]),)

由输出的结果可知,在反向求梯度的时候,当i = j,其结果为正值;当i != j时,其结果为负值。与下列求导式一致:

①i = j时

②i != j时

三、感知机

1、单层感知机

#一个神经元
x = torch.rand(1,10)
w = torch.rand(1,10,requires_grad=True)
a = torch.sigmoid(x@w.t())
loss = F.mse_loss(torch.ones(1,1),a)
loss = loss.backward()
print(w)
tensor([[0.7482, 0.8185, 0.8484, 0.4469, 0.6821, 0.9002, 0.8074, 0.1035, 0.8236,
         0.0828]], requires_grad=True)

当有多个神经元:

#多个神经元
x = torch.rand(1,10)
w = torch.rand(2,10,requires_grad=True)
a = torch.sigmoid(x@w.t())
loss = F.mse_loss(torch.ones(1,2),a)
loss.backward()
print(w)

tensor([[0.2317, 0.3277, 0.5031, 0.8199, 0.8951, 0.3164, 0.1837, 0.0314, 0.9359,
         0.1265],
        [0.9429, 0.7510, 0.3555, 0.4035, 0.6221, 0.8966, 0.3446, 0.1877, 0.0359,
         0.4099]], requires_grad=True)

2、链式法则

代码如下:

x = torch.tensor(1.)
w1 = torch.tensor(2.,requires_grad=True)
b1 = torch.tensor(1.,requires_grad=True)
w2 = torch.tensor(2.,requires_grad=True)
b2 = torch.tensor(1.,requires_grad=True)
y1 = x*w1 + b1
y2 = y1*w2 + b2
#分两步求导
dy2_dy1 = torch.tensor(torch.autograd.grad(y2,[y1],retain_graph=True))
dy1_dw1 = torch.tensor(torch.autograd.grad(y1,[w1],retain_graph=True))
#直接求导
dy2_dw1 = torch.autograd.grad(y2,[w1],retain_graph=True)
print("链式求导:",dy2_dy1*dy1_dw1,"自动求导:",dy2_dw1)
链式求导: tensor([2.]) 自动求导: (tensor(2.),)

over...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容