当前位置: 首页 > news >正文

【深度学习】使用飞桨paddle实现波士顿房价预测任务

使用飞桨实现波士顿房价预测任务

由于开始学习深度学习,因此每次开始都熟悉一下深度学习模型的基本步骤:
在这里插入图片描述
在之前的学习中,我们学习了使用Python和NumPy实现波士顿房价预测任务的方法,本章我们将尝试使用飞桨paddle重写房价预测任务,体会二者的异同。在数据处理之前,需要先加载飞桨框架的相关类库。

1. 数据处理

数据处理的代码不依赖飞桨框架实现,与使用Python构建房价预测任务的代码相同,因此独立为单独的代码。
在这里插入图片描述

# 导入需要用到的package
import numpy as np
from sklearn.preprocessing import MinMaxScalerdef load_data():# 从文件导入数据datafile = './work/housing.data'data = np.fromfile(datafile, sep=' ')# 每条数据包括14项,其中前面13项是影响因素,第14项是相应的房屋价格中位数feature_names = [ 'CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE','DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV' ]feature_num = len(feature_names)# 将原始数据进行Reshape,变成[N, 14]这样的形状data = data.reshape([data.shape[0] // feature_num, feature_num])# 将原数据集拆分成训练集和测试集# 这里使用80%的数据做训练,20%的数据做测试# 测试集和训练集必须是没有交集的ratio = 0.8offset = int(data.shape[0] * ratio)train_data, test_data = data[:offset], data[offset:]# # 计算训练集的最大值,最小值# maximums, minimums = training_data.max(axis=0), \#                         training_data.min(axis=0)## # 对数据进行归一化处理# for i in range(feature_num):#     data[:, i] = (data[:, i] - minimums[i]) / (maximums[i] - minimums[i])# 使用训练集计算最大值和最小值scaler = MinMaxScaler()# 只在训练集上拟合scaler.fit(train_data)data = scaler.transform(data)# 训练集和测试集的划分比例train_data = data[:offset]test_data = data[offset:]return train_data, test_data

在后续的使用通过引用即可

from load_data import load_data
train_data, test_data = load_data()

2.模型设计

模型设计的实质是定义线性回归的网络结构,建议通过创建Python类的方式构建模型,该类需要继承paddle.nn.Layer父类,并且在类中定义init函数和forward函数。forward是飞桨前向计算逻辑的函数,在调用模型实例时会自动执行,其使用的网络层需要在init中声明。

init函数:在类的初始化函数中声明每一层网络的实现函数。在房价预测任务中,只需要定义一层全连接层。
forward函数:在构建神经网络时实现前向计算过程,并返回预测结果,在本任务中返回的是房价预测结果。

#加载飞桨、NumPy和相关类库
import paddle
from paddle.nn import Linear
import paddle.nn.functional as F
import numpy as np
import os
import random
from load_data import load_dataclass Regressor(paddle.nn.Layer):# self代表类的实例自身def __init__(self):# 初始化父类中的一些参数super(Regressor, self).__init__()# 定义一层全连接层,输入维度是13,输出维度是1self.fc = Linear(in_features=13, out_features=1)# 网络的前向计算def forward(self, inputs):x = self.fc(inputs)return x

3.训练配置

  • 声明定义好的回归模型实例为Regressor,并将模型的状态设置为train。
  • 使用load_data函数加载训练数据和测试数据。
  • 设置优化算法和学习率,优化算法采用随机梯度下降,学习率设置为0.01。

训练配置的代码实现如下:

# 声明定义好的线性回归模型
model = Regressor()
# 开启模型训练模式,模型的状态设置为train
model.train()
# 使用load_data加载训练集数据和测试集数据
train_data, test_data = load_data()
# 定义优化算法,采用随机梯度下降SGD
# 学习率设置为0.01
opt = paddle.optimizer.SGD(learning_rate=0.005, parameters=model.parameters())

4.训练过程

由于model.train()已经被Regressor用来设置模型的状态,因此新增了一个train_model来作为训练过程方法。

    def train_model(self, train_data, num_epochs, batch_size=10, eta=0.01):# 定义模型训练轮次epoch(外层循环)for epoch_id in range(num_epochs):# 在每轮迭代开始之前,对训练集数据进行样本乱序np.random.shuffle(train_data)# 对训练集数据进行拆分,batch_size设置为10mini_batches = [train_data[k:k + batch_size] for k in range(0, len(train_data), batch_size)]# 定义模型训练(内层循环)for iter_id, mini_batch in enumerate(mini_batches):x = np.array(mini_batch[:, :-1])  # 将当前批的房价影响因素的数据转换为np.array格式y = np.array(mini_batch[:, -1:])  # 将当前批的标签数据(真实房价)转换为np.array格式# 将np.array格式的数据转为张量tensor格式house_features = paddle.to_tensor(x, dtype='float32')prices = paddle.to_tensor(y, dtype='float32')# 前向计算predicts = model(house_features)# 计算损失,损失函数采用平方误差square_error_costloss = F.square_error_cost(predicts, label=prices)avg_loss = paddle.mean(loss)if iter_id % 20 == 0:print("epoch: {}, iter: {}, loss is: {}".format(epoch_id, iter_id, avg_loss.numpy()))# 反向传播,计算每层参数的梯度值avg_loss.backward()# 更新参数,根据设置好的学习率迭代一步opt.step()# 清空梯度变量,进行下一轮计算opt.clear_grad()

5.numpy和python构建深度学习模型和飞桨的比较

5.1 前向计算forward

	# paddledef forward(self, inputs):x = self.fc(inputs)return x# numpy+pythondef forward(self, x):z = np.dot(x, self.w) + self.breturn z

在Python310\Lib\site-packages\paddle\nn\functional\common.py路径下,可以看到paddle底层封装的方法和numpy+python是一致的
在这里插入图片描述

5.2.计算损失函数 loss

	import paddle.nn.functional as F# 计算损失,损失函数采用平方误差square_error_costloss = F.square_error_cost(predicts, label=prices)avg_loss = paddle.mean(loss)def loss(self, z, y):error = z - ynum_samples = error.shape[0]cost = error * errorcost = np.sum(cost) / num_samplesreturn cost

在Python310\Lib\site-packages\paddle\nn\functional\loss.py路径下,可以看到paddle封装了均方误差square_error_cost的方法,该方法中并没有/N,因此还计算了avg_loss = paddle.mean(loss)
在这里插入图片描述

5.3.梯度计算gradient

# paddle# 定义优化算法,采用随机梯度下降SGD# 学习率设置为0.01opt = paddle.optimizer.SGD(learning_rate=0.005, parameters=model.parameters())# 反向传播,计算每层参数的梯度值avg_loss.backward()# 更新参数,根据设置好的学习率迭代一步opt.step()# 清空梯度变量,进行下一轮计算opt.clear_grad()# numpy + pythondef gradient(self, x, y):z = self.forward(x)N = x.shape[0]gradient_w = 1. / N * np.sum((z - y) * x, axis=0)gradient_w = gradient_w[:, np.newaxis]gradient_b = 1. / N * np.sum(z - y)return gradient_w, gradient_bdef update(self, gradient_w, gradient_b, eta=0.01):self.w = self.w - eta * gradient_wself.b = self.b - eta * gradient_b

6.模型保存和推理

6.1.模型保存

# 保存模型参数,文件名为LR_model.pdparams
paddle.save(model.state_dict(), 'LR_model.pdparams')
print("模型保存成功, 模型参数保存在LR_model.pdparams中")

在这里插入图片描述

6.2.模型推理

需要注意的是在模型推理后,需要做反向的归一化处理,这里会用到max_values, min_values,这里的最大最小值是用训练数据在归一化之前获取的,为了避免重新load data,因此在返回数据时,将这两个数据一并返回。

#加载飞桨、NumPy和相关类库
import paddle
import numpy as np
from load_data import load_data
from train_paddle import Regressor
train_data, test_data, max_values, min_values = load_data()def load_one_example():# 从测试集中随机选择一条作为推理数据# 从测试集中随机选择一条作为推理数据idx = np.random.randint(0, test_data.shape[0])idx = -10one_data, label = test_data[idx, :-1], test_data[idx, -1]# 将数据格式修改为[1,13]one_data = one_data.reshape([1, -1])return one_data, labelif __name__ == '__main__':# 将模型参数保存到指定路径中model_dict = paddle.load('LR_model.pdparams')model = Regressor()model.load_dict(model_dict)# 将模型状态修改为.evalmodel.eval()one_data, label = load_one_example()# 将数据格式转换为张量one_data = paddle.to_tensor(one_data,dtype="float32")predict = model(one_data)# 对推理结果进行后处理print(predict.numpy(), max_values[-1], min_values[-1])predict = predict * (max_values[-1] - min_values[-1]) + min_values[-1]# 对label数据进行后处理label = label * (max_values[-1] - min_values[-1]) + min_values[-1]print("Inference result is {}, the corresponding label is {}".format(predict.numpy(), label))

在这里插入图片描述
这里的label是原始数据,predict是预测数据。

6.3 用plt绘制test_data曲线图

	N = y.shape[0]  # 数据点的数量# 由于 x 在这个例子中是为了生成 y 而存在的,并且我们实际上不会用它来绘图(因为我们只有 y 和 predict),# 我们可以简单地使用 range(N) 来作为 x 轴的索引,但这在绘制曲线图时通常不是必需的,因为 Matplotlib 会自动处理。# 然而,为了演示目的,我们将创建一个与 y 和 predict 相同长度的 x_index 数组。x_index = np.arange(N)# 绘制原始数据 yplt.plot(x_index, y.flatten(), color='blue', label='Original Data (y)', alpha=0.6, linewidth=1)# 绘制预测数据 predictplt.plot(x_index, predict.numpy().flatten(), color='red', label='Predicted Data (predict)', linewidth=2)# 添加标题和标签(注意:这里我们没有使用实际的 x 值作为横轴标签,因为只有 y 和 predict)plt.title('Comparison of Original Data and Predicted Data')plt.xlabel('Index')  # 或者你可以使用 'Sample Number'、'Data Point' 等标签plt.ylabel('Value')plt.legend()# 显示图表plt.grid(True)plt.show()

可以看到,整体预测得并不是很好。
在这里插入图片描述

7 使用飞桨高层API实现波士顿房价预测任务

如上代码使用飞桨的基础API完成了波士顿房价预测任务,是否有更加快捷地实现方法呢?答案是肯定的。下面使用飞桨高层API实现波士顿房价预测任务,代码实现如下:

#加载飞桨、NumPy和相关类库
import paddle
from paddle.nn import Linear
paddle.set_default_dtype("float32")
import paddle.nn.functional as F
import numpy as np
import matplotlib.pyplot as pltclass Regressor(paddle.nn.Layer):# self代表类的实例自身def __init__(self):# 初始化父类中的一些参数super(Regressor, self).__init__()# 定义一层全连接层,输入维度是13,输出维度是1self.fc = Linear(in_features=13, out_features=1)# 网络的前向计算def forward(self, inputs):x = self.fc(inputs)return xif __name__ == '__main__':# 使用飞桨高层API加载波士顿房价预测数据集,包括训练集和测试集# paddle.text:用于加载文本领域数据集。train_dataset = paddle.text.datasets.UCIHousing(mode='train')eval_dataset = paddle.text.datasets.UCIHousing(mode='test')# 模型训练model = paddle.Model(Regressor())# model.prepare:用于定义模型训练参数,如优化器paddle.optimizer.SGD、损失函数paddle.nn.MSELoss等。model.prepare(paddle.optimizer.SGD(learning_rate=0.005, parameters=model.parameters()),paddle.nn.MSELoss())# model.fit:用于模型训练,并指定相关参数,如训练轮次epochs,批大小batch_size,可视化的模型方式verbose。model.fit(train_dataset, eval_dataset, epochs=10, batch_size=10, verbose=1)# model.evaluate:用于在测试集上评估模型的损失函数值和评价指标。由于本实践没有定义模型评价指标,因此只输出损失函数值。本实践使用均方误差损失(Mean Squared Error,MSE)。result = model.evaluate(eval_dataset, batch_size=10)print("result:", result)test_data = eval_dataset.datax = test_data[:, :-1]  # 所有行,列从第 0 列到倒数第 2 列# 提取最后一列作为 Yy = test_data[:, -1].reshape([-1, 1])# model.predict:用于模型推理。x = paddle.to_tensor(x, dtype="float32")result_pred = model.predict(x, batch_size=1) # result_pred是一个list,元素数目对应模型的输出数目result_pred = result_pred[0] # tuple,其中第一个值是arraypredict = np.vstack(result_pred)# y = y * (max_values[-1] - min_values[-1]) + min_values[-1]print("Inference result is {}, the corresponding label is {}".format(predict, y))N = y.shape[0]  # 数据点的数量# 由于 x 在这个例子中是为了生成 y 而存在的,并且我们实际上不会用它来绘图(因为我们只有 y 和 predict),# 我们可以简单地使用 range(N) 来作为 x 轴的索引,但这在绘制曲线图时通常不是必需的,因为 Matplotlib 会自动处理。# 然而,为了演示目的,我们将创建一个与 y 和 predict 相同长度的 x_index 数组。x_index = np.arange(N)# 绘制原始数据 yplt.plot(x_index, y.flatten(), color='blue', label='Original Data (y)', alpha=0.6, linewidth=1)# 绘制预测数据 predictplt.plot(x_index, predict.flatten(), color='red', label='Predicted Data (predict)', linewidth=2)# 添加标题和标签(注意:这里我们没有使用实际的 x 值作为横轴标签,因为只有 y 和 predict)plt.title('Comparison of Original Data and Predicted Data')plt.xlabel('Index')  # 或者你可以使用 'Sample Number'、'Data Point' 等标签plt.ylabel('Value')plt.legend()# 显示图表plt.grid(True)plt.show()

在这里插入图片描述

学习总结

1、numpy+python和paddle训练过程是相同的,paddle对前向计算、计算损失和反向传播梯度进行了封装,不再需要逐一编写代码,这就是使用飞桨框架的威力!但是通过numpy+python比较容易理解深度学习的过程。
2、模型推理时,需要将测试数据转换为张量x = paddle.to_tensor(x, dtype=“float32”)
3、将一行数据的x,y分离出来的代码

x = test_data[:, :-1]
y = test_data[:, -1].reshape([-1, 1])
如果只需要分离部分记录:
x = test_data[0:3][:, :-1]
y = test_data[0:3][:, -1].reshape([-1, 1])
# 这是Numpy库的广播功能

4、用plt绘制曲线图时,需要用到y和predict,其中y的shap是(N,1),需要用y.flatten()降维到(N,)。predict还是张量,需要用predict.numpy()先转换为numpy格式,再通过flatten()降维。
5、使用飞桨高层API加载波士顿房价预测数据集是下载下来的,也可以指定数据集路径。
6、目前还没有定义模型评价指标,后续再学习

相关文章:

【深度学习】使用飞桨paddle实现波士顿房价预测任务

使用飞桨实现波士顿房价预测任务 由于开始学习深度学习,因此每次开始都熟悉一下深度学习模型的基本步骤: 在之前的学习中,我们学习了使用Python和NumPy实现波士顿房价预测任务的方法,本章我们将尝试使用飞桨paddle重写房价预测任…...

钉钉多维表:数据管理与协作的新篇章

在当今数字化时代,数据的高效管理和团队协作已成为企业竞争力的关键因素之一。钉钉多维表,作为一款基于钉钉平台的数据协作管理工具,正以其独特的功能和优势,引领着数据管理与协作的新潮流。本文将为您全面解析钉钉多维表的定义、特点、功能亮点、应用场景以及如何使用,让您轻松…...

高级推理的多样化推理与验证

25年2月来自波士顿大学、NotBadMath.AI、谷歌、哥伦比亚大学、MIT、Intuit公司和斯坦福大学的论文“Diverse Inference and Verification for Advanced Reasoning”。 OpenAI o1、o3 和 DeepSeek R1 等推理 LLM 在数学和编码方面取得重大进展,但仍发现 IMO 组合问题…...

深入理解 MySQL 8 C++ 源码:SELECT MOD(MONTH(NOW()), 2) 的函数执行过程

MySQL 作为最流行的关系型数据库之一,其内部实现机制一直是开发者探索的热点。本文将以一条简单的 SQL 查询 SELECT MOD(MONTH(NOW()), 2) 为例,深入分析 MySQL 8 源码中内置函数 MOD、MONTH 和 NOW 的执行过程,揭示其底层实现逻辑。 一、SQL…...

【算法系列】leetcode1419 数青蛙 --模拟

一、题目 二、思路 模拟⻘蛙的叫声。 当遇到 r o a k 这四个字符的时候,我们要去看看每⼀个字符对应的前驱字符,有没有⻘蛙叫出来。如果有⻘蛙叫出来,那就让这个⻘蛙接下来喊出来这个字符;如果没有则为异常字符串,直接…...

蓝桥杯 Java B 组之背包问题、最长递增子序列(LIS)

Day 4:背包问题、最长递增子序列(LIS) 📖 一、动态规划(Dynamic Programming)简介 动态规划是一种通过将复杂问题分解成更小的子问题来解决问题的算法设计思想。它主要用于解决具有最优子结构和重叠子问题…...

Git如何将一个分支的内容同步到另一个分支

在 Git 中,可以通过多种方法将一个分支的内容同步到另一个分支。以下是几种常用的方法: 1. 使用 merge 命令 这是最常见的方法,将一个分支的更改合并到另一个分支。 # 切换到目标分支 git checkout target-branch# 合并源分支的内容 git m…...

[C#]C# winform部署yolov12目标检测的onnx模型

yolov12官方框架:github.com/sunsmarterjie/yolov12 【测试环境】 vs2019 netframework4.7.2 opencvsharp4.8.0 onnxruntime1.16.3 【效果展示】 【调用代码】 using System; using System.Collections.Generic; using System.ComponentModel; using System.…...

51c大模型~合集69

我自己的原文哦~ https://blog.51cto.com/whaosoft/12221979 #7项基于SAM万物分割模型研究工作 1、CC-SAM: SAM with Cross-feature Attention and Context for Ultrasound Image Segmentation #ECCV2024 #SAM #图像分割 #医学图像 Segment Anything Model (SAM) 在自…...

2025寒假周报4

2025寒假天梯训练7-CSDN博客 眨眼间寒假训练就告一段落了,准备回校继续战斗了。这周练了3场OI赛制的篮球杯,感觉非常糟糕,不像天梯赛,天梯赛打起来非常舒适顺畅,一直都不喜欢OI赛制,打着非常不稳定..还需要…...

自学Java-AI结合GUI开发一个石头迷阵的游戏

自学Java-AI结合GUI开发一个石头迷阵的游戏 准备环节1、创建石头迷阵的界面2、打乱顺序3、控制上下左右移动4、判断是否通关5、统计移动步骤,重启游戏6、拓展问题 准备环节 技术: 1、GUI界面编程 2、二维数组 3、程序流程控制 4、面向对象编程 ∙ \bulle…...

buuctf-[极客大挑战 2019]Knife题解

一个很简单的web题,进入界面 网页名还加白给的shell,并且给的提示也很明显,给了一个一句话木马再加上菜刀,很怀疑是一个webshell题,那么直接打开蚁剑测试连接拿shell 用提示的一句话木马的密码,测试链接发现…...

Spring MVC 对象转换器:初级开发者入门指南

Spring MVC 对象转换器:初级开发者入门指南 为什么需要对象转换器? 在 Web 应用中,我们经常需要处理不同类型的对象。例如:前端数据到后端对象 :用户通过表单提交的数据通常是HttpServletRequest 对象,我们…...

语音直播交友app出海:语音直播交友系统软件源码搭建国际化发展技术层面分析

随着移动互联网的普及和全球社交需求的增长以及国内如火如荼的Ai大模型引起的全球发展热潮,语音直播软件出海成为了具有巨大发展潜力的业务领域。以下是一些关键的技术方向,将为语音直播软件在国际市场的成功推广及搭建合作奠定基础。 通信技术 实时语音…...

Web Scraper,强大的浏览器爬虫插件!

Web Scraper是一款功能丰富的浏览器扩展爬虫工具,有着直观的图形界面,无需编写代码即可自定义数据抓取规则,高效地从网页中提取结构化数据,而且它支持灵活的数据导出选项,广泛应用于电商监控、内容聚合、市场调研等多元…...

EasyRTC:基于WebRTC与P2P技术,开启智能硬件音视频交互的全新时代

在数字化浪潮的席卷下,智能硬件已成为我们日常生活的重要组成部分,从智能家居到智能穿戴,从工业物联网到远程协作,设备间的互联互通已成为不可或缺的趋势。然而,高效、低延迟且稳定的音视频交互一直是智能硬件领域亟待…...

go 定时任务 gocron timer

选型推荐(DeepSeek) 简单任务调度: 推荐使用 cron 或 gocron,它们轻量且易用。 复杂任务调度: 推荐使用 go-quartz,支持任务依赖和持久化。 分布式任务调度: 推荐使用 asynq,基于 Redis 实现,适合分布式…...

uniapp引入uview组件库(可以引用多个组件)

第一步安装 npm install uview-ui2.0.31 第二步更新uview npm update uview-ui 第三步在main.js中引入uview组件库 第四步在uni.scss中引入import "uview-ui/theme.scss"样式 第五步在文件中使用组件...

MySQL主从架构

MySQL主从架构 MySQL REPLICATION 在实际生产环境中,如果对数据库的读和写都在一个数据库服务器中操作。无论是在安全性、高可用性,还是高并发等各个方面都是完全不能满足实际需求的,因此,一般来说都是通过主从复制(…...

科普mfc100.dll丢失怎么办?有没有简单的方法修复mfc100.dll文件

当电脑频繁弹窗提示“mfc100.dll丢失”或应用程序突然闪退时,这个看似普通的系统文件已成为影响用户体验的核心痛点。作为微软基础类库(MFC)的核心组件,mfc100.dll直接关联着Visual Studio 2010开发的大量软件运行命脉。从工业设计…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...