游戏AI的创造思路-技术基础-深度学习(5)

继续深度学习技术的探讨,填坑不断,头秃不断~~~~~

 

3.5. 自编码器(AE)

3.5.1. 定义

自编码器(Autoencoder, AE)是一种数据的压缩算法,其中压缩和解压缩函数是数据相关的、有损的、从样本中自动学习的。

它通常用于学习数据的高效编码,在神经网络的形式下,自编码器可以用于降维和特征学习。

在游戏AI中,自编码器可以被用于数据的压缩、特征提取或异常检测等任务。

3.5.2. 形成过程

自编码器起源于神经网络和深度学习的发展。

它是一种特殊的神经网络结构,由两部分组成:

  • 编码器:编码器负责将输入数据压缩成一个较低维度的表示
  • 解码器:解码器则负责从这个低维表示中恢复原始数据。

在训练过程中,自编码器的目标是让输出尽可能接近输入,从而学习到输入数据的有效表示。

3.5.3. 运行原理

3.5.3.1.运行原理及基本框架
  • 编码器:接收原始输入数据,并通过一系列神经网络层将其压缩成一个较低维度的隐藏表示(也称为编码)。这个过程通常涉及线性变换和非线性激活函数的应用。
  • 解码器:接收编码器的输出(即隐藏表示),并通过另一系列神经网络层尝试重构原始输入数据。解码器的目标是尽可能准确地还原原始输入。
  • 训练:通过反向传播算法和优化方法(如梯度下降)来训练自编码器。训练过程中,模型会尝试最小化输入数据和重构数据之间的差异,通常使用均方误差(MSE)等损失函数来衡量这种差异。

在游戏AI中,自编码器(AE)算法并没有特定的数学公式,因为它是一个神经网络结构,由编码器和解码器两部分组成,通过训练来优化模型的参数。然而,我们可以描述其关键组成部分和前向传播的过程。

编码器

编码器部分通常是一个或多个神经网络层,它将输入数据 (x) 映射到一个隐藏表示 (h)。这个过程可以用以下方式表示(尽管这不是一个具体的数学公式):

[ h = f(x; \theta_e) ]

其中,(f) 是编码器的神经网络函数,(\theta_e) 是编码器的参数(如权重和偏置),(x)是输入数据,(h)是得到的隐藏表示。

解码器

解码器部分也是一个或多个神经网络层,它将隐藏表示 (h) 映射回与原始输入数据维度相同的重构数据 (r)。这个过程可以表示为:

[ r = g(h; \theta_d) ]

其中,(g)是解码器的神经网络函数,(\theta_d) 是解码器的参数,(h)是编码器的输出(即隐藏表示),(r) 是重构的数据。

自编码器的训练

自编码器的训练目标是最小化输入数据(x) 和重构数据 (r) 之间的差异。这通常通过优化一个损失函数(如均方误差MSE)来实现:

[ \text{MSE}(x, r) = \frac{1}{n} \sum_{i=1}{n} (x_i - r_i)2 ]

其中,(n)是输入数据的维度,(x_i)(r_i) 分别是输入数据和重构数据在第(i) 维上的值。

需要注意的是,自编码器的具体实现和公式可能会因应用场景、网络结构和优化目标的不同而有所变化。上述描述和公式提供了一个基本的框架和概念。

3.5.3.2. 示例代码

在游戏AI或任何其他领域中,自编码器(Autoencoder, AE)的实现主要涉及深度学习框架,如TensorFlow或PyTorch。

由于C++不是深度学习领域的主流语言,直接使用C++来实现自编码器可能比较复杂,并且通常需要依赖额外的库,如Dlib或Tiny-DNN。(C++也有不擅长的部分哦)

下面,我将给出使用Python和PyTorch实现自编码器的示例代码,并提供C++使用Tiny-DNN库实现自编码器的基本框架。

Python代码

import torch  
import torch.nn as nn  
import torch.optim as optim  # 定义自编码器模型  
class Autoencoder(nn.Module):  def __init__(self, input_dim):  super(Autoencoder, self).__init__()  self.encoder = nn.Sequential(  nn.Linear(input_dim, 64),  nn.ReLU(),  nn.Linear(64, 32)  )  self.decoder = nn.Sequential(  nn.Linear(32, 64),  nn.ReLU(),  nn.Linear(64, input_dim)  )  def forward(self, x):  x = self.encoder(x)  x = self.decoder(x)  return x  # 设定输入维度  
input_dim = 784  # 例如,使用28x28的MNIST图像  
model = Autoencoder(input_dim)  # 定义损失函数和优化器  
criterion = nn.MSELoss()  
optimizer = optim.Adam(model.parameters())  # 假设我们有一些训练数据X_train  
# X_train = ... (需要加载或生成数据)  # 训练自编码器  
for epoch in range(num_epochs):  for data in dataloader:  # 假设dataloader是加载训练数据的DataLoader  inputs, _ = data  optimizer.zero_grad()  outputs = model(inputs)  loss = criterion(outputs, inputs)  loss.backward()  optimizer.step()  print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item()}')

C++代码

在C++中,你可以使用Tiny-DNN这样的库来构建和训练神经网络。以下是一个简化的自编码器实现框架:

#include <tiny_dnn/tiny_dnn.h>  using namespace tiny_dnn;  
using namespace tiny_dnn::layers;  int main() {  // 创建网络模型  network<sequential> net;  net << fc(784, 64)  // 编码器第一层  << relu()      // 激活函数  << fc(64, 32)  // 编码器第二层  << relu()      // 激活函数  << fc(32, 64)  // 解码器第一层  << relu()      // 激活函数  << fc(64, 784); // 解码器第二层  // 设置优化器和损失函数  adam optimizer;  mse_loss loss;  // 假设你已经有了一些训练数据  // std::vector<vec_t> train_data; // 输入数据  // std::vector<vec_t> train_labels; // 这里的“标签”实际上就是输入数据,因为我们要重构它  // 训练网络  for (int epoch = 0; epoch < num_epochs; epoch++) {  for (size_t i = 0; i < train_data.size(); i++) {  const auto& in = train_data[i];  const auto& target = train_labels[i]; // 在自编码器中,标签就是输入  net.train_once(in, target, optimizer, loss);  }  // 可以添加一些代码来打印损失或验证误差等  }  return 0;  
}

C++代码是一个简化的框架,你需要自己添加数据加载、预处理和后处理逻辑。此外,Tiny-DNN库需要单独安装,并且可能需要根据你的系统环境进行配置。

在实际应用中,你可能还需要调整网络结构、学习率、批次大小等参数以获得最佳性能。此外,对于大规模数据集或复杂模型,通常建议使用Python和成熟的深度学习框架(如PyTorch或TensorFlow),因为这些框架提供了更丰富的功能和更高效的计算性能。

3.5.4. 优缺点

  • 优点

    • 无监督学习:自编码器是一种无监督学习方法,不需要标注数据,因此适用于大量未标注数据的场景。
    • 数据降维和特征提取:自编码器能够学习到输入数据的高效表示,从而实现数据的降维和特征提取。
    • 泛化能力强:由于自编码器是从数据中学习压缩和解压缩函数的,因此它具有一定的泛化能力,可以处理与训练数据类似的新数据。
  • 缺点

    • 对异常数据敏感:在异常检测等任务中,自编码器可能难以处理与训练数据分布差异较大的异常数据。
    • 训练数据需求:为了训练出有效的自编码器模型,通常需要大量的训练数据。此外,在异常识别等特定任务中,训练数据需要为正常数据,以确保模型能够学习到正常的数据分布。

3.5.5. 存在的问题和解决方法

以下讨论2种常见的问题,欢迎评论区探讨更多的问题和解决方法

问题1:自编码器可能无法很好地处理复杂的非线性关系或高度变化的数据分布。

解决方法:可以采用更复杂的神经网络结构(如深度自编码器、卷积自编码器等)或引入其他技术(如正则化、dropout等)来提高模型的复杂度和泛化能力。

问题2:在异常检测任务中,自编码器可能难以准确识别出与训练数据分布差异较大的异常数据。

解决方法:可以结合其他异常检测技术(如基于密度的方法、基于距离的方法等)来提高异常检测的准确性。此外,还可以尝试使用变分自编码器(VAE)等生成模型来生成可能的异常样本,从而增强模型对异常的识别能力。

3.5.6. 应用于游戏AI

自编码器(Autoencoder, AE)在游戏AI中有多种应用场景,以下是一些实际应用场景及其相应的Python代码示例。

3.5.6.1. 实际应用场景
  1. 特征降维与数据压缩
    游戏中的数据往往维度很高,例如玩家的行为数据、游戏场景的状态等。自编码器可以用于将这些高维数据压缩到较低的维度,同时保留重要特征,便于后续的分析和处理。

  2. 异常检测
    通过训练自编码器来重构正常行为的数据,当输入异常数据时,自编码器的重构误差会显著增大,从而可以用于检测游戏中的异常行为,如作弊、外挂等。

  3. 生成模型
    自编码器可以用作生成模型的一部分,生成新的游戏内容,如地图、角色或物品等。这在游戏设计和测试中非常有用。

  4. 预测与决策支持
    利用自编码器提取的特征可以输入到其他机器学习模型中,用于玩家行为预测、游戏结果预测等,从而辅助游戏AI做出更智能的决策。

3.5.6.2. Python代码示例(特征降维)

以下是一个简单的自编码器实现,用于特征降维和数据压缩。

import torch  
import torch.nn as nn  
import torch.optim as optim  
from torch.utils.data import DataLoader, TensorDataset  # 假设我们有一些高维游戏数据  
# X_train 为训练数据,形状为 (n_samples, input_dim)  
# 这里只是一个示例,你需要用实际的游戏数据替换它  
input_dim = 100  # 假设输入维度为100  
n_samples = 1000  # 假设有1000个样本  
X_train = torch.randn(n_samples, input_dim)  # 生成随机数据作为示例  # 定义自编码器模型  
class Autoencoder(nn.Module):  def __init__(self, input_dim, encoding_dim):  super(Autoencoder, self).__init__()  self.encoder = nn.Sequential(  nn.Linear(input_dim, encoding_dim),  nn.ReLU(True)  )  self.decoder = nn.Sequential(  nn.Linear(encoding_dim, input_dim),  nn.Sigmoid()  # 如果输入数据被归一化到[0,1],则使用Sigmoid作为激活函数  )  def forward(self, x):  x = self.encoder(x)  x = self.decoder(x)  return x  # 设置编码维度  
encoding_dim = 32  # 压缩后的维度  
model = Autoencoder(input_dim, encoding_dim)  
criterion = nn.MSELoss()  
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 创建数据加载器  
dataset = TensorDataset(X_train)  
dataloader = DataLoader(dataset, batch_size=64, shuffle=True)  # 训练自编码器  
num_epochs = 100  
for epoch in range(num_epochs):  for data in dataloader:  inputs, = data  optimizer.zero_grad()  outputs = model(inputs)  loss = criterion(outputs, inputs)  loss.backward()  optimizer.step()  print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item()}')  # 使用训练好的自编码器对游戏数据进行压缩和解压  
compressed = model.encoder(X_train)  
reconstructed = model.decoder(compressed)

上面示例中,我们创建了一个简单的自编码器,它由一个编码器和一个解码器组成。编码器将输入数据从100维压缩到32维,然后解码器尝试从这32维重构原始100维数据。

通过训练自编码器来最小化重构误差,我们可以得到一个能够有效压缩和解压游戏数据的模型。(C++的暂时没搞出来,先不放了)

3.5.6.3. 用于反作弊检测
3.5.6.3.1. 反作弊检测基本方法

在游戏AI中使用自编码器(AE)进行反作弊检测时,基本思路是训练自编码器来重构正常玩家的行为数据。

作弊行为的数据通常与正常行为模式差异较大,因此当输入作弊数据时,自编码器的重构误差会相对较高。通过设定一个阈值,可以检测出可能的作弊行为。

以下是一个简化的Python代码示例,展示了如何使用自编码器进行反作弊检测:

import torch  
import torch.nn as nn  
import torch.optim as optim  
from sklearn.model_selection import train_test_split  
from sklearn.metrics import mean_squared_error  # 假设我们已经有了一组玩家的正常行为数据  
# X 为正常行为数据,形状为 (n_samples, input_dim)  
# 这里使用随机数据作为示例  
input_dim = 50  # 假设输入数据的维度是50  
n_samples = 1000  # 假设有1000个正常行为样本  
X = torch.randn(n_samples, input_dim)  # 生成随机数据作为正常行为数据示例  # 定义自编码器模型  
class Autoencoder(nn.Module):  def __init__(self, input_dim):  super(Autoencoder, self).__init__()  self.encoder = nn.Sequential(  nn.Linear(input_dim, 256),  nn.ReLU(),  nn.Linear(256, 128),  nn.ReLU(),  nn.Linear(128, 64)  )  self.decoder = nn.Sequential(  nn.Linear(64, 128),  nn.ReLU(),  nn.Linear(128, 256),  nn.ReLU(),  nn.Linear(256, input_dim),  nn.Sigmoid()  # 假设输入数据已被归一化到[0, 1]  )  def forward(self, x):  x = self.encoder(x)  x = self.decoder(x)  return x  # 初始化模型、损失函数和优化器  
model = Autoencoder(input_dim)  
criterion = nn.MSELoss()  
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 分割数据集为训练集和测试集  
X_train, X_test = train_test_split(X, test_size=0.2, random_state=42)  # 训练自编码器  
num_epochs = 100  
for epoch in range(num_epochs):  optimizer.zero_grad()  outputs = model(X_train)  loss = criterion(outputs, X_train)  loss.backward()  optimizer.step()  if (epoch + 1) % 10 == 0:  print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item()}')  # 在测试集上评估自编码器  
X_test_reconstructed = model(X_test)  
test_mse = mean_squared_error(X_test.detach().numpy(), X_test_reconstructed.detach().numpy())  
print(f'Test MSE: {test_mse}')  # 设定作弊检测的阈值  
threshold = test_mse * 2  # 这里的阈值是示例值,实际应用中需要根据情况调整  # 假设我们有一些待检测的数据(可能是作弊数据)  
# X_check 形状为 (n_check_samples, input_dim)  
X_check = torch.randn(10, input_dim)  # 使用随机数据作为待检测数据的示例  
X_check_reconstructed = model(X_check)  
check_mse = nn.MSELoss()(X_check, X_check_reconstructed).item()  # 判断是否存在作弊行为  
if check_mse > threshold: print("可能的作弊行为被检测到!")  
else:  print("未检测到作弊行为。")

在这个示例中,我们首先定义了一个自编码器模型,并使用正常行为数据进行训练。

训练完成后,我们在测试集上评估模型的性能,并根据测试集上的重构误差设定一个阈值。

最后,我们使用这个阈值来检测待检查数据中是否存在作弊行为。

如果重构误差超过了设定的阈值,则可能表示存在作弊行为。

3.5.6.3.2. 阈值的设定

自编码器(AE)算法在游戏AI中用于反作弊检测时,测试集上的重构误差设定阈值的方法至关重要。

  • 阈值设定方法
  • 基于统计分布:分析测试集上的重构误差分布,可以选择一个合适的阈值,如平均值加上若干倍的标准差,来区分正常行为与异常行为。
  • 基于业务需求:根据实际业务需求和安全容忍度,设定一个可接受的最高重构误差作为阈值。
  • 交叉验证:通过交叉验证的方式,在不同的测试集上评估自编码器的性能,并根据多次实验的结果来确定一个稳定的阈值。
  • 专家判断:结合领域专家的知识和经验,对重构误差的阈值进行设定和调整。(通常,游戏公司或游戏开发者会招募专业玩家或者头部玩家进行内测和公测,同时也会长期招募反作弊专业玩家对训练数据进行标注,标注后的数据用于训练和调整阈值。当然,游戏公司或游戏开发者也会故意创造作弊器和作弊方法,用来帮助算法进行反作弊训练。~~~~~~~~小声说,有些不太OK的具有编程能力的玩家也会监守自盗偷偷的做一些不法的东东,鄙视
  • 阈值调整与优化
  • 在实际应用中,根据反馈和效果不断调整阈值,以达到最佳的反作弊检测效果。
  • 可以考虑使用动态阈值,即根据实时数据或周期性评估来调整阈值。
  • 作弊行为检测
  • 对于新的游戏行为数据,使用训练好的自编码器进行重构,并计算重构误差。
  • 如果重构误差超过设定的阈值,则将该行为标记为可能的作弊行为,进行进一步的审查和处理。

本篇先聊到这里,后面慢慢填坑接着聊 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/33754.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[ios逆向]查看ios安装包ipa签名证书embedded.mobileprovision解密 附带解密环境openssl

openssl smime -inform der -verify -noverify -in embedded.mobileprovision 解密embedded.mobileprovision文件 链接&#xff1a;https://pan.baidu.com/s/1UwNOWONKV1SNj5aX_ZZCzQ?pwdglco 提取码&#xff1a;glco –来自百度网盘超级会员V8的分享 可以使用everything 查看…

matlab绘制二维曲线,如何设置线型、颜色、标记点类型、如何设置坐标轴、matlab 图表标注、在图中标记想要的点

matlab绘制二维曲线&#xff0c;如何设置线型、颜色、标记点类型、如何设置坐标轴、matlab 图表如何标注、如何在图中标记想要的点 matlab绘制二维曲线&#xff0c;如何在图中标记想要的点。。。如何设置线型、颜色、标记点类型。。。如何设置坐标轴。。。matlab 图表标注操作…

计算机系统基础知识(上)

目录 计算机系统的概述 计算机的硬件 处理器 存储器 总线 接口 外部设备 计算机的软件 操作系统 数据库 文件系统 计算机系统的概述 如图所示计算机系统分为软件和硬件&#xff1a;硬件包括&#xff1a;输入输出设备、存储器&#xff0c;处理器 软件则包括系统软件和…

山东大学-科技文献阅读与翻译(期末复习)(选择题+翻译)

目录 选择题 Chapter1 1.which of the following is not categorized as scientific literature 2.Which of the followings is defined as tertiary(三级文献) literature? 3.Which type of the following international conferences is listed as Number one conference…

如何做好药店布局,实现客流回归?

随着我国医药市场的不断发展&#xff0c;药店数量逐年增多&#xff0c;竞争愈发激烈。在这种背景下&#xff0c;如何做好药店布局&#xff0c;吸引客流回归&#xff0c;成为药店经营者关注的核心问题。 要想实现店铺形象美观大方、有效引导客流动向&#xff0c;增加顾客在店内…

TDengine 推出新连接器,与 Wonderware Historian 无缝连接

在最新发布的TDengine 3.2.3.0 版本中&#xff0c;我们进一步更新了 TDengine 的数据接入功能&#xff0c;推出了一款新的连接器&#xff0c;旨在实现 Wonderware Historian&#xff08;现称为 AVEVA Historian&#xff09;与 TDengine 的集成。这一更新提供了更加便捷和高效的…

设计模式5-策略模式(Strategy)

设计模式5-策略模式 简介目的定义结构策略模式的结构要点 举例说明1. 策略接口2. 具体策略类3. 上下文类4. 客户端代码 策略模式的反例没有使用策略模式的代码 对比分析 简介 策略模式也是属于组件协作模式一种。现代软件专业分工之后的第一个结果是框架语音应用程序的划分。组…

Linux文件IO操作的学习

文件IO&#xff1a; 文件描述符最小是0&#xff0c;非负数 Open的返回值是3&#xff0c;因为0&#xff0c;1&#xff0c;2被占用了。 read&#xff1a; 使用read和write实现cat操作 实现cp复制操作&#xff1a; 生成与原文件大小一致的空洞文件 文件IO和标准IO互相转换可以使用…

OnlyOffice-8.1版本深度测评

2024年6月19日&#xff0c;ONLYOFFICE 发布了最新版本 8.1&#xff0c;带来了超过30项新功能和432个 bug 修复。本文将详细评测该版本的新功能和改进&#xff0c;帮助用户全面了解这一升级带来的实际体验提升。 一、功能全面的 PDF 编辑器 PDF 是日常工作中不可或缺的文件格式…

上海展会闭幕RFID技术助力档案管理

上海国际智慧档案展于近日圆满落幕&#xff0c;各参展企业在展会上展示了最新的档案管理技术和解决方案。其中&#xff0c;铨顺宏以其创新的技术和出色的表现&#xff0c;吸引了众多业内人士和观众的关注。 在此次展会上&#xff0c;铨顺宏展示了其全新的RFID智能档案管理。能够…

哈啰集团全面接入通义灵码,AI 生成代码占比 20%,研发提效 12%

6 月 21 日&#xff0c;在阿里云 AI 智领者峰会上海站&#xff0c;哈啰集团算法总监贾立宣布&#xff0c; 哈啰集团已全面接入阿里云通义灵码专属版&#xff0c; 不仅提升了内部研发效率&#xff0c;实现 AI 代码采用率超过 20%&#xff0c;还将灵码接入了哈啰自研 Copilot “海…

【CPP】插入排序:直接插入排序、希尔排序

目录 1.插入排序1.1直接插入排序简介代码分析 1.2直接插入对比冒泡排序简介代码对比分析(直接插入排序与冒泡的复杂度效率区别) 1.3希尔排序简介代码分析 1.插入排序 基本思想&#xff1a;把一个待排数字按照关键码值插入到一个有序序列中&#xff0c;得到一个新的有序序列。 …

“Cannot resolve ch.qos.logback:logback-classic:1.2.3”问题解决办法

当我们添加依赖配置时&#xff0c;通常会遇见如下错误&#xff1a; 这个问题是由于项目中使用了 logback-classic 版本1.2.3&#xff0c;但是无法从当前所配置的仓库中解析到这个特定的版本。可以尝试检查依赖配置&#xff0c;确保指定的仓库中包含了 logback-classic 版本1.2.…

MCU的最佳存储方案CS创世 SD NAND

大家都知道MCU是一种"麻雀"虽小&#xff0c;却"五脏俱全"的主控。它的应用领域非常广泛&#xff0c;小到手机手表&#xff0c;大到航空航天的设备上都会用到MCU.市面上目前几个主流厂商有意法半导体&#xff08;其中最经典的一款就是STM32系列&#xff09;…

【思科】IPv6 过渡技术 - IPv6 in IPv4隧道

【思科】IPv6 过渡技术 - IPv6 in IPv4隧道 实验要求实现思路IPv6 in IPv4 与 GRE 不同点注意点配置R1基础配置OSPFv3 局域网可达 R2基础配置局域网环境(OSPFv3)&#xff1a;IPv6 网络IPv6 in IPv4隧道 R3R4基础配置局域网环境(OSPFv3)&#xff1a;IPv6 网络IPv6 in IPv4隧道 R…

【机器学习】——【线性回归模型】——详细【学习路线】

目录 1. 引言 2. 线性回归理论基础 2.1 线性模型概述 2.2 最小二乘法 3. 数学基础 3.1 矩阵运算 3.2 微积分 3.3 统计学 4. 实现与应用 4.1 使用Scikit-learn实现线性回归 4.2 模型评估 5. 深入理解 5.1 多元线性回归 5.2 特征选择 5.3 理解模型内部 6. 实战与项…

算法学习DAY01

目录 一、算法优劣的核心指标 二、常数时间操作 1、常见的常数时间的操作 2、位运算 &#xff08;1&#xff09;&#xff08;<<&#xff09;左移运算符 &#xff08;2&#xff09;&#xff08;>>&#xff09;右移运算符 &#xff08;3&#xff09;&#xff0…

第27课 原理图的简介

什么是原理图&#xff1f; 原理图就是由元器件连接而成的电路图&#xff0c;它表征了你所设计电路的基本原理。 原理图上的所有元器件&#xff0c;都要从你所画好的元器件符号库中调用。元器件的信息会显示在原理图上&#xff0c;如型号、位号、特性值等。 按照我们的设计&am…

WPF/C#:数据绑定到方法

在WPF Samples中有一个关于数据绑定到方法的Demo&#xff0c;该Demo结构如下&#xff1a; 运行效果如下所示&#xff1a; 来看看是如何实现的。 先来看下MainWindow.xaml中的内容&#xff1a; <Window.Resources><ObjectDataProvider ObjectType"{x:Type local…

【2024.6.25】今日 IT之家精选新闻

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…