两分钟了解神经网络中的梯度求解

两分钟了解神经网络中的梯度求解

  • 1.梯度
    • 1.1 pytorch的自动微分机制
    • 1.2 利用pytorch backward方法求导数(梯度)
    • 1.3自动微分 优化器求最小值
  • 总结

作者声明:本人才疏学浅,写文章记录和大家一起学习成长。
前情提要:不太懂张量的可以看一下我的另一篇文章: 两分钟了解张量
不太懂卷积神经网络的卷积的可以看看我的这篇文章: 两分钟通过代码理解卷积

1.梯度

有关梯度的概念,高数书上解释是方向导数的一个单位向量。挺抽象。
个人认为在神经网络中,梯度可以直接理解成导数,打个比方y=kx。
y的导数就是 (y+y)/(x+x),当x逼近0的值,就是高数的导数概念嘛。

1.1 pytorch的自动微分机制

神经网络通常依赖反向传播求梯度来更新网络参数,求梯度过程通常是一件非常复杂而容易出错的事情。

而深度学习框架可以帮助我们自动地完成这种求梯度运算。

Pytorch一般通过反向传播 backward 方法 实现这种求梯度计算。该方法求得的梯度将存在对应自变量张量的grad属性下。

除此之外,也能够调用torch.autograd.grad 函数来实现求梯度计算。

这就是Pytorch的自动微分机制。

1.2 利用pytorch backward方法求导数(梯度)

backward 方法通常在一个标量张量上调用,该方法求得的梯度将存在对应自变量张量的grad属性下。

如果调用的张量非标量,则要传入一个和它同形状 的gradient参数张量。

相当于用该gradient参数张量与调用张量作向量点乘,得到的标量结果再反向传播。
输入:
1, 标量的反向传播

import numpy as np 
import torch 

# f(x) = a*x**2 + b*x + c的导数

x = torch.tensor(0.0,requires_grad = True) # x需要被求导
a = torch.tensor(1.0)
b = torch.tensor(-2.0)
c = torch.tensor(1.0)
y = a*torch.pow(x,2) + b*x + c 

y.backward()
dy_dx = x.grad
print(dy_dx)

输出:

tensor(-2.)

2, 非标量的反向传播
输入:

import numpy as np 
import torch 

# f(x) = a*x**2 + b*x + c

x = torch.tensor([[0.0,0.0],[1.0,2.0]],requires_grad = True) # x需要被求导
a = torch.tensor(1.0)
b = torch.tensor(-2.0)
c = torch.tensor(1.0)
y = a*torch.pow(x,2) + b*x + c 

gradient = torch.tensor([[1.0,1.0],[1.0,1.0]])

print("x:\n",x)
print("y:\n",y)
y.backward(gradient = gradient)
x_grad = x.grad
print("x_grad:\n",x_grad)

输出:


x:
 tensor([[0., 0.],
        [1., 2.]], requires_grad=True)
y:
 tensor([[1., 1.],
        [0., 1.]], grad_fn=<AddBackward0>)
x_grad:
 tensor([[-2., -2.],
        [ 0.,  2.]])

反向传播的梯度就是x梯度的负数。

1.3自动微分 优化器求最小值

输入:

import numpy as np 
import torch 

# f(x) = a*x**2 + b*x + c的最小值


x = torch.tensor(0.0,requires_grad = True) # x需要被求导
a = torch.tensor(1.0)
b = torch.tensor(-2.0)
c = torch.tensor(1.0)

optimizer = torch.optim.SGD(params=[x],lr = 0.01)


def f(x):
    result = a*torch.pow(x,2) + b*x + c 
    return(result)

for i in range(500):
    optimizer.zero_grad()
    y = f(x)
    y.backward()
    optimizer.step()
   
    
print("y=",f(x).data,";","x=",x.data)

输出:

y= tensor(0.) ; x= tensor(1.0000)

如此就是神经网络训练三部曲:求梯度,反向传播,更新loss。最终使得loss最小

总结

重点了解梯度的含义即可,网络训练可以在实操中慢慢理解掌握。

点个赞、关注一下,给博主更多动力呗。么么哒~

参考:
https://github.com/lyhue1991/eat_pytorch_in_20_days

你可能感兴趣的:(神经网络,深度学习,pytorch,python)