第三节 微分和自动求导

2.4微分

用微分解决问题的思想,把一个比较大(或者无法用常规方法解决)的问题无限分割,直到问题缩小到能够比较简单的解决。深度学习中,我们训练模型,不断更新他们,使他们的效果变得更好。衡量模型有多好的标准,是损失函数。

2.4.1 导数与微分

关于导数的例子:

import matplotlib.pyplot as plt
import numpy as np
from IPython import display
from d2l import torch as d2l


def f(x):  # 定义函数
    return 3 * x ** 2 - 4 * x


def numberical_lim(f, x, h):
    return (f(x + h) - f(x)) / h


h = 0.1
for i in range(5):
    print(f'h={h:.5f},numberical lim={numberical_lim(f, 2, h):.5f}')  # 当x=2时,计算其导数
    h *= 0.1


def use_svg_display():  # 使用svg格式在调用显示绘图
    display.set_matplotlib_formats('svg')


def set_figsize(figzize=(3.5, 2.5)):  # 设置matplotlib图表的大小。
    use_svg_display()
    d2l.plt.rcParams['figure.figsize'] = figzize


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()


def plot(X, Y=None, xlabel=None, ylabel=None, legend=None, xlim=None,
         ylim=None, xscale='linear', yscale='linear',
         fmts=('-', 'm--', 'g-.', 'r:'), figsixe=(3.5, 2.5), axes=None):
    if legend is None:
        legend = []
        set_figsize(figsixe)
        axes = axes if axes else d2l.plt.gca()

        # 如果 “X”有一个轴,则输出Ture
        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)


x = np.arange(0, 3, 0.1)
plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])
plt.show()

2.4.2 偏导数

将导数的概念扩展到多元函数上,就有了偏导数的概念。

2.4.3 梯度

我们可以连结一个多元函数对其所有变量的偏导数,以得到该函数的梯度向量。梯度在深度学习模型训练的作用是提供一个正确的方向,梯度的方向即变化率最大的方向,更够更加快的找到目标,实现模型的优化。

2.2.4 链式法则

在很多时候,多元函数都是复合的,链式法则能使我们能够微分复合函数,即复合函数求导.

2.5 自动求导

深度学习框架可以自动计算求导,即自动求导,来加快这项工作。

实际中,根据我们设计的模型,系统会构建一个计算图,来跟踪计算是那些数据通过哪些操作组合产生的数据通过哪些操作组合起来产生输出。

2.5.1 grad()和backwark()函数

首先要先把张量的.requires_grad 属性设置为True

backward()是求导,会记录在grad中,grad的值会不断累加,使用之前需要清零

# 对函数y = 2x.T*x关于列向量x求导
import torch
x=torch.arange(4.0)
print(x)
x.requires_grad_(True)
print(x.grad)    # 默认是None
y=2 *torch.dot(x,x)   #函数y
print(y)
print(y.backward())    #y.backward  对函数y自动求梯度
print(x.grad)
print(x.grad==4*x)
#默认情况下,pytorch会累计梯度,我们需要清除之前的值
x.grad.zero_()
print(x.grad)
y=x.sum()
print(y)
y.backward()     ## 标量才能使用backward()函数,如果是矩阵,需要.sum().backward
print(x.grad)
#  计算偏导数之和
x.grad.zero_()
y=x*x
print(torch.ones(len(x)))
y.sum().backward()   #等价于y.backward(torch.ones(len(x)))  调用原矩阵和维度为1相乘,结果是原矩阵的和 相当于.sum()
print(x.grad)
x.grad.zero_()
y=x*x
u=y.detach()  #分离出一个不需要梯度的变量
z=u*x
print(z)
print(z.sum())
z.sum().backward()
print(x.grad==u)
x.grad.zero_()
y.sum().backward()
print(x.grad)
print(x.grad==2*x)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值