gumbel-softmax的使用、课程学习的使用、有监督的对比学习的使用、无监督的对比学习的使用

news2024/11/27 2:32:16

一、gumbel-softmax的使用

gumbel-softmax里面的 τ \tau τ值越接近无穷获得的向量越接近一个均匀分布的向量; τ \tau τ值越接近0获得的向量越接近一个one-hard vector τ \tau τ值越接近1则gumbel-softmax就和softmax越类似
在这里插入图片描述

# score:代表序列内每个item的sorce,这里的分数不是one-hard的,需要gumbel来将其转化为one-hard vector,batchsize*max_seq_len*2
# mask:这个序列的mask矩阵,batchsize*max_seq_len*1
# gumbel_tau:温度参数

mask = mask.squeeze()

# 获得one-hard vector的score,batchsize*max_seq_len*2
score_gumbel_softmax = F.gumbel_softmax(score, tau=self.gumbel_tau, hard=True)

# 获取序列每个item的neg_flag和pos_flag
neg_flag = score_gumbel_softmax[:, :, 1] * mask
pos_flag = (1 - neg_flag) * mask

二、课程学习的使用

这里用到了课程学习(从易到难),最后得到经过课程学习筛选的loss和。因为我们是从易到难,所以是先删除loss较大的值,然后再逐步减小被删除值的个数。 当然也可以从难到易,代码同从易到难

r"""
loss_list:重构loss,batchsize*max_seq_len
drop_rate:课程学习的μ,代表需要删除比例
"""

# 将整个序列loss的最后一维进行升序排序
# loss_list_sorted代表被排序好的值
# loss_index_sorted代表被排序的loss值的索引
loss_list_sorted, loss_index_sorted = torch.sort(loss_list, descending=False, dim=-1)

# 获得loss的保留率
remind_rate = 1 - drop_rate

# 获得需要保留多少个loss
remind_num = int(remind_rate * len(loss_list))

# 先删除loss较大的值,保留loss较小的值
processed_loss_list_sorted = loss_list_sorted[:remind_num]

# 将获得的loss相加,获得这一个batch里面的loss总和
recommender_ce_loss = torch.sum(processed_loss_list_sorted)

三、有监督的对比学习的使用

在这里插入图片描述
在这里插入图片描述
上图为有监督的对比学习,而下面的代码是我根据有监督的对比学习和推荐项目进行修改的版本,具体公式为:
L = − ∑ i = 1 M 1 M y i − 1 ∑ j = 1 P l y j = + ln ⁡ ( exp ⁡ ( sim ( s i ,   s j ) / τ ) exp ⁡ ( sim ( s i ,   s j ) / τ ) + ∑ k = 1 P l y j = − exp ⁡ ( sim ( s i ,   s k ) / τ ) ) \mathcal{L}=-\sum\limits_{i=1}^{M}\frac{1}{M_{y_{i}}-1}\sum\limits_{j=1}^{P}l_{y_{j}=+}\ln{\left(\frac{\exp{\left(\text{sim}\left(s_{i},\ s_{j}\right)/\tau\right)}}{\exp{\left(\text{sim}\left(s_{i},\ s_{j}\right)/\tau\right)}+\sum\limits_{k=1}^{P}l_{y_{j}=-}\exp{\left(\text{sim}\left(s_{i},\ s_{k}\right)/\tau\right)}}\right)} L=i=1MMyi11j=1Plyj=+ln exp(sim(si, sj)/τ)+k=1Plyj=exp(sim(si, sk)/τ)exp(sim(si, sj)/τ)
这里的P是句子的长度

# seq_emb:
# item_seq_emb:序列的emb,batsize*max_seq_len*feat_dim
# item_pos_flag:序列内正样本的mask
# mask:序列的mask矩阵
# tau:温度参数

item_seq_emb = item_seq_emb * mask

target_seq_emb = seq_emb.unsqueeze(1).expand_as(
    item_seq_emb
).to(torch.float)
# 这步得到它的相似度矩阵
similarity_matrix = F.cosine_similarity(item_seq_emb, target_seq_emb, dim=2)

# 这步给相似度矩阵求exp, 并且除以温度参数T, 注意要乘mask
similarity_matrix_after_exp = torch.exp(similarity_matrix / tau) * mask.squeeze()

# 这步产生了正样本(五噪音item)的相似度矩阵,其他位置都是0
sim = item_pos_flag * similarity_matrix_after_exp

# 用原先的相似度矩阵减去正样本矩阵得到负样本(噪音item)的相似度矩阵
no_sim = similarity_matrix_after_exp - sim
# 把负样本矩阵按行求和,得到的是对比损失的分母(还差一个与分子相同的那个相似度,后面会加上)
no_sim_sum = torch.sum(no_sim, dim=1, keepdim=True)

'''
将上面的矩阵扩展一下,再转置,加到sim(也就是正样本矩阵上),然后再把sim矩阵与sim_num矩阵做除法。
至于为什么这么做,就是因为对比损失的分母存在一个正样本的相似度,就是分子的数据。
'''
no_sim_sum_expend = no_sim_sum.expand_as(item_pos_flag)
sim_sum = sim + no_sim_sum_expend

# 为了防止自监督对比学习的分母为0
zero_anomaly_process = sim_sum.le(0.).float() * 1e-10
anomaly_process_sim_sum = sim_sum + zero_anomaly_process

sim_div = torch.div(sim, anomaly_process_sim_sum)

'''
由于loss矩阵中,存在0数值,那么在求-log的时候会出错。这时候,我们就将loss矩阵里面为0的地方
全部加上1,然后再去求loss矩阵的值,那么-log1 = 0 ,就是我们想要的。
'''
sim_div_sum = sim_div + sim_div.eq(0)

# 接下来就是算一个批次中的sup_con_loss了
sim_div_sum_log = -torch.log(sim_div_sum)  # 求-log

# 返回一个一维的张量
sup_con_loss = torch.sum(
    torch.sum(sim_div_sum_log, dim=1) / (torch.sum(item_pos_flag, dim=-1))
)

四、无监督的对比学习的使用

L i ,   j = − log ⁡ exp ⁡ ( sim ( z i ,   z j ) / τ ) ∑ k = 1 ,   k ≠ i 2 N exp ⁡ ( sim ( z i ,   z k ) / τ ) \mathcal{L_{i,\ j}}=-\log{\frac{\exp{\left(\text{sim}\left(\boldsymbol{z}_{i},\ \boldsymbol{z}_{j}\right)/\tau\right)}}{\sum\limits_{k=1,\ k\neq{i}}^{2N}\exp{\left(\text{sim}\left(\boldsymbol{z}_{i},\ \boldsymbol{z}_{k}\right)/\tau\right)}}} Li, j=logk=1, k=i2Nexp(sim(zi, zk)/τ)exp(sim(zi, zj)/τ)
L = 1 2 N ∑ k = 1 N [ l ( 2 k − 1 ,   2 k ) + l ( 2 k ,   2 k − 1 ) ] L=\frac{1}{2N}\sum\limits_{k=1}^{N}\left[l\left(2k-1,\ 2k\right)+l\left(2k,\ 2k-1\right)\right] L=2N1k=1N[l(2k1, 2k)+l(2k, 2k1)]

def contrastiveLoss(
        target_emb,  # (bs, dim)
        class_prototype_emb,    # (class_num, dim)
        prototype_mask,  # (bs, class_num)
        tau,
):
    target_emb_normalize = F.normalize(target_emb, dim=1)  # (bs, dim)  --->  (bs, dim)
    class_prototype_emb_normalize = F.normalize(class_prototype_emb, dim=1)  # (class_num, dim)  --->  (class_num, dim)

    target_seq_emb_repeat = target_emb_normalize.unsqueeze(1).repeat(
        1, class_prototype_emb.shape[0], 1
    ).to(torch.float)   # (bs, class_num, dim)
    class_prototype_emb_repeat = class_prototype_emb_normalize.unsqueeze(0).repeat(
        target_emb.shape[0], 1, 1
    ).to(torch.float)   # (bs, class_num, dim)

    similarity_matrix = F.cosine_similarity(target_seq_emb_repeat, class_prototype_emb_repeat,
                                            dim=2)

    # 这步给相似度矩阵求exp, 并且除以温度参数T, 注意要乘mask
    similarity_matrix_after_exp = torch.exp(similarity_matrix / tau)

    # 这步产生了正样本(五噪音item)的相似度矩阵,其他位置都是0
    sim = prototype_mask * similarity_matrix_after_exp

    # 用原先的相似度矩阵减去正样本矩阵得到负样本(噪音item)的相似度矩阵
    no_sim = similarity_matrix_after_exp - sim

    # 把负样本矩阵按行求和,得到的是对比损失的分母(还差一个与分子相同的那个相似度,后面会加上)
    no_sim_sum = torch.sum(no_sim, dim=1, keepdim=True)

    '''
    将上面的矩阵扩展一下,再转置,加到sim(也就是正样本矩阵上),然后再把sim矩阵与sim_num矩阵做除法。
    至于为什么这么做,就是因为对比损失的分母存在一个正样本的相似度,就是分子的数据。
    '''
    no_sim_sum_expend = no_sim_sum.expand_as(prototype_mask)
    sim_sum = sim + no_sim_sum_expend

    sim_div = torch.div(sim, sim_sum)

    '''
    由于loss矩阵中,存在0数值,那么在求-log的时候会出错。这时候,我们就将loss矩阵里面为0的地方
    全部加上1,然后再去求loss矩阵的值,那么-log1 = 0 ,就是我们想要的。
    '''
    sim_div_sum = sim_div + sim_div.eq(0)

    # 接下来就是算一个批次中的con_loss了
    sim_div_sum_log = -torch.log(sim_div_sum)  # 求-log
    con_loss = torch.sum(
        torch.sum(sim_div_sum_log, dim=1)
    )

    return con_loss

或者使用现成的库

class SupervisedContrastiveLoss(nn.Module):
    def __init__(self, temperature=0.1):
        super(SupervisedContrastiveLoss, self).__init__()
        self.temperature = temperature

    def forward(self, feature_vectors, labels):
        # Normalize feature vectors
        feature_vectors_normalized = F.normalize(feature_vectors, p=2, dim=1)
        # Compute logits
        logits = torch.div(
            torch.matmul(
                feature_vectors_normalized, torch.transpose(feature_vectors_normalized, 0, 1)
            ),
            self.temperature,
        )
        return losses.NTXentLoss(temperature=0.07)(logits, torch.squeeze(labels))

criterion = SupervisedContrastiveLoss(temperature=0.5).to('cuda:0') # Custom Implementation

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

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

相关文章

Ubuntu服务器使用NTP功能同步时间

前提: 1. 要明确自己的需求,是设计一个NTP服务器,然后给内网的其他用户提供NTP服务? 2. 还是发现自己Ubuntu系统时间错误,想要同步一个时间进来? 如果是2,继续往下看吧,如果是1&am…

2021年一篇强人工智能论文,基于AGI Brain改进的二代版本

AGI Brain II: The Upgraded Version with Increased Versatility Index返回论文和资料目录 1.论文简介 论文基于19年提出的第一代AGI Brain I 改进。主要有两点改进,1.提出一个AGI指标,2.用Mamdani模糊推理联想记忆代替原本的神经网络NN表示外显记忆&…

字节跳动最爱考的前端面试题:计算机网络基础

注意:每道题前面出现的 (xx) 数字代表这道题出现的频次,此 计算机网络 基础是基于 30 篇前端面经整理出的问题和对应的回答、参考链接等。文章内容为拿到 Offer 的本人整理。 (3)问:HTTP 缓存 HTTP 缓存又分为强缓存和…

ArcGIS基础实验操作100例--实验55栅格与ASCII转换

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台:ArcGIS 10.6 实验数据:请访问实验1(传送门) 高级编辑篇--实验55 栅格与ASCII转换 目录 一、实验背景 二、实验数据 三、实验步骤 (1&a…

nodejs+vue+element+eachers构建开源项目大型连续剧(3)建立前端基础项目(暂时用的vue2框架)

书接上回,在第二集我们成功安装了mysql数据库,并通过nodejs服务器关联到数据库,并成功更改了数据库中的数据。这一集呢,主要是进行一个前端vue2项目的构建,后面如果大家想要看vue3的话可以后续更新,毕竟现在…

计算机原理二_操作系统概述

目录儿三、操作系统概述3.1 操作系统的基本概念3.1.1 操作系统的概念3.1.2 操作系统的目标和功能3.1.2.1 目标3.1.2.2 功能3.1.3 操作系统的特征3.2 操作系统的发展与分类3.2.1 分类3.3 操作系统的运行环境3.3.1 操作系统的运行机制3.3.1.1 用户态、核心态3.3.1.2 时钟与中断3.…

SLAM初探

SLAM初探 1.视觉SLAM框架 整个视觉SLAM包括以下流程 传感器信息读取,主要是相机图像信息的读取和处理前端视觉里程计,它的任务是估算相邻图像之间相机的运动和局部的地图后端优化,接受不同时刻视觉里程计输出的相机位姿以及回环检测的信息&…

【C++高阶数据结构】LRU

​ 🏆个人主页:企鹅不叫的博客 ​ 🌈专栏 C语言初阶和进阶C项目Leetcode刷题初阶数据结构与算法C初阶和进阶《深入理解计算机操作系统》《高质量C/C编程》Linux ⭐️ 博主码云gitee链接:代码仓库地址 ⚡若有帮助可以【关注点赞收藏…

LeetCode刷题复盘笔记—一文搞懂动态规划之583. 两个字符串的删除操作问题(动态规划系列第四十篇)

今日主要总结一下动态规划的一道题目,583. 两个字符串的删除操作 题目:583. 两个字符串的删除操作 Leetcode题目地址 题目描述: 给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意…

ArcGIS基础实验操作100例--实验56 TIFF与GRID栅格转换

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台:ArcGIS 10.6 实验数据:请访问实验1(传送门) 高级编辑篇--实验56 TIFF与GRID栅格转换 目录 一、实验背景 二、实验数据 三、实验步骤 (…

orika 工具下划线转驼峰不同字段名映射

1.问题: 业务需要把第三方接口的带下划线的字段规范为驼峰的字段 第三方接口的bean对象: public class ObjectsDetail extends XMLElementData implements Serializable {private static final long serialVersionUID 5080447582610246168L;private String objectclass;priv…

用300行Python代码实现一个人脸识别系统源码,基于dlib

用300行Python代码实现一个人脸识别系统 完整代码下载地址:用300行Python代码实现一个人脸识别系统源码,基于dlib 今天我们来python实现一个人脸识别系统,主要是借助了dlib这个库,相当于我们直接调用现成的库来进行人脸识别&…

科技云报道:“大建设”时期,AI算力何去何从?

科技云报道原创。 算力就是生产力,得算力者得天下。 随着新一代人工智能技术的快速发展和突破,以深度学习计算模式为主的AI算力需求呈指数级增长。 数据显示,在1960到2010年间,AI的计算复杂度每两年翻一番;在2010到2…

fastposter v2.11.0 天花板级的海报生成器

fastposter v2.11.0 天花板级的海报生成器 🔥🔥🔥 fastposter海报生成器是一款快速开发海报的工具。只需上传一张背景图,在对应的位置放上组件(文字、图片、二维🐴、头像)即可生成海报。 点击代…

实验二十一 配置NAT

实验二十一 配置NAT实验要求: 静态NAT: 在Router的公网侧接口GE0/0/1下配置静态NAT,将私有 IP地址 192.168.0.2与公有IP地址202.10.1.3绑定起来。 NAT SERVER的配置 动态NAT和easy IP的配置网络拓扑图:操作步骤:一、静态NAT1、配置…

Actipro-wpf-controls-22.1.4 2023注册版

Actipro WPF 控件 用于构建漂亮的 Windows Presentation Foundation 桌面应用程序的大量 UI 控件 特征 超过 100 个 WPF 控件和组件在各种产品中可用,Ω578867473它们通过丰富的特性和功能改进应用程序的 UI。 受办公室启发的用户界面 复制现代 Office 应用程序的外…

【数据结构】计数排序、基数排序

文章目录计数排序基数排序计数排序 计数排序也是非比较排序的一种,在之前的博客介绍的都是比较排序,跟之前的比较排序相比计数排序并不是很常用,不常用的原因也是它的局限性耗费空间很大,只能对整数进行排序,并且数据在…

【验证码逆向专栏】某验四代滑块验证码逆向分析

文章目录声明逆向目标通讯流程验证码流程分析逆向分析captcha_id 参数challenge 参数w 参数结果验证声明 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与…

剑指 Offer 27. 二叉树的镜像(Leetcode 226. 翻转二叉树)(二叉树后序遍历)

题目: 链接:剑指 Offer 27. 二叉树的镜像;Leetcode 226. 翻转二叉树 难度:简单 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,…