深度学习——微积分求导,反向传播
目录
- 一、导数
- 二、自动微分,反向传播
- 2.1 对向量求导的例子
- 2.1 求和函数的梯度
一、导数
举一个关于导数的实例,定义一个函数 u = f ( x ) = 3 x 2 − 4 x u=f(x)=3x^2-4x u=f(x)=3x2−4x
pip install matplotlib
import numpy as np
from matplotlib_inline import backend_inline
import torch
def f(x):
return 3 * x ** 2 - 4 * x
定义一个求导函数:通过令x=1并让h趋近于0,观察 f ( x + h ) − f ( x ) h \frac {f(x+h)-f(x)} {h} hf(x+h)−f(x)的数值结果趋近于2
def numerial_lim(f,x,h):
return (f(x+h)-f(x))/h
h=0.1
for i in range(5):
print(f'h={h:.5f}, numerial limit = {numerial_lim(f, 1, h):.5f}')
h *= 0.1
为了对导数进行可视化,将使用python中流行的绘图库matplotlib包生成图形。
from matplotlib import pyplot as plt
def use_svg_display(): #@save
"""使用svg格式在Jupyter中显示绘图"""
backend_inline.set_matplotlib_formats('svg')
def set_figsize(figsize=(3.5, 2.5)): #@save
"""设置matplotlib的图表大小"""
use_svg_display()
plt.rcParams['figure.figsize'] = figsize
#@save
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
"""设置matplotlib的轴"""
axes.set_xlabel(xlabel)
axes.set_ylabel(ylabel)
axes.set_xscale(xscale)
axes.set_yscale(yscale)
axes.set_xlim(xlim)
axes.set_ylim(ylim)
if legend:
axes.legend(legend)
axes.grid()
from matplotlib import pyplot as plt
def use_svg_display(): #@save
"""使用svg格式在Jupyter中显示绘图"""
backend_inline.set_matplotlib_formats('svg')
def set_figsize(figsize=(3.5, 2.5)): #@save
"""设置matplotlib的图表大小"""
use_svg_display()
plt.rcParams['figure.figsize'] = figsize
#@save
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
"""设置matplotlib的轴"""
axes.set_xlabel(xlabel)
axes.set_ylabel(ylabel)
axes.set_xscale(xscale)
axes.set_yscale(yscale)
axes.set_xlim(xlim)
axes.set_ylim(ylim)
if legend:
axes.legend(legend)
axes.grid()
x = np.arange(0, 3, 0.1)
plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])
现在可以绘制函数及其在x=1处的切线y=2x-3, 其中系数是2切线的斜率。
二、自动微分,反向传播
深度学习框架通过自动计算导数,即自动微分来加快求导。在实验中,根据设计好的模型,系统会构建一个计算图,来跟踪计算是哪些数据通过哪些操作组合起来产生输出。自动微分使系统能够随后反向传播梯度,意味着跟踪整个计算图,填充关于每个参数的偏导数。
2.1 对向量求导的例子
对函数 y = 2 x T x y=2\bm x^T \bm x y=2xTx关于列向量 x \bm x x求导,先创建变量 x \bm x x,并为其分配一个初始值。
import torch
x = torch.arange(4.0)
x
在计算
y
y
y关于
x
\bm x
x的梯度之前,需要一个区域来存储梯度。
x=torch.arange(4.0,requires_grad=True)
x.grad
y = 2*torch.dot(x,x)
y
x是一个长度为4的向量,计算x和x的点积,得到了我们赋值给y的标量输出。 接下来,通过调用反向传播函数来自动计算y关于x每个分量的梯度,并打印这些梯度。
y.backward()
x.grad
函数
y
=
2
x
T
x
y=2\bm x^T \bm x
y=2xTx关于
x
\bm x
x的梯度应为
4
x
4x
4x,快速验证梯度是否计算正确。
x.grad == 4*x
2.1 求和函数的梯度
现在计算x的另一个函数(求和函数)的梯度,每个变量的导数系数应该为1.
# 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()
y = x.sum()
y.backward()
x.grad