Skip to content

Commit

Permalink
enrich(contrast learning): add SimCLR framework
Browse files Browse the repository at this point in the history
  • Loading branch information
GaoangLiu committed Nov 20, 2023
1 parent eb27b5d commit 513a01a
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 23 deletions.
15 changes: 11 additions & 4 deletions _drafts/2022/bm25.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,24 @@ $$\text{sim}(p, q) = E_Q(q)^T E_P(p)$$
其中, $E_Q(q)$ 是问题 $q$ 的向量表示,$E_P(p)$ 是段落 $p$ 的向量表示。$p, q$ 的相似度即它们的内积。选择内积来计算相似度是因为,1. 内积简单,计算速度快;2. 通过消融实验对比,其他方式例如 L2 范数,在效果没有特别大的差异,且都比余弦相似度效果要好。

## 模型结构
Dual Encoder 结构(也称 biEncoder),每个 encoder 都是一个 BERT,这跟[SBERT]({{site.baseurl}}/2022/10/18/Semantic-Similarity/#sbert)中的结构比较类似。不同之处在于 SBERT 中是 Siamese 结构(Siamese Dual Encoder,SDE,如下图左),即两个 encoder 共享参数,而 DRP 中是 Asymmetric Dual Encoder(ADE,如下图右),两个 encoder 的参数是独立的。关于 dual encoder 更多内容,可以阅读一个小论文 [《Exploring Dual Encoder Architectures for Question Answering》](https://aclanthology.org/2022.emnlp-main.640.pdf)
Dual Encoder 结构(也称 biEncoder),每个 encoder 都是一个 BERT,这跟[SBERT]({{site.baseurl}}/2022/10/18/Semantic-Similarity/#sbert)中的结构比较类似。不同之处在于 SBERT 中是 Siamese 结构(Siamese Dual Encoder,SDE,如下图左),即两个 encoder 共享参数,而 DRP 中是 Asymmetric Dual Encoder(ADE,如下图中),两个 encoder 的参数是独立的。关于 dual encoder 更多内容,可以阅读一个小论文 [《Exploring Dual Encoder Architectures for Question Answering》](https://aclanthology.org/2022.emnlp-main.640.pdf)

<figure style="text-align:center">
<img src="https://image.ddot.cc/202311/dual-encoders_20231118_0406.png" width=578pt>
<figcaption style="text-align: center;">SDE v.s. ADE</figcaption>
<img src="https://image.ddot.cc/202311/dual-encoders_20231120_1825.png" width=778pt>
<figcaption style="text-align: center;">SDE v.s. ADE v.s. Cross encoder</figcaption>
</figure>

## 训练
DPR 训练的目的是要学习得到一个嵌入函数/映射,将相关的 query/answer 映射到向量空间中距离相似的向量,这本质上是一个度量学习的问题。那流程无怪乎选择 Siamese Networks 或者 Triplet Networks,通过最小优化损失函数,来学习得到这个嵌入函数。

DPR 的损失函数定义为:
DPR 使用了 [N-pair 损失函数](https://papers.nips.cc/paper_files/paper/2016/file/6b180037abbebea991d8b1232f8a8ca9-Paper.pdf),N-pair loss 的一般形式是

$$\begin{aligned}
\mathcal{L}_{\text{N-pair}}(x, x^+, \{x_i^-\}_{i=1}^{N-1}) &= \log(1 + \sum_{i=1}^{N-1} \exp(f(x)^T f(x_i^-) - f(x)^T f(x^+))) \\\
&= - \log \frac{\exp(f(x)^T f(x^+))}{\exp(f(x)^T f(x^+)) + \sum_{i=1}^{N-1} \exp(f(x)^T f(x_i^-))}
\end{aligned}$$

因为是通过相似度来确定 query, passage 距离的,这里 $f=\text{sim}$:

$$ \mathcal{L}(a) = - \log \frac{e^{\text{sim}(q_i, p_i^+) / \tau}}{(\sum_{j=1}^{n} e^{\text{sim}(q_i, p_j^-) / \tau}) + e^{\text{sim}(q_i, p_i^+) / \tau}}$$

Expand Down
22 changes: 20 additions & 2 deletions _drafts/2022/contrast_learning.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ categories:
- nlp
---

文本表示学习就是将一段文本映射到低维向量空间,获取句子的**语义表示**,大致经历过四个阶段:
# 表征学习
文本表征学习就是将一段文本映射到低维向量空间,获取句子的**语义表示**,大致经历过四个阶段:

- 统计类型,典型的方法是利用 TD-IDF 抽取关键词,用关键词表示表征整个句子。
- 深度模型阶段,此阶段方式较多,自从 glove、word2vec 等词粒度的表示出现后,在此基础有比较多的延伸工作,从对句子中的词向量简单平均、到有偏平均 SIF[1],后来引入 CNN、LSTM 等模型利用双塔、单塔方式进行学习句子表示,比较典型的几个工作有
Expand All @@ -20,7 +21,24 @@ categories:
- 由于 Bert 通过 SEP 分割,利用 CLS 运用到匹配任务场景存在计算量过大的问题,Sentence-BERT[6] 提出将句子拆开,每个句子单独过 encoder,借鉴 InferSent 的表示交互,来学习句子表达。
- 20 年在图像领域兴起的对比学习引入到 NLP。

# 思想
# 对比学习
对比学习(contrast learning)一般划分到无监督学习(USL)的范畴,典型范式就是:<span style="color:blue">[代理任务](https://stats.stackexchange.com/questions/404602/pretext-task-in-computer-vision)+目标函数</span>,这两项也是对比学习与有监督学习(SL)最大的区别。


SL 中有输入 $x$,有对应的 ground truth $y$,计算模型输出的 $y_p$ 与 $y$ 通过目标函数计算损失,指导模型训练。对于 USL 来说,是没有 ground truth 的,而这里就是代理任务发挥作用的地方,代理任务用来定义正负样本,我们通过训练一个模型来解决代理任务,从而学习到一个好的表征,使得这个表征可以轻松适应到下游任务。[SimCLR](https://arxiv.org/pdf/2002.05709.pdf) 的框架如下图,大体流程:
1. 数据增强,采样,构造正负样本。
2. 通过对比损失训练特征提取器 (encoder) $f$ 及一个映射头 $g$,$g$ 用来将 $f$ 的输出映射到一个低维空间。在 SimCLR 中 projection head 是一个两层的 MLP,维度是 128 维。
3. 在下游任务中,把 projection head 去掉,只保留 $f$,用 $f$ 的输出作为特征,进行下游任务的训练。

<figure class="half">
<img src="https://image.ddot.cc/202311/simclr_20231120_2017.png" width="700" />
<figcaption>SimCLR framework</figcaption>
</figure>




# 在 NLP 中应用
对比学习的目标是使得**相似的东西表示越相似,不相似的东西越不相似**。一般训练过程:

1. 通过数据增强的方式构造训练数据集,对于一条数据,数据集需要包含正例(相似的数据)和负例(不相似的数据)。
Expand Down
18 changes: 18 additions & 0 deletions _drafts/2023/prefix_tunning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
layout: post
title: Prefix Tunning
date: 2023-11-19
tags: [prefix-tunning, peft]
categories:
- nlp
---

- [ ] Prefix-tunning 是什么,解决什么问题?
- [ ] 是如何解决这个问题的?
- [ ] 有什么特点?
- [ ] 适用场景?


主流的 NLP 任务都是 pretraining + fine-tuning 的范式,即在预训练模型的基础上,针对特定任务进行微调。这种方法的优点是简单,但在当下模型越来越大的情况下,fine-tuning 的成本也越来越高。另外,fine-tuning 也有一些缺点,例如,模型的泛化能力不强,对于一些小数据集,模型的效果很差。针对这些问题,有一些研究者提出了一些方法,例如,[《Prefix-Tuning: Optimizing Continuous Prompts for Generation》](https://arxiv.org/pdf/2101.00190.pdf) 就是一种新的 fine-tuning 方法,它可以在不改变模型参数的情况下,通过修改输入的前缀来优化模型的效果。这种方法的优点是可以在不改变模型参数的情况下,优化模型的效果,而且可以在小数据集上取得很好的效果。

是一种轻量的 NLG 任务调参技术,解决 fine-tuning 方法在 LLM 上
17 changes: 7 additions & 10 deletions _drafts/2023/rag.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,12 @@ categories:
- nlp
---

本文关注以下几个问题 。
- [ ] RAG 是什么?
- [ ] 如何实现的?
- [ ] 有什么优势 ?
- [ ] 使用场景有哪些?
ChatGPT 爆火之后,有一段时间内很多公司都在竞相做向量数据库,一些数据库厂商也在竞相在传统数据库上增加向量存储功能,支持相似度检索。常规做法是通过预训练获取一个大模型,然后将数据向量化并存储。这种做法有几个问题:
1. 幻觉问题。这是 LLM 的通病之一 。
2. 无法更新、扩展。模型一旦训练好,就无法更新了,而且更新模型的成本很高。
3. 可解释性差。难以解释解释为什么这个向量与这个文档相关。

ChatGPT 爆火之后,有一段时间内很多公司都在竞相做向量数据库,一些数据库厂商也在竞相在传统数据库上增加向量存储功能。常见的做法是通过预训练获取一个大模型,然后将数据向量化并存储。


关于检索,一个比较引入注目的技术是 RAG (Retrieval-Augmented Generation)。这个技术由 meta 于 2020 年在论文 [《Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks》](https://arxiv.org/pdf/2005.11401.pdf) 中提出,它是一个检索增强的生成模型,通过检索得到的上下文信息来指导生成,从而提高生成的质量。这里面有两个主要的模块,一个是检索,使用的技术是 DPR(Dense Passage Retrieval),即是 20 年推出的“暴打前浪 BM25” 的技术,同样也是 meta 的工作。DPR 整体结构是一个 dual encoder: document encoder 和 query encoder,两个 encoder 使用的模型都是 $\text{BERT}_\text{BASE}$。关于 DPR 的机制,我们在之前的文章[《Okapi-BM25》]({{site.baseur}}/2022/11/17/Okapi-BM25/)里稍有提过。另一个模块是 seq2seq 生成器,模型使用的 [BART-large](https://arxiv.org/abs/1910.13461)(也是 meta 的工作)。
知识难以更新的问题对于一些信息动态更新的任务来说,是一个巨大的挑战。例如,对于一些 QA 任务,答案可能会随着时间的推移而变化,e.g., “最近一届奥运会在哪个城市举办的?”,这时候就需要更新模型的知识,传统的做法对于这一问题就无能为力了。LLM 在近两年的发展中,一个被广泛认可的技术是 RAG (Retrieval-Augmented Generation)。这个技术由 meta 于 2020 年在论文 [《Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks》](https://arxiv.org/pdf/2005.11401.pdf) 中提出,它是一个检索增强的生成模型,通过检索得到的上下文信息来指导生成,从而提高生成的质量。这里面比较关键的一环是“检索增强”,检索用到的知识可以轻松地随时更改或补充,在需要更新知识时,不需要重新训练整个模型。RAG 使用的检索方案是 DPR(Dense Passage Retrieval),即是 20 年推出的“暴打前浪 BM25” 的技术,同样也是 meta 的工作。DPR 整体结构是一个 dual encoder: document encoder 和 query encoder,两个 encoder 使用的模型都是 $\text{BERT}_\text{BASE}$。关于 DPR 的机制,我们在之前的文章[《Okapi-BM25》]({{site.baseur}}/2022/11/17/Okapi-BM25/)里稍有提过。另一个模块是 seq2seq 生成器,模型使用的 [BART-large](https://arxiv.org/abs/1910.13461)(也是 meta 的工作)。


# RAG 结构
Expand All @@ -40,7 +36,7 @@ p_\text{RAG-sequence}(y\lvert x) &\approx \sum_{z\in \mathcal{Z}} p_\eta(z\lvert
对应的 RAG-token 在生成每一个 token 时都有一个对应的边际分布,训练模型也即是最大化下面的概率:

$$\begin{aligned}
p_\text{RAG-token}(y\lvert x) &\approx \prod_{i=1}^N \sum_{z\in \mathcal{Z}} p_\eta(z\lvert x)p_\theta(y_i\lvert x, z, y_{1,...,i-1})
p_\text{RAG-token}(y\lvert x) &\approx \prod_{i=1}^N \sum_{z\in \mathcal{Z}} p_\eta(z\lvert x)p_\theta(y_i\lvert x, z_i, y_{1,...,i-1})
\end{aligned}$$

## Retriever
Expand Down Expand Up @@ -90,6 +86,7 @@ $$p(z\lvert x) = \frac{p(x\lvert z)p(z)}{p(x)}$$


## 参考
- [NeurIPS 2020|RAG:为知识密集型任务而生](https://zhuanlan.zhihu.com/p/264485658)
- [变分推断(Variational Inference)进展简述](https://zhuanlan.zhihu.com/p/88336614)
- [《Variational Inference: A Review for Statisticians》](https://arxiv.org/pdf/1601.00670.pdf)
- [变分推断(Variational Inference)初探](https://www.cnblogs.com/song-lei/p/16210740.html)
15 changes: 11 additions & 4 deletions _posts/2022/2022-11-17-Okapi-BM25.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,24 @@ $$\text{sim}(p, q) = E_Q(q)^T E_P(p)$$
其中, $$E_Q(q)$$ 是问题 $$q$$ 的向量表示,$$E_P(p)$$ 是段落 $$p$$ 的向量表示。$$p, q$$ 的相似度即它们的内积。选择内积来计算相似度是因为,1. 内积简单,计算速度快;2. 通过消融实验对比,其他方式例如 L2 范数,在效果没有特别大的差异,且都比余弦相似度效果要好。

## 模型结构
Dual Encoder 结构(也称 biEncoder),每个 encoder 都是一个 BERT,这跟[SBERT]({{site.baseurl}}/2022/10/18/Semantic-Similarity/#sbert)中的结构比较类似。不同之处在于 SBERT 中是 Siamese 结构(Siamese Dual Encoder,SDE,如下图左),即两个 encoder 共享参数,而 DRP 中是 Asymmetric Dual Encoder(ADE,如下图右),两个 encoder 的参数是独立的。关于 dual encoder 更多内容,可以阅读一个小论文 [《Exploring Dual Encoder Architectures for Question Answering》](https://aclanthology.org/2022.emnlp-main.640.pdf)
Dual Encoder 结构(也称 biEncoder),每个 encoder 都是一个 BERT,这跟[SBERT]({{site.baseurl}}/2022/10/18/Semantic-Similarity/#sbert)中的结构比较类似。不同之处在于 SBERT 中是 Siamese 结构(Siamese Dual Encoder,SDE,如下图左),即两个 encoder 共享参数,而 DRP 中是 Asymmetric Dual Encoder(ADE,如下图中),两个 encoder 的参数是独立的。关于 dual encoder 更多内容,可以阅读一个小论文 [《Exploring Dual Encoder Architectures for Question Answering》](https://aclanthology.org/2022.emnlp-main.640.pdf)

<figure style="text-align:center">
<img src="https://image.ddot.cc/202311/dual-encoders_20231118_0406.png" width=578pt>
<figcaption style="text-align: center;">SDE v.s. ADE</figcaption>
<img src="https://image.ddot.cc/202311/dual-encoders_20231120_1825.png" width=778pt>
<figcaption style="text-align: center;">SDE v.s. ADE v.s. Cross encoder</figcaption>
</figure>

## 训练
DPR 训练的目的是要学习得到一个嵌入函数/映射,将相关的 query/answer 映射到向量空间中距离相似的向量,这本质上是一个度量学习的问题。那流程无怪乎选择 Siamese Networks 或者 Triplet Networks,通过最小优化损失函数,来学习得到这个嵌入函数。

DPR 的损失函数定义为:
DPR 使用了 [N-pair 损失函数](https://papers.nips.cc/paper_files/paper/2016/file/6b180037abbebea991d8b1232f8a8ca9-Paper.pdf),N-pair loss 的一般形式是

$$\begin{aligned}
\mathcal{L}_{\text{N-pair}}(x, x^+, \{x_i^-\}_{i=1}^{N-1}) &= \log(1 + \sum_{i=1}^{N-1} \exp(f(x)^T f(x_i^-) - f(x)^T f(x^+))) \\\
&= - \log \frac{\exp(f(x)^T f(x^+))}{\exp(f(x)^T f(x^+)) + \sum_{i=1}^{N-1} \exp(f(x)^T f(x_i^-))}
\end{aligned}$$

因为是通过相似度来确定 query, passage 距离的,这里 $$f=\text{sim}$$

$$ \mathcal{L}(a) = - \log \frac{e^{\text{sim}(q_i, p_i^+) / \tau}}{(\sum_{j=1}^{n} e^{\text{sim}(q_i, p_j^-) / \tau}) + e^{\text{sim}(q_i, p_i^+) / \tau}}$$

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ author: berrysleaf
{:toc}


文本表示学习就是将一段文本映射到低维向量空间,获取句子的**语义表示**,大致经历过四个阶段:
# 表征学习
文本表征学习就是将一段文本映射到低维向量空间,获取句子的**语义表示**,大致经历过四个阶段:



Expand All @@ -26,7 +27,24 @@ author: berrysleaf
- 由于 Bert 通过 SEP 分割,利用 CLS 运用到匹配任务场景存在计算量过大的问题,Sentence-BERT[6] 提出将句子拆开,每个句子单独过 encoder,借鉴 InferSent 的表示交互,来学习句子表达。
- 20 年在图像领域兴起的对比学习引入到 NLP。

# 思想
# 对比学习
对比学习(contrast learning)一般划分到无监督学习(USL)的范畴,典型范式就是:<span style="color:blue">[代理任务](https://stats.stackexchange.com/questions/404602/pretext-task-in-computer-vision)+目标函数</span>,这两项也是对比学习与有监督学习(SL)最大的区别。


SL 中有输入 $$x$$,有对应的 ground truth $$y$$,计算模型输出的 $$y_p$$$$y$$ 通过目标函数计算损失,指导模型训练。对于 USL 来说,是没有 ground truth 的,而这里就是代理任务发挥作用的地方,代理任务用来定义正负样本,我们通过训练一个模型来解决代理任务,从而学习到一个好的表征,使得这个表征可以轻松适应到下游任务。[SimCLR](https://arxiv.org/pdf/2002.05709.pdf) 的框架如下图,大体流程:
1. 数据增强,采样,构造正负样本。
2. 通过对比损失训练特征提取器 (encoder) $$f$$ 及一个映射头 $$g$$$$g$$ 用来将 $$f$$ 的输出映射到一个低维空间。在 SimCLR 中 projection head 是一个两层的 MLP,维度是 128 维。
3. 在下游任务中,把 projection head 去掉,只保留 $$f$$,用 $$f$$ 的输出作为特征,进行下游任务的训练。

<figure class="half">
<img src="https://image.ddot.cc/202311/simclr_20231120_2017.png" width="700" />
<figcaption>SimCLR framework</figcaption>
</figure>




# 在 NLP 中应用
对比学习的目标是使得**相似的东西表示越相似,不相似的东西越不相似**。一般训练过程:

1. 通过数据增强的方式构造训练数据集,对于一条数据,数据集需要包含正例(相似的数据)和负例(不相似的数据)。
Expand Down
24 changes: 24 additions & 0 deletions _posts/2023/2023-11-19-Prefix-Tunning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
layout: post
title: Prefix Tunning
date: 2023-11-19
tags: prefix-tunning peft
categories: nlp
author: berrysleaf
---
* content
{:toc}


- [ ] Prefix-tunning 是什么,解决什么问题?



- [ ] 是如何解决这个问题的?
- [ ] 有什么特点?
- [ ] 适用场景?


主流的 NLP 任务都是 pretraining + fine-tuning 的范式,即在预训练模型的基础上,针对特定任务进行微调。这种方法的优点是简单,但在当下模型越来越大的情况下,fine-tuning 的成本也越来越高。另外,fine-tuning 也有一些缺点,例如,模型的泛化能力不强,对于一些小数据集,模型的效果很差。针对这些问题,有一些研究者提出了一些方法,例如,[《Prefix-Tuning: Optimizing Continuous Prompts for Generation》](https://arxiv.org/pdf/2101.00190.pdf) 就是一种新的 fine-tuning 方法,它可以在不改变模型参数的情况下,通过修改输入的前缀来优化模型的效果。这种方法的优点是可以在不改变模型参数的情况下,优化模型的效果,而且可以在小数据集上取得很好的效果。

是一种轻量的 NLG 任务调参技术,解决 fine-tuning 方法在 LLM 上
8 changes: 8 additions & 0 deletions assets/progress.json
Original file line number Diff line number Diff line change
Expand Up @@ -486,5 +486,13 @@
[
"2023-11-18",
738
],
[
"2023-11-19",
453
],
[
"2023-11-20",
292
]
]
Binary file added images/2023/11/simclr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/graphviz/2023/a.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 513a01a

Please sign in to comment.