深度学习|求导公式:梯度逆传播规律

引言

我们知道,神经网络的能够学习处理任务的核心是计算损失的梯度,而误差逆传播算法是求梯度的一种通用且高效的办法。使用误差逆传播算法求解神经网络的梯度,其实就是求网络中使用的各种基本运算的局部导数的过程。这期我们将回顾各类基本运算的求导公式,然后演示如何将这些公式运用在误差逆传播算法求解网络梯度。

在这里插入图片描述

依赖模块统一导入

此处我们统一导入本文所需的所有依赖模块,下文中不再重复演示。

import numpy as np
import matplotlib.pyplot as plt

作图准备

此处我们准备一个可以绘制下文所有函数图形的 draw 方法,并准备作图用的数据,方便后续演示。

def draw(X, func, func_derivative, title, x_point=1, color='orange', **kwargs):
    """
    绘制函数、切线、导数函数的图形
    :param X: 输入数据
    :param func: 函数
    :param func_derivative: 函数导数
    :param title: 图形标题
    :param x_point: 切线点的 x 轴坐标
    :param color: 图形颜色
    :param kwargs: 函数的参数
    """

    # 创建子图,figsize 参数指定图形的大小为 12 x 5
    fig, axs = plt.subplots(1, 2, figsize=(12, 4.5))

    # 绘制函数图形
    axs[0].plot(X, func(**kwargs)(X), label=title, color=color)
    axs[0].set_title(title)
    axs[0].set_xlabel('Input')
    axs[0].set_ylabel('Output')

    # 绘制在 x_point 处的切线
    func_x_point = func(**kwargs)(x_point)
    func_prime = func_derivative(**kwargs)(x_point)
    tangent_line_func = func_x_point + func_prime * (x - x_point)
    axs[0].plot(x, tangent_line_func,
                label=f"Tangent to {
      
      title} at x={
      
      x_point}", linestyle=':', color='red')
    axs[0].scatter([x_point], [func_x_point], color='red')

    # legend 函数用于显示图例
    axs[0].legend()
    # grid 函数用于显示网格
    axs[0].grid(True)

    # 绘制导数函数图形
    axs[1].plot(X, func_derivative(**kwargs)(X), label=f"Derivative of {
      
      title}", color=color)
    axs[1].set_title(f"Derivative of {
      
      title}")
    axs[1].set_xlabel('Input')
    axs[1].set_ylabel('Output')
    axs[1].legend()
    axs[1].grid(True)

    # tight_layout 函数用于调整子图之间的间距
    plt.tight_layout()
    plt.show()

数据准备

# x 从 -2 到 2,等间隔的 400 个点,用于绘制函数图形
x = np.linspace(-2, 2, 400)

基础函数的求导

常数函数

常数函数是指函数的值在定义域内保持为常数 c c c,即:

f ( x ) = c f(x) = c f(x)=c

常数函数的导数为零:

d d x [ c ] = 0 \frac{d}{dx}[c] = 0 dxd[c]=0

使用 Python 实现常数函数及其导数:

def constant_function(c):
    return lambda x: np.full_like(x, c)


def constant_derivative(c):
    return lambda x: np.zeros_like(x)

查看常数函数及其导数的图形:

# 绘制常数 c=1 时,常数函数的图形、常数函数在 x=1.0 处的切线、常数函数的导数图形
draw(x, constant_function, constant_derivative, "Constant Function(c=1)", x_point=1.0, color='blue', c=1)

在这里插入图片描述

常数函数的图形是一条截距为 c c c 的水平直线,其导数为零,导数函数的图形是一条全为零的水平直线。

幂函数

幂函数是指函数的定义域为实数,求关于 x x x n n n 次幂的函数,其中 n n n 是整数,即:

f ( x ) = x n f(x) = x^n f(x)=xn

幂函数 f ( x ) = x n f(x) = x^n f(x)=xn 的导数为:

d d x [ x n ] = n x n − 1 \frac{d}{dx}[x^n] = nx^{n-1} dxd[xn]=nxn1

使用 Python 实现幂函数及其导数:

def power_function(n):
    return lambda x: np.power(x, n)


def power_derivative(n):
    return lambda x: n * np.power(x, n - 1)

查看幂函数及其导数的图形:

# 绘制指数 n=2 时,幂函数的图形、幂函数在 x=1.0 处的切线、幂函数的导数图形
draw(x, power_function, power_derivative, "Power Function(n=2)", x_point=1.0, color='blue', n=2)

在这里插入图片描述

# 绘制指数 n=3 时,幂函数的图形、幂函数在 x=1.0 处的切线、幂函数的导数图形
draw(x, power_function, power_derivative, "Power Function(n=3)", x_point=1.0, color='blue', n=3)

在这里插入图片描述

幂函数的图形是一条经过原点的曲线,其导数为 n x n − 1 nx^{n-1} nxn1,导数函数的图形是一条经过原点的曲线。

指数函数

指数函数是指函数的定义域为实数,求实数 a a a x x x 次幂的函数,即:

f ( x ) = a x f(x) = a^x f(x)=ax

指数函数的导数为:

d d x [ a x ] = a x ln ⁡ ( a ) \frac{d}{dx}[a^x] = a^x \ln(a) dxd[ax]=axln(a)

a = e a=e a=e 时,这个函数被称为自然指数函数:

f ( x ) = e x f(x) = e^x f(x)=ex

自然指数函数的导数为:

d d x [ e x ] = e x \frac{d}{dx}[e^x] = e^x dxd[ex]=ex

使用 Python 实现指数函数及其导数:

def exp_function(a):
    return lambda x: np.exp(x) if a == np.e else np.power(a, x)


def exp_derivative(a):
    return lambda x: np.exp(x) if a == np.e else np.power(a, x) * np.log(a)

查看指数函数及其导数的图形:

# 绘制底数 a=e 时,指数函数的图形、指数函数在 x=1.0 处的切线、指数函数的导数图形
draw(x, exp_function, exp_derivative, "Exp Function(a=e)", x_point=1.0, color='blue', a=np.e)

在这里插入图片描述

draw(x, exp_function, exp_derivative, "Exp Function(a=10)", x_point=1.0, color='blue', a=10)

在这里插入图片描述

对数函数

对数函数是指函数的定义域为正实数,求底数为 a a a 的实数 x x x 的对数的函数,即:

f ( x ) = log ⁡ a ( x ) f(x) = \log_a(x) f(x)=loga(x)

对数函数的导数为:

d d x [ log ⁡ a ( x ) ] = 1 x ln ⁡ ( a ) \frac{d}{dx}[\log_a(x)] = \frac{1}{x \ln(a)} dxd[loga(x)]=xln(a)1

当底数 a = e a=e a=e 时,我们称这样的对数函数为自然对数函数:

f ( x ) = ln ⁡ ( x ) f(x) = \ln(x) f(x)=ln(x)

自然对数函数的导数为:

d d x [ ln ⁡ ( x ) ] = 1 x \frac{d}{dx}[\ln(x)] = \frac{1}{x} dxd[ln(x)]=x1

常用对数 log ⁡ 10 ( x ) \log_{10}(x) log10(x) 的导数:

d d x [ log ⁡ 10 ( x ) ] = 1 x ln ⁡ ( 10 ) \frac{d}{dx}[\log_{10}(x)] = \frac{1}{x \ln(10)} dxd[log10(x)]=xln(10)1

使用 Python 实现对数函数及其导数:

def log_function(base):
    return lambda x: np.log(x) / np.log(base)


def log_derivative(base):
    return lambda x: 1 / (x * np.log(base))

查看对数函数及其导数的图形:

x_log = np.linspace(0.01, 3, 400)
draw(x_log, log_function, log_derivative, "Log Function(base=e)", x_point=1.0, color='blue', base=np.e)

在这里插入图片描述

draw(x_log, log_function, log_derivative, "Log Function(base=10)", x_point=1.0, color='blue', base=10)

在这里插入图片描述

三角函数

三角函数是指函数的定义域为实数,求三角形的角度的函数,常见的三角函数包括正弦函数 sin ⁡ ( x ) \sin(x) sin(x)、余弦函数 cos ⁡ ( x ) \cos(x) cos(x) 和正切函数 tan ⁡ ( x ) \tan(x) tan(x)

正弦函数 sin ⁡ ( x ) \sin(x) sin(x) 的导数:

d d x [ sin ⁡ ( x ) ] = cos ⁡ ( x ) \frac{d}{dx}[\sin(x)] = \cos(x) dxd[sin(

评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三余知行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值