Quiet
  • HOME
  • ARCHIVE
  • CATEGORIES
  • TAGS
  • LINKS
  • ABOUT

Alex

  • HOME
  • ARCHIVE
  • CATEGORIES
  • TAGS
  • LINKS
  • ABOUT
Quiet主题
  • 算法
  • 模型

鸢尾花神经网络分类案例

Alex.Y
Science

2025-03-25 16:25:00

鸢尾花神经网络分类案例

1. Case Background

​ 鸢尾花(Iris)数据集是机器学习领域中最经典的数据集之一。它由三种不同品种的鸢尾花的测量数据组成:山鸢尾(setosa)、变色鸢尾(versicolor)和维吉尼亚鸢尾(virginica).

​ 鸢尾花数据集包含了150个样本,每个样本有四个特征:花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)和花瓣宽度(petal width)。除了样本数据外,每个样本还有一个对应的目标类别,即鸢尾花的品种。

神经网络模型

2. Python Code

import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix, accuracy_score
from sklearn.decomposition import PCA
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

"""
torch:PyTorch深度学习框架,用于构建和训练神经网络。
torch.nn:包含了构建神经网络所需的各种层和损失函数。
torch.optim:提供了各种优化算法,如Adam、SGD等。
sklearn.datasets.load_iris:用于加载鸢尾花数据集。
sklearn.model_selection.train_test_split:用于将数据集划分为训练集和测试集。
sklearn.preprocessing.StandardScaler:用于对数据进行标准化处理。
sklearn.metrics.confusion_matrix和sklearn.metrics.accuracy_score:用于评估模型的性能。
sklearn.decomposition.PCA:用于对数据进行主成分分析(PCA)降维。
numpy:用于数值计算。
matplotlib.pyplot:用于绘制图表。
seaborn:基于matplotlib的可视化库,提供更美观的图表样式。
"""

# 1.加载数据集:特征数据存储在 X 中,标签数据存储在 y 中
iris = load_iris()
X = iris.data
y = iris.target

# 2.数据预处理
# 1)划分训练集和测试集(train_test_split 函数)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 测试集占比为 20%。stratify=y 表示进行分层抽样,确保训练集和测试集中各类别的比例与原始数据集相同。

# 2)数据标准化(StandardScaler, 使数据具有零均值和单位方差)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# fit_transform 方法用于计算训练集的均值和标准差,并对训练集进行标准化;
# transform 方法使用训练集的均值和标准差对测试集进行标准化。

# 3)转换为 PyTorch 张量,以便输入到神经网络模型中
X_train_tensor = torch.FloatTensor(X_train_scaled)
y_train_tensor = torch.LongTensor(y_train)
X_test_tensor = torch.FloatTensor(X_test_scaled)
y_test_tensor = torch.LongTensor(y_test)

# 4.模型构建
class IrisClassifier(nn.Module):
"""
定义一个名为 IrisClassifier 的神经网络模型,继承自 nn.Module。
该模型包含三个全连接层和一个 ReLU 激活函数。forward 方法定义了模型的前向传播过程,
输入数据依次通过三个全连接层和 ReLU 激活函数,最终输出预测结果。
"""
def __init__(self):
super().__init__()
self.layer1 = nn.Linear(4, 10)
self.layer2 = nn.Linear(10, 10)
self.output = nn.Linear(10, 3)
self.relu = nn.ReLU()

def forward(self, x):
x = self.relu(self.layer1(x))
x = self.relu(self.layer2(x))
x = self.output(x)
return x

model = IrisClassifier()

# 5.定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)
# 使用交叉熵损失函数 nn.CrossEntropyLoss() 作为模型的损失函数,用于衡量模型预测结果与真实标签之间的差异。
# 使用 Adam 优化器 optim.Adam() 来更新模型的参数,学习率设置为 0.01。


# 6.模型训练
epochs = 1000
losses = []

for epoch in range(epochs):
optimizer.zero_grad()
outputs = model(X_train_tensor)
loss = criterion(outputs, y_train_tensor)
loss.backward()
optimizer.step()
losses.append(loss.item())
if (epoch + 1) % 100 == 0:
print(f"Epoch {epoch+1}/{epochs}, Loss: {loss.item():.4f}")
# 设置训练的轮数为 1000 轮,在每一轮训练中,首先将优化器的梯度清零,然后通过模型进行前向传播得到预测结果,计算损失值。
# 接着进行反向传播,计算梯度,最后使用优化器更新模型的参数。每 100 轮打印一次损失值,并将每一轮的损失值存储在 losses 列表中。

# 7.训练损失曲线可视化
plt.figure(figsize=(8, 5))
plt.plot(losses)
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.title("Training Loss Curve")
plt.show()
# 使用 matplotlib 绘制训练损失曲线,横坐标为训练轮数,纵坐标为损失值。通过观察损失曲线,可以判断模型是否收敛。

# 8.模型评估
with torch.no_grad():
y_pred = model(X_test_tensor)
predicted_labels = torch.argmax(y_pred, dim=1)
accuracy = accuracy_score(y_test, predicted_labels)
print(f"Test Accuracy: {accuracy:.2%}")
# 在测试集上评估模型的性能,使用 torch.no_grad() 上下文管理器关闭梯度计算,以减少内存消耗。
# 通过模型进行前向传播得到预测结果,使用 torch.argmax() 函数获取预测结果的类别索引。
# 使用 accuracy_score() 函数计算模型在测试集上的准确率,并打印结果。

# 9.混淆矩阵可视化
cm = confusion_matrix(y_test, predicted_labels)
plt.figure(figsize=(8, 6))
sns.heatmap(
cm,
annot=True,
fmt="d",
cmap="Blues",
xticklabels=iris.target_names,
yticklabels=iris.target_names,
)
plt.xlabel("Predicted Label")
plt.ylabel("True Label")
plt.title("Confusion Matrix")
plt.show()
# 使用 confusion_matrix() 函数计算模型在测试集上的混淆矩阵,用于直观地展示模型的分类结果。
# 使用 seaborn 的 heatmap() 函数绘制混淆矩阵热力图,横坐标为预测标签,纵坐标为真实标签。

# 10.PCA 降维可视化
pca = PCA(n_components=2)
X_train_pca = pca.fit_transform(X_train_scaled)
X_test_pca = pca.transform(X_test_scaled)
# 使用主成分分析(PCA)将特征数据降维到二维,方便进行可视化。n_components=2 表示将数据降维到二维。

h = 0.02 # 网格步长
x_min, x_max = X_train_pca[:, 0].min() - 1, X_train_pca[:, 0].max() + 1
y_min, y_max = X_train_pca[:, 1].min() - 1, X_train_pca[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

# 将网格点通过PCA逆变换回原始特征空间
mesh_points = np.c_[xx.ravel(), yy.ravel()]
X_inverse = pca.inverse_transform(mesh_points)
X_inverse_tensor = torch.FloatTensor(X_inverse)
# 生成一个二维网格,用于绘制决策边界。将网格点通过 PCA 逆变换回原始特征空间,并转换为 PyTorch 张量。

with torch.no_grad():
outputs = model(X_inverse_tensor)
Z = torch.argmax(outputs, dim=1).numpy()
Z = Z.reshape(xx.shape)
# 在网格点上进行预测,得到每个网格点的类别标签。

plt.figure(figsize=(10, 6))
plt.contourf(xx, yy, Z, alpha=0.3, cmap="Paired")
scatter = plt.scatter(
X_train_pca[:, 0],
X_train_pca[:, 1],
c=y_train,
cmap="Paired",
edgecolors="k",
label="Train",
)
plt.scatter(
X_test_pca[:, 0],
X_test_pca[:, 1],
c=y_test,
cmap="Paired",
marker="x",
s=100,
linewidth=1,
label="Test",
)
plt.xlabel("Principal Component 1")
plt.ylabel("Principal Component 2")
plt.legend(
handles=scatter.legend_elements()[0],
labels=iris.target_names.tolist(),
title="Species",
)
plt.title("Decision Regions Visualized with PCA")
plt.show()
# 使用 contourf() 函数绘制决策区域,使用 scatter() 函数绘制训练集和测试集的数据点。
# 通过可视化决策区域和数据点,可以直观地观察模型的分类效果。

​

3. Output

4. 神经网络训练

Train process

收集数据,整理数据; 搭建神经网络,即 目标函数 ,真实值和目标函数值直接估计误差的损失函数
用损失函数值前向输入值求导, 根据导数的反方向去更新网络参数(权重w和偏置b),目的是让损失函数值最终为0,最终生成模型

梯度:函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大。
前向传播:前向传播就是前向调用,就是把x代入到方程中,去求y值。
反向传播:反向传播就是根据误差和学习率,将参数权重进行调整。

数据预处理:

数据按比例缩放
归一化(normalization):将数据放缩到0~1区间,利用公式(x-min)/(max-min)。
标准化(Standardization):将数据转化为标准的正态分布,均值为0,方差为1。

正则化:正则化的主要作用是防止过拟合,
对模型添加正则化项可以限制模型的复杂度,使得模型在复杂度和性能达到平衡。

独热码编码 (one hot):
one hot编码是将类别变量转换为机器学习算法易于使用的一种形式的过程。one-hot通常用于特征的转换。
礼拜一,礼拜二,礼拜三,礼拜四,礼拜五,礼拜六,礼拜日。
写成 【 0 , 0, 3, 0, 0, 0, 0】
比如:一周七天,第三天可以编码为 [0,0,1,0,0,00]

训练集、测试集,测试集

训练集:用来训练模型的数据,用来学习的

验证集:用来验证模型的数据,主要是看下模型的训练情况

测试集: 训练完成之后,验证模型的数据

训练集———–学生的课本;学生 根据课本里的内容来掌握知识。

验证集————作业,通过作业可以知道 不同学生学习情况、进步的速度快慢。

测试集———–考试,考的题是平常都没有见过,考察学生举一反三的能力。

损失函数

损失函数用来评价模型的预测值和真实值不一样的程度,损失函数越好,通常模型的性能越好。

f(x) 表示预测值,Y 表示真实值,

优化器

优化器就是在深度学习反向传播过程中,指引损失函数(目标函数)的各个参数往正确的方向更新合适的大小,使得更新后的各个参数让损失函数(目标函数)值不断逼近全局最小。

激活函数

激活函数就是对输入进行过滤,可以理解为一个过滤器

常见的非线性激活函数通常可以分为两类:
输入单个变量输出单个变量: sigmoid函数,Relu函数;
输入多个变量输出多个变量: 如Softmax函数,Maxout函数。

对于二分类问题,在输出层可以选择 sigmoid 函数。

对于多分类问题,在输出层可以选择 softmax 函数。

由于梯度消失问题,尽量sigmoid函数和tanh的使用。

tanh函数由于以0为中心,通常性能会比sigmoid函数好。

ReLU函数是一个通用的函数,一般在隐藏层都可以考虑使用。

有时候要适当对现有的激活函数稍作修改,以及考虑使用新发现的激活函数。

Referer:

  1. 深度学习神经网络入门案例详细解析-鸢尾花案例 https://blog.csdn.net/weixin_46969441/article/details/121043572
  2. 案例4:鸢尾花分类(pytorch)https://blog.csdn.net/shadowtalon/article/details/146476428
上一篇

高等数学-5-数据科学的分布

下一篇

高等数学-4-随机变量/概率统计

©2026 By Alex. 主题:Quiet
Quiet主题