【d2l】2.4.微积分
【d2l】2.4.微积分
本节主要讲解了微分、偏导、梯度和链式法则
其中梯度需要着重强调
梯度
对于一个多元函数,我们可以对所有变量做偏导数,从而得到该函数的梯度向量
函数\(f:\mathbb{R}^n \rightarrow \mathbb{R}\)输入了一个\(n\)维向量\(x = [x_1, x_2,..., x_n]^\top\),输出一个标量。
则\(f(x)\)的梯度为
\[\nabla_xf(x) = [\frac{\partial f(x_1)}{x_1}, \frac{\partial f(x_2)}{x_2}, ..., \frac{\partial f(x_n)}{x_n}]
\]
梯度有以下常用性质
- \(\nabla_x Ax = A^\top\)
- \(\nabla_x x^\top A = A\)
- \(\nabla_x x^\top Ax = (A + A^\top)x\)
- \(\nabla_x ||x||^2 = \nabla_x x^\top x = 2x\)
以上的性质事实上是在说明一件事情:向量对向量的导数是一个矩阵,拿第一个性质举例
\[Ax =
\left [
\begin{matrix}
a_1^\top x\\
a_2^\top x\\
\vdots \\
a_n^\top x
\end{matrix}
\right ]
\]
于是对于每一行都能求偏导
\[\frac{\partial(a_i^\top x)}{\partial x} = a_i
\]
堆叠起来正好是矩阵的转置
在这样的基础上考虑第三个性质,可以知道是类似的,只不过是对一个二次型求偏导【考虑第\(k\)维】
\[\frac{\partial}{\partial x_k}\sum_{i, j}A_{ij}x_ix_j = \sum_{j}A_{kj}x_j + \sum_{i}A_{ik}x_i
\]
左右分别是\(A\)和\(A^\top\)
最后一个性质就是第三个性质的特例了,几何意义就是距离原点越远,梯度越大
曲线绘制
本节还有一个相对重要的内容,即曲线的绘制
由于我的pytorch版本较高,d2l可能不太有效,因此我考虑一步步自己构造一个d2l_local自带库
首先在项目的根目录设置一个d2l_local,要在notebook导入的话需要在系统路径加入一点东西
import sys
sys.path.appened("..") # 这样就会从项目根目录找自带库了
from d2l_local import torch as d2l
然后就是关于曲线的绘制了,首先要实现使用svg格式绘图、设置图标大小、设置轴的函数
def use_svg_display():
"""使用svg格式在Jupyter中显示绘图"""
backend_inline.set_matplotlib_formats('svg')
def set_figsize(figsize = (3.5, 2.5)):
"""设置图表大小"""
use_svg_display()
plt.rcParams['figure.figsize'] = figsize
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()
最后就是用一个plot函数封装,这样就能简洁地绘制不同曲线了
ef plot(X, Y = None, xlabel = None, ylabel = None, legend = None,
xlim = None, ylim = None, xscale = 'linear', yscale = 'linear',
fmts = ('-', 'm--', 'g-.', 'r:'), figsize = (3.5, 2.5), axes = None):
"""绘制数据点"""
if legend is None:
legend = []
set_figsize(figsize)
axes = axes if axes else plt.gca()
# 如果X有一个轴就返回True
def has_one_axis(X):
return ( hasattr(X, "ndim") and X.ndim == 1
or isinstance(X, list) and not hasattr(X[0], "__len__"))
if has_one_axis(X):
X = [X]
if Y is None:
X, Y = [[]] * len(X), X
elif has_one_axis(Y):
Y = [Y]
if len(X) != len(Y):
X = X * len(Y)
axes.cla()
for x, y, fmt in zip(X, Y, fmts):
if len(x):
axes.plot(x, y, fmt)
else:
axes.plot(y, fmt)
set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)

浙公网安备 33010602011771号