濬哲的博客

人生如棋,落子无悔

前言

在机器学习和深度学习中,分类问题是核心任务之一。但你是否真正理解:

  • 为什么多分类用 softmax + 交叉熵?
  • 为什么二分类用 sigmoid + 二元交叉熵?
  • 为什么交叉熵损失函数要这样设计?

很多人在写代码时只是简单地调用 CrossEntropyLoss,却不清楚背后的数学原理和逻辑关系。

🎯 本文将为你揭示: 1. Softmax、交叉熵、极大似然估计(MLE)三者的内在联系 2. 从数学原理到实际应用的完整推导过程 3. 二分类作为多分类特例的统一理解

让我们从最基础的概念开始,构建完整的知识体系。

阅读全文 »

前言

近期在做推荐系统的时候再一次遇见了 word2vec,之前在学 nlp 的时候看过,不过看的比较快没有去深入研究其中的一些细节,到现在已经差不多了。这篇文章提出的 Embedding 对于 nlp 和 rec 的意义过于重大,趁着这两天公司事情不是很多,我打算来好好精读一下 word2vec 的系列文章。

word2vec 系列作品简介

word2vec 最早在 2013 年由 Tomas Mikolov 在《Efficient Estimation of Word Representations in Vector Space》中提出,后续还有两篇工作更加完善地进行了阐释。我把这三篇文章链接放在下面,大家可以按照顺序进行阅读。

Mikolov 的开山之作(2013 年第一篇) 《Efficient Estimation of Word Representations in Vector Space》

  • 首次提出了 word2vec 算法,包含两个模型:CBOW 和 skip-gram
  • 对比了之前在语言表示的一些 work,比如 NNLM

Mikolov 的后续论文(2013 年第二篇) 《Distributed Representations of Words and Phrases and their Compositionality》

  • 这篇论文在 NeurIPS 2013 发表,是 Word2Vec 的第二篇论文,比第一篇更详细。
  • 它引入了 负采样(Negative Sampling) 和 层次 Softmax(Hierarchical Softmax) 等优化方法,并提供了更完整的训练目标函数描述

Rong (2014) 的详细推导论文 《word2vec Parameter Learning Explained》(Xin Rong, 2014)

这是对 Word2Vec 数学原理最完整的解释之一,涵盖了: - Skip-gram 和 CBOW 的 损失函数推导 - 原始 Softmax 的梯度计算 - 负采样(NEG)和层次 Softmax(HS)的优化方法 - 训练过程的详细数学分析

什么是词向量

计算机是无法理解我们的自然语言的,想让计算机理解自然语言就要对齐进行编码。一种常见的编码手段就是独热编码(one-hot)。但是这种编码的维度非常高并且很稀疏,任意两个向量之间还都是正交的,因此无法捕获两个词语的相关性特征。如果有一种方法能够将其映射到一系列低维稠密向量,机器就可以很好的学习不同词语之间的关系,比如:丈夫 - 妻子 + 国王 = 王后” 这样的关系。这就是词向量(Embedding) 的由来,其中产生词向量最经典的模型就是 word2vec

word2vec 的基本框架

word2vec 是 Google 研究团队里的 Tomas Mikolov 等人于 2013 年的《Efficient Estimation of Word Representations in Vector Space》以及后续的《《Distributed Representations ofWords and Phrases and their Compositionality》两篇文章中提出的一种高效训练词向量的方法,包含 Continuous Bag-of-Words Model (CBOW) 和 Continuous Skip-gram Model (skip-gram) 两个模型

alt text

其中,CBOW 模型是给定一个词的上下文词,希望预测这个词;而 skip-gram 是给定一个词,希望预测它的上下文词

跳元模型(Skip-Gram)

1)Skil-gram 语料构建

以 “we soon believe what he desire” 为例,滑动窗口大小

alt text

Skip-gram 是一个多分类的模型,当中心词是 believe 时,应该使得” We”,“soon”,“what”,“he” 出现概率最大,即

假设上下文词是在给定中心词的情况下独立生成的(即条件独立性)。在这种情况下,上述条件概率可以重写为:

2)Skip-gram 模型结构

下图是 Skip-gram 模型结构,输入词” believe” 先经过一个隐藏层,得到其隐向量 ,然后再和矩阵 做乘法,最后套上一个 softmax,得到所有词的输出概率。

alt text

根据上图的模型结构,我们可以得出,给定输入词 的词向量 ,输出其它词的概率为:

定义条件概率: 给定中心词 (w_c ),其上下文窗口内的某个词 (w_o) 的条件概率由 softmax 计算:

其中: - Missing superscript or subscript argument _c^:中心词 (w_c) 的向量(来自输入矩阵 (W ) 的)。 - :上下文词 (w_o) 的向量(来自输出矩阵 (W’) 的)。 - :词汇表。

这里举一个例子说明上图模型结构是如何根据输入词 ,预测输出词 的概率。就拿计算 为例,如图所示。

alt text

3)Skip-gram 模型训练

Skip-gram 的目标是最大化所有训练样本(中心词 - 上下文词对)的联合概率。假设语料库有 (T) 个词,窗口大小为 (m),则每个中心词 (w_t) 对应 (2m) 个上下文词,其似然函数为:

为了简化计算,我们通常取对数,得到对数似然函数

其中: - (= {W, W’}) 是模型参数(即两个词向量矩阵)。 - ( P (w_{t + j} | w_t) ) 是单个中心词 - 上下文词对的对数概率。

损失函数(Loss Function) 由于优化问题通常转化为最小化损失函数,我们对对数似然取负,得到负对数似然损失(Negative Log-Likelihood, NLL): [ () = - {t=1}^T {-m j m, j} P (w_{t + j} | w_t) ] 其中: - () 是为了归一化,使损失与语料库大小无关。 - 最小化 ( () ) 等价于最大化 ( () )。

计算梯度(以原始 softmax 为例) 为了优化损失函数,我们需要计算梯度。以单个中心词 - 上下文词对 ( (w_c, w_o) ) 为例: [ {c,o}() = -P (w_o | w_c) = -() ] 展开后: [ {c,o}() = -’_o c + ( {i=1}^V (’_i _c) ) ]

** 对中心词向量 (_c) 的梯度 ** [ = -‘o + {i = 1}^V P (w_i | w_c) ’_i ] 其中: - ( -‘o ) 是正样本(真实上下文词)的梯度。 - ( {i = 1}^V P (w_i | w_c) ’_i ) 是所有可能上下文词的期望梯度(负样本贡献)。

** 对上下文词向量 (’_o) 的梯度 ** [= -_c + P (w_o | w_c) _c]

4)优化改进:负采样(Negative Sampling)

由于原始 softmax 计算复杂度高(( O (V) )),Word2Vec 采用 负采样(NEG) 近似优化: [ _{c,o}() = -(’_o c) - {k = 1}^K (-’_k _c) ] 其中: - ( (x) = ) 是 sigmoid 函数。 - (K) 是负样本数量(通常 (K = 5 20))。 - 负样本 (w_k) 从噪声分布 ( P_n (w) ) 中采样(如 ( P_n (w) (w)^{3 / 4} ))。

相比于原来需要计算所有词的预测误差,负采样方法只需要对采样出的几个负样本计算预测误差。这样一来,Skip-gram 模型的优化目标从一个多分类问题转化为一个近似二分类问题,模型结构变成如图的形式。

负采样把” 从海量词汇中选最合适的词” 的多分类问题,转化为” 判断当前词对是否合理” 的二分类问题。这类似于:

原始问题:“这些 10000 个选项中哪个是正确的?”

负采样:“我告诉你 1 个正确选项和 5 个错误选项,请学会区分它们”

alt text

梯度计算(负采样版): [ = ( (’_o _c) - 1 ) ‘o + {k=1}^K (’_k _c) ’_k ]


总结

概念 公式
条件概率 ( P(w_o | w_c) = )
似然函数 ( () = {t=1}^T {-m j m} P(w_{t+j} | w_t) )
损失函数 ( () = - {t=1}^T {-m j m} P(w_{t+j} | w_t) )
负采样损失 ( _{c,o}() = -(’_o c) - {k=1}^K (-’_k _c) )

核心思想
- 通过最大化共现词对的概率,最小化非共现词对的概率,使词向量空间对齐语义关系。 - 负采样大幅提升了训练效率,避免了 softmax 的高计算成本。

参考资料

https://blog.csdn.net/v_JULY_v/article/details/102708459

https://zhuanlan.zhihu.com/p/352169069

前言

这两天完成了之前文本分类的任务,做了一周多,也跑出了比较好的结果。接下来要开始推荐系统相关的工作,之前从没有接触过,可以说是从零开始。Mentor 给我推荐了 SASRec 这篇文章,然后说后面的推荐系统构建以这个为基线,于是花了一个下午通读了论文,并且复现了代码

论文标题:Self-Attentive Sequential Recommendation 论文链接 论文原始代码(TF 实现) 论文代码(Pytorch 实现)

阅读全文 »

基本思想

协同过滤(Collaborative Filtering)推荐算法是最经典、最常用的推荐算法。核心思想为:物以类聚,人以群分

目前应用比较广泛的协同过滤算法是基于邻域的方法,主要有:

基于用户的协同过滤算法(UserCF):给用户推荐和他兴趣相似的其他用户喜欢的产品。 基于物品的协同过滤算法(ItemCF):给用户推荐和他之前喜欢的物品相似的物品。

找出最相似的人或物品:最相似的 TOP - N 根据相似的人或物品进行推荐

相似度算法

余弦相似度

不考虑长度,有时候会得到不是很靠谱的结果 两部电影,两个用户分别打分: ||m1|m2| |–|–|–| |u1|8|5| |u2|1|0.5|

余弦相似度很接近,但实际上一点也不相似

皮尔逊相关系数

也是一种余弦相似度,但是进行了向量中心化

杰卡德相似度

杰卡德相似度(Jaccard Similarity)是一种用于衡量两个集合相似度的指标,定义为两个集合交集的大小与并集的大小之比。其公式为:

其中 是两个集合, 表示交集的元素个数, 表示并集的元素个数。

适用场景: 杰卡德相似度常用于处理 “是否发生” 这类的隐式反馈数据(如用户是否点击、是否购买等),特别适合用于布尔型(0-1)数据的相似度计算。

举例: 假设 ,则

,交集大小为 2 ,并集大小为 5 所以

总结: 杰卡德相似度越接近 1,表示两个集合越相似;越接近 0,表示越不相似。

Jaccard 相似度表示两个集合的交集元素个数在并集中所占的比例 ,所以适用于隐式反馈数据(0-1)。 余弦相似度在度量文本相似度、用户相似度、物品相似度的时候都较为常用。 皮尔逊相关度,实际上也是一种余弦相似度。不过先对向量做了中心化,范围在 − 1 −1 到 1 1。 相关度量的是两个变量的变化趋势是否一致,两个随机变量是不是同增同减。 不适合用作计算布尔值向量(0-1)之间相关度。

前言

感觉每次看 pytorch 的代码,都会被其中的张量的维度给绕晕,尤其是遇到一些操作改变维度的时候,自己写的代码也是经常报维度的错误。正好最近学弟在看李沐老师的《动手学深度学习》的预备知识部分,为了解答一些问题,我也去重温了这一块知识,并对其中最重要也是最容易绕进去的张量降维与广播机制进行整理。

阅读全文 »

前言

记录一下自己使用 transformers 库的一些常见 work,以及各种参数等

Model 类

1
output = model(**input)

PyTorch 模型的 forward 方法通常接受关键字参数(如 input_ids、attention_mask、labels)

Tokenizer 对象是 callable,因此可以直接传入一个字符串,返回一个 dict。最主要的是 ID 的 list,同时也会返回 attention mask:

报错:

1
KeyError: "The `metric_for_best_model` training argument is set to 'eval_accuracy', which is not found in the evaluation metrics. The available evaluation metrics are: ['eval_runtime', 'eval_samples_per_second', 'eval_steps_per_second', 'epoch']. Consider changing the `metric_for_best_model` via the TrainingArguments."

首先看一下 compute_metrics 中 return 的 key 是否和 TrainingArguments 中 metric_for_best_model 的类型相同 Hugging Face 的 Trainer 原生支持多卡训练,无需手动包装 DataParallel:

Trainer 会自动根据 CUDA_VISIBLE_DEVICES 使用所有可用 GPU。

xlm-roberta-base 30 分类 3 RTX Titan 24G 显存 maxlength(tokenizer 中设定)=256 50w 条训练数据 epoch = 3 per_device_batch_size = 64

lr=3e-5

一开始开了 fp16,梯度直接爆炸了,不知道为什么 关闭了就好了不少

前言

我们在接触深度学习框架 pytorch 的时候,经常会听到 “自动微分” 这个词,以及他相较于传统微分算法的种种优点,那什么是微分算法,有哪些微分算法,和我们大学数学中学的微积分有什么关系与区别。这几个问题我将在下面一一解答。

阅读全文 »

前言

大学数学已经全部还给老师了,现在由于需要接触机器学习,其中不乏向量、矩阵、梯度的相关概念,然后各种求导公式看的云里雾里。为了彻底解决这方面的困惑,我决定把关于机器学习中各种和导数相关的概念都整理出来,以便自己的理解以及后续的查阅参考。

阅读全文 »
0%