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

news2025/2/21 13:11:07

实验和完整代码

完整代码实现和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 = epsilon

    def 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 * x
        return 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所以得乘2
        for dim in hidden_units:
            layers.append(nn.Linear(input_dim, dim))
            layers.append(Dice())
            layers.append(nn.Dropout(dropout))
            input_dim = dim
        layers.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: 上下文特征维度字典, 如果没有上下文特征,可以设置为 None
        embedding_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 = None
        self.context_embed_size = 0
        if 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_dim
        item_embed_size = len(item_feat_dims) * embedding_dim

        mlp_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_dim

        for 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_dim
        
        mlp_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:
            预测结果
        """
        # 生成序列掩码,因为数据中做了对齐,没有数据的部分值已被填为了0
        
        if 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.coloradmin.cn/o/2301108.html

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

相关文章

【前端】如何安装配置WebStorm软件?

文章目录 前言一、前端开发工具WebStorm和VS Code对比二、官网下载三、安装1、开始安装2、选择安装路径3、安装选项4、选择开始菜单文件夹5、安装成功 四、启动WebStorm五、登录授权六、开始使用 前言 WebStorm 是一款由 JetBrains 公司开发的专业集成开发环境(IDE…

【Golang学习之旅】Go 语言微服务架构实践(gRPC、Kafka、Docker、K8s)

文章目录 1. 前言:为什么选择Go语言构建微服务架构1.1 微服务架构的兴趣与挑战1.2 为什么选择Go语言构建微服务架构 2. Go语言简介2.1 Go 语言的特点与应用2.2 Go 语言的生态系统 3. 微服务架构中的 gRPC 实践3.1 什么是 gRPC?3.2 gRPC 在 Go 语言中的实…

Spring核心思想之—AOP(面向切面编程)

目录 一 .AOP概述 二. Spring AOP 使用 2.1 引入AOP依赖 2.2 编写AOP程序 三. Spring AOP详情 3.1 切点(Pointcut) 3.2 连接点(Join Point) 3.3通知(Advice) 3.4切面(Aspect) 3.5通知 3.6 PointCut (公共切点)…

关于使用雪花算法生成唯一ID,返回给前端ID不一致的问题

问题 在某个项目中,使用雪花算法生成的唯一ID,从数据库查询到数据后返回给前端,但是前端接受到的数据ID和数据库原先生成的不一致 但是前端展示的数据: 原因 原因是后端使用Long类型来存储雪花算法生成的ID,但是这个数值已经超过前端数值类型的范围,导致前端在存储这个数值…

axios post请求 接收sse[eventsource]数据的

axios 接收sse数据的 axios 接收sse数据的 EventSource什么 基于 HTTP 协议实现,通过与服务器建立一个持续连接,实现了服务器向客户端推送事件数据的功能。在客户端,EventSource 对象通过一个 URL 发起与服务器的连接。连接成功后&#xff0…

大语言模型常用微调与基于SFT微调DeepSeek R1指南

概述 大型语言模型(LLM,Large Language Model)的微调(Fine-tuning)是指在一个预训练模型的基础上,使用特定领域或任务的数据对模型进行进一步训练,以使其在该领域或任务上表现更好。微调是迁移…

聚焦地灾防治,助力城市地质安全风险防控

城市是人类社会发展的重要载体,承载着经济繁荣、文化交流和人口聚集等重要功能。然而,由于城市建设过程中地质条件复杂,地质灾害风险隐患存在,城市地质安全等问题日益突出,引起人们的广泛关注。为保障城市发展的安全和…

为什么WP建站更适合于谷歌SEO优化?

在当今数字时代,建立一个网站似乎变得容易,但要构建一个真正能够带来流量和订单的网站却并非易事。特别是在谷歌SEO优化方面,不同的建站程序在SEO支持方面的效果差异显著。对于希望提升搜索引擎表现的用户来说,WordPress无疑是最佳…

用deepseek学大模型08-长短时记忆网络 (LSTM)

deepseek.com 从入门到精通长短时记忆网络(LSTM),着重介绍的目标函数,损失函数,梯度下降 标量和矩阵形式的数学推导,pytorch真实能跑的代码案例以及模型,数据, 模型应用场景和优缺点,及如何改进解决及改进方法数据推导…

(蓝桥杯——10. 小郑做志愿者)洛斯里克城志愿者问题详解

题目背景 小郑是一名大学生,她决定通过做志愿者来增加自己的综合分。她的任务是帮助游客解决交通困难的问题。洛斯里克城是一个六朝古都,拥有 N 个区域和古老的地铁系统。地铁线路覆盖了树形结构上的某些路径,游客会询问两个区域是否可以通过某条地铁线路直达,以及有多少条…

小胡说技书博客分类(部分目录):服务治理、数据治理与安全治理对比表格

文章目录 一、对比表格二、目录2.1 服务2.2 数据2.3 安全 一、对比表格 下表从多个维度对服务治理、数据治理和安全治理进行详细对比,为读者提供一个直观而全面的参考框架。 维度服务治理数据治理安全治理定义对软件开发全流程、应用交付及API和接口管理进行规范化…

开源模型应用落地-DeepSeek-R1-Distill-Qwen-7B-LoRA微调-LLaMA-Factory-单机单卡-V100(一)

一、前言 如今,大语言模型领域热闹非凡,各种模型不断涌现。DeepSeek-R1-Distill-Qwen-7B 模型凭借其出色的效果和性能,吸引了众多开发者的目光。而 LLaMa-Factory 作为强大的微调工具,能让模型更好地满足个性化需求。 在本篇中&am…

uni-app发起网络请求的三种方式

uni.request(OBJECT) 发起网络请求 具体参数可查看官方文档uni-app data:请求的参数; header:设置请求的 header,header 中不能设置 Referer; method:请求方法; timeout:超时时间,单位 ms&a…

EasyRTC:智能硬件适配,实现多端音视频互动新突破

一、智能硬件全面支持,轻松跨越平台障碍 EasyRTC 采用前沿的智能硬件适配技术,无缝对接 Windows、macOS、Linux、Android、iOS 等主流操作系统,并全面拥抱 WebRTC 标准。这一特性确保了“一次开发,多端运行”的便捷性&#xff0c…

LeetCode1287

LeetCode1287 目录 题目描述示例思路分析代码段代码逐行讲解复杂度分析总结的知识点整合总结 题目描述 给定一个非递减的整数数组 arr,其中有一个元素恰好出现超过数组长度的 25%。请你找到并返回这个元素。 示例 示例 1 输入: arr [1, 2, 2, 6, 6, 6, 6, 7,…

深度学习笔记之自然语言处理(NLP)

深度学习笔记之自然语言处理(NLP) 在行将开学之时,我将开始我的深度学习笔记的自然语言处理部分,这部分内容是在前面基础上开展学习的,且目前我的学习更加倾向于通识。自然语言处理部分将包含《动手学深度学习》这本书的第十四章&#xff0c…

自动化测试框架搭建-单次接口执行-三部曲

目的 判断接口返回值和提前设置的预期是否一致,从而判断本次测试是否通过 代码步骤设计 第一步:前端调用后端已经写好的POST接口,并传递参数 第二步:后端接收到参数,组装并请求指定接口,保存返回 第三…

DeepSeek R1生成图片总结2(虽然本身是不能直接生成图片,但是可以想办法利用别的工具一起实现)

DeepSeek官网 目前阶段,DeepSeek R1是不能直接生成图片的,但可以通过优化文本后转换为SVG或HTML代码,再保存为图片。另外,Janus-Pro是DeepSeek的多模态模型,支持文生图,但需要本地部署或者使用第三方工具。…

ESP32 ESP-IDF TFT-LCD(ST7735 128x160) LVGL基本配置和使用

ESP32 ESP-IDF TFT-LCD(ST7735 128x160) LVGL基本配置和使用 📍项目地址:https://github.com/lvgl/lv_port_esp32参考文章:https://blog.csdn.net/chentuo2000/article/details/126668088https://blog.csdn.net/p1279030826/article/details/…

【笔记】LLM|Ubuntu22服务器极简本地部署DeepSeek+联网使用方式

2025/02/18说明:2月18日~2月20日是2024年度博客之星投票时间,走过路过可以帮忙点点投票吗?我想要前一百的实体证书,经过我严密的计算只要再拿到60票就稳了。一人可能会有多票,Thanks♪(・ω・)&am…