[数值计算-18]:最小二乘的求解法3 - 链式求导与梯度下降法求解loss函数的最优化参数(Python, 超详细、可视化)

2023-11-09

作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/119978818


目录

前置文章

第1章 导数与偏导

1.1 一元简单函数求导

1.2 N元简单函数求偏导

1.3 一元复合函数链式求导

1.4 多元复合函数链式求偏导

1.5 多元复合函数线性相加函数的链式求偏导

第2章 用最小二乘法的损失函数进行曲线拟合

2.0 前置条件

2.1 步骤1: 构建样本

2.2 步骤2:构建拟合函数

2.3 步骤3:利用python库提供算法求拟合函数的参数 (仅供参考)

2.4 步骤3:利用自定义的梯度下降法计算拟合函数的参数

2.4.1 使用最小二乘定义损失函数(残差函数)

2.4.2 链式求导

2.4.3 梯度下降法求解最佳w,b参数值

2.4.4 可视化迭代过程

2.5 步骤4:利用获得的拟合函数进行数据预测 

2.6 步骤5:可视化拟合函数


前置文章

[数值计算-15]:函数近似值的线性与非线性拟合的原理与Python代码示例

https://blog.csdn.net/HiWangWenBing/article/details/119973082

[数值计算-16]:最小二乘的解法1 - 一元二次方程解析法求解

https://blog.csdn.net/HiWangWenBing/article/details/119978799

[数值计算-17]:最小二乘的解法2 - 二元二次线性方程组求解

https://blog.csdn.net/HiWangWenBing/article/details/119977443

第1章 导数与偏导

1.1 一元简单函数求导

一元函数:就是只有一个自变量的函数。

简单函数:就是初等函数的线性加减得到的函数。

导数(Derivative),也叫导函数值。又名微商,是微积分中的重要基础概念。当函数y=f(x)的自变量x在一点x0上产生一个增量Δx时,函数输出值的增量Δy与自变量增量Δx的比值在Δx趋于0时的极限a如果存在,a即为在x0处的导数,记作f'(x0)或df(x0)/dx。

一元函数的切线和导数,有现成的公式求导数,如下图所示:

例题1:

y = f(x) = 2x^{2} + 4x + 1   ; x为自变量

导数:f '(x) =  2*2x^1 + 4 = 4x^1 + 4 = 4x + 4

例题2:

y = f(x) = wx + b  ; x为自变量,w,b为常量

导数:f '(x) = w + 0   = w

1.2 N元简单函数求偏导

多元函数:所谓多元函数,求是有包含有多个自变量的初等函数。

简单函数:就是初等函数的线性加减得到的函数。

 那么,对于二元函数或多元函数,求导数,该如何计算呢?

这就需要用到偏导数的概念:通过临时固化其他维度分量的数值,用来求解多元函数在某个维度方向的导数或切线斜率。

然后,把所有维度方向的导数组成一个向量,就得到多元函数在空间中某一点处的导数或梯度P = {P1, P2, P3.....Pn}; 其中Pi是在i维度方向上的偏导数。

其中:

x1, x2,....Xi......表示的是维度方向,而不是指在单个维度方向上的数值序列. 

{x1.0, x1.1, x1.2.....x1.n..}  表示在x1的维度方向的序列

{x2.0, x2.1, x2.2.....x2.n..}  表示在x2的维度方向的序列

{xi.0,  xi.1, xi.2  .....xi.n..}  表示在x2的维度方向的序列

因此,多元简单函数与一元简单函数的导数基本是一致的,唯一的区别就是:每个变量都有各自的偏导数,在求解某个变量Xi的偏导数是,需要假定其他变量为常数。

例题1:z = f(x,y) = 3x^{2} + 2xy + 2y^{2} + 1  ; x,y为自变量

z对x的偏导数:\frac{\partial z}{\partial x} = 6x + 2y + 0 = 6x + 2y

z对y的偏导数:\frac{\partial z}{\partial y} = 0 + 2x + 4y + 0 = 2x + 4y

例题2:z = f(w,b) = wx + b  #变量为w和b

z对w的偏导数:\frac{\partial z}{\partial w} = x_{i}

z对b的偏导数:\frac{\partial z}{\partial b} = 1

1.3 一元复合函数链式求导

例题1:z = f(u)= u^{2}, u=f(x) = wx + b => z(w,b) = (wx + b)^2

z对x的导数:\frac{\partial z}{\partial x} = \frac{\partial z}{\partial u} * \frac{\partial u}{\partial x} = 2u * w = (wx+b) * w

1.4 多元复合函数链式求偏导

例题1:w,b为参数,(xi,yi为常数)

 z = f(u)= u^{2}, u=f(w,b) = wx_{i} + b - y_{i} => z(w,b) = (wx_{i} + b - y_{i})^2

z对w的偏导数:\frac{\partial z}{\partial w} = \frac{\partial z}{\partial u} * \frac{\partial u}{\partial w} = 2u * x_{i}= 2( wx_{i} + b - y_{i}) * x_{i}

z对b的偏导数:\frac{\partial z}{\partial b} = \frac{\partial z}{\partial u} * \frac{\partial u}{\partial b} = 2u * 1 = 2(wx_{i} + b - y_{i})

1.5 多元复合函数线性相加函数的链式求偏导

例题1:w,b为参数,(xi,yi)为常数

z =\frac{1}{N} \sum f(u)= \frac{1}{N}\sum u_{i}^{2}

u=f(w,b) = wx_{i} + b - y_{i}

 z(w,b) =\frac{1}{N} \sum (wx_{i} + b - y_{i})^2

(1) z对w的偏导数:

\frac{\partial z}{\partial w} = \frac{1}{N}\sum \frac{\partial z}{\partial u} * \frac{\partial u}{\partial w} = \frac{1}{N}\sum 2u * x_{i}= \frac{2}{N} \sum ( wx_{i} + b - y_{i}) * x_{i}

\frac{\partial z}{\partial w} = \frac{2}{N}*((\sum (x_{i} * x_{i}))*w + (\sum x_{i})*b - \sum (x_{i} * y_{i}))

\frac{\partial z}{\partial w} = (\frac{2}{N}\sum (x_{i} * x_{i}))*w + (\frac{2}{N}\sum (x_{i}))*b - \frac{2}{N}\sum (x_{i} * y_{i})

(2)z对b的偏导数:

\frac{\partial z}{\partial b} = \frac{1}{N}\sum \frac{\partial z}{\partial u} * \frac{\partial u}{\partial b} =\frac{1}{N} \sum 2u * 1 = \frac{2}{N}\sum (wx_{i} + b - y_{i})

\frac{\partial z}{\partial b} = \frac{2}{N}* ((\sum (x_{i})) * w + N *b - \sum y_{i})

 \frac{\partial z}{\partial b} = (\frac{2}{N}*\sum (x_{i})) * w + 2*b - \frac{2}{N}\sum y_{i}

第2章 用最小二乘法的损失函数进行曲线拟合

2.0 前置条件

#导入库
from math import *
import time
import numpy as np
import matplotlib.pyplot as plt #画图工具
from pylab import mpl           #中文字体
from scipy import optimize      #最小二乘算法的算法库

2.1 步骤1: 构建样本

#步骤1:构建样本

#(1) 采用np, 直接手工生成样本的输入:一组等距离的分布在[-1,1]之间的100个点
sample_numbers = 50

x_data = np.linspace(0, 1, sample_numbers)

#(2) 为这些数据手工打上理论输出值(标签值):y = 2x + 1
y_data_pure =  2 * x_data + 1.0

#(3)为了模拟现实情况,通过随机数来模拟数据噪声
noise_range = 0.4
np.random.seed(10) #设置随机种子, 确保不同时候,执行结果是相同的
#randn(n)生成的0为均值,1为标准差的正态分布的n个随机数。
y_noise = np.random.randn(*x_data.shape) * noise_range  # *x_data.shape:输入样本的维度或个数

#(4)人工生成样本的输出:理论值 + 噪声
y_data_noise = y_data_pure + y_noise

#(5) 显示样本数据
# 样本的散点图
plt.scatter(x_data, y_data_noise, label="sample", color="black")

# 内在的、理论的曲线图
plt.plot(x_data, y_data_pure, label="f_pure(x)", color="blue", linewidth = 4)

#设置属性
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
plt.title("线性拟合")
plt.legend(loc="upper left")
plt.show()

2.2 步骤2:构建拟合函数

#步骤2:构建拟合函数:二元一次拟合函数
def f_line_wb(x, w, b):
    return (w*x + b)

2.3 步骤3:利用python库提供算法求拟合函数的参数 (仅供参考)

#步骤3-1:利用python库提供的最小二乘算法来计算拟合函数的参数
print("使用无噪声数据:")
popt, pcov = optimize.curve_fit(f_line_wb, x_data, y_data_pure)
print(popt)
print(pcov)
w_scipy =  popt[0]
b_scipy =  popt[1]
print("参数w=", w_scipy)
print("参数b=", b_scipy)

print("\n使用有噪声数据:")
popt, pcov = optimize.curve_fit(f_line_wb, x_data, y_data_noise)
print(popt)
print(pcov)
w_scipy =  popt[0]
b_scipy =  popt[1]
print("参数w=", w_scipy)
print("参数b=", b_scipy)
使用无噪声数据:
[2. 1.]
[[ 0. -0.]
 [-0.  0.]]
参数w= 2.0
参数b= 1.0

使用有噪声数据:
[1.91826746 1.08186076]
[[ 0.0310567  -0.01552835]
 [-0.01552835  0.01045787]]
参数w= 1.9182674578022025
参数b= 1.0818607577986927

2.4 步骤3:利用自定义的梯度下降法计算拟合函数的参数

2.4.1 使用最小二乘定义损失函数(残差函数)

(1)定义损失函数

# 定义残差函数或损失
def f_loss(input_f, w, b, input_x_data, input_y_data_noise):    
    loss = np.mean((input_f(input_x_data, w, b) - input_y_data_noise)**2)
    return (loss)
(2)测试损失函数
# 测试残差函数或损失函数
err0 = f_loss(f_line_wb, 2, 1, x_data, y_data_pure)
print("Mean Err under Case0:",err0)

err1 = f_loss(f_line_wb, 2, 1, x_data, y_data_noise)
print("Mean Err under Case1:",err1)

err2 = f_loss(f_line_wb, 2, 1.1, x_data, y_data_noise)
print("Mean Err under Case2:",err2)

err3 = f_loss(f_line_wb, 2, 0.9, x_data, y_data_noise)
print("Mean Err under Case3:",err3)

err4 = f_loss(f_line_wb, 2.1, 1, x_data, y_data_noise)
print("Mean Err under Case4:",err4)

err5 = f_loss(f_line_wb, 1.9, 1, x_data, y_data_noise)
print("Mean Err under Case5:",err5)

err6 = f_loss(f_line_wb, 1, 2, x_data, y_data_noise)
print("Mean Err under Case6:",err6)

# 问题:w, b 为多少时?残差值最小呢?
Mean Err under Case0: 0.0
Mean Err under Case1: 0.1315572426174743
Mean Err under Case2: 0.13335834500408647
Mean Err under Case3: 0.14975614023086212
Mean Err under Case4: 0.1322429501791569
Mean Err under Case5: 0.13760622893334273
Mean Err under Case6: 0.41311935413207634

(3)可视化损失函数

  • 可视化空间线性图形:  z轴为恒定值1
# 可视化空间线性数据
w_line = np.linspace(-10, 10, 10)
b_line = np.linspace(-10, 10, 10)

# 假定z轴的loss数值恒定为: z = 1
loss = 1 

fig = plt.figure()
ax = plt.axes(projection='3d')        #使用matplotlib.pyplot创建坐标系
ax.scatter3D(w_line, b_line, loss, cmap='Blues')  #绘制三维散点图
plt.show()

  • 可视化空间线性图形:  z轴为损失函数
#二元(w,b)残差函数的线性图形
w_line = np.linspace(-10, 10, 30)
b_line = np.linspace(-10, 10, 30)

size = len(w_line)
loss = []

# 假定z轴的loss数值来自残差函数: z = f_loss
for i in range(size):
    err = f_loss(f_line_wb, w_line[i], b_line[i], x_data, y_data_noise)
    loss.append(err)

fig = plt.figure()
ax = plt.axes(projection='3d')        #使用matplotlib.pyplot创建坐标系
ax.scatter3D(w_line, b_line, loss, cmap='Blues')  #绘制三维散点图
ax.plot3D(w_line , b_line, loss,'gray')               #绘制三维曲线图
plt.show()

  •  可视化空间网格图形:  z轴为恒定值1
# 可视化空间线性数据到空间网格数据的转换
w_line = np.linspace(-10, 10, 10)
b_line = np.linspace(-10, 10, 10)

w_line_grid ,b_line_grid = np.meshgrid(w_line, b_line)      #空间的点序列转换成网格点

# 假定z轴的loss数值恒定为: z = 1
loss = 1

fig = plt.figure()
ax = plt.axes(projection='3d')        #使用matplotlib.pyplot创建坐标系
ax.scatter3D(w_line_grid, b_line_grid, loss, cmap='rainbow')  #绘制三维散点图
plt.show()

  •  可视化空间网格图形:  z轴为二次函数-1
# 可视化空间图形
w_line = np.linspace(-10, 10, 20)
b_line = np.linspace(-10, 10, 20)

w_line_grid ,b_line_grid = np.meshgrid(w_line, b_line)      #空间的点序列转换成网格点

# 假定z轴的loss数值来自于 z = x^2 + y^2
loss = w_line_grid**2 + b_line_grid**2

fig = plt.figure()
ax = plt.axes(projection='3d')        #使用matplotlib.pyplot创建坐标系
ax.scatter3D(w_line_grid, b_line_grid, loss, cmap='rainbow')  #绘制三维散点图
plt.show()

  • 可视化空间网格图形:  z轴为二次函数-2
# 可视化空间图形
w_line = np.linspace(-10, 10, 20)
b_line = np.linspace(-10, 10, 30)

w_line_grid ,b_line_grid = np.meshgrid(w_line, b_line)      #空间的点序列转换成网格点
print("w_line_grid shape", w_line_grid.shape)
print("b_line_grid shape", b_line_grid.shape)

# 假定z轴的loss数值来自于: z = 3*x^2 - y^2 + 1
loss = 3*w_line_grid**2 - b_line_grid**2 + 1
print("loss shape", loss.shape)

fig = plt.figure()
ax = plt.axes(projection='3d')        #使用matplotlib.pyplot创建坐标系
ax.scatter3D(w_line_grid, b_line_grid, loss, cmap='rainbow')  #绘制三维散点图
plt.show()
w_line_grid shape (30, 20)
b_line_grid shape (30, 20)
loss shape (30, 20)

  • 可视化空间网格图形:  z轴为二次函数-3
# 可视化空间图形
w_line = np.linspace(-10, 10, 20)
b_line = np.linspace(-10, 10, 30)

w_line_grid ,b_line_grid = np.meshgrid(w_line, b_line)      #空间的点序列转换成网格点
print("w_line_grid shape", w_line_grid.shape)
print("b_line_grid shape", b_line_grid.shape)

# 假定z轴的loss数值来自于: z = (1/3) * x^2 + x * y + y^2 + 1
loss = (1/3)*w_line_grid**2 + w_line_grid * b_line_grid + b_line_grid**2 + 1
print("loss shape", loss.shape)

fig = plt.figure()
ax = plt.axes(projection='3d')        #使用matplotlib.pyplot创建坐标系
ax.scatter3D(w_line_grid, b_line_grid, loss, cmap='rainbow')  #绘制三维散点图
plt.show()

w_line_grid shape (30, 20)
b_line_grid shape (30, 20)
loss shape (30, 20)

 

  •  可视化空间网格图形:  z轴为损失函数
# 可视化空间图形
w_line = np.linspace(-10, 10, 20)
b_line = np.linspace(-10, 10, 30)
print("w_line len:" ,len(w_line))
print("b_Line len:", len(b_line))

w_line_grid ,b_line_grid = np.meshgrid(w_line, b_line)      #空间的点序列转换成网格点
print("w_line_grid shape", w_line_grid.shape)
print("b_line_grid shape", b_line_grid.shape)

# 假定z轴的loss数值来自于残差函数: z = f_loss
loss = np.zeros((len(w_line_grid),len(w_line_grid[0])))
print("loss shape:", loss.shape)

for i in range (len(w_line_grid)):
    for j in range (len(w_line_grid[0])):
        loss[i][j] =  f_loss(f_line_wb, w_line_grid[i][j], b_line_grid[i][j], x_data, y_data_noise)
        
fig = plt.figure()
ax = plt.axes(projection='3d')        #使用matplotlib.pyplot创建坐标系
ax.scatter3D(w_line_grid, b_line_grid, loss, label="loss", cmap='rainbow')  #绘制三维散点图
plt.show()
w_line len: 20
b_Line len: 30
w_line_grid shape (30, 20)
b_line_grid shape (30, 20)
loss shape: (30, 20)

2.4.2 链式求导

(1)一元线性函数求导

# 原函数yi=f(xi) = w*xi + b
# 对x的导函数: x为参数,w,b为常量
def fv1(xi, w, b):
    num = len(xi)
    rst = np.ones(num) * w
    return (rst)

#显示上述函数图形
x_line = np.linspace(0, 1, 30)
y_fv1 = fv1(x_line, 2, 1)

#对w的偏导函数
plt.scatter(x_line, y_fv1, label="sample", color="black")
plt.plot   (x_line, y_fv1, label="curve", color="blue", linewidth = 4)

(2)二元线性求偏导 

# 残差:err = f(w,b, xi, yi) = w*xi + b - yi
# 对w求偏导数:w为变量,xi为常量, b为常量
def fv1_w(w, b, xi, yi):
    num = len(w)
    rst = np.ones(num) * xi  #对w偏导,其值为xi
    return (rst)

# 对b求偏导数:w为常量,xi为常量, b为变量
def fv1_b(w, b, xi, yi):
    num = len(b)
    rst = np.ones(num)  #对w偏导,其值恒定为1
    return (rst)

#显示上述函数图形
x_line = np.linspace(0, 1, 30)
y_fv1_w = fv1_w(x_line, 0, 2, 3)   #在点(2,2)的偏导函数
y_fv1_b = fv1_b(0, x_line, 2, 3)   #在点(2,2)的偏导函数

# 在b=0, (xi=0, yi=0)处对w的偏导函数
plt.scatter(x_line, y_fv1_w, label="w sample", color="black")
plt.plot   (x_line, y_fv1_w, label="w cruve", color="blue", linewidth = 4)

# 在w=0, (xi=0, yi=0)处对b的偏导函数
# 在b=0, (xi=0, yi=0)处对w的偏导函数
plt.scatter(x_line, y_fv1_b, label="b sample", color="black")
plt.plot   (x_line, y_fv1_b, label="b curve", color="blue", linewidth = 4)

 (3)二元二次非线性函数求偏导

# loss = np.mean( w * xdata + b - y_data_noise)**2)
# 残差函数对 w 的一阶偏导数
def f_loss_fv1_w(w, b, input_x_data, input_y_data_noise):
    loss_fv = 2 * np.mean(input_x_data * input_x_data) * w + 2 * np.mean(input_x_data) * b -  2 * np.mean(input_x_data * input_y_data_noise)
    return (loss_fv)

# 残差函数对 b 的一阶偏导数
def f_loss_fv1_b(w, b, input_x_data, input_y_data_noise):
    loss_fv = 2 * np.mean(input_x_data) * w  + 2 * b - 2 * np.mean(input_y_data_noise)
    return (loss_fv)

(4)通过偏导求在某一点的梯度
# 计算指定(w,b)点的梯度
gradient_w = f_loss_fv1_w(2,1, x_data, y_data_pure)
print(gradient_w)

gradient_b = f_loss_fv1_b(2,1, x_data, y_data_pure)
print(gradient_b)

gradient_w = f_loss_fv1_w(2,1, x_data, y_data_noise)
print(gradient_w)

gradient_b = f_loss_fv1_b(2,1, x_data, y_data_noise)
print(gradient_b)
4.440892098500626e-16
4.440892098500626e-16
-0.026816393770928926
-0.08198897613387857

备注:当w=2,b=1时,梯度接近为0

2.4.3 梯度下降法求解最佳w,b参数值

(1)定义梯度下降法的迭代函数

# 用梯度下降法求w,b的值
#自定义最小二乘求解拟合函数参数:偏导 + 梯度下降法    
def usr_gradient_descent_fit(input_f, input_x_data, input_y_data_noise, learning_rate = 0.1, max_loop = 300):
    w_data  = []   #存放w值的迭代序列
    b_data  = []   #存放b值的迭代序列
    z_data  = []   #存放loss值的迭代序列
    w_diff_data  = []
    b_diff_data  = []
    
    w_k  = 0.
    b_k  = 0.
    z_k  = 0.
    
    #保存初始信息
    w_data.append(w_k)
    b_data.append(b_k)
    
    z_k = f_loss(input_f, w_k, b_k, input_x_data, input_y_data_noise)
    z_data.append(z_k)

    w_diff_data.append(w_k)
    b_diff_data.append(b_k)
    
    for k in range(max_loop):
        # (1)学习率与计算梯度!!!
        step_x = learning_rate * f_loss_fv1_w(w_k, b_k , input_x_data, input_y_data_noise)
        step_y = learning_rate * f_loss_fv1_b(w_k, b_k , input_x_data, input_y_data_noise)
        
        # (2)最重要的梯度下降迭代!!!
        w_k1 = w_k - step_x
        b_k1 = b_k - step_y

        # (3)计算迭代后的残差 !!!
        z_k1 = f_loss(input_f, w_k1, b_k1, input_x_data, input_y_data_noise)
        
        
        # (4)记录中间迭代过程
        
        # 计算迭代前后w,b的差(作为x的偏差)
        w_diff = step_x
        b_diff = step_y
        z_diff = z_k1 - z_k
        
        # 保存当前的迭代点信息
        w_data.append(w_k1)
        b_data.append(b_k1)
        z_data.append(z_k1)
        
        w_diff_data.append(w_diff)
        b_diff_data.append(b_diff)
        
        # (5)为新一轮迭代做准备
        w_k = w_k1
        b_k = b_k1
        z_k = z_k1
    
    #返回 w,b值以及中间迭代过程的数据
    return ((w_k, b_k, z_k), (w_data, b_data, z_data), (w_diff_data, b_diff_data))

(2)调用迭代函数接近w和b的最佳值

print("使用无噪声数据:")
rst = usr_gradient_descent_fit(f_line_wb, x_data, y_data_pure)
w_grad, b_grad, e_grad = rst[0]
print("参数w=", w_grad)
print("参数b=", b_grad)
print("残差e=", e_grad)

print("\n使用有噪声数据:")
rst = usr_gradient_descent_fit(f_line_wb, x_data, y_data_noise)
w_grad, b_grad, e_grad = rst[0]
print("参数w=", w_grad)
print("参数b=", b_grad)
print("残差e=", e_grad)
使用无噪声数据:
参数w= 1.9817535011137024
参数b= 1.0097929273554476
残差e= 2.9325459666068766e-05

使用有噪声数据:
参数w= 1.9015879580969595
参数b= 1.0908126753128762
残差e= 0.12932179354125223

备注:

对于无噪声样本,残差值接近于0,: 2.9325459666068766e-05

对于有噪声样本,残差值不可能为0,一定有一定的残差值:0.12932179354125223

2.4.4 可视化迭代过程

(1) w,b,残差的并发收敛过程

# w,b,残差的并发收敛过程
w_data, b_data, e_data = rst[1]
w_diff, b_diff = rst[2]

fig = plt.figure()
ax = plt.axes(projection='3d')        #使用matplotlib.pyplot创建坐标系
ax.scatter3D(w_data, b_data, e_data, label="loss", cmap='rainbow')  #绘制三维散点图
plt.show()

 (2)w参数的迭代过程:反映的是w值本身数值的变化过程

print("w参数的迭代过程")
print("参数w=", w_grad)
num = len(w_data)
x_seq = np.array(range(0,num))

plt.scatter(x_seq, w_data, label="sample", color="blue")

 

 (3)w的偏差变化过程:反映的是相邻两次w值之间的迭代步长的变化。

print("w的偏差变化过程")
print("final w_diff = ", w_diff[-1])

num = len(w_diff)
x_seq = np.array(range(0, num))

plt.scatter(x_seq, w_diff, label="sample", color="blue")
w的偏差变化过程
final w_diff =  -0.00023128483534975432

(4)b参数的迭代过程:反映的是b值本身数值的变化过程

print("b参数的迭代过程")
print("参数b=", b_grad)

num = len(w_data)
x_seq = np.array(range(0,num))

plt.scatter(x_seq, b_data, label="sample", color="blue")
b参数的迭代过程
参数b= 1.0908126753128762

 (5)b的偏差变化过程:反映的是相邻两次b值之间的迭代步长的变化。

print("b的偏差变化过程")
print("final b_diff = ", b_diff[-1])

num = len(b_diff)
x_seq = np.array(range(0, num))

plt.scatter(x_seq, b_diff, label="sample", color="blue")
b的偏差变化过程
final b_diff =  0.0001241309691854653

 (5)残差的变化过程

print("残差的变化过程")
print("残差e=", e_grad)

num = len(w_data)
x_seq = np.array(range(0,num))

plt.scatter(x_seq, e_data, label="sample", color="blue")

2.5 步骤4:利用获得的拟合函数进行数据预测 

# 步骤4:利用获得的拟合函数进行数据预测
print("scipy:", w_scipy,b_scipy)
print("user :", w_usr, b_usr)
print("grad :", w_grad, b_grad)

# scipy算法的拟合数据
y_data_scipy = f_line_wb(x_data, w_scipy, b_scipy)

# 线性方程组求解的拟合数据
# y_data_usr  = f_line_wb(x_data, w_usr, b_usr)

# 最小二乘+梯度下降算法的拟合数据
y_data_grad = f_line_wb(x_data, w_grad, b_grad)
scipy: 1.9182674578022025 1.0818607577986927
grad : 1.9015879580969595 1.0908126753128762

2.6 步骤5:可视化拟合函数

#步骤5: 图形化展示
#(1) 显示样本数据曲线
plt.scatter(x_data, y_data_noise, label="sample", color="black")

#(2) 显示理论数据曲线
plt.plot(x_data, y_data_pure, label="intrinsic", color="blue", linewidth = 2)

#(3-1) 显示预测数据曲线 -  scipy库实现
plt.plot(x_data, y_data_scipy,  label="predict",  color="red",  linewidth = 2)

#(3-2) 显示预测数据曲线 -  自定义实现
# plt.plot(x_data, y_data_usr,  label="predict",  color="green",  linewidth = 2)

#(3-3) 显示预测数据曲线 -  自定义梯度下降法
plt.plot(x_data, y_data_grad,  label="predict",  color="green",  linewidth = 2)

#设置属性
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
plt.title("线性拟合")
plt.legend(loc="upper left")
plt.show()

 备注:

  • scipy库提供的拟合结果(红色red)与自定义的梯度下降法拟合的结果(绿色blue),基本重合。


作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/119978818

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[数值计算-18]:最小二乘的求解法3 - 链式求导与梯度下降法求解loss函数的最优化参数(Python, 超详细、可视化) 的相关文章

随机推荐

  • MFC中使用CBitmap类进行绘图

    大家看名字就可以知道 这个类是用来绘制位图的 即以 bmp 为后缀的图片 一般游戏之中 需要使用的图片比较多 都会将图片先存为文件 然后从文件中读取 而从文件中读取图片的步骤有以下几步 1 建立一个与窗口DC兼容的内存DC 我们加载的图片是
  • 推荐几个Python爬虫接单渠道

    说起兼职 我有一位做了4年Python工程师的朋友 爬虫做副业起码挣了20W 写各种奇葩爬虫挣钱 爬虫兼职方式多 单也很多 首先是爬虫外包活 国内有平台接单 价格500 4000不等 也可以帮互联网运营爬数据做网站 那群人一天到晚死磕数据
  • CXF拦截器

    引言 CXF拦截器是Apache CXF里面一个很重要的功能 它能够动态操作响应数据和请求数据 降低代码的耦合性 提供代码的内聚性 这对于CXF这个以处理消息为中心的服务框架来说是非常有用的 CXF通过在Interceptor中对消息进行特
  • mysql 创建订单表语句_MySQL创建表语句

    表 t admin tabs 列信息 Field Type Collation Null Key Default Extra Privileges Comment admin id int 11 unsigned NULL NO PRI N
  • local reference table overflow 内存泄露

    local reference table overflow JNI层coding经常会遇到ReferenceTable overflow问题 特别是当jni函数被反复调用上千上万次的时候 现汇总如下 未完待续 并欢迎补充 嘻嘻 总体原则
  • FileZilla连接阿里云服务器:尝试连接“ECONNREFUSED - 连接被服务器拒绝”失败

    4 FileZilla连接阿里云服务器 目的 可以更好的管理云文件 1 在远程服务器端通过指令vim etc ssh sshd config开放22号端口 2 设置云服务器的安全组ID 添加20 21 3 然后启动FileZilla 新建站
  • 6.143 指针习题10

    关于二维数组 指针运算问题 注意二维指针需要解两次引用 即第 0 个元素是 a 见下例 include
  • android studio 监听返回键,最强 Android Studio 使用小技巧和快捷键

    第一步 新建一个project 或者如果你已经有project的话 那就直接新建一个module 注意选择Java library 然后下一步 第二步 编写MyClass java 第三步 在MyClass java文件右击 选择run M
  • getjson ajax webpy,ajaxwebpy

    ajaxweb py is a framework for the library web py It which makes it very easy to make sites interactive using AJAX techno
  • 手机有时触摸失灵解决方法

    1 屏幕不干净造成的屏幕不灵敏 用干净的无尘布将手机上的脏污 水渍擦拭干净 2 手机有贴膜 确认用户是否贴膜之后出现屏幕失灵问题 可将膜去掉再使用对比 3 操作耽搁软件时屏幕失灵 可备份好软件数据 进入设置 应用与权限 更多设置 应用管理
  • seed+transformer+finetune+图文融合+VLP+Prompt Learning整合

    1 Seed 在神经网络中 参数默认是进行随机初始化的 不同的初始化参数往往会导致不同的结果 如果不设置的话每次训练时的初始化都是随机的 导致结果不确定 当得到比较好的结果时我们通常希望这个结果是可以复现的 如果设置初始化 则每次初始化都是
  • 剑指 Offer 66. 构建乘积数组(java+python)

    给定一个数组 A 0 1 n 1 请构建一个数组 B 0 1 n 1 其中 B i 的值是数组 A 中除了下标 i 以外的元素的积 即 B i A 0 A 1 A i 1 A i 1 A n 1 不能使用除法 示例 输入 1 2 3 4 5
  • jmeter性能测试——性能的评定标准

    性能的评定标准 性能指标 响应时间 指的是从客户端发出请求开始 到接收到服务器的响应 并且看到响应的内容为止 这个时间段 称为响应时间 响应时间 网络传输的时间 服务器处理的时间 浏览器解析呈现的时间 如何弱化网络传输的时间和浏览器解析呈现
  • PackageInstaller 原理简

    http topic csdn net u 20110410 23 43571CFA 87B2 4E36 880C 1FA499BA32B0 html 应用安装是智能机的主要特点 即用户可以把各种应用 如游戏等 安装到手机上 并可以对其进行
  • 华为OD机试 - 任务最优调度(Java)

    题目描述 给定一个正整数数组表示待系统执行的任务列表 数组的每一个元素代表一个任务 元素的值表示该任务的类型 请计算执行完所有任务所需的最短时间 任务执行规则如下 任务可以按任意顺序执行 且每个任务执行耗时间均为1个时间单位 两个同类型的任
  • Nuxt 3.0 全栈开发:五种数据获取 API 选择和应用最佳实践

    Nuxt 3 0 全栈开发 杨村长 掘金小册核心知识 工程架构 全栈进阶 项目实战 快速精通 Nuxt3 开发 Nuxt 3 0 全栈开发 由杨村长撰写 299人购买https s juejin cn ds S6p7MVo 上一讲我们学习了
  • elementui 集成富文本编辑器vue-quill-editor

    第一步 安装vue quill editor cnpm install vue quill editor S 第二步 VUE项目集成vue quill editor main js 文件 添加如下代码片段 import VueQuillEd
  • 概率论 方差公式_考研冲刺篇

    众所周知 概率论的知识点又多又杂 需要我们系统的归类并掌握 这样才能获得得分 为此 小业整理了 2020考研数学 概率论各章节知识点梳理 的相关内容 希望对大家有所帮助 第一部分 随机事件和概率 1 样本空间与随机事件 2 概率的定义与性质
  • keil5打开MDK4的程序提示不兼容

    1 如下图 我的程序是用keil4写的 可是用keil5打开会提示不兼容的问题 keil提供了两个解决方案 Migrate to Device Pack 迁移到设备包 和 Install Legacy Support 安装遗留支持 用第二种
  • [数值计算-18]:最小二乘的求解法3 - 链式求导与梯度下降法求解loss函数的最优化参数(Python, 超详细、可视化)

    作者主页 文火冰糖的硅基工坊 https blog csdn net HiWangWenBing 本文网址 https blog csdn net HiWangWenBing article details 119978818 目录 前置文