AI数学基础

115 阅读10分钟

应用场景:

  • 微积分:重点关注微分(对函数进行求导)部分,因为人工智能领域有一个很重要的算法,叫做神级网络反向传播,通过反向传播算法,可以更新神经网络里面的每一个参数,更新的时候是要计算出每一个参数的导数等于多少,也就是要求出微分是多少?

    以下几个案例:

    1、激活函数作图:用于描述激活函数。

    2、展示二维图像切线

    3、展示三维函数切面

    4、神经网络反向传播:链式求导法则

    5、制作梯度下降求最小值的动画

    6、实现三维平面的梯度下降

  • 线性代数:在人工智能领域,有一块叫计算机视觉,要处理的就是一些图像信息,图像信息对于电脑而言是一个矩阵,这样就和线性代数的矩阵产生关联了

    相关案例:

    1、创建矩阵

    2、把矩阵保存成图片:可以知道神经网络,在中间层通过特征图学了些什么东西

    3、图像亮度增强

    4、图像对比度增强

    5、矩阵基本运算

    6、计算特征值与特征向量

    7、图像的SVD压缩

  • 概率论:在人工智能领域,例如图形操作用到了线性代数,通过矩阵相加实现亮度增强或下降,添加的内容可以再加入一些噪声,使用python模拟随机试验概率质量函数示意图求期望、方差、协方差模拟常见的概率分布,模拟大数定律、模拟中心极限定理

线性代数:人工智能数据基础

基础概念

  • 标量(Scalar):一个标量是一个单独的数值,它只有大小,没有方向。在数学中,通常用实数或复数表示。例如,温度、质量、时间等都是标量。
  • 向量(Vector):一个向量是具有大小和方向的量。它由一系列有序的数值组成,表示空间中的一个点或物体的位置或移动方向。在数学中,向量通常表示为一个列或行矩阵。例如,速度、力、位移等都是向量。
  • 矩阵(Matrix):一个矩阵是一个二维数组,其中的每个元素都是一个标量。它可以表示多个向量或者多个量之间的关系,也可以表示线性变换。在数学和计算机科学中,矩阵常用于解线性方程组、表示图形变换等。
  • 张量(Tensor):张量是一个可以在多个方向上有分量的数学对象。它是向量的推广,可以看作多维数组。标量是零阶张量,向量是一阶张量,矩阵是二阶张量,而更高阶的张量可以有更多的维度。在物理学、工程学和机器学习等领域中,张量常用于表示物理量、数据集合等复杂的数据结构。

实战案例:创建向量、矩阵、张量

  • 创建向量(一维)
import numpy as np
​
# 创建向量(一维)
vector = np.array([1, 2, 3, 4, 5])
vector_norm = np.linalg.norm(vector)
​
print("Vector:\n", vector)
print("Vector的范数长度:\n", vector_norm)
​
运行结果:
Vector:
 [1 2 3 4 5]
Vector的范数长度:
 7.416198487095663
  • 创建矩阵(二维)
import numpy as np
​
# 创建矩阵(二维)
matrix = np.array([
    [1, 2, 3], 
    [4, 5, 6], 
    [7, 8, 9]
])
matrix_norm = np.linalg.norm(matrix)
​
print("matrix:\n", matrix)
print("matrix的范数长度:\n", matrix_norm)
​
运行结果:
matrix:
 [[1 2 3]
 [4 5 6]
 [7 8 9]]
matrix的范数长度:
 16.881943016134134
  • 创建张量(三维)
import numpy as np
​
# 创建张量(三维)
tensor = np.array([
    [[1,2],[3,4]],
    [[5,6],[7,8]],
    [[9,10],[11,12]]
])
tensor_norm = np.linalg.norm(tensor)
​
print("tensor:\n", tensor)
print("tensor的范数长度:\n", tensor_norm)
​
运行结果:
tensor:
 [[[ 1  2]
  [ 3  4]][[ 5  6]
  [ 7  8]][[ 9 10]
  [11 12]]]
tensor的范数长度:
 25.495097567963924

实战案例:将Numpy矩阵保存成本地图像

import numpy as np
import cv2
​
# 创建一个大小为 224*224 的二维矩阵,值为0-255之间
two_d_matrix = np.random.randint(0, 256, (224, 224), dtype=np.uint8)
​
# 创建一个大小为 3*224*224 的三维矩阵,值为0-255之间
three_d_matrix = np.random.randint(0, 256, (3, 224, 224), dtype=np.uint8)
​
# 在 OpenCv 中,图像的通道顺序为 高 * 宽 * 通道数
three_d_matrix_transposed = three_d_matrix.transpose(1, 2, 0)
​
# 将画面显示出来
cv2.imshow('two_d_matrix', two_d_matrix)
cv2.imshow('three_d_matrix', three_d_matrix_transposed)
cv2.waitKey(0)
cv2.destroyAllWindows()
​
# 使用 OpenCv 将图片保存本地
cv2.imwrite('two_d_matrix.jpg', two_d_matrix)
cv2.imwrite('three_d_matrix.jpg', three_d_matrix_transposed)

实战案例:图像增强(调整对比度)

  • 标量与矩阵的乘法,即可实现对比度增强及减弱

  • 代码如下:

    import numpy as np
    import cv2
    ​
    # 读取图像
    image = cv2.imread('robot.png')
    ​
    # 增加对比度
    increased_contrast = cv2.convertScaleAbs(image, alpha=1.5)
    ​
    # 减少对比度
    decreased_contrast = cv2.convertScaleAbs(image, alpha=0.5)
    ​
    # 将图像进行横向拼接
    combined_image = np.hstack((image, increased_contrast, decreased_contrast))
    ​
    # 显示图片
    cv2.imshow('image, increased_contrast, decreased_contrast', combined_image)
    # 画面固定屏幕当中
    cv2.waitKey(0)
    # 关闭所有已经打开的窗口,可以帮助释放资源并关闭窗口,确保程序的正常退出
    cv2.destroyAllWindows()
    
  • 练习:标量与矩阵相乘以及矩阵相加

    import numpy as np
    ​
    # 定义矩阵A和B
    A = np.array([[1, 2], [3, 4]])
    B = np.array([[5, 6], [7, 8]])
    ​
    # 定义标量C
    C = 3
    ​
    # 标量与矩阵的乘法
    scalar_matrix_multiplication = C * A
    ​
    # 矩阵的加法
    matrix_addition = A + B
    ​
    print('标量与矩阵的乘法:', scalar_matrix_multiplication)
    print('矩阵的加法:', matrix_addition)
    ​
    运行结果:
    标量与矩阵的乘法: [[ 3  6]
     [ 9 12]]
    矩阵的加法: [[ 6  8]
     [10 12]]
    

Python 实现解方程组

解以下方程: X1 + 2X2 + 3X3 = 5 X1 + 6X2 + 7X3 = 9 X1 + 10X2 + 6X3 = 8

  • 手推

        | 1  2  3 |            | 5 |
    A = | 1  6  7 |        B = | 9 |
        | 1  10 6 |            | 8 |
      
              | 1  2  3 | 5 |
    (A | B) = | 1  6  7 | 9 |
              | 1  10 6 | 8 |
              
              | 1  2  3 | 5 |
    r3 - r2 = | 1  6  7 | 9 |
              | 0  4 -1 |-1 |
              
              | 1  2  3 | 5 |
    r2 - r1 = | 0  4  4 | 4 |
              | 0  4 -1 |-1 |
              
              | 1  2  3 | 5 |
    r3 - r2 = | 0  4  4 | 4 |
              | 0  0 -5 |-5 |
              
    r2 * 1/4  | 1  2  3 | 5 |
    ------- = | 0  1  1 | 1 |
    r3 * -1/5 | 0  0  1 | 1 |
    ​
    x1 + 2X2 + 3X3 = 5
    X2 + X3 = 1
    X3 = 1
    ​
    所以最终结果:
    X3 = 1
    X2 = 0
    X1 = 2
    
  • 代码

    import numpy as np
    ​
    # 创建系数矩阵
    A = np.array([
      [1, 2, 3],
      [1, 6, 7],
      [1, 10, 6]
    ])
    ​
    # 创建常数向量
    B = np.array([5, 9, 8])
    ​
    # 解方程
    x = np.linalg.solve(A, B)
    ​
    # 打印结果
    print('解:', x)
    ​
    运行结果:
    解: [2. 0. 1.]
    

特征向量与特征值实操

特征值和特征向量是线性代数中的重要概念,它们通常在矩阵和线性变换的理论中发挥作用。

  • 特征值是一个标量,用来表示线性变换对应的特定方向上的缩放比例。如果我们把线性变换想象成一个拉伸机,特征值就是拉伸或缩放的倍数,它反映了变换对于特定方向上向量的伸缩程度。
  • 特征向量则是在线性变换下不改变方向的向量。换句话说,它们是变换后的向量方向保持不变的向量。在拉伸机的例子中,特征向量就是被拉伸后方向不变的箭头,它们指示了变换的主要方向。

这两个概念通常是通过矩阵的特征方程来计算的,特征方程是一个关于特征值的多项式方程。解这个方程可以得到特征值,而对应每个特征值,我们可以找到对应的特征向量。

  • 求解以下矩阵的特征值与特征向量

    A = | 4  1 |
        | 2  3 |
    
    • 计算特征值方程

      det(A - λI) = det( 4 - λ    1   )  = ( 4 - λ)( 3 - λ) - 2 = λ² - 7λ + 10 = 0
                       (   2    3 - λ )
      
    • 求特征值方程

      λ² - 7λ + 10 = 0   λ1 = 5, λ2 = 2
      
    • 求特征向量方程

      (A - λI)χ = 0
      
    • 计算结果

      当 λ1 = 5 时,特征向量为 0.707
                             0.707
                              
      当 λ1 = 5 时,特征向量为 -0.447
                             0.894
      
  • 代码解方程

    import numpy as np
    ​
    # 定义矩阵A
    A = np.array([
        [4,1],
        [2,3]
    ])
    ​
    # 使用numpy求特征值和特征向量
    eigenvalues, eigenvectors = np.linalg.eig(A)
    ​
    print('特征值',eigenvalues)
    print('特征向量',eigenvectors)
    ​
    运行结果:
    特征值 [5. 2.]
    特征向量 [[ 0.70710678 -0.4472136 ]
     [ 0.70710678  0.89442719]]
    
  • 案例实战:图像的SVD分解

    对一幅图像进行SVD分解后可以得到三个矩阵:

    • U矩阵:包含了“左奇异向量”,可以想象成是一组基础的图像模式。
    • Σ矩阵:包含了“奇异值”,表明了每个图像模式的重要性或权重。较大的奇异值对应于图像中更重要的特征。
    • V矩阵:包含了“右奇异向量”,它与U矩阵类似,但从不同角度描述了图像的特征。

    通过这种分解,图像转化为一系列的模式和对应的权重。可通过用较少的数据来描述一幅图像,同时保留其关键特征,从而实现图片的信息压缩功能。

    import cv2  # 导入 OpenCV 库
    import numpy as np  # 导入 NumPy 库用于科学计算# 读取图像
    image = cv2.imread('robot.bmp', 0)  # 使用 OpenCV 读取灰度图像
    ​
    print("Shape of image:", image.shape)  # 打印图像的形状# 对图像进行 SVD 分解
    U, S, V = np.linalg.svd(image.astype(np.float64), full_matrices=False)
    # image.astype(np.float64) 将图像数据类型转换为 float64,以便进行数值计算
    # full_matrices=False 表示不返回完整的 U 和 V 矩阵# 定义要保留的奇异值数量
    k = 10  # 选择保留的奇异值数量s_k = np.diag(S[:k])  # 提取前 k 个奇异值构成的对角矩阵# 重构图像
    compressed_image = np.dot(U[:, :k], np.dot(s_k, V[:k, :]))
    # 使用前 k 个奇异值重构图像
    # np.dot() 用于矩阵乘法compressed_image = np.clip(compressed_image, 0, 255).astype(np.uint8)
    # 将图像像素值限制在 0 到 255 之间,并将数据类型转换为 uint8# 显示图像
    cv2.imshow('Original Image', image)  # 显示原始图像
    cv2.imshow('Compressed Image', compressed_image)  # 显示压缩后的图像
    ​
    cv2.waitKey(0)  # 等待按键
    cv2.destroyAllWindows()  # 关闭所有窗口
    

微积分:数学背后的AI力量

基本概念

是数学中的一个基本概念,主要用于研究函数随变量变化的快慢,即变化率。给出一个函数 f(x),如果我们想要计算在某一点 x = a 处的导数,我们会考虑函数在 x 接近 a 时的变化情况。

更正式地说,函数 f(x) 在点 x = a 处的导数定义为:

f(a)=limh0f(a+h)f(a)hf'(a) = \lim_{{h \to 0}} \frac{f(a+h) - f(a)}{h}

如果这个极限存在,我们就说函数在点 a 是可导的。

几何意义:在几何上,导数表示的是曲线在某一点处切线的斜率。假设你有一个函数 f(x) 的图形,这个图形在每一点上都有一个斜率,这个斜率就是该点处的导数。当你在图形上选择一个点,并尝试画出恰好触碰曲线在那一点的直线(即切线),那么这条切线的斜率(即斜率的升高与横向移动的比率)就是那点处函数的导数。如果导数是正值,切线向上倾斜;如果导数是负值,切线向下倾斜;如果导数是零,切线是水平的。

常见导数

初等函数导数
xnx^nnxn1n \cdot x^{n-1}
exe^xexe^x
axa^xaxln(a)a^x \ln(a)
ln(x)\ln(x)1x\frac{1}{x}
loga(x)\log_a(x)1xln(a)\frac{1}{x \ln(a)}
sin(x)\sin(x)cos(x)\cos(x)
cos(x)\cos(x)sin(x)-\sin(x)
tan(x)\tan(x)sec2(x)\sec^2(x)
arcsin(x)\arcsin(x)11x2\frac{1}{\sqrt{1 - x^2}}
arccos(x)\arccos(x)11x2-\frac{1}{\sqrt{1 - x^2}}
arctan(x)\arctan(x)11+x2\frac{1}{1 + x^2}

深度学习中的激活函数

激活函数表达式导数特点
Sigmoidσ(x)=11+exσ(x) = \frac{1}{ 1+ e^{-x}}σ(x)=σ(x)(1σ(x))σ'(x) = σ(x)(1-σ(x))将输入压缩到(0,1)区间,用于二分类问题,在深层网络中容易产生梯度消失
Tanhtanh(x)=exexex+extanh(x) = \frac{e^x-e^-x}{e^x+e^-x}tanh(x)=1tanh2(x)tanh'(x) = 1 - tanh^2(x)将输入压缩到(-1,1)区间,比sigmoid有更大的输出范围,也可能导致梯度消失
ReLUReLU(x)=max(0,x)ReLU(x) = max(0,x)ReLU(x)={1,if x>00,if x<=0\text{ReLU}'(x) = \begin{cases} 1, & \text{if } x > 0 \\ 0, & \text{if } x<=0 \end{cases}在正区间内保持梯度不变,解决了梯度消失问题,但在负区间梯度为0
Leaky ReLULeakyReLU(x)=max(0.01x,x)LeakyReLU(x) = max(0.01x,x)LeakyReLU(x)={1,if x>0α,if x<=0\text{LeakyReLU}'(x) = \begin{cases} 1, & \text{if } x > 0 \\ \alpha, & \text{if } x<=0 \end{cases}解决了ReLU在负区间梯度为0的问题,允许小梯度存在
Parametric ReLUPReLU(x)=max(αx,x)PReLU(x) = max(αx,x)PReLU(x)={1,if x>0α,if x<=0\text{PReLU}'(x) = \begin{cases} 1, & \text{if } x > 0 \\ \alpha, & \text{if } x<=0 \end{cases}ReLU的泛化形式,其中α是一个可学习的参数
ELUELU(x)={x,if x>0α(ex1),if x<=0ELU(x) = \begin{cases} x, & \text{if } x > 0 \\ \alpha (e^x - 1), & \text{if } x <=0 \end{cases}ELU(x)={1,if x>0αex,if x<=0\text{ELU}'(x) = \begin{cases} 1, & \text{if } x > 0 \\ \alpha e^x, & \text{if } x <= 0 \end{cases}试图结合sigmoid和ReLU的优点,输出对负值有小幅度的响应
SoftmaxSoftmax(xi)=exijexjSoftmax(x_i) = \frac{e^{x_i}}{\sum_{j}e^{x_j}}Softmax(xi)xi={Softmax(xi)(1Softmax(xi)),if i=jSoftmax(xi)Softmax(xj),if i!=j\frac{∂Softmax(x_i)}{∂x_i} = \begin{cases} Softmax(x_i)(1-Softmax(x_i)), & \text{if } i = j \\ -Softmax(x_i)Softmax(x_j), & \text{if } i != j \end{cases}用于多分类问题的输出层,输出值的和为1,代表概率分布

Python绘制激活函数

  • Sigmoid

    import numpy as np
    import matplotlib.pyplot as plt
    
    # 定义 Sigmoid 激活函数
    def sigmoid(x):
        return 1 / (1 + np.exp(-x))
    
    # 绘制激活函数图像的函数
    def plot_activation_function(func, x, title):
        # 计算函数值
        y = func(x)
        
        # 绘制函数图像
        plt.plot(x, y)
        plt.title(title)
        plt.xlabel('x')
        plt.ylabel('f(x)')
        plt.grid(True)
        plt.show()
    
    # 生成 x 范围数组
    x_value = np.arange(-10, 10, 0.1)
    
    # 绘制 Sigmoid 函数图像
    plot_activation_function(sigmoid, x_value, 'Sigmoid')
    
  • tanh

    import numpy as np
    import matplotlib.pyplot as plt
    
    # 定义 Sigmoid 激活函数
    def sigmoid(x):
        return 1 / (1 + np.exp(-x))
        
    def tanh(x):
        return np.tanh(x)
    
    # 绘制激活函数图像的函数
    def plot_activation_function(func, x, title):
        # 计算函数值
        y = func(x)
        
        # 绘制函数图像
        plt.plot(x, y)
        plt.title(title)
        plt.xlabel('x')
        plt.ylabel('f(x)')
        plt.grid(True)
        plt.show()
    
    # 生成 x 范围数组
    x_value = np.arange(-10, 10, 0.1)
    
    # 绘制 Sigmoid 函数图像
    plot_activation_function(sigmoid, x_value, 'Sigmoid')
    
    plot_activation_function(tanh, x_value, 'tanh')
    
  • relu

    import numpy as np
    import matplotlib.pyplot as plt
    
    # 定义 Sigmoid 激活函数
    def sigmoid(x):
        return 1 / (1 + np.exp(-x))
        
    def tanh(x):
        return np.tanh(x)
        
    def relu(x):
        return np.maximum(0,x)
    
    # 绘制激活函数图像的函数
    def plot_activation_function(func, x, title):
        # 计算函数值
        y = func(x)
        
        # 绘制函数图像
        plt.plot(x, y)
        plt.title(title)
        plt.xlabel('x')
        plt.ylabel('f(x)')
        plt.grid(True)
        plt.show()
    
    # 生成 x 范围数组
    x_value = np.arange(-10, 10, 0.1)
    
    # 绘制 Sigmoid 函数图像
    # plot_activation_function(sigmoid, x_value, 'Sigmoid')
    
    # plot_activation_function(tanh, x_value, 'tanh')
    
    plot_activation_function(relu, x_value, 'relu')
    
  • leak_relu

    import numpy as np
    import matplotlib.pyplot as plt
    
    # 定义 Sigmoid 激活函数
    def sigmoid(x):
        return 1 / (1 + np.exp(-x))
        
    def tanh(x):
        return np.tanh(x)
        
    def relu(x):
        return np.maximum(0,x)
        
    def leak_relu(x,alpha=0.01):
        return np.where(x>0,x,x*alpha)
    
    # 绘制激活函数图像的函数
    def plot_activation_function(func, x, title):
        # 计算函数值
        y = func(x)
        
        # 绘制函数图像
        plt.plot(x, y)
        plt.title(title)
        plt.xlabel('x')
        plt.ylabel('f(x)')
        plt.grid(True)
        plt.show()
    
    # 生成 x 范围数组
    x_value = np.arange(-10, 10, 0.1)
    
    # 绘制 Sigmoid 函数图像
    # plot_activation_function(sigmoid, x_value, 'Sigmoid')
    
    # plot_activation_function(tanh, x_value, 'tanh')
    
    # plot_activation_function(relu, x_value, 'relu')
    
    plot_activation_function(leak_relu, x_value, 'leak_relu')
    
  • parametric_relu

    import numpy as np
    import matplotlib.pyplot as plt
    
    # 定义 Sigmoid 激活函数
    def sigmoid(x):
        return 1 / (1 + np.exp(-x))
        
    def tanh(x):
        return np.tanh(x)
        
    def relu(x):
        return np.maximum(0,x)
        
    def leak_relu(x,alpha=0.01):
        return np.where(x>0,x,x*alpha)
        
    def parametric_relu(x,parm=0.5):
        return np.where(x>0,x,x*parm)
    
    # 绘制激活函数图像的函数
    def plot_activation_function(func, x, title):
        # 计算函数值
        y = func(x)
        
        # 绘制函数图像
        plt.plot(x, y)
        plt.title(title)
        plt.xlabel('x')
        plt.ylabel('f(x)')
        plt.grid(True)
        plt.show()
    
    # 生成 x 范围数组
    x_value = np.arange(-10, 10, 0.1)
    
    # 绘制 Sigmoid 函数图像
    # plot_activation_function(sigmoid, x_value, 'Sigmoid')
    # plot_activation_function(tanh, x_value, 'tanh')
    # plot_activation_function(relu, x_value, 'relu')
    # plot_activation_function(leak_relu, x_value, 'leak_relu')
    
    plot_activation_function(parametric_relu, x_value, 'parametric_relu')
    
  • elu

    import numpy as np
    import matplotlib.pyplot as plt
    ​
    # 定义 Sigmoid 激活函数
    def sigmoid(x):
        return 1 / (1 + np.exp(-x))
        
    def tanh(x):
        return np.tanh(x)
        
    def relu(x):
        return np.maximum(0,x)
        
    def leak_relu(x,alpha=0.01):
        return np.where(x>0,x,x*alpha)
        
    def parametric_relu(x,parm=0.5):
        return np.where(x>0,x,x*parm)
        
    def elu(x,alph=1):
        return np.where(x>0,x,alph*(np.exp(x)-1))
    ​
    # 绘制激活函数图像的函数
    def plot_activation_function(func, x, title):
        # 计算函数值
        y = func(x)
        
        # 绘制函数图像
        plt.plot(x, y)
        plt.title(title)
        plt.xlabel('x')
        plt.ylabel('f(x)')
        plt.grid(True)
        plt.show()
    ​
    # 生成 x 范围数组
    x_value = np.arange(-10, 10, 0.1)
    ​
    # 绘制 Sigmoid 函数图像
    # plot_activation_function(sigmoid, x_value, 'Sigmoid')
    # plot_activation_function(tanh, x_value, 'tanh')
    # plot_activation_function(relu, x_value, 'relu')
    # plot_activation_function(leak_relu, x_value, 'leak_relu')
    # plot_activation_function(parametric_relu, x_value, 'parametric_relu')
    ​
    plot_activation_function(elu, x_value, 'elu')
    

微分和积分

  • 微分概念:函数 f(x) 在点 的微分,通常表示为 df 或 df(x) ,在几何上对应于函数图像在 x 点的且线上,x 的一个小变化 dx 所引起的函数值 f(x) 的变化。这个变化成为函数 f 的微分,在数学上可以写作:

    df(x)=f(x)dxdf(x) = f'(x)dx

    其中 f'(x) 是函数 f 在 x 处的导数。

    • 加法法则:如果有两个函数 u(x) 和 v(x),它们的和为 f(x) = u(x) + v(x), 那么 f(x) 的导数是这两个函数导数的和:

      ddx[u(x)+v(x)]=ddxu(x)+ddxv(x)\frac{d}{dx}[u(x) + v(x)] = \frac{d}{dx}u(x) + \frac{d}{dx}v(x)
    • 乘法法则:如果有两个函数 u(x) 和 v(x),它们的乘积为 f(x) = u(x) * v(x),那么 f(x) 的导数是:

      ddx[u(x)v(x)]=u(x)ddxv(x)+v(x)ddxu(x)\frac{d}{dx}[u(x)*v(x)]=u(x)\frac{d}{dx}v(x) + v(x)\frac{d}{dx}u(x)
    • 除法法则:如果有两个函数 u(x) 和 v(x),它们的商为 f(x) = u(x) / v(x),那么 f(x) 的导数是:

      ddx[u(x)v(x)]=v(x)ddxu(x)u(x)ddxv(x)[v(x)]2\frac{d}{dx}[\frac{u(x)}{v(x)}]=\frac{v(x)\frac{d}{dx}u(x)-u(x)\frac{d}{dx}v(x)}{[v(x)]^2}
  • 积分:求曲线面积

案例:二维图像切线

import numpy as np  # 导入NumPy库,用于数值计算
import matplotlib.pyplot as plt  # 导入matplotlib库,用于绘图# 定义函数
def f(x):
    return x ** 2  # 定义函数 f(x) = x²# 导数(梯度)
def df(x):
    return 2 * x  # 函数 f(x) 的导数(梯度)为 2x# 检测原始函数
x = np.linspace(-3, 3, 100)  # 在区间[-3, 3]内生成100个等间距的点作为横坐标
y = f(x)  # 计算对应的纵坐标值
​
plt.figure(figsize=(8, 6))  # 创建一个8x6的图形窗口
plt.plot(x, y, label="f(x) = x²")  # 绘制原始函数曲线,标签为"f(x) = x²"# 计算当 x = 1 时的梯度和切线
x1 = 1  # 切线所在点的横坐标
y1 = f(x1)  # 切线所在点的纵坐标
slope = df(x1)  # 切线的斜率(梯度)# 切线方程, y = m(x - x1) + y1
def tangent_line(x, x1, y1, slope):
    return slope * (x - x1) + y1  # 计算切线的纵坐标# 切点附近绘制切线
x_tangent = np.linspace(x1 - 1, x1 + 1, 10)  # 在 x=1 附近生成横坐标
y_tangent = tangent_line(x_tangent, x1, y1, slope)  # 计算切线的纵坐标# 绘制切线
plt.plot(x_tangent, y_tangent, label="Tangent at x = 1", color='red')  # 绘制切线,标签为"Tangent at x = 1",颜色为红色
# 绘制切点
plt.scatter([x1], [y1], color='black')  # 在切点处绘制黑色的点
# 设置图形
plt.xlabel('x')  # 设置横坐标轴标签为"x"
plt.ylabel('f(x)')  # 设置纵坐标轴标签为"f(x)"
plt.title('Function and Its Tangent at x = 1')  # 设置图形标题为"Function and Its Tangent at x = 1"
plt.legend()  # 显示图例
plt.grid(True)  # 显示网格线
plt.show()  # 显示图形

案例:三位函数切面

import numpy as np
import matplotlib.pyplot as plt
​
# 创建 x , y 数据点
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
# 生成网格坐标矩阵
x, y = np.meshgrid(x, y)
​
# 定义三维函数
def f(x, y):
    return x ** 2 + y ** 2
    
# 计算z的值
z = f(x, y)
​
# 创建图形和轴
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
​
# 绘制表面
surf = ax.plot_surface(x, y, z, cmap='viridis', alpha=0.5)
​
# 定义要突出显示的点
point_x, point_y = 1.0, 1.0
point_z = f(point_x, point_y)
​
# 绘制该点
ax.scatter(point_x, point_y, point_z, color='red', s=50)
​
# 切平面的法线
normal = np.array([2 * point_x, 2 * point_y, -1])
​
# 定义平面上所有的点 x_plan, y_plan, z_plan
x_plan = np.linspace(-5, 5, 10)
y_plan = np.linspace(-5, 5, 10)
# 转为网格坐标
x_plan, y_plan = np.meshgrid(x_plan, y_plan)
z_plan = (-normal[0] * (x_plan - point_x) - normal[1] * (y_plan - point_y)) / normal[2] + point_z
​
# 绘制切平面
ax.plot_surface(x_plan, y_plan, z_plan, color='yellow', alpha=0.5)
​
# 设置标签和标题
ax.set_xlabel('x axis')
ax.set_ylabel('y axis')
ax.set_zlabel('z axis')
ax.set_title("3D Surface Plot whith Tangent Plane")
plt.show()

链式求导法

设有两个函数 y=f(u) 和 u=g(x),它们都在相应的点可导。如果我们定义一个复合函数 y=f(g(x)),那么复合函数 y 关于 x 的导数是:

dydx=dydududx\frac{dy}{dx} = \frac{dy}{du} * \frac{du}{dx}

这里,du/dy 是外函数 f(u) 关于其变量 u 的导数,而 dx/du 是内函数 g(x) 关于 x 的导数。

  • 小案例

    假设有符合函数

    h(x)=(3x+2)2h(x) = (3x + 2)^2

    ,对它进行求导,令 :

    f(u)=u2g(x)=3x+2f(u) = u^2,g(x)=3x+2
    • 首先求 g(x)的导数:

      g(x)=3g'(x)=3
    • 然后求 f(u) 对 u 的导数:

      f(u)=2uf'(u)=2u
    • 将 g(x) 代入 f'(u) 得到 f'(g(x)) = 2(3x+2)

    • 最后将 f'(g(x)) 和 g'(x) 相乘得到 h'(x): h'(x) = 2(3x+2)*3。

反向传播算法

反向传播算法

概率论:数据科学与AI的关键