DIN:引入注意力机制的深度学习推荐系统,

实验和完整代码

完整代码实现和jupyter运行:https://github.com/Myolive-Lin/RecSys--deep-learning-recommendation-system/tree/main

引言

在电商与广告推荐场景中,用户兴趣的多样性和动态变化是核心挑战。传统推荐模型(如Embedding & MLP)通过池化操作将用户历史行为压缩为固定长度的向量,导致用户兴趣表示过于静态化。为解决这一问题,阿里巴巴团队提出了深度兴趣网络(Deep Interest Network, DIN)通过自适应注意力机制动态建模用户兴趣,显著提升了点击率预测(CTR)的精度。本文将深入解析DIN的数学模型、结构设计及训练优化技术。

2. 问题定义与特征体系

特征结构(见表1):

类别特征组示例维度编码类型
用户画像性别、年龄低维(~10)One-hot
用户行为浏览商品ID高维(~10⁹)Multi-hot
广告属性商品ID、类目ID高维(~10⁷)One-hot
上下文时间、页面位置低维(~10)One-hot

用户行为特征(如visited_goods_ids)是多热编码(Multi-hot) 向量,包含丰富的兴趣信息,但传统池化方法无法捕捉其与候选广告的动态相关性。
这些特征的维度和稀疏性对模型的设计提出了巨大挑战。DIN 的创新之处在于如何有效地处理这些特征,并动态地捕捉用户兴趣。

3. Deep Interest Network(DIN)架构

DIN 的核心创新在于如何动态地建模用户兴趣。在基础模型中,用户兴趣的表示是通过 Pooling 层固定下来的,对于同一个用户,其兴趣向量在面对不同广告时保持不变。然而,这种表示方式无法捕捉用户兴趣的多样性和动态性。DIN 通过引入局部激活单元(Local Activation Unit),解决了这一问题。

3.1 局部激活单元

DIN 的关键在于局部激活单元的设计。它通过计算用户历史行为与候选广告的相关性,动态地生成用户兴趣的表示。具体来说,局部激活单元的输出是一个加权和:

v U ( A ) = f ( v A , e 1 , e 2 , … , e H ) = ∑ j = 1 H a ( e j , v A ) e j v_U(A) = f(v_A, e_1, e_2, \dots, e_H) = \sum_{j=1}^{H} a(e_j, v_A) e_j vU(A)=f(vA,e1,e2,,eH)=j=1Ha(ej,vA)ej

其中, { e 1 , e 2 , … , e H } \{e_1, e_2, \dots, e_H\} {e1,e2,,eH} 是用户行为的嵌入向量, v A v_A vA 是广告的嵌入向量, a ( ⋅ ) a(\cdot) a() 是一个前馈网络,用于计算激活权重。与传统的注意力机制不同,DIN 放弃了对权重进行归一化的操作,以保留用户兴趣的强度信息。

例如,假设一个用户的历史行为中有 90% 是服装相关,10% 是电子产品相关。当候选广告是 T 恤时,它会激活大部分与服装相关的行为,因此 v U v_U vU 的值会更大,表示用户对 T 恤的兴趣更强。

3.2 架构设计

DIN 的架构在基础模型的基础上引入了局部激活单元。对于用户行为特征,DIN 使用局部激活单元动态计算用户兴趣的表示,而其他部分的结构保持不变。这种设计使得用户兴趣的表示能够根据不同的广告动态变化,从而更准确地捕捉用户的兴趣。

架构如下:
在这里插入图片描述

王喆老师也给出DIN的另外一种形式如:
在这里插入图片描述


4. 基础模型:Embedding & MLP

以下是其基础架构——Embedding 和多层感知机(MLP)。

4.1 Embedding 层

由于输入特征是高维稀疏的二进制向量,Embedding 层的作用是将它们转换为低维密集的表示。对于第 i 个特征组 t i t_i ti,其 Embedding 字典 W i W_i Wi 的维度为 D × K i D \times K_i D×Ki,其中 D D D 是嵌入向量的维度, K i K_i Ki 是特征组的维度。Embedding 操作遵循表查找机制:

  • 如果 t i t_i ti 是 one-hot 向量,且第 j 个元素为 1,则嵌入表示为 e i = w i j e_i = w_{ij} ei=wij
  • 如果 t i t_i ti 是 multi-hot 向量,且第 i 1 , i 2 , … , i k i_1, i_2, \dots, i_k i1,i2,,ik 个元素为 1,则嵌入表示为一组向量 { e i 1 , e i 2 , … , e i k } \{e_{i1}, e_{i2}, \dots, e_{ik}\} {ei1,ei2,,eik}

4.2 Pooling 层和 Concat 层

由于用户行为的数量不同,multi-hot 特征向量的非零值数量会因实例而异。为了将这些可变长度的嵌入向量转换为固定长度的向量,通常使用 Pooling 层。最常见的 Pooling 方法是求和(sum pooling)和平均(average pooling):

e i = pooling ( e i 1 , e i 2 , … , e i k ) e_i = \text{pooling}(e_{i1}, e_{i2}, \dots, e_{ik}) ei=pooling(ei1,ei2,,eik)

通过 Pooling 层,所有特征组的嵌入向量被转换为固定长度的向量,然后通过 Concat 层拼接在一起,形成最终的特征表示。

4.3 MLP 和损失函数

MLP 是一个多层感知机网络,用于自动学习特征的组合。其目标函数通常采用负对数似然函数:

L = − 1 N ∑ ( x , y ) ∈ S [ y log ⁡ p ( x ) + ( 1 − y ) log ⁡ ( 1 − p ( x ) ) ] L = -\frac{1}{N} \sum_{(x,y) \in S} \left[ y \log p(x) + (1 - y) \log (1 - p(x)) \right] L=N1(x,y)S[ylogp(x)+(1y)log(1p(x))]

其中, S S S 是训练集, x x x 是输入特征, y ∈ { 0 , 1 } y \in \{0, 1\} y{0,1} 是标签, p ( x ) p(x) p(x) 是网络输出的点击概率。


5. 训练技术

在阿里巴巴的广告系统中,商品和用户的数量达到了数亿级别。训练如此大规模的深度网络是一个巨大的挑战。DIN 提出了两种重要的训练技术,以应对这一挑战。

5.1 小批量感知正则化(Mini-batch Aware Regularization)

由于亿级参数使用l2的消耗过大传统的正则化方法(如 ℓ 2 \ell_2 2 ℓ 1 \ell_1 1)难以直接应用。DIN 提出了一种小批量感知正则化方法,它只计算每个小批量中出现的特征参数的 ℓ 2 \ell_2 2 范数。具体来说:

L 2 ( W ) ≈ ∑ j = 1 K ∑ m = 1 B α m j n j ∥ w j ∥ 2 L_2(W) \approx \sum_{j=1}^{K} \sum_{m=1}^{B} \frac{\alpha_{mj}}{n_j} \|w_j\|^2 L2(W)j=1Km=1Bnjαmjwj2

其中, n j n_j nj表示在样本中特征id j 出现的数量, α m j \alpha_{mj} αmj 表示在第 m 个小批量中是否存在特征 j。B表示mini-batches数量, B m B_m Bm 表示第m个 mini-batch。这种方法大大减少了计算量,同时有效地防止了过拟合。

数。

5.2 数据自适应激活函数(Dice)

在深度学习中,激活函数的选择对模型的性能至关重要。DIN 提出了一种数据自适应激活函数 Dice,它通过输入数据的均值和方差动态调整激活函数的行为:

f ( s ) = p ( s ) ⋅ s + ( 1 − p ( s ) ) ⋅ α s f(s) = p(s) \cdot s + (1 - p(s)) \cdot \alpha s f(s)=p(s)s+(1p(s))αs

其中,

p ( s ) = 1 1 + e − s − E [ s ] Var [ s ] + ϵ p(s) = \frac{1}{1 + e^{-\frac{s - E[s]}{\sqrt{\text{Var}[s] + \epsilon}}}} p(s)=1+eVar[s]+ϵ sE[s]1

Dice 的设计使得激活函数能够根据输入数据的分布动态调整,从而更好地适应不同层的输入分布。

## ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fp0-xtjj-private.juejin.cn%2Ftos-cn-i-73owjymdk6%2F0e030454d23449aa9f37600b9437f096~tplv-73owjymdk6-jj-mark-v1%3A0%3A0%3A0%3A0%3A5o6Y6YeR5oqA5pyv56S-5Yy6IEAgTGV3aXMxMjM%3D%3Aq75.awebp%3Fpolicy%3DeyJ2bSI6MywidWlkIjoiOTkzNzkxMTQ0MTA2MTEifQ%253D%253D%5C%26rk3s%3De9ecf3d6%5C%26x-orig-authkey%3Df32326d3454f2ac7e96d3d06cdbb035152127018%5C%26x-orig-expires%3D1739634553%5C%26x-orig-sign%3DVYk9c9xMx6%252F3hKcodBJa2WPaRQQ%253D&pos_id=img-86Y0DFed-1739636550252)

6实验

原论文使用的Amazon Dataset,但是由于已经失效,于是使用DIN模型pytorch代码逐行细讲 给出的Amazon-100k数据集进行处理(注:免责声明: 本文使用的数据集为 Amazon-100k 数据集,该数据集来源不明确,且未能找到该数据集的原始出处。请读者在使用该数据集时注意遵循相应的版权和数据使用规定。

labeluserIDitemIDcateIDhist_item_listhist_cate_list
0AZPJ9LUT0FEPYB00AMNNTIALiterature & Fiction[0307744434, 0062248391, 0470530707, 097892462…][Books, Books, Books, Books, Books]
1AZPJ9LUT0FEPY0800731603Books[0307744434, 0062248391, 0470530707, 097892462…][Books, Books, Books, Books, Books]
0A2NRV79GKAU726B003NNV10ORussian[0814472869, 0071462074, 1583942300, 081253836…][Books, Books, Books, Books, Baking, Books, Books, Books]
1A2NRV79GKAU726B000UWJ91OBooks[0814472869, 0071462074, 1583942300, 081253836…][Books, Books, Books, Books, Baking, Books, Books, Books]
0A2GEQVDX2LL4V30321334094Books[0743596870, 0374280991, 1439140634, 0976475731][Books, Books, Books, Books]
0A3CV7NJJC20JTB098488789XBooks[034545197X, 0765326396, 1605420832, 1451648448][Books, Books, Books, Books]
1A3CV7NJJC20JTB0307381277Books[034545197X, 0765326396, 1605420832, 1451648448][Books, Books, Books, Books]
0A208PSIK2APSKN0957496184Books[0515140791, 147674355X, B0055ECOUA, B007JE1B1…][Books, Books, Bibles, Literature & Fiction, Literature & Fiction]
1A208PSIK2APSKN1480198854Books[0515140791, 147674355X, B0055ECOUA, B007JE1B1…][Books, Books, Bibles, Literature & Fiction, Literature & Fiction]
0A1GRLKG8JA19OAB0095VGR4ILiterature & Fiction[031612091X, 0399163832, 1442358238, 1118017447][Books, Books, Books, Books]

使用Ordinal Encoding处理后得到:

使用Ordinal_itemID,Ordinal_cateID经过Embedding后拼接成的向量来表示目标向量

labelOrdinal_userIDOrdinal_itemIDOrdinal_cateIDOrdinal_hist_item_listOrdinal_hist_cate_list
04491768074419[206424, 142847, 182786, 69605, 197011][386, 386, 386, 386, 386]
144917101880386[206424, 142847, 182786, 69605, 197011][386, 386, 386, 386, 386]
0198046163264[78315, 2890, 54255, 137135, 124338][386, 386, 300, 386, 386]
11980421400386[78315, 2890, 54255, 137135, 124338][386, 386, 300, 386, 386]
017385220405386[0, 30271, 97772, 12556, 137554][0, 386, 386, 386, 386]
028177210244386[0, 98594, 185606, 19190, 15365][0, 386, 386, 386, 386]
12817716915386[0, 98594, 185606, 19190, 15365][0, 386, 386, 386, 386]
01219323175386[24471, 189598, 130748, 33111, 100134][386, 386, 365, 419, 419]
112193114216386[24471, 189598, 130748, 33111, 100134][386, 386, 365, 419, 419]
0567532074419[0, 18220, 48157, 191849, 146917][0, 386, 386, 386, 386]

将上述数据进行数据集拆分和训练,训练结果如下:
在这里插入图片描述

如上图所示,模型在第3个epoch时已经开始出现拟合现象。通过对比原论文的图表(下图),可以看到在该论文的实验中,Test Loss在第2个epoch时便开始上升,AUC也呈现出收敛的趋势。然而,由于数据集的差异,并且博主使用的正则化方法为原始的L2正则化,两个实验的结果不能直接进行比较。如果有任何错误或者不准确的地方,还请指正,谢谢!
在这里插入图片描述

7. torch实现

https://github.com/zhougr1993/DeepInterestNetwork 论文中也有使用tensorflow实现版本

正则化方面使用的是l2
数据集使用的是DIN模型pytorch代码逐行细讲提到的amazon-books-100k,但博主找了挺久未找到原官方出处,这里就不提供下载地址

Dice激活函数

class Dice(nn.Module):def __init__(self, alpha=0.0, epsilon=1e-8):"""初始化 Dice 激活函数。:param alpha: 可学习的参数,用于控制负值部分的缩放。:param epsilon: 一个小常数,用于数值稳定性。"""super(Dice, self).__init__()self.alpha = nn.Parameter(torch.tensor(alpha))  # 可学习参数self.epsilon = epsilondef forward(self, x):"""前向传播函数。:param x: 输入张量,形状为 (batch_size, ...)。:return: 经过 Dice 激活后的张量。"""# 计算输入 x 的均值和方差mean = x.mean(dim=0, keepdim=True)  # 沿 batch 维度计算均值,保留维度var = x.var(dim=0, keepdim=True, unbiased=False)  # 沿 batch 维度计算方差,不使用无偏估计# 计算控制函数 p(s)p_s = 1 / (1 + torch.exp(-(x - mean) / torch.sqrt(var + self.epsilon)))# 应用 Dice 激活函数output = p_s * x + (1 - p_s) * self.alpha * xreturn output

LocalActivationUnit Attention块计算

#定义激活单元(Activation Unit)
class LocalActivationUnit(nn.Module):def __init__(self, embedding_dim, hidden_units = [36], dropout = 0.5):super(LocalActivationUnit, self).__init__()layers = []input_dim = embedding_dim  *2 * 3 #开始的输入维度为 cate和behavior的cat所以得乘2for dim in hidden_units:layers.append(nn.Linear(input_dim, dim))layers.append(Dice())layers.append(nn.Dropout(dropout))input_dim = dimlayers.append(nn.Linear(input_dim, 1))self.mlp = nn.Sequential(*layers)def forward(self, behavior_embeds, target_embed, mask):"""Args:behavior_embeds: 历史行为序列嵌入 (batch_size, seq_len, embed_dim)target_embed: 候选物品嵌入 (batch_size, embed_dim)mask: 序列填充掩码 (batch_size, seq_len)Returns:注意力权重 (batch_size, seq_len)"""seq_len = behavior_embeds.size(1)# 扩展候选物品嵌入以匹配序列长度target_embed = target_embed.unsqueeze(1).expand(-1, seq_len, - 1) #-1:表示保留该维度的原始大小,seq_len:表示将第 1 维(即新增的维度)扩展到与 behavior_embeds 的序列长度一致。#拼接行为序列和候选物品嵌入concat_embeds = torch.cat([behavior_embeds, target_embed, target_embed - behavior_embeds], dim = -1) #最后一个维度进行拼接#计算每一个序列的权重scores = self.mlp(concat_embeds).squeeze(-1) #(batch_size, seq_len, 1) 转换为 (batch_size, seq_len)#应用sigmoid获取权重weights = torch.sigmoid(scores) #(batch_size, seq_len)if mask is not None:weights = weights * mask #(batch_size, seq_len)return weights

DIN模型

class DIN(nn.Module):"""Args:user_feat_dims: 用户特征维度字典item_feat_dims: 总物品特征维度字典context_feat_dims: 上下文特征维度字典, 如果没有上下文特征,可以设置为 Noneembedding_dim: 嵌入维度mlp_dims: MLP隐藏层维度列表dropout: Dropout概率Output:预测结果这里并没有使用sigmoid激活,而是通过softmax输出两个类别的概率"""def __init__(self, user_feat_dims, item_feat_dims, context_feat_dims, embedding_dim=8, mlp_dims=[200, 80], dropout=0.2):super(DIN, self).__init__()# 用户特征嵌入层self.user_embeddings = nn.ModuleDict({feat: nn.Embedding(dim, embedding_dim)for feat, dim in user_feat_dims.items()})# 物品特征嵌入层self.item_embeddings = nn.ModuleDict({feat: nn.Embedding(dim, embedding_dim)for feat, dim in item_feat_dims.items()})# 上下文特征层self.context_embeddings = Noneself.context_embed_size = 0if context_feat_dims is not None:self.context_embeddings = nn.ModuleDict({feat: nn.Embedding(dim, embedding_dim)for feat, dim in context_feat_dims.items()})self.context_embed_size = len(context_feat_dims) * embedding_dim# 注意力单元层self.attention = LocalActivationUnit(embedding_dim, hidden_units=[80, 40], dropout=dropout)# 计算MLP输入维度user_embed_size = len(user_feat_dims) * embedding_dimitem_embed_size = len(item_feat_dims) * embedding_dimmlp_input_dim = user_embed_size + item_embed_size + self.context_embed_size + embedding_dim*2  # 最后一个是user_interest维度,因为使用了item_id和cate_id 所以维度是2 * embedding_dim# MLP层mlp_layers = []input_dim = mlp_input_dimfor hidden_dim in mlp_dims:mlp_layers.append(nn.Linear(input_dim, hidden_dim))mlp_layers.append(Dice())mlp_layers.append(nn.Dropout(dropout))input_dim = hidden_dimmlp_layers.append(nn.Linear(input_dim, 2))self.mlp = nn.Sequential(*mlp_layers)def forward(self, user_features, target_item_features, context_features, hist_behavior_seq, hist_cate_seq):"""Args:user_features: 用户特征字典target_item_features: 目标物品特征字典context_features: 上下文特征字典hist_behavior_seq: 历史行为序列,形状为(batch_size, seq_len)hist_cate_seq: 历史行为类别列表,形状为(batch_size, seq_len)Returns:预测结果"""# 生成序列掩码,因为数据中做了对齐,没有数据的部分值已被填为了0if hist_behavior_seq is not None:# 确保 hist_behavior_seq 是布尔张量mask = (hist_behavior_seq != 0).float()else:mask = None# 用户特征嵌入user_embeds = [self.user_embeddings[feat](user_features[feat]) for feat in user_features]user_embeds = torch.cat(user_embeds, dim=1)  # (batch_size, user_embed_size)# 目标特征嵌入item_embeds = [self.item_embeddings[feat](target_item_features[feat]) for feat in target_item_features]target_item_embed = torch.cat(item_embeds, dim=1)  # (batch_size, item_embed_size)# 上下文特征嵌入,如果没有上下文特征,就用0填充context_embed = torch.zeros(len(user_embeds), self.context_embed_size).to(user_embeds.device)if self.context_embeddings is not None:context_embeds = [self.context_embeddings[feat](context_features[feat]) for feat in context_features]context_embed = torch.cat(context_embeds, dim=1)  # (batch_size, context_embed_size)# 历史行为序列处理if len(hist_behavior_seq) > 0 and len(hist_cate_seq) > 0:hist_behavior_embed = self.item_embeddings['Ordinal_itemID'](hist_behavior_seq)  # (batch_size, seq_len, item_embed_size)hist_cate_embed = self.item_embeddings['Ordinal_cateID'](hist_cate_seq)  # (batch_size, seq_len, item_embed_size)hist_embed = torch.cat([hist_behavior_embed, hist_cate_embed], dim=2)  # (batch_size, seq_len, item_embed_size*2)weights = self.attention(hist_embed, target_item_embed, mask)  # (batch_size, seq_len)user_interest = torch.sum(hist_embed * weights.unsqueeze(-1), dim=1)  # (batch_size, item_embed_size * 2)else:user_interest = torch.zeros(len(user_embeds), self.item_embeddings['Ordinal_itemID'].embedding_dim).to(user_embeds.device)# 拼接特征combined = torch.cat([user_embeds, target_item_embed, context_embed, user_interest], dim=1)  # (batch_size, mlp_input_dim)# 通过MLP获取预测结果logit = self.mlp(combined).squeeze(-1)output = torch.softmax(logit, dim=1)return output

Reference

  1. Guorui Zhou, Chengru Song, Xiaoqiang Zhu, Ying Fan, Han Zhu, Xiao Ma, Yanghui Yan, Junqi Jin, Han Li, and Kun Gai. “Deep Interest Network for Click-Through Rate Prediction.” In Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining, 1-9. ACM, 2018.

  2. 王喆《深度学习推荐系统》

  3. 推荐系统中的注意力机制——阿里深度兴趣网络(DIN)

  4. DIN模型pytorch代码逐行细讲

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

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

相关文章

网页五子棋——用户模块

目录 用户注册 注册时序图 约定前后端交互接口 后端实现 controller 层接口设计 service 层接口设计 dao 层接口设计 全局异常处理 接口测试 前端实现 register.html css common.css register.css js 注册模块测试 用户登录 登录时序图 约定前后端交互接口 …

深度学习04 数据增强、调整学习率

目录 数据增强 常用的数据增强方法 调整学习率 学习率 调整学习率 ​调整学习率的方法 有序调整 等间隔调整 多间隔调整 指数衰减 余弦退火 ​自适应调整 自定义调整 数据增强 数据增强是通过对训练数据进行各种变换(如旋转、翻转、裁剪等)&am…

Ubuntu22.04 Deepseek-R1本地容器化部署/内网穿透/OPENWEBUI,打造个人AI助手!

1. 前言 本地部署DeepSeek并实现内网穿透,为家庭成员提供强大的AI支持。通过使用Ollama、Docker、OpenWebUI和Nginx,内网穿透,我们可以轻松实现快速响应和实时搜索功能。 2.软硬件环境 系统:ubuntu22.04, cuda12GPU: RTX2080Ti …

DeepSeek与ChatGPT的全面对比

在人工智能(AI)领域,生成式预训练模型(GPT)已成为推动技术革新的核心力量。OpenAI的ChatGPT自发布以来,凭借其卓越的自然语言处理能力,迅速占据市场主导地位。然而,近期中国AI初创公…

[HarmonyOS]鸿蒙(添加服务卡片)推荐商品 修改卡片UI(内容)

什么是服务卡片 ? 鸿蒙系统中的服务卡片(Service Card)就是一种轻量级的应用展示形式,它可以让用户在不打开完整应用的情况下,快速访问应用内的特定功能或信息。以下是服务卡片的几个关键点: 轻量级&#…

【数据结构】 栈和队列

在计算机科学的世界里,数据结构是构建高效算法的基础。栈(Stack)和队列(Queue)作为两种基本且重要的数据结构,在软件开发、算法设计等众多领域都有着广泛的应用。今天,我们就来深入探讨一下栈和…

「软件设计模式」桥接模式(Bridge Pattern)

深入解析桥接模式:解耦抽象与实现的艺术 一、模式思想:正交维度的优雅解耦 桥接模式(Bridge Pattern)通过分离抽象(Abstraction)与实现(Implementation),使二者可以独立…

新建github操作

1.在github.com的主页根据提示新建一个depository。 2.配置用户名和邮箱 git config --global user.name "name" git config --global user.email "email" 3.生成ssh秘钥 ssh-keygen -t rsa 找到public key 对应的文件路径 cat /root/.ssh/id_rsa 复制显…

【力扣】108.将有序数组转换为二叉搜索树

AC截图 题目 思路 因为nums数组是严格递增的,所以只需要每次选出中间节点,然后用左边部分构建左子树,用右边部分构建右子树。 代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* …

如何在 Mac 上解决 Qt Creator 安装后应用程序无法找到的问题

在安装Qt时,遇到了一些问题,尤其是在Mac上安装Qt后,发现Qt Creator没有出现在应用程序中。通过一些搜索和操作,最终解决了问题。以下是详细的记录和解决方法。 1. 安装Qt后未显示Qt Creator 安装完成Qt后,启动应用程…

Spring AI发布!让Java紧跟AI赛道!

1. 序言 在当今技术发展的背景下,人工智能(AI)已经成为各行各业中不可忽视的重要技术。无论是在互联网公司,还是传统行业,AI技术的应用都在大幅提升效率、降低成本、推动创新。从智能客服到个性化推荐,从语…

数据库脚本MySQL8转MySQL5

由于生产服务器版本上部署的是MySQL5,而开发手里的脚本代码是MySQL8。所以只能降版本了… 升级版本与降级版本脚本转换逻辑一样 MySQL5与MySQL8版本SQL脚本区别 大多数无需调整、主要是字符集与排序规则 MySQL5与MySQL8版本SQL字符集与排序规则 主要操作&…

STM32物联网终端实战:从传感器到云端的低功耗设计

STM32物联网终端实战:从传感器到云端的低功耗设计 一、项目背景与挑战分析 1.1 物联网终端典型需求 (示意图说明:传感器数据采集 → 本地处理 → 无线传输 → 云端存储) 在工业物联网场景中,终端设备需满足以下核心需…

牛客寒假训练营3

M 牛客传送门 代码如下: const int N2e610,M1e410; const int INF0x3f3f3f3f; const int mod998244353; ll n;void solve(){string s; cin >> s;string ns"nowcoder";sort(s.begin(),s.end(…

BY组态:构建灵活、可扩展的自动化系统

引言 在现代工业自动化领域,BY组态(Build Your Own Configuration)作为一种灵活、可扩展的解决方案,正逐渐成为工程师和系统集成商的首选。BY组态允许用户根据具体需求自定义系统配置,从而优化生产效率、降低成本并提…

DeepSeek 通过 API 对接第三方客户端 告别“服务器繁忙”

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 上一期分享了如何在本地部署 DeepSeek R1 模型,但通过命令行运行的本地模型,问答的交互也要使用命令行,体验并不是很好。这期分享几个第三方客户端,涵盖了桌…

【第10章:自然语言处理高级应用—10.4 NLP领域的前沿技术与未来趋势】

各位技术探险家们,今天我们要开启一场穿越语言智能奇点的时空之旅。从正在改写物理定律的万亿参数大模型,到能看懂《星际穿越》剧本的跨模态AI,再到正在颠覆编程方式的神经-符号混合系统……这篇万字长文将带你摸清NLP技术进化的七块关键拼图。(建议边读边做笔记,文末有技…

自动驾驶---如何打造一款属于自己的自动驾驶系统

在笔者的专栏《自动驾驶Planning决策规划》中,主要讲解了行车的相关知识,从Routing,到Behavior Planning,再到Motion Planning,以及最后的Control,笔者都做了相关介绍,其中主要包括算法在量产上…

探索 DeepSeek:AI 领域的璀璨新星

在人工智能飞速发展的当下,DeepSeek 作为行业内的重要参与者,正以独特的技术和广泛的应用备受瞩目。 DeepSeek 是一家专注于实现 AGI(通用人工智能)的中国人工智能公司。它拥有自主研发的深度学习框架,能高效处理海量…

centos部署open-webui

提示:本文将简要介绍一下在linux下open-webui的安装过程,安装中未使用虚拟环境。 文章目录 一、open-webui是什么?二、安装流程1.openssl升级2.Python3.11安装3.sqlite安装升级4.pip 下载安装open-webui 总结 一、open-webui是什么? Open W…