FinalMLP:用于推荐系统的简单但强大的双流 MLP 模型

原文地址:FinalMLP: A Simple yet Powerful Two-Stream MLP Model for Recommendation Systems

了解 FinalMLP 如何转变在线推荐:通过尖端 AI 研究解锁个性化体验

2024 年 2 月 14 日

介绍

世界正在向数字时代发展,在这个时代,每个人都可以通过点击距离获得几乎所有他们想要的东西。可访问性、舒适性和大量的产品为消费者带来了新的挑战。我们如何帮助他们获得个性化的选择,而不是在浩瀚的选择海洋中搜索?这就是推荐系统的用武之地。

推荐系统可以帮助组织增加交叉销售和长尾产品的销售,并通过分析客户最喜欢什么来改进决策。不仅如此,他们还可以学习过去的客户行为,给定一组产品,根据特定的客户偏好对它们进行排名。使用推荐系统的组织在竞争中领先一步,因为它们提供了增强的客户体验。

在本文中,我们将重点介绍FinalMLP,这是一个旨在提高在线广告和推荐系统中点击率(CTR)预测的新模型。通过将两个多层感知器(MLP)网络与门控和交互聚合层等高级功能集成在一起,FinalMLP优于传统的单流MLP模型和复杂的双流CTR模型。作者通过基准数据集和现实世界的在线A/B测试测试了它的有效性。

除了提供FinalMLP及其工作原理的详细视图外,我们还提供了实现和将其应用于公共数据集的演练。我们在一个图书推荐设置中测试了它的准确性,并评估了它解释预测的能力,利用作者提出的两流架构。

FinalMLP: (F)特征门控层和(IN)交互层(A)聚合层(L)在两个mlp之上

FinalMLP[1]是建立在DualMLP[2]之上的两流多层感知器(MLP)模型,通过引入两个新概念对其进行增强:

  • 基于门控的特征选择增加了两个流之间的区别,使每个流专注于从不同的特征集学习不同的模式。例如,一个流侧重于处理用户特征,而另一个流侧重于处理项目特征。
  • 多头双线性融合改进了两个流的输出如何通过建模特征交互进行组合。使用依赖于求和或串联等线性操作的传统方法可能不会发生这种情况。

    img

Figure 2: FinalMLP architecture (source)

它是如何工作的?

如前所述,FinalMLP是由两个简单并行的MLP网络组成的两流CTR模型,从不同的角度学习特征交互,它由以下关键组件组成:

特征embedding 是一种将高维和稀疏的原始特征映射到密集数字表示的常用方法。无论是分类的、数值的还是多值的,每个特征都被转换成一个embedding向量并连接起来,然后再输入feature Selection模块。

将Categorical Features转换为单热特征向量,并与词汇量n、embedding维数d的可学习embedding矩阵相乘,生成其嵌入[3]。

数值特征可以通过以下方式转换为嵌入:1)将数值存储为离散特征,然后将它们作为分类特征处理,或者2)给定标准化标量值xj,embedding可以作为xj与vj 的乘法, vj 是j域中所有特征的共享embedding向量[3].

多值 f特征可以表示为将值序列转换为长度为k的单热编码向量(k为序列的最大长度),然后乘以一个可学习的embedding矩阵来生成其嵌入[3]。

img

图3:每种特征类型的embedding创建(由作者提供的图像)

The feature Selection Layer用于获取特征重要性权重,以抑制噪声特征,使重要特征对模型预测的影响更大。

如前所述,FinalMLP使用基于门控的特征选择,这是一个带有门控机制的MLP。它接收嵌入作为输入,并产生与输入相同维数的权重向量。特征重要性权重是通过对权重向量应用sigmoid函数,然后对乘数2进行乘数,生成一个范围为[0,2]的向量来获得的。然后通过特征embedding与特征重要性权重的逐元素积得到加权特征。

这个过程减少了两个流之间的同质学习,使特征交互的学习更加互补。它被独立地应用于每个流,以区分每个流的特征输入,并允许它们专注于用户或项目维度。

img

图4:使用独立MLP的特征选择过程,每个流都有一个门控机制(图片来自作者)

流级融合层需要结合两个流的输出,以获得最终的预测概率。通常,组合两个输出依赖于求和或连接操作。然而,FinalMLP的作者提出了一个双线性交互聚合层,将两个输出结合起来,从特征交互中获得线性组合可能无法获得的信息。

受transformers结构中的注意力层的启发,作者将双线性融合扩展为多头双线性融合层。它用于降低计算复杂度和提高模型的可扩展性。

双线性融合方程包括:

img

方程1:双线性融合方程

其中σ是一个s型函数,b是偏置项,01是一个流的输出。w1是要应用到o1的可学习权值,o2是另一个流的输出,w2是要应用到o2的可学习权值。最后,w3为提取特征交互信息的双线性项中的可学习矩阵。如果将w3设置为零矩阵,则退化为传统的串联融合。

双线性融合多头双线性融合的区别在于,它不是使用来自两个流的整个向量应用双线性融合,而是将输出o1o2chunks到k子空间中。在每个子空间中进行双线性融合,聚合并馈送s型函数以产生最终概率。

图5:多头双线性融合的实践(图片来源:作者)

使用FinalMLP创建图书推荐模型

在本节中,我们将在许可CC0:公共领域下的Kaggle的公共数据集上实现FinalMLP。该数据集包含有关用户、图书以及用户对图书的评分的信息。

该数据集由以下内容组成:

  • User-ID —用户标识
  • Location —以逗号分隔的字符串,包含用户所在的城市、州和国家
  • Age — 用户的年龄
  • ISBN — 图书标识符
  • Book-Rating — 用户对某本书的评分
  • Book-Title — 书的标题
  • Book-Author — 书的作者
  • Year-of-Publication — 该书出版的年份
  • Publisher — 出版这本书的编辑

我们将根据与每个用户的相关性对图书进行排名。之后,我们使用归一化贴现累积增益(nDCG)将我们的排名与实际排名进行比较(根据用户给出的评级对图书进行排序)。

nDCG是一种评估推荐系统质量的度量标准,它根据结果的相关性来衡量结果的排名。它考虑每个项目的相关性及其在结果列表中的位置,排名越高,重要性越大。nDCG的计算方法是将折扣累积收益(DCG)与理想DCG (iDCG)进行比较,后者是将排名较低的物品的收益进行折扣,而理想DCG是给出完美排名的最高可能DCG。这个标准化分数的范围在0到1之间,其中1表示理想的排名顺序。因此,nDCG为我们提供了一种理解系统如何有效地向用户呈现相关信息的方法。

我们从导入库开始:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
%matplotlib inline
%load_ext autoreload
%autoreload 2
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import random
from sklearn.metrics import ndcg_score
from sklearn.decomposition import PCA
from sentence_transformers import SentenceTransformer
import os
import logging
from fuxictr.utils import load_config, set_logger, print_to_json
from fuxictr.features import FeatureMap
from fuxictr.pytorch.torch_utils import seed_everything
from fuxictr.pytorch.dataloaders import H5DataLoader
from fuxictr.preprocess import FeatureProcessor, build_dataset
import src
import gc
import os

然后,我们加载三个数据集并将它们合并为一个数据集:

1
2
3
4
5
6
books_df = pd.read_csv('data/book/Books.csv')
users_df = pd.read_csv('data/book/Users.csv')
ratings_df = pd.read_csv('data/book/Ratings.csv')df = pd.merge(users_df, ratings_df, on='User-ID', how='left')
df = pd.merge(df, books_df, on='ISBN', how='left')

之后,我们进行一些探索性数据分析,以识别数据中的问题:

  1. 删除用户对书没有评价的地方。
1
df = df[df['Book-Rating'].notnull()]
  1. 检查缺失的值并将缺失的Book-AuthorPublisher替换为unknown类别。
1
2
3
4
print(df.columns[df.isna().any()].tolist())df['Book-Author'] = df['Book-Author'].fillna('unknown')
df['Publisher'] = df['Publisher'].fillna('unknown')
  1. 删除书中缺失信息的评论。
1
df = df[df['Book-Title'].notnull()]
  1. 将非整数’出版年份’替换为空值。
1
df['Year-Of-Publication'] = pd.to_numeric(df['Year-Of-Publication'], errors='coerce')
  1. 检查“年龄”、“出版年份”和“图书评级”分布,以识别异常情况。
1
2
3
4
5
6
7
8
9
10
11
plt.rcParams["figure.figsize"] = (20,3)
sns.histplot(data=df, x='Age')
plt.title('Age Distribution')
plt.show()sns.histplot(data=df, x='Year-Of-Publication')
plt.title('Year-Of-Publication Distribution')
plt.show()
sns.histplot(data=df, x='Book-Rating')
plt.title('Book-Rating Distribution')
plt.show()

Figure 6: Data Distribution (image made by the author)

图6:数据分布(作者图片)

最后,我们通过以下方式清理数据:

  • 替换age > 100 (这似乎是一个错误),丢失的值稍后处理。
  • 将上限限制为2021年,因为这是数据集在Kaggle中发布的时间,并将Year-of-Publication <= 0 替换为稍后处理的缺失值。
  • 删除rating = 0的观察,因为这些书被用户阅读但没有评级。
  • 从“位置”创建3个新功能(“城市”,“州”,“国家”)。既然城市太吵了,我们就不去了。
  • 为FinalMLP创建一个二进制标签,我们考虑与用户相关的率高于7的书籍。
1
2
3
4
5
6
7
8
df['Age'] = np.where(df['Age'] > 100, None, df['Age'])df['Year-Of-Publication'] = np.where(df['Year-Of-Publication'].clip(0, 2021) <= 0, None, df['Year-Of-Publication'])
df = df[df['Book-Rating'] > 0]
df['city'] = df['Location'].apply(lambda x: x.split(',')[0].strip()) # too noisy, we will not use
df['state'] = df['Location'].apply(lambda x: x.split(',')[1].strip())
df['country'] = df['Location'].apply(lambda x: x.split(',')[2].strip())
df['label'] = (df['Book-Rating'] > 7)*1

清理数据集后,我们将数据分为训练、验证和测试,随机选择70%的用户进行训练,10%的用户进行验证,20%的用户进行测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
# create list with unique users
users = df['User-ID'].unique()# shuffle list
random.shuffle(users)
# create list of users to train, to validate and to test
train_users = users[:int(0.7*len(users))]
val_users = users[int(0.7*len(users)):int(0.8*len(users))]
test_users = users[int(0.8*len(users)):]
# train, val and test df
train_df = df[df['User-ID'].isin(train_users)]
val_df = df[df['User-ID'].isin(val_users)]
test_df = df[df['User-ID'].isin(test_users)]

在将数据输入模型之前,我们将对数据进行一些预处理:

我们使用多语言编码器为文本特征Book-Title创建嵌入,并使用PCA降低维度,解释了80%的方差。

我们使用多语言编码器,因为标题是用不同的语言编写的。请注意,我们首先提取不同的Book-title,以便在用户多于另一本书时不影响降维。

1
2
3
4
5
6
7
8
9
10
11
12
13
# create embeddings
train_embeddings = utils.create_embeddings(train_df.copy(), "Book-Title")
val_embeddings = utils.create_embeddings(val_df.copy(), "Book-Title")
test_embeddings = utils.create_embeddings(test_df.copy(), "Book-Title")# reduce dimensionality with PCA
train_embeddings, pca = utils.reduce_dimensionality(train_embeddings, 0.8)
val_embeddings = pca.transform(val_embeddings)
test_embeddings = pca.transform(test_embeddings)
# join embeddings to dataframes
train_df = utils.add_embeddings_to_df(train_df, train_embeddings, "Book-Title")
val_df = utils.add_embeddings_to_df(val_df, val_embeddings, "Book-Title")
test_df = utils.add_embeddings_to_df(test_df, test_embeddings, "Book-Title")

我们用中值填充数值特征的缺失值,并使用MinMaxScaler对数据进行归一化。

1
2
3
4
5
6
7
8
# set numerical columns
NUMERICAL_COLUMNS = [i for i in train_df.columns if "Book-Title_" in i] + ['Age', 'Year-Of-Publication']# define preprocessing pipeline and transform data
pipe = utils.define_pipeline(NUMERICAL_COLUMNS)
train_df[NUMERICAL_COLUMNS] = pipe.fit_transform(train_df[NUMERICAL_COLUMNS])
val_df[NUMERICAL_COLUMNS] = pipe.transform(val_df[NUMERICAL_COLUMNS])
test_df[NUMERICAL_COLUMNS] = pipe.transform(test_df[NUMERICAL_COLUMNS])

准备好提供给FinalMLP的所有数据后,我们必须创建两个yaml配置文件:dataset_config.yamlmodel_config.yaml

dataset_config.yaml负责定义模型中使用的特性。此外,它还定义了它们的数据类型(它们在embedding层中的处理方式不同)以及到训练集、验证集和测试集的路径。你可以看到配置文件的主要部分如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FinalMLP_book:data_root: ./data/book/feature_cols:-   active: truedtype: floatname: [Age, Book-Title_0, Book-Title_1, Book-Title_2, Book-Title_3, Book-Title_4, Book-Title_5, Book-Title_6, Book-Title_7,Book-Title_8, ...]type: numeric-   active: truedtype: strname: [Book-Author, Year-Of-Publication, Publisher, state, country]type: categoricalfill_na: unknownlabel_col: {dtype: float, name: label}min_categr_count: 1test_data: ./data/book/test.csvtrain_data: ./data/book/train.csvvalid_data: ./data/book/valid.csv

model_config.yaml负责设置模型的超参数。您还必须定义哪些流将处理用户特性,哪些流将处理项目特性。该文件应定义如下:

1
2
3
4
5
6
FinalMLP_book:dataset_id: FinalMLP_bookfs1_context: [Age, state, country]fs2_context: [Book-Author, Year-Of-Publication, Publisher, Book-Title_0, Book-Title_1, Book-Title_2, Book-Title_3,Book-Title_4, Book-Title_5, ...]model_root: ./checkpoints/FinalMLP_book/

我们回到Python并加载最近创建的配置文件。然后,我们创建特征映射(即,每个分类特征中有多少个类别,如果存在,它应该如何替换不同特征中的缺失值,等等)。我们将csv转换为h5文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Get model and dataset configurations
experiment_id = 'FinalMLP_book'
params = load_config(f"config/{experiment_id}/", experiment_id)
params['gpu'] = -1 # cpu
set_logger(params)
logging.info("Params: " + print_to_json(params))
seed_everything(seed=params['seed'])# Create Feature Mapping and convert data into h5 format
data_dir = os.path.join(params['data_root'], params['dataset_id'])
feature_map_json = os.path.join(data_dir, "feature_map.json")
if params["data_format"] == "csv":# Build feature_map and transform h5 datafeature_encoder = FeatureProcessor(**params)params["train_data"], params["valid_data"], params["test_data"] = \\build_dataset(feature_encoder, **params)
feature_map = FeatureMap(params['dataset_id'], data_dir)
feature_map.load(feature_map_json, params)
logging.info("Feature specs: " + print_to_json(feature_map.features))

之后,我们就可以开始模型的训练过程了。

1
2
3
4
5
6
model_class = getattr(src, params['model'])
model = model_class(feature_map, **params)
model.count_parameters() # print number of parameters used in modeltrain_gen, valid_gen = H5DataLoader(feature_map, stage='train', **params).make_iterator()
model.fit(train_gen, validation_data=valid_gen, **params)

最后,我们可以预测看不见的数据;我们只需要将批大小更改为1就可以对所有观察值进行评分。

1
2
3
4
# to score all observations
params['batch_size'] = 1
test_gen = H5DataLoader(feature_map, stage='test', **params).make_iterator()
test_df['score'] = model.predict(test_gen)

我们选择了一个有不止一本书评级的客户,并且每本书都有不同的评级,以实现没有关系的适当排名。它的nDCG分数是0.986362,因为我们放错了2本书,距离为1位。

我们还使用Recall来评估FinalMLP。召回率是一个度量系统从一个集合中识别所有相关项目的能力的度量,表示为从可用的所有相关项目中检索到的相关项目的百分比。当我们指定Recall@K(比如Recall@3)时,我们关注的是系统在前K个推荐中识别相关项目的能力。这种适应对于评估推荐系统至关重要,因为用户主要关注的是最热门的推荐。K的选择(例如,3)取决于典型的用户行为和应用程序的上下文。

如果我们看一下这个客户的Recall@3,我们有100%,因为另外三本相关的书被放在了前3个位置。

1
2
3
4
true_relevance = np.asarray([test_df[test_df['User-ID'] == 1113]['Book-Rating'].tolist()])
y_relevance = np.asarray([test_df[test_df['User-ID'] == 1113]['score'].tolist()])ndcg_score(true_relevance, y_relevance)

我们还计算了剩余测试集的nDCG分数,并将FinalMLP性能与CatBoost Ranker进行了比较,如图7所示。虽然这两个模型都表现得很好,但FinalMLP在这个测试集上的表现略好,每个用户的平均nDCG为0.963298,而CatBoost Ranker *only*达到了0.959977

img

图7:CatBoost Ranker与FinalMLP的nDCG对比(图片来源:作者)

在可解释性方面,该模型执行特征选择,使我们能够提取权重向量。然而,解释和理解每个特性的重要性并不简单。请注意,在embedding层之后,我们最终得到了一个930维的向量,这使得将其映射回原始特征变得更加困难。尽管如此,我们可以尝试通过提取每个流的输出经过线性处理后的绝对值来理解每个流的重要性,这些线性处理由前面提到的线性项给出,如公式2所示。

img

方程2:线性项

为此,我们需要更改 InteractionAggregation模块,并添加以下代码行来提取每一步后的线性转换值:

1
2
3
4
5
6
7
... 		  self.x_importance = []self.y_importance = []def forward(self, x, y):self.x_importance.append(torch.sum(torch.abs(self.w_x(x))))self.y_importance.append(torch.sum(torch.abs(self.w_y(y))))
...

经过训练后,我们可以预测并绘制出每个流的线性变换所产生的绝对值。如图8所示,项目流比用户流更重要。之所以会出现这种情况,是因为我们有更多关于物品的功能,但也因为用户功能非常普遍。

img

图8:用户流和项目流的重要性对比(作者图片)

结论

推荐系统通过提供个性化推荐和授权组织做出驱动增长和创新的数据驱动决策来增强用户体验。

在本文中,我们介绍了为推荐系统开发的最新模型之一。最后,mlp是一个具有两个独立网络的深度学习模型。每个网络都将其学习集中在两个不同视角中的一个:用户和项目。然后将从每个网络学习到的不同模式馈送到一个融合层,该融合层负责将每个网络的学习结合起来。它创建用户-项目对交互的单一视图,以生成最终分数。该模型在我们的用例中表现良好,击败了CatBoost Ranker。

请注意,算法的选择可能取决于您要解决的问题和您的数据集。对几种方法进行相互比较测试总是好的做法。您还可以考虑测试xDeepFM、AutoInt、hen或DLRM。

参考文献

[1] Kelong Mao, Jieming Zhu, Liangcai Su, Guohao Cai, Yuru Li, Zhenhua Dong. FinalMLP: An Enhanced Two-Stream MLP Model for CTR Prediction. arXiv:2304.00902, 2023.

[2] Jiajun Fei, Ziyu Zhu, Wenlei Liu, Zhidong Deng, Mingyang Li, Huanjun Deng, Shuo Zhang. DuMLP-Pin: A Dual-MLP-dot-product Permutation-invariant Network for Set Feature Extraction. arXiv:2203.04007, 2022.

[3] Jieming Zhu, Jinyang Liu, Shuai Yang, Qi Zhang, Xiuqiang He. BARS-CTR: Open Benchmarking for Click-Through Rate Prediction. arXiv:2009.05794, 2020.

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

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

相关文章

持安科技孙维伯:零信任在攻防演练下的最佳实践|DISCConf 2023

近日&#xff0c;在2023数字身份安全技术大会上&#xff0c;持安科技联合创始人孙维伯应主办方的特别邀请&#xff0c;发表了主题为“零信任在攻防演练下的最佳实践”的演讲。 孙维伯在2023数字身份安全技术大会上发表演讲 以下为本次演讲实录&#xff1a; 我是持安科技的联合…

【c++】 STL的组件简介与容器的使用时机

STL六大组件简介 STL提供了六大组件&#xff0c;彼此之间可以组合套用&#xff0c;这六大组件分别是:容器、算法、迭代器、仿函数、适配器&#xff08;配接器&#xff09;、空间配置器。 容器&#xff1a;各种数据结构&#xff0c;如vector、list、deque、set、map等,用来存放…

微信云开发-- Mac安装 wx-server-sdk依赖

第一次上传部署云函数时&#xff0c;会提示安装依赖wx-server-sdk 一. 判断是否安装wx-server-sdk依赖 先创建一个云函数&#xff0c;然后检查云函数目录。 如果云函数目录下只显示如下图所示三个文件&#xff0c;说明未安装依赖。 如果云函数目录下显示如下图所示四个文件&a…

EdgeX Foundry 边缘物联网中间件平台

文章目录 1.EdgeX Foundry2.平台架构3.平台服务3.1.设备服务3.2.核心服务3.3.支持服务3.4.应用服务3.5.安全服务3.6.管理服务 EdgeX Foundry # EdgeX Foundryhttps://iothub.org.cn/docs/edgex/ https://iothub.org.cn/docs/edgex/edgex-foundry/1.EdgeX Foundry EdgeX Found…

嵌入式 Linux 下的 LVGL 移植

目录 准备创建工程修改配置修改 lv_drv_conf.h修改 lv_conf.h修改 main.c修改 Makefile 编译运行更多内容 LVGL&#xff08;Light and Versatile Graphics Library&#xff09;是一个轻量化的、开源的、在嵌入式系统中广泛使用的图形库&#xff0c;它提供了一套丰富的控件和组件…

微软为金融界带来革命性突破——推出Microsoft 365中的下一代AI助手:Microsoft Copilot for Finance

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

雷龙CS SD NAND(贴片式TF卡)测评体验

前段时间有幸免费得到了雷龙出品的贴片式的TF卡的芯片及转接板&#xff0c;两片贴片式nand芯片&#xff0b;一个转接板&#xff0c;一种一个已让官方焊接完好&#xff1b;如下图所示&#xff1a; 正面&#xff1a; 背面&#xff1a; 通过转接板&#xff0c;可以将CS SD NAND(贴…

数电实验之流水灯、序列发生器

最近又用到了数电实验设计的一些操作和设计思想&#xff0c;遂整理之。 广告流水灯 实验内容 用触发器、组合函数器件和门电路设计一个广告流水灯&#xff0c;该流水灯由 8 个 LED 组成&#xff0c;工作时始终为 1 暗 7 亮&#xff0c;且这一个暗灯循环右移。 1) 写出设计过…

关于DisableIEToEdge插件闪退问题的解决方案

关于DisableIEToEdge插件闪退问题.今天终于测试找到最佳解决方案了&#xff01; 1.管理员权限运行Windows powershell. 2.执行一下两条命令修复系统环境 DISM.exe /Online /Cleanup-image /Restorehealth sfc /scannow 3.关闭Windows安全中心的所有安全选项。 4.管理员权限运行…

【计算机考研择校】四川大学vs电子科技大学哪个难度更大?

川大在文科&#xff0c;经管方面比科大强&#xff0c;医学在国内都很强。但工科方面特别是电子信息领域明显是科大强于川大。毕竟一个是综合大学&#xff0c;一个是工科大学不可同日而语。 就业上&#xff0c;电子科大在IT领域的社会声誉口碑不错。就业一向都很好。这个多问问…

张俊将出席用磁悬浮技术改变生活演讲

演讲嘉宾&#xff1a;张俊 空压机销售总监 亿昇(天津)科技有限公司 演讲题目&#xff1a;用磁悬浮技术改变生活 会议简介 “十四五”规划中提出&#xff0c;提高工业、能源领城智能化与信息化融合&#xff0c;明确“低碳经济”新的战略目标&#xff0c;热能产业是能源产业和…

Python环境下一种改进的基于梯度下降的自适应短时傅里叶变换

在数字信号处理技术中&#xff0c;傅里叶变换及其逆变换是一种信号时频分析方法。该方法将信号的时域描述及频域描述联系在一起&#xff0c;时域信号可通过正变换转变为频域信号&#xff0c;频域信号可通过逆变换转变为时域信号进行分析。但傅里叶变换及其逆变换是一种信号的整…

Linux/Centos 部署静态IP,解决无法访问目标主机、Destination Host Unreachable、无法ping通互联网的问题

Linux/Centos 部署IP&#xff0c;解决无法访问目标主机、Destination Host Unreachable、无法ping通互联网的问题 Linux/Centos 部署静态IP查物理机/自身电脑的IP设置VMware上的虚拟网络编辑器设置网卡IP&#xff0c;激活至此就可访问百度了 Linux/Centos 部署静态IP 需要注意…

软考基础知识2

1.DMA控制方式&#xff1a;直接内存存取。数据在内存与I/O设备间直接成块传送&#xff0c;不需要CPU的任何干涉&#xff0c;由DMA硬件直接执行完成。 例题&#xff1a; 2.程序计数器总是存下一个指令的地址。 例题&#xff1a; 3.可靠度的计算&#xff1a; 例题&#xff1a…

吸猫毛空气净化器哪个好?推荐除猫毛效果好宠物空气净化器品牌

当下有越来越多的家庭选择养宠物&#xff01;尽管家里变得更加温馨&#xff0c;但养宠可能会带来异味和空气中的毛发增多可能会带来健康问题&#xff0c;这是一个大问题&#xff01; 不想家里弥漫着异味&#xff0c;特别是来自宠物便便的味道&#xff0c;所以需要一款能够处理…

ABAP - SALV教程02 - 开篇:打开SALV的三种方式之二

全屏模式生成SALV的方式&#xff1a;http://t.csdnimg.cn/CzNLz本文讲解生成可控模式的SALV&#xff0c;该方式需要依赖自己创建屏幕的自定义控件区域&#xff08;Custom Control&#xff09;实现步骤&#xff1a;需要注意的点是SALV的实例对象和dispaly方法一定是在屏幕PBO事件…

利用IP地址识别风险用户:保护网络安全的重要手段

随着互联网的发展和普及&#xff0c;网络安全问题日益突出&#xff0c;各种网络诈骗、恶意攻击等风险不断涌现&#xff0c;给个人和企业的财产安全和信息安全带来了严重威胁。在这样的背景下&#xff0c;利用IP地址识别风险用户成为了保护网络安全的重要手段之一。IP数据云探讨…

JVM内存回收算法

1.1 引用计数法 每个对象创建的时候&#xff0c;会分配一个引用计数器&#xff0c;当这个对象被引用的时候计数器就加1&#xff0c;当不被引用或者引用失效的时候计数器就会减1。任何时候&#xff0c;对象的引用计数器值为0就说明这个对象不被使用了&#xff0c;就认为是“垃圾…

奇舞周刊第521期:“一切非 Rust 项目均为非法”

奇舞推荐 ■ ■ ■ 拜登&#xff1a;“一切非 Rust 项目均为非法” 科技巨头要为Coding安全负责。这并不是拜登政府对内存安全语言的首次提倡。“程序员编写代码并非没有后果&#xff0c;他们的⼯作⽅式于国家利益而言至关重要。”白宫国家网络总监办公室&#xff08;ONCD&…

在idea中用模板骨架初始创建maven管理的web项目时没有src有关的目录的解决方案

一.问题如下 二.解决方法 首先关闭当前项目&#xff0c;接着修改全局设置&#xff0c;重新创建项目 在VM Options中添加"-DarchetypeCataloginternal"&#xff0c;点击ok保存 点击创建&#xff0c;如果创建成功没报错且有src&#xff0c;就ok了。 当然如果出现以下…