基于 PyTorch 搭建多层感知机模型实现葡萄酒数据集分类

本案例由开发者:山东科技大学-崔宾阁老师提供

1 概述

1.1 案例介绍

随着葡萄酒市场的不断发展,对葡萄酒进行准确分类对于葡萄酒的生产、销售都具有重要意义。华为开发者空间云主机平台提供了稳定高效的开发环境,使开发者能够在云端快速搭建应用。

本案例依托华为开发者空间提供的云主机与CodeArts IDE,并利用深度学习框架PyTorch搭建多层感知机(MLP)模型实现葡萄酒(Wine)数据集分类。PyTorch是一个开源的机器学习库,广泛用于各种深度学习任务,如计算机视觉、自然语言处理等。它提供了强大的自动微分功能和灵活的张量计算能力,使得开发者能够轻松地构建和训练复杂的神经网络模型。多层感知机(MLP)是一种前馈神经网络,它包含一个或多个隐藏层。MLP能够学习非线性模型,因此在许多复杂的分类和回归任务中表现出色。

通过本案例,开发者将学习如何运用PyTorch框架进行数据预处理、MLP模型定义以及模型的训练与评估。同时,开发者将熟悉华为云主机平台及CodeArts IDE开发环境,提升项目实战能力,为后续更复杂的项目开发打下坚实基础。

1.2 适用对象

  • 个人开发者
  • 高校学生

1.3 案例时间

本案例总时长预计60分钟。

1.4 案例流程

edf9a41da83e4317aef54736c98c1897

说明:

① 申请并登录华为开发者空间—云主机,打开CodeArts IDE创建工程;

② 在云主机CodeArts IDE for Python中配置环境,安装项目所需的依赖包;

③ 在云主机CodeArts IDE for Python中编写项目代码并运行;

1.5 资源总览

本案例预计花费总计0元。

资源名称规格单价(元)时长(分钟)
开发者空间—云主机鲲鹏通用计算增强型 kC2 | 4vCPUs | 8G | Ubuntu免费60
CodeArts IDECodeArts IDE for Python免费60


2 操作步骤

2.1 配置开发者空间—云主机

本案例中,使用华为开发者空间所提供的云主机平台以及CodeArts IDE + Python开发工具,基于Pytorch搭建多层感知机(MLP)模型实现葡萄酒(Wine)数据集分类。点击链接( https://support.developer.huaweicloud.com/doc/development/resource-tools/zh-cn_topic_0000002367559525-0000002367559525 可跳转至免费领取云主机指南。

1. 在浏览器中输入华为云开发者空间网址:https://developer.huaweicloud.com/developerspace,进入到华为云开发者空间页面。

在华为开发者空间页面点击“免费领取”,跳转到开发者空间页面,如未领取根据页面提示进行云主机领取。

c00bf4ecb0f0497e97cff91b6afad344

2. 在开发者空间页面,点击左侧“工作台”按钮进入工作台页面,再点击“配置云主机”进行云主机的配置。

7197c7bbae4e477b979b0b3aab78164d

3. 在配置云主机窗口中自定义云主机名称,配置完毕后点击“安装”。

982f9e0bcb1c49648c834075c17b3626

4. 安装完毕后点击“打开云主机”>“进入桌面”即可进入云主机。

4991ccf4eeaf460f90269331b03759cf

5. 等待环境云主机下载镜像、安装系统、安装工具集,首次进入云主机大约需要3至5分钟。

31ea6cd40b734969b1c10493070d7e66

6. 环境准备完毕后,即可进入云主机,云主机桌面如下图所示。

73591e7169344ac794107561a2442ecc

2.2 创建项目

CodeArts IDE是一个集成开发环境(IDE),兼具源代码编辑器的简易性和开发人员工具的强大功能,如代码补全和调试。它将精简的源代码编辑器与强大的开发者工具结合在一起。

1. 双击打开云主机桌面上的CodeArts IDE for Python。

5bfd6948e1a44cbba68d8a9f236d25e5

2. 首次使用CodeArts IDE创建工程,可直接点击左侧栏目中的“新建工程”,项目名称为“WineClassifierMLP”(用户可自行取名),工程存放位置、Python解释器直接使用默认配置,接着点击右下角蓝色“创建”按钮。

00e4f7d058a1435dad3fd64077956451

3. 在新建的“WineClassifierMLP”工程项目中,点击左上角的“文件”,依次点击“新建”—>“文件”,新建一个Jupyter Notebook类型的文件。

e435629e1fd94b7e8ac2fee3595787c2

4. 在弹出的窗口中,选择文件类型为“Jupyter Notebook .ipynb支持”,从而创建一个Jupyter Notebook文件,该文件是一种交互式文档,支持分步执行代码。

0d894620dc4446b48303f0efe0d2af86

5. 新创建的.ipynb文件默认命名为“Untitled-1.ipynb”,当保存该文件时,会提示重命名。点击右上角“选择内核”,为代码运行提供支持。

21ba1fcc37734d89973aeeeb4bfda02a

6. 在“选择内核”窗口中,点击第一项,选择“Jupyter”内核源。若在保存文件后,按提示 “安装/启动建议的扩展python+jupyter”却因版本冲突无法成功安装,此时可尝试重置云主机,更新到最新的IDE版本,之后再重新进行内核相关操作。

52b71518827e4997b3d539955fa88e7a

7. 内核选择在新建工程时新建的虚拟环境,点击第三项“venv(Python3.12.3)”。

2aec6c82df414b8988534a6e20a1b6fc

8. 选择完成后,可以在右上角看到当前Notebook文件运行用到的内核。

a47a8703b7de4d6da5ce5408d99bc497

9. 在Notebook文件的代码单元格中输入代码,点击单元格左上角的运行按钮,安装ipykernel模块,该模块是将Python环境注册为Jupyter内核的关键组件。

50c54d07a71a4223a5ed4c896ebb29af

10. 可以在右下角看到ipykernel包的安装,大约等待5-8分钟,该包安装完成。

c73c9256fc4a4b5f9888ca4a86920084

2.3 葡萄酒分类数据集介绍

本案例采用的葡萄酒分类数据集,由加州大学欧文分校(UCI)的Arthur D. Anderson博士于1991年创建,旨在为葡萄酒化学成分与其产地之间的关联研究提供数据支持。该数据集包含了来自意大利三个不同产区的178种葡萄酒样本,每种样本记录了13种化学成分的测量值。这13种化学成分分别为酒精、苹果酸、灰、灰分的碱度、镁、总酚、黄酮类化合物、非黄烷类酚类、原花色素、颜色强度、色调、稀释葡萄酒的OD280/OD315、脯氨酸。其中第1类有59个样本,第2类有71个样本,第3类有48个样本。

下图使用“print()”函数输出一些关于葡萄酒数据集的基本信息,包括特征名称、目标类别、 数据形状和目标形状,并展示了数据集的前五行数据。

51bd1b0823a2414b98eda137f0735709

2.4 安装项目所需的依赖包

1. 首先点击CodeArts for Python下方工具栏中的“终端”进入到命令行交互界面,然后输入下面代码中的命令,以激活环境。

source /home/developer/IDEProjects/WineClassifierMLP/venv/bin/activate

16bb7701a6394a86b566c6fb0f618740

2. 在终端界面中输入下面代码中的安装命令,以安装项目所需的依赖包。

pip3 install torch torchvision torchaudio scikit-learn matplotlib 

如果安装太慢,可以使用国内源,如使用下面代码中的命令进行安装。

pip3 install torch torchvision torchaudio scikit-learn matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

0c70bc849c004895a067d3e6c2916ccc

3. 安装依赖包预计需要10-15分钟,具体取决于网络环境。当终端界面出现如下图所示的信息时,表示项目所需的依赖包安装成功。同时,通过点击单元格代码左侧的“运行”按钮,等待3秒左右后如果出现一个绿色的“√”,也可验证项目所需的依赖包安装成功。

20c2a4d8987e4a7dbbeef6341b8cc086

2.5 编写并运行代码

代码基于PyTorch搭建了一个多层感知机模型(MLP)用于实现葡萄酒(Wine)数据集分类,完整代码可以通过此链接https://github.com/xxxxfff/MLP进行获取,对于代码的详细讲解如下:

1. 导入必要的包

(1) torch.nn:PyTorch中的神经网络模块,包含各种神经网络层和激活函数。

(2) torch.optim:PyTorch中的优化器模块,用于更新模型的权重。

(3) torch.utils.data:PyTorch中的数据加载工具,用于创建数据加载器。

(4) sklearn.datasets:Scikit-learn中的数据集模块,用于加载Wine数据集。

(5) sklearn.model_selection:Scikit-learn中的模型选择模块,用于划分训练集和测试集。

(6) sklearn.preprocessing:Scikit-learn中的预处理模块,用于数据标准化。

(7) numpy:用于数值计算。

(8) matplotlib.pyplot:用于绘制图表。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import numpy as np
import matplotlib.pyplot as plt

点击“+ 代码”新建代码单元格,在新建的代码单元格中编写并运行“导入必要的包”的代码,运行成功的截图如下。

5606b1c5881d4754a1c17bfe16dc7bb3

2. 加载数据集

创建数据集加载函数 load_data(),在函数中使用sklearn.datasets.load_wine()加载Wine数据集。

# 加载数据集
def load_data():
    data = load_wine()
    X = data.data
    y = data.target
    return X, y

点击“+ 代码”新建代码单元格,在新建的代码单元格中编写并运行“创建加载数据集函数load_data()”的代码,运行成功的截图如下。

a72fc528c4be494ab898c66b2a1e2b06

3. 数据预处理

创建数据预处理函数 preprocess_data(),首先使用StandardScaler对特征数据进行标准化处理,使每个特征的均值为0,标准差为1,然后将标准化后的数据和目标变量转换为PyTorch张量。

# 数据预处理
def preprocess_data(X, y):
    # 数据标准化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)
    # 转换为 PyTorch 张量
    X_tensor = torch.tensor(X_scaled, dtype=torch.float32)
    y_tensor = torch.tensor(y, dtype=torch.long)
    return X_tensor, y_tensor

点击“+ 代码”新建代码单元格,在新建的代码单元格中编写并运行“创建数据预处理函数preprocess_data()”的代码,运行成功的截图如下。

26ea14a663d94bf9b7622dc5059dbe20

4. 构建MLP模型

使用PyTorch的torch.nn模块定义一个多层感知机(MLP)模型,在__init__方法中,定义了模型的各个层,包含三个全连接层和ReLU激活函数,在forward方法中,定义了数据在模型中的前向传播路径。

# 构建 MLP 模型
class MLP(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, hidden_size)
        self.fc3 = nn.Linear(hidden_size, output_size)
    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x = self.relu(x)
        x = self.fc3(x)
        return x

点击“+ 代码”新建代码单元格,在新建的代码单元格中编写并运行“构建MLP模型”的代码,运行成功的截图如下。

95797f889e55467ea752fb0e74901bf8

5. 训练模型

创建训练模型函数 train_model(),在train_model()函数中,使用model.train()将模型设置为训练模式,然后遍历每个epoch,对训练数据进行迭代,并计算每个epoch的平均损失和准确率,并记录到losses和accuracies列表中,最终返回losses和accuracies列表。

# 训练模型
def train_model(model, train_loader, criterion, optimizer, num_epochs=20):
    model.train()
    losses = []
    accuracies = []
    for epoch in range(num_epochs):
        epoch_loss = 0
        correct = 0
        total = 0
        for inputs, targets in train_loader:
            optimizer.zero_grad()
            outputs = model(inputs)
            loss = criterion(outputs, targets)
            loss.backward()
            optimizer.step()
            epoch_loss += loss.item()
            _, predicted = torch.max(outputs.data, 1)
            total += targets.size(0)
            correct += (predicted == targets).sum().item()
        epoch_loss /= len(train_loader)
        epoch_accuracy = correct / total
        losses.append(epoch_loss)
        accuracies.append(epoch_accuracy) 
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {epoch_loss:.4f}, Accuracy: {epoch_accuracy:.4f}')
    return losses, accuracies

点击“+ 代码”新建代码单元格,在新建的代码单元格中编写并运行“创建训练模型函数train_model()”的代码,运行成功的截图如下。

8f9a889efe114c03b9e36695b2b64ac4

6. 评估模型

创建评估模型函数 test_model(),在test_model()函数中,使用model.eval()将模型设置为评估模式,并使用torch.no_grad()禁用梯度计算,以提高评估速度。然后遍历测试数据,计算测试集的准确率。

# 评估模型
def test_model(model, test_loader):
    model.eval()
    with torch.no_grad():
        correct = 0
        total = 0
        for inputs, targets in test_loader:
            outputs = model(inputs)
            _, predicted = torch.max(outputs.data, 1)
            total += targets.size(0)
            correct += (predicted == targets).sum().item()
    accuracy = correct / total
    print(f'Test Accuracy: {accuracy:.4f}')
    return accuracy

点击“+ 代码”新建代码单元格,在新建的代码单元格中编写并运行“创建评估模型函数test_model()”的代码,运行成功的截图如下。

4cdbc1d7a6104c908a700fa22401fc7d

7. 创建绘制训练损失和精度函数

创建plot_training_history()函数来绘制训练损失和精度随训练轮数的变化,首先使用matplotlib库创建一个图形,包含两个子图。第一个子图绘制训练损失随训练轮数(epoch)的变化,第二个子图绘制训练准确率随训练轮数(epoch)的变化。然后使用plt.legend()添加图例,并使用plt.tight_layout()调整子图布局,最后使用plt.savefig('training_loss_and_accuracy.png') 将图形保存为当前文件夹下的training_loss_and_accuracy.png图片。

# 绘制训练损失和精度并保存图片
def plot_training_history(losses, accuracies):
    plt.figure(figsize=(12, 5))
    plt.subplot(1, 2, 1)
    plt.plot(losses, label='Training Loss')
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    plt.title('Training Loss')
    plt.legend()
    plt.subplot(1, 2, 2)
    plt.plot(accuracies, label='Training Accuracy')
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy')
    plt.title('Training Accuracy')
    plt.legend()
    plt.tight_layout() 
    # 保存图片
    plt.savefig('training_loss_and_accuracy.png')

点击“+ 代码”新建代码单元格,在新建的代码单元格中编写并运行“创建绘制训练损失和精度函数plot_training_history()”的代码,运行成功的截图如下。

0760c13744b7449f825220116a4d38e2

8. 创建主函数

(1) 加载数据:调用load_data函数加载Wine数据集。

(2) 数据预处理:调用preprocess_data函数对数据进行预处理。

(3) 划分训练集和测试集:使用train_test_split将样本划分为训练集和测试集,训练集占80%,测试集占20%。

(4) 创建DataLoader:使用TensorDataset和DataLoader创建训练集和测试集的数据加载器。

(5) 定义模型、损失函数和优化器:调用MLP类创建模型实例,使用交叉熵损失函数(CrossEntropyLoss)计算损失,使用Adam优化器进行优化。

(6) 训练模型:调用train_model函数训练模型,共训练20轮。

(7) 评估模型:调用test_model函数评估模型在测试集上的性能。

(8) 绘制训练损失和精度并保存图片:调用plot_training_history函数绘制训练损失和精度的图表,并将图表保存为training_loss_and_accuracy.png。

# 主函数
def main():
    # 加载数据
    X, y = load_data()  
    # 数据预处理
    X_tensor, y_tensor = preprocess_data(X, y)
    # 划分训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(X_tensor, y_tensor, test_size=0.2, random_state=42)
    # 创建 DataLoader
    train_dataset = TensorDataset(X_train, y_train)
    test_dataset = TensorDataset(X_test, y_test)
    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
    # 定义模型、损失函数和优化器
    input_size = X.shape[1]
    hidden_size = 100
    output_size = 3
    model = MLP(input_size, hidden_size, output_size)
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    # 训练模型
    losses, accuracies = train_model(model, train_loader, criterion, optimizer, num_epochs=20)
    # 评估模型
    test_accuracy = test_model(model, test_loader)
    # 绘制训练损失和精度并保存图片
    plot_training_history(losses, accuracies)

点击“+ 代码”新建代码单元格,在新建的代码单元格中编写并运行“创建主函数main()”的代码,运行成功的截图如下。

ecf80d3968bb483f882b35e024a74a98

9. 调用主函数

最后使用if __name__ == "__main__":代码块调用主函数,从而实现对葡萄酒数据集(Wine)的分类。

if __name__ == "__main__":
    main()

点击“+ 代码”新建代码单元格,在新建的代码单元格中编写并运行“调用主函数”的代码,运行成功的截图如下。等待5秒左右后,返回模型训练和测试的运行结果,并将training_loss_and_accuracy.png保存到当前文件夹下。从运行结果图中可以看到随着训练轮数(共20轮)的增加,Loss损失函数的值在缓慢地降低以及Accuracy准确率的值在缓慢地升高。

5822b7745af944f39ee33f56b67e0a72

下图是训练损失(Training Loss)和训练准确率(Training Accuracy)的折线图,横轴表示训练轮次,纵轴分别表示损失和准确率,可以看到随着训练轮数的增加,Training Loss的值在缓慢地降低以及Training Accuracy的值在缓慢地升高。这是因为在训练过程中模型通过不断地优化参数,逐步学习到数据中的特征和模式,减少预测误差,从而提高了准确率。

b803bb6b76e549e6b02839c8b7b864d3

至此本次实验全部内容完成。

2.6 拓展思考

1. 尝试增加MLP模型的隐藏层,观察模型的性能是否有所提升。

2. 尝试不同的激活函数,如ReLU、Sigmoid、Tanh等,比较它们对模型性能的影响。

3. 逐步增加训练轮数(epoch),观察模型的性能是否随着训练轮数的增加而提高。


3 释放资源

3.1 关闭云主机

1. 首先点击云主机桌面上面的“关机”按钮,然后在弹出来的提示框点击“确定”按钮,关闭云主机。

a555f9fde8fc456784225833ef9c7aa4

2. 点击“确定”按钮后页面自动跳转到开发者空间页面,可以看到我的云主机显示“关机中”,说明云主机正在关机。    

b3d2876a746c4b9ebc8afe969403572d

3.2 检查资源

云主机关机后,等待3至5分钟,当我的云主机显示“已就绪”时,说明云主机成功关机,下次使用云主机只需点击“打开云主机”>“进入桌面”即可,可参考2.1小节。    

7425a202d5f74ff5862f73b77d8992ed

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值