【机器学习】任务十:从函数分析到机器学习应用与BP神经网络

目录

1.从函数分析到机器学习应用

[1.1 3D曲面图可视化报告](#1.1 3D曲面图可视化报告)

[1.1.1 目标](#1.1.1 目标)

[1.1.2 代码分析](#1.1.2 代码分析)

[1.1.3 结果分析](#1.1.3 结果分析)

[1.1.4 观察与总结](#1.1.4 观察与总结)

[1.1.5 结论](#1.1.5 结论)

[1.2 一元函数梯度计算报告](#1.2 一元函数梯度计算报告)

[1.2.1 目标](#1.2.1 目标)

[1.2.2 代码分析](#1.2.2 代码分析)

[1.2.4 计算结果](#1.2.4 计算结果)

[1.2.5 优势与意义](#1.2.5 优势与意义)

[1.2.6 结论](#1.2.6 结论)

[1.3 一元函数梯度和二阶导数计算报告](#1.3 一元函数梯度和二阶导数计算报告)

[1.3.1 目标](#1.3.1 目标)

[1.3.2 代码分析](#1.3.2 代码分析)

[1.3.3 计算结果](#1.3.3 计算结果)

[1.3.4 优势与意义](#1.3.4 优势与意义)

[1.3.5 结论](#1.3.5 结论)

[1.4 多元函数梯度计算报告](#1.4 多元函数梯度计算报告)

[1.4.1 目标](#1.4.1 目标)

[1.4.2 代码分析](#1.4.2 代码分析)

[1.4.3 梯度计算解析](#1.4.3 梯度计算解析)

[1.4.4 优势与意义](#1.4.4 优势与意义)

[1.4.5 结论](#1.4.5 结论)

[1.5 线性回归模型训练报告](#1.5 线性回归模型训练报告)

[1.5.1 目标](#1.5.1 目标)

[1.5.2 代码分析](#1.5.2 代码分析)

[1.5.3 结果分析](#1.5.3 结果分析)

[1.5.4 优势与意义](#1.5.4 优势与意义)

[1.5.5 结论](#1.5.5 结论)

2.基于BP神经网络的鸢尾花分类任务

2.1神经网络

[2.1.1 BP神经](#2.1.1 BP神经)

[2.1.2 BP神经网络的工作流程](#2.1.2 BP神经网络的工作流程)

[2.1.3 总结](#2.1.3 总结)

[2.1.4 任务目标](#2.1.4 任务目标)

[2.2 实验过程](#2.2 实验过程)

[2.2.1 数据加载与预处理](#2.2.1 数据加载与预处理)

[2.2.2 激活函数及其导数](#2.2.2 激活函数及其导数)

[2.2.3 BP神经网络实现](#2.2.3 BP神经网络实现)

[2.2.4 模型训练与测试](#2.2.4 模型训练与测试)

[2.3 总结与改进建议](#2.3 总结与改进建议)


1.从函数分析到机器学习应用

1.1 3D曲面图可视化报告

1.1.1 目标

本次代码的目标是生成一个3D曲面图,用于展示数学函数 f(x,y)=−(x2+y2)的特性。通过在指定范围内绘制该函数,直观展示其三维空间中的变化情况。

1.1.2 代码分析

(1)函数定义:

python 复制代码
def fun(x, y):
    return -(np.power(x, 2) + np.power(y, 2))

函数 fun(x, y) 用于计算 −(x2+y2)的值,这是一种二次函数,其结果用于生成曲面图的Z轴值,构成抛物面。

(2)3D图表设置:

python 复制代码
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

通过 plt.figure() 初始化图表,并添加了一个3D子图(projection='3d')用于绘制三维曲面。

(3)数据生成:

python 复制代码
X0 = np.arange(-3, 3, 0.25)
X1 = np.arange(-3, 3, 0.25)
X0, X1 = np.meshgrid(X0, X1)
Z = fun(X0, X1)

使用 np.arange 生成从-3到3的范围,步长为0.25的数列。np.meshgrid 将生成的X0和X1网格化,形成二维坐标平面,随后通过 fun(X0, X1) 计算Z轴值。

(4)曲面绘制:

python 复制代码
surf = ax.plot_surface(X0, X1, Z, cmap=plt.cm.winter)

使用 plot_surface 绘制曲面图,并通过 cmap=plt.cm.winter 设置了颜色映射,以便通过颜色反映Z值的大小。

(5)坐标轴标签:

python 复制代码
ax.set_xlabel('X0', color='r')
ax.set_ylabel('X1', color='g')
ax.set_zlabel('f(x)', color='b')

设置了每个坐标轴的标签,并分别使用红色(X轴)、绿色(Y轴)和蓝色(Z轴)标注,增强了图表的可视化效果。

(6)颜色条:

python 复制代码
fig.colorbar(surf)

添加了颜色条,帮助解释图表中颜色和Z值的对应关系。

(7)总体代码:

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 定义函数
def fun(x, y):
    return -(np.power(x, 2) + np.power(y, 2))

# 创建 3D 图形对象
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')  # 添加3D子图

# 生成数据
X0 = np.arange(-3, 3, 0.25)
X1 = np.arange(-3, 3, 0.25)
X0, X1 = np.meshgrid(X0, X1)
Z = fun(X0, X1)

# 绘制曲面图,并使用 cmap 着色
surf = ax.plot_surface(X0, X1, Z, cmap=plt.cm.winter)
ax.set_xlabel('X0', color='r')
ax.set_ylabel('X1', color='g')
ax.set_zlabel('f(x)', color='b')  # 给三个坐标轴注明坐标名称

# 添加颜色条
fig.colorbar(surf)
plt.show()

1.1.3 结果分析

生成的图表展示了函数 f(x,y)=−(x2+y2)的抛物面特性,呈现一个以原点为中心的对称碗状结构。颜色从蓝到绿,代表Z值从低到高的变化。右侧的颜色条清晰标注了每种颜色对应的具体值范围。

1.1.4 观察与总结

  • 图表清晰地展示了函数的形态,其对称性和凹形特性一目了然。
  • 使用颜色渐变提高了数据的直观表现能力,有助于快速理解函数的深度和高度变化。
  • 坐标轴的颜色标注增强了可读性,使得三个维度的意义更加明确。

1.1.5 结论

该3D曲面图成功地将数学函数的空间特性可视化,为多变量函数的探索提供了直观的工具。类似的图表对于研究函数的分布特性、对称性或寻找极值点具有重要意义。

1.2 一元函数梯度计算报告

1.2.1 目标

本次代码的目标是通过TensorFlow框架,计算函数 f(x)=x2+2x−1 在指定点 x=2 处的一阶梯度(即导数)。

1.2.2 代码分析

(1)函数定义:

python 复制代码
def func(x):
    return x ** 2 + 2 * x - 1

定义了一元二次函数 f(x)=x2+2x−1。该函数的导数可通过自动微分工具计算,或手动计算为 f′(x)=2x+2。

(2)自动梯度计算:

python 复制代码
with tf.GradientTape() as tape:
    tape.watch(x)
    y = func(x)

使用 TensorFlow 的 tf.GradientTape 实现自动梯度计算。tape.watch(x) 监测变量 x 的变化,确保其参与梯度计算。

(3)梯度提取:

python 复制代码
order_1 = tape.gradient(target=y, sources=x)

调用 tape.gradient 方法,计算目标函数 y 对变量 x 的一阶梯度。

(4)输出结果:

python 复制代码
print("函数 x ** 2 + 2 * x - 1 在 x = 2 处的梯度为: ", order_1.numpy())

将计算出的梯度转为NumPy数组,并在终端打印结果。

1.2.4 计算结果

根据代码执行,函数 f(x)=x2+2x−1 在 x=2 处的一阶导数为: f′(x)=2x+2代入 x=2,可得: f′(2)=2×2+2=6

程序输出与手动计算一致,验证了代码的正确性。

1.2.5 优势与意义

(1)代码优势:

  • 利用 TensorFlow 自动微分机制,无需手动推导导数公式,适合复杂函数梯度计算。
  • 可扩展至更高维度、多变量函数的梯度和偏导数计算。

(2)应用场景:

  • 自动梯度计算在机器学习中十分重要,广泛应用于反向传播算法中优化模型参数。
  • 数学建模或科学计算中,也可用于快速验证导数或梯度公式的正确性。

1.2.6 结论

本代码成功计算了一元二次函数在给定点的梯度,结果准确无误。TensorFlow 的自动梯度工具不仅提升了计算效率,也大幅减少了手动推导的可能错误。

1.3 一元函数梯度和二阶导数计算报告

1.3.1 目标

本次代码的目标是通过TensorFlow框架,计算函数 f(x)=x2+2x−1 在指定点 x=2 处的一阶梯度和二阶导数,验证自动微分机制的准确性。

1.3.2 代码分析

(1)变量定义:

python 复制代码
x = tf.Variable(2.0, trainable=True)

定义变量 xxx,设置其值为 2.0,并声明其为可训练变量,以便被 GradientTape 监测并参与梯度计算。

(2)嵌套的梯度计算:

python 复制代码
with tf.GradientTape() as tape1:
    with tf.GradientTape() as tape2:
        y = x ** 2 + 2 * x - 1
        order_1 = tape2.gradient(y, x)
    order_2 = tape1.gradient(order_1, x)
  • 第一层 tape2 负责计算目标函数 f(x)f(x)f(x) 的一阶梯度。
  • 第二层 tape1 监测一阶梯度的变化,计算其对 xxx 的导数,从而得到函数的二阶导数。

(3)结果输出:

python 复制代码
print("在 x = 2 处的一阶梯度为: ", order_1.numpy())
print("在 x = 2 处的二阶梯度为: ", order_2.numpy())

将一阶梯度和二阶梯度的计算结果打印出来。

1.3.3 计算结果

根据程序输出:

  • 一阶梯度(导数):f′(x)=2x+2,在 x=2 时,f′(2)=2×2+2=6。
  • 二阶导数:f′′(x)=2,为常数。在 x=2 时,f′′(2)=2。

两项结果与手动计算完全一致,验证了代码的正确性。

1.3.4 优势与意义

代码优势:

  • 利用 GradientTape 实现嵌套梯度计算,无需显式推导复杂函数的二阶导数,尤其适用于多变量函数的高阶导数计算。
  • 灵活性高,可扩展至任意阶梯度计算。

应用场景:

  • 高阶导数计算在物理建模(如加速度计算)和机器学习优化中(如Hessian矩阵计算)具有广泛应用。
  • 自动微分降低了复杂计算的门槛,适合分析函数的曲率和极值点。

1.3.5 结论

本代码成功计算了一元二次函数在指定点的梯度和二阶导数,结果精确,充分体现了 TensorFlow 自动微分工具的强大功能。代码逻辑清晰,适合作为高阶导数计算的模板。

1.4 多元函数梯度计算报告

1.4.1 目标

本次代码的目标是利用 TensorFlow 框架,计算多元函数

在点 x=[1.0,2.0,3.0] 处的梯度。

1.4.2 代码分析

(1)函数定义:

python 复制代码
def func(x):
    return x[0] ** 2 + 3 * x[0] * x[1] + x[1] ** 2 + x[2] ** 3

定义了一个多元函数 f(x)f(x)f(x),其中 xxx 是一个三维张量。该函数包含二次项和三次项的组合。

(2)自动梯度计算:

python 复制代码
x = tf.Variable([1.0, 2.0, 3.0], dtype=tf.float32)
with tf.GradientTape() as tape:
    tape.watch(x)
    y = func(x)
  • 变量 x 被定义为可训练张量,初值为 [1.0,2.0,3.0]。
  • 通过 GradientTape 监控张量 x,对其参与的运算生成梯度。

(3)梯度提取:

python 复制代码
order_1 = tape.gradient(target=y, sources=x)
print("多元函数 x = [1.0, 2.0, 3.0] 的梯度为:", [grad.numpy() for grad in order_1])
  • 使用 tape.gradient 方法计算目标函数 f(x) 对 x 的一阶梯度。
  • 因为 x 是一个张量列表,其梯度也是一个张量列表,逐项提取值后输出。

(4)输出结果: 程序输出:

多元函数 x = [1.0, 2.0, 3.0] 的梯度为: [8.0, 7.0, 27.0]

1.4.3 梯度计算解析

多元函数的梯度为:

在 x=[1.0,2.0,3.0]x = [1.0, 2.0, 3.0]x=[1.0,2.0,3.0] 处,逐项计算:

程序计算的结果与手动推导一致,验证了代码的正确性。

1.4.4 优势与意义

(1)代码优势:

  • 自动计算多元函数的梯度,无需手动推导偏导数公式。
  • 对任意维度和复杂度的函数,均能通过 GradientTape 快速计算梯度。

(2)应用场景:

  • 梯度计算在机器学习中至关重要,用于优化目标函数。
  • 多元函数梯度计算也适用于科学计算、最优控制和物理建模等领域。

1.4.5 结论

本代码准确计算了多元函数在指定点的梯度,结果精确,代码结构清晰,体现了 TensorFlow 自动微分的高效性和灵活性。代码适用于复杂多维问题的梯度计算,是学习和实践自动微分的优秀示例。

1.5 线性回归模型训练报告

1.5.1 目标

通过 TensorFlow 框架实现一个简单的线性回归模型,拟合目标函数 y=10x+5。最终验证模型对新输入数据的预测能力。

1.5.2 代码分析

(1)损失函数定义:

python 复制代码
def loss(y_true, y_pred):
    return tf.keras.losses.MeanSquaredError()(y_true, y_pred)

使用均方误差(MSE)作为损失函数,衡量预测值 ypred 和真实值 ytrue 的差距。

(2)训练数据生成:

python 复制代码
x_train_inch = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], dtype=np.float32)
y_train_price = np.array([10 * num + 5 for num in x_train_inch], dtype=np.float32)

模拟生成线性关系的数据:输入 x 为从 1 到 11 的整数,目标输出 y 通过公式 y=10x+5 计算。

(3)模型参数初始化:

python 复制代码
w1 = tf.Variable(random.random(), trainable=True, dtype=tf.float32)
w0 = tf.Variable(random.random(), trainable=True, dtype=tf.float32)

初始化两个可训练参数 w1 和 w0​ ,分别对应线性回归模型的斜率和截距。

(4)梯度下降更新函数:

python 复制代码
def step_gradient(real_x, real_y, learning_rate):
    with tf.GradientTape() as tape:
        pred_y = w1 * real_x + w0
        reg_loss = loss(real_y, pred_y)
    w1_gradients, w0_gradients = tape.gradient(reg_loss, (w1, w0))
    w1.assign_sub(w1_gradients * learning_rate)
    w0.assign_sub(w0_gradients * learning_rate)
  • 使用 GradientTape 计算损失函数对 w1 和 w0 的梯度。
  • 更新规则:参数值减去学习率乘以梯度。

(5)训练循环:

python 复制代码
learning_rate = 0.01
num_iterations = 1000

for _ in range(num_iterations):
    step_gradient(tf.convert_to_tensor(x_train_inch), tf.convert_to_tensor(y_train_price), learning_rate)

通过 1000 次迭代,不断更新模型参数,最终使其拟合数据分布。

(6)模型评估:

python 复制代码
wheat = 0.9
price = w1 * wheat + w0
print("price = {:.2f}".format(price.numpy()))

使用训练好的模型预测 x=0.9 对应的 y 值,并输出预测结果。

1.5.3 结果分析

拟合的模型: 程序输出:

拟合得到的模型近似为: y ≈ 10.005026817321777x + 4.961641311645508

说明模型基本收敛,参数 w1 和 w0​ 的值非常接近目标函数的真实值 w1=10、w0=5。

预测结果: 对于输入 x=0.9,程序输出:

price = 13.97

预测结果接近真实值 y=10×0.9+5=14,误差很小,说明模型拟合效果良好。

1.5.4 优势与意义

(1)代码优势:

  • 使用 TensorFlow 的自动微分和变量更新功能,简化了梯度计算过程。
  • 代码清晰明了,易于理解和扩展。

(2)应用场景:

  • 线性回归模型是数据建模的基础,可扩展至多元线性回归、逻辑回归等。
  • 适用于简单预测任务或作为复杂模型的初步验证工具。

1.5.5 结论

本代码成功实现了线性回归模型的训练,最终模型参数与真实目标函数参数非常接近,预测结果准确,证明了模型的拟合能力和代码的有效性。

2.基于BP神经网络的鸢尾花分类任务

2.1神经网络

2.1.1 BP神经

BP神经网络(Back Propagation Neural Network,反向传播神经网络)是一种前馈神经网络,通过误差反向传播算法来训练模型权重和偏置。它是人工神经网络中最常见的模型之一,特别适用于非线性函数的拟合和分类问题。

(1)BP神经网络的基本组成

  1. 输入层:负责接收输入数据,每个节点对应一个特征。
  2. 隐藏层:通过权重和激活函数进行非线性变换,可以有一层或多层。
  3. 输出层:生成预测结果,节点数由任务的输出维度决定(如分类问题中类别数,回归问题中输出值数)。

(2)BP神经网络的特点

  • 基于误差反向传播算法,即将输出误差反向传播,调整网络参数(权重和偏置)。
  • 可以处理多维输入和非线性问题。
  • 通过梯度下降法或其变种来优化目标函数。

2.1.2 BP神经网络的工作流程

BP神经网络主要包括两个阶段:前向传播(Forward Propagation)反向传播(Backward Propagation)

(1)前向传播

  • 输入数据通过输入层传递到隐藏层,再通过激活函数变换,最终传递到输出层。
  • 计算输出值 ypred。
  • 如果输出值与实际值(目标值)不符,计算误差(损失函数)。

计算公式

  • 假设权重矩阵为 W,偏置为 b,激活函数为 f(⋅),则:
  • 其中 l表示第 l层,a(l−1)是上一层的输出。

(2)误差计算

  • 定义损失函数 L,例如平方误差:

(3)反向传播

通过链式法则计算每个参数对损失函数的梯度,调整参数以减少误差。

步骤

1.输出层误差

其中 z(L)是输出层的输入,f′(z)是激活函数的导数。

2.隐藏层误差

3.梯度更新: 使用梯度下降法调整权重和偏置:

其中 η是学习率。

(4)参数更新

  • 通过多次迭代(Epoch)优化损失函数,直到达到期望的精度或停止条件。

2.1.3 总结

(1)BP神经网络的核心思想是:

  1. 前向传播:计算预测值。
  2. 误差计算:定义损失函数。
  3. 反向传播:计算梯度并更新参数。
  4. 迭代训练:通过多轮训练优化模型。

(2)优点

  • 能有效处理复杂的非线性问题。
  • 在适当设置网络结构和参数时,具有很强的拟合能力。

(3)缺点

  • 容易陷入局部最优。
  • 梯度消失问题影响深层网络训练。

为了改进其性能,可以结合改进优化算法(如Adam、RMSProp)或使用更深层的网络架构(如卷积神经网络、深度学习网络)。

2.1.4 任务目标

使用BP(反向传播)神经网络实现对鸢尾花数据集的分类,主要包括以下步骤:

  1. 数据加载与预处理。
  2. 自定义BP神经网络的实现,包括前向传播、反向传播和梯度更新。
  3. 训练模型并在测试集上评估分类性能。

2.2 实验过程

2.2.1 数据加载与预处理

(1)代码

python 复制代码
# 1.加载和预处理数据
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder, StandardScaler

# 加载鸢尾花数据集
iris = load_iris()
X, y = iris.data, iris.target

# 数据标准化和独热编码
# 标准化:将每个特征的值调整到均值为0,标准差为1
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 独热编码:将类别标签转化为独热向量 (如 0 -> [1, 0, 0])
encoder = OneHotEncoder()
y = encoder.fit_transform(y.reshape(-1, 1)).toarray()

# 划分训练集和测试集
# 将80%的数据用于训练,20%用于测试
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

(2)分析

  1. 标准化处理 :使用StandardScaler将特征数据的均值调整为0,标准差调整为1,提升训练的稳定性。
  2. 独热编码:将分类标签(0, 1, 2)转为独热向量形式,便于多分类任务的神经网络训练。
  3. 数据划分:将数据集按8:2比例划分为训练集和测试集。

2.2.2 激活函数及其导数

(1)代码

python 复制代码
# 2.定义激活函数和导数
# Sigmoid 激活函数
def sigmoid(x):
    """
    将输入值压缩到 (0, 1) 范围,用于激活神经元。
    """
    return 1 / (1 + np.exp(-x))

# Sigmoid 激活函数的导数
def sigmoid_derivative(x):
    """
    用于计算反向传播中的梯度。
    对 Sigmoid 函数求导的结果是 f'(x) = f(x) * (1 - f(x))。
    """
    return x * (1 - x)

(2)解析

  1. Sigmoid激活函数:将输入值映射到(0, 1)范围,用于神经元的激活操作。 f(x)=11+e−x
  2. Sigmoid函数的导数:用于反向传播中梯度计算: f′(x)=f(x)⋅(1−f(x))

2.2.3 BP神经网络实现

(1)代码

python 复制代码
# 3.定义 BP 神经网络类
class BPNeuralNetwork:
    def __init__(self, input_size, hidden_size, output_size, learning_rate=0.01):
        """
        初始化神经网络参数,包括权重、偏置和学习率。
        参数:
        - input_size: 输入层节点数
        - hidden_size: 隐藏层节点数
        - output_size: 输出层节点数
        - learning_rate: 学习率,控制梯度更新步长
        """
        # 输入层到隐藏层的权重矩阵,初始化为随机值
        self.weights_input_hidden = np.random.uniform(-1, 1, (input_size, hidden_size))
        # 隐藏层的偏置
        self.bias_hidden = np.zeros((1, hidden_size))
        
        # 隐藏层到输出层的权重矩阵,初始化为随机值
        self.weights_hidden_output = np.random.uniform(-1, 1, (hidden_size, output_size))
        # 输出层的偏置
        self.bias_output = np.zeros((1, output_size))
        
        # 学习率
        self.learning_rate = learning_rate

    def forward(self, X):
        """
        执行前向传播,计算隐藏层和输出层的激活值。
        参数:
        - X: 输入数据
        返回:
        - final_output: 网络的最终输出
        """
        # 计算隐藏层的加权输入 (Z = X * W + b)
        self.hidden_input = np.dot(X, self.weights_input_hidden) + self.bias_hidden
        # 隐藏层的激活输出 (A = Sigmoid(Z))
        self.hidden_output = sigmoid(self.hidden_input)

        # 计算输出层的加权输入 (Z = H * W + b)
        self.final_input = np.dot(self.hidden_output, self.weights_hidden_output) + self.bias_output
        # 输出层的激活输出 (A = Sigmoid(Z))
        self.final_output = sigmoid(self.final_input)

        return self.final_output

    def backward(self, X, y, output):
        """
        执行反向传播,计算误差并更新权重和偏置。
        参数:
        - X: 输入数据
        - y: 实际标签
        - output: 模型输出
        """
        # 输出层误差 (Error = y - output)
        output_error = y - output
        # 输出层梯度 (Delta = Error * f'(output))
        output_delta = output_error * sigmoid_derivative(output)

        # 隐藏层误差 (传播到隐藏层的误差)
        hidden_error = np.dot(output_delta, self.weights_hidden_output.T)
        # 隐藏层梯度 (Delta = Error * f'(hidden_output))
        hidden_delta = hidden_error * sigmoid_derivative(self.hidden_output)

        # 更新隐藏层到输出层的权重和偏置
        self.weights_hidden_output += self.learning_rate * np.dot(self.hidden_output.T, output_delta)
        self.bias_output += self.learning_rate * np.sum(output_delta, axis=0, keepdims=True)

        # 更新输入层到隐藏层的权重和偏置
        self.weights_input_hidden += self.learning_rate * np.dot(X.T, hidden_delta)
        self.bias_hidden += self.learning_rate * np.sum(hidden_delta, axis=0, keepdims=True)

    def train(self, X, y, epochs):
        """
        训练神经网络。
        参数:
        - X: 训练数据
        - y: 训练标签
        - epochs: 训练的迭代次数
        """
        for epoch in range(epochs):
            # 前向传播
            output = self.forward(X)

            # 反向传播
            self.backward(X, y, output)

            # 每隔100个 epoch 打印一次损失值
            if epoch % 100 == 0:
                loss = np.mean(np.square(y - output))  # 均方误差
                print(f"Epoch {epoch}, Loss: {loss}")

    def predict(self, X):
        """
        使用训练好的网络进行预测。
        参数:
        - X: 测试数据
        返回:
        - 预测类别(最大概率对应的索引)
        """
        output = self.forward(X)
        return np.argmax(output, axis=1)  # 返回概率最大的类别索引

(2)详细解析

1. 初始化网络参数

  • 输入层到隐藏层、隐藏层到输出层的权重和偏置分别初始化。
  • 使用随机值初始化权重,偏置初始化为0,学习率控制参数更新步长。

2. 前向传播

  • 隐藏层计算
  • 输出层计算

3. 反向传播

  • 输出层误差
  • 隐藏层误差

4. 权重更新


2.2.4 模型训练与测试

(1)代码

python 复制代码
# 4.训练和评估模型
# 4.1 初始化神经网络
input_size = X_train.shape[1]  # 输入层节点数:特征数量
hidden_size = 2  # 隐藏层节点数:可以调节
output_size = y_train.shape[1]  # 输出层节点数:类别数量
learning_rate = 0.1  # 学习率

# 创建网络实例
bp_nn = BPNeuralNetwork(input_size, hidden_size, output_size, learning_rate)

# 训练神经网络
bp_nn.train(X_train, y_train, epochs=1000)

# 使用测试集进行预测
predictions = bp_nn.predict(X_test)

# 计算准确率
accuracy = np.mean(predictions == np.argmax(y_test, axis=1))
print(f"Test Accuracy: {accuracy * 100:.2f}%")

(2)实验结果

1.训练过程

复制代码
Epoch 0, Loss: 0.22128556516365086
Epoch 100, Loss: 0.021410587809142765
Epoch 200, Loss: 0.013800814452345782
Epoch 300, Loss: 0.012100929959213873
Epoch 400, Loss: 0.011392964488187917
Epoch 500, Loss: 0.011017511806778143
Epoch 600, Loss: 0.010790199253609335
Epoch 700, Loss: 0.010640489751476679
Epoch 800, Loss: 0.010535921139959336
Epoch 900, Loss: 0.01045957534860003

测试集准确率

Test Accuracy: 100.00%

2.3 总结与改进建议

(1)模型表现

  • BP神经网络成功实现对鸢尾花数据的分类,测试集准确率达到100%。

(2)改进建议

  • 非线性激活函数:可尝试ReLU等激活函数,加速训练。
  • 优化算法:引入Adam等优化算法提升收敛速度。
  • 正则化:通过Dropout或L2正则防止过拟合。
相关推荐
捕鲸叉16 分钟前
C++设计模式和编程框架两种设计元素的比较与相互关系
开发语言·c++·设计模式
未知陨落1 小时前
数据结构——二叉搜索树
开发语言·数据结构·c++·二叉搜索树
大波V51 小时前
设计模式-参考的雷丰阳老师直播课
java·开发语言·设计模式
无敌最俊朗@1 小时前
unity3d————接口基础知识点
开发语言·c#
winfredzhang1 小时前
如何使用 python 中的 Pillow 创建可自定义的图标生成器
python·pillow·图标·png
一丝晨光2 小时前
gcc 1.c和g++ 1.c编译阶段有什么区别?如何知道g++编译默认会定义_GNU_SOURCE?
c语言·开发语言·c++·gnu·clang·gcc·g++
qq_273900232 小时前
pytorch detach方法介绍
人工智能·pytorch·python
南城花随雪。2 小时前
Spring框架之装饰者模式 (Decorator Pattern)
java·开发语言·装饰器模式
究极无敌暴龙战神X2 小时前
前端学习之ES6+
开发语言·javascript·ecmascript
虞书欣的62 小时前
Python小游戏24——小恐龙躲避游戏
开发语言·python·游戏·小程序·pygame