├── README.md └── docs ├── .nojekyll ├── README.md ├── _sidebar.md ├── index.html ├── resources └── AI部落联盟.jpg ├── 深度学习应用 ├── 前言.md ├── 自然语言处理任务 │ ├── 1-language_modeling-语言模型.md │ ├── 2-translation-机器翻译.md │ ├── 3-question_answering-机器问答.md │ ├── 4-summarization-摘要生成.md │ ├── 5-token_classification-词_符号_token级别分类任务.md │ ├── images │ │ ├── causal_language_modeling.png │ │ ├── masked_language_modeling.png │ │ ├── model_parameters.png │ │ ├── question_answering.png │ │ ├── request_error.png │ │ ├── summarization.png │ │ ├── text_classification.png │ │ ├── token_classification.png │ │ └── translation.png │ └── 前言.md └── 计算机视觉任务 │ ├── 1-Vision Transformer使用和facebook自监督学习DINO训练方法.md │ └── 前言.md ├── 深度学习数学基础 ├── 0-前言.md ├── 1.1-标量、向量、矩阵和张量.md ├── 1.2-简单的线性代数.md ├── 2.1-标量:导数的概念.md ├── 2.2-标量:链式法则.md ├── 2.3-标量:求导常用公式.md ├── 2.4-多个标量:多元函数求导、偏导数.md ├── 2.5-方向导数和梯度.md ├── 2.6-向量的梯度和Jacobian矩阵.md ├── 2.7-矩阵和张量的梯度.md ├── 2.8-神经网络中几个实用的梯度计算.md ├── 2021-06-05.md ├── 3.1-神经网络中的反向传播.md ├── 3.2-单层神经网络梯度计算例子.md ├── 4.1-Pytorch自动求梯度.md └── 4.2-Tensorflow自动求梯度.md └── 深度学习模型基础 └── transformer基本原理讲解 ├── 0-前言.md ├── 1.1-图解attetion.md ├── 1.2-图解transformer.md ├── 1.3-图解BERT.md ├── 1.4-图解GPT.md └── pictures ├── 1-2-translation.gif ├── 1-3-encoder-decoder.gif ├── 1-4-context-example.png ├── 1-5-word-vector.png ├── 1-6-rnn.png ├── 1-7-attetion.png ├── 1-8-attention-vis.png ├── 1-seq2seq.gif ├── 2-2layer.png ├── 2-6words.webp ├── 2-8z.webp ├── 2-all-att.png ├── 2-am.webp ├── 2-attention-output.webp ├── 2-attention-word.png ├── 2-decoder.gif ├── 2-decoder.webp ├── 2-encoder-decoder.gif ├── 2-encoder-decoder.png ├── 2-encoder.png ├── 2-input-output.png ├── 2-it-attention.webp ├── 2-linear.png ├── 2-loss.webp ├── 2-lyn.png ├── 2-multi-encoder.webp ├── 2-multi-head.png ├── 2-positin4.png ├── 2-position.png ├── 2-position2.png ├── 2-position3.png ├── 2-put-together.webp ├── 2-qkv-multi.png ├── 2-qkv.png ├── 2-resnet.png ├── 2-sum.png ├── 2-target.png ├── 2-think.png ├── 2-think2.png ├── 2-to1.webp ├── 2-trained.webp ├── 2-trans-example.png ├── 2-transformer-stru.png ├── 2-transformer.png ├── 2-translation.png ├── 2-x-encoder.png ├── 2-x.png ├── 3-bert-2sent.webp ├── 3-bert-app.png ├── 3-bert-bl.webp ├── 3-bert-cls.png ├── 3-bert-clss.webp ├── 3-bert-elmo.png ├── 3-bert-encoder.webp ├── 3-bert-fea.webp ├── 3-bert-feature.png ├── 3-bert-input.png ├── 3-bert-mask.webp ├── 3-bert-output.png ├── 3-bert.webp ├── 3-cnn.png ├── 3-elmo-emb.png ├── 3-elmo-pre.webp ├── 3-elmo-pre1.png ├── 3-elmo-pre2.webp ├── 3-elmo.webp ├── 3-openai-down.png ├── 3-openai-method.webp ├── 3-openai-next.webp ├── 3-openai.webp ├── 3-single-vector.png ├── 3-stru.png ├── 3-trash.png ├── 3-wordvector.webp ├── 4-att-3.webp ├── 4-att-31.webp ├── 4-att-32.webp ├── 4-att-33.webp ├── 4-att-34.webp ├── 4-att-it.png ├── 4-decoder.webp ├── 4-decoder1.webp ├── 4-encoder.webp ├── 4-full.gif ├── 4-full.webp ├── 4-gpt-bert.webp ├── 4-gpt-fllow.webp ├── 4-gpt-his.webp ├── 4-gpt-his2.webp ├── 4-gpt-it.webp ├── 4-gpt-out.webp ├── 4-gpt-out1.webp ├── 4-gpt-out3.webp ├── 4-gpt-out4.webp ├── 4-gpt-pos.webp ├── 4-gpt-query.webp ├── 4-gpt-score.webp ├── 4-gpt-sum.webp ├── 4-gpt-token-pos.png ├── 4-gpt-token.png ├── 4-gpt2-1.png ├── 4-gpt2-a.png ├── 4-gpt2-it.webp ├── 4-gpt2-it1.webp ├── 4-gpt2-it2.webp ├── 4-gpt2-it3.png ├── 4-gpt2-it4.webp ├── 4-gpt2-it5.webp ├── 4-gpt2-it6.webp ├── 4-gpt2-it7.webp ├── 4-gpt2-it8.webp ├── 4-gpt2-output.webp ├── 4-gpt2-output2.webp ├── 4-gpt2-r.png ├── 4-gpt2-self.png ├── 4-gpt2-start.webp ├── 4-gpt2-the.gif ├── 4-mask-matrix.webp ├── 4-mask-q.webp ├── 4-mask-s.webp ├── 4-mask-soft.webp ├── 4-mask.png ├── 4-mask.webp ├── 4-music.webp ├── 4-music1.png ├── 4-music2.png ├── 4-music3.png ├── 4-project.png ├── 4-stru.webp ├── 4-sum.png ├── 4-sum1.png ├── 4-sum2.png ├── 4-trans-decoder.webp ├── 4-trans.png ├── 4-transformer.webp ├── 4-vector.webp ├── 4-wiki.png ├── 4-wiki1.webp └── 4-word2vec.webp /README.md: -------------------------------------------------------------------------------- 1 | # 深度学习基础 2 | > [深度学习基础Github](https://github.com/erenup/deeplearningbasics) 3 | > 4 | > 欢迎来到深度学习基础教程。本教程面向所有**深度学习爱好者/学生/求职人员/算法工程师新手**,希望能从深度学习数学知识、深度学习模型基础、深度学习应用等三个方面对深度学习相关内容进行总结学习。 5 | > 6 | > 笔者在自学深度学习的过程中,发现大部分教程、资料对于深度学习所涉及的数学知识、实践操作讲解并不能让自己完全理解,所以在学习了李沐老师的《动手学深度学习》、斯坦福cs224n、斯坦福231n等各个经典课程之后,笔者将学习过程进行总结,也算是对自己知识体系的一个梳理。 7 | > 8 | > 希望读者在看完本教程之后,能基于高中数学/大学本科一年级数学基础知识和简单的Python编程知识来对深度学习知识进行扎实学习和应用。 9 | > 10 | > 本教程做为交流学习使用,整理了众多资料,由于自己精力有限,暂时无法对所有内容进行重写和图片自创. 本教程参考了北京理工大学毛京中老师的《高等数学》、李沐老师的《动手学深度学习》、斯坦福cs231n、斯坦福224n、各知乎精华问答、各大牛博客知识,如果**涉及侵权请联系我删除**,谢谢! 11 | > 12 | > 如果您在文章中发现错误之处,请帮忙在github提交issue/request,我将及时进行修正,谢谢! 13 | > 14 | 15 | ## 使用说明 16 | - **深度学习数学基础**从标量、向量、矩阵、张量讲起,然后逐步展开求导、偏导、方向导数、梯度,最后对单层神经网络进行了求梯度演示。 17 | - **深度学习模型基础**希望能够对常用的模型结构(transformer、lstm、cnn、mlp)进行通俗易懂的讲解。 18 | - **深度学习应用**希望能为常见的深度学习任务提供详细的例子,帮助读者一步步读取数据、预处理数据、调用正确的模型、运行模型、后处理模型预测结果、得到接近SOTA的结果。 19 | 20 | ## 主要内容-持续更新中 21 | 22 | * [首页](/) 23 | * [深度学习数学基础-初步完结](./docs/深度学习数学基础/0-前言.md) 24 | * [1.1 标量、向量、矩阵、张量](./docs/深度学习数学基础/1.1-标量、向量、矩阵和张量.md) 25 | * [1.2 简单的线性代数](./docs/深度学习数学基础/1.2-简单的线性代数.md) 26 | * [2.1-标量:导数的概念](./docs/深度学习数学基础/2.1-标量:导数的概念.md) 27 | * [2.2-标量:链式法则](./docs/深度学习数学基础/2.2-标量:链式法则.md) 28 | * [2.3-标量:求导常用公式](./docs/深度学习数学基础/2.3-标量:求导常用公式.md) 29 | * [2.4-多个标量:多元函数求导、偏导数](./docs/深度学习数学基础/2.4-多个标量:多元函数求导、偏导数.md) 30 | * [2.5-方向导数和梯度](./docs/深度学习数学基础/2.5-方向导数和梯度.md) 31 | * [2.6-向量的梯度和Jacobian矩阵](./docs/深度学习数学基础/2.6-向量的梯度和Jacobian矩阵.md) 32 | * [2.7-矩阵和张量的梯度](./docs/深度学习数学基础/2.7-矩阵和张量的梯度.md) 33 | * [2.8-神经网络中几个实用的梯度计算](./docs/深度学习数学基础/2.8-神经网络中几个实用的梯度计算.md) 34 | * [3.1-神经网络中的反向传播](./docs/深度学习数学基础/3.1-神经网络中的反向传播.md) 35 | * [3.2-单层神经网络梯度计算例子](./docs/深度学习数学基础/3.2-单层神经网络梯度计算例子.md) 36 | * [4.1-Pytorch自动求梯度](./docs/深度学习数学基础/4.1-Pytorch自动求梯度.md) 37 | * [4.2-Tensorflow自动求梯度](./docs/深度学习数学基础/4.2-Tensorflow自动求梯度.md) 38 | * [深度学习模型基础-更新中](./docs/深度学习模型基础/transformer基本原理讲解/0-前言.md) 39 | * [1.1-图解attetion](./docs/深度学习模型基础/transformer基本原理讲解/1.1-图解attetion.md) 40 | * [1.2-图解transformer](./docs/深度学习模型基础/transformer基本原理讲解/1.2-图解transformer.md) 41 | * [1.3-图解BERT](./docs/深度学习模型基础/transformer基本原理讲解/1.3-图解BERT.md) 42 | * [1.4-图解GPT](./docs/深度学习模型基础/transformer基本原理讲解/1.4-图解GPT.md) 43 | * [深度学习应用-更新中](./docs/深度学习应用/前言.md) 44 | * [自然语言处理](./docs/深度学习应用/自然语言处理任务/前言.md) 45 | * [1-语言模型](./docs/深度学习应用/自然语言处理任务/1-language_modeling-语言模型.md) 46 | * [2-机器翻译](./docs/深度学习应用/自然语言处理任务/2-translation-机器翻译.md) 47 | * [3-机器问答](./docs/深度学习应用/自然语言处理任务/3-question_answering-机器问答.md) 48 | * [4-摘要生成](./docs/深度学习应用/自然语言处理任务/4-summarization-摘要生成.md) 49 | * [5-token 分类](./docs/深度学习应用/自然语言处理任务/5-token_classification-词_符号_token级别分类任务.md) 50 | * [计算机视觉]() 51 | * [1-Vit和自监督学习](./docs/深度学习应用/计算机视觉任务/1-Vision%20Transformer使用和facebook自监督学习DINO训练方法.md) 52 | 53 | 54 | 55 | 56 | > 我的知乎是[多多笔记](http://www.zhihu.com/people/nai-ping-46-76) 57 | > 58 | > 可以添加这个微信号联系我:bit_pku_eecs,备注:交流,可以帮拉入transformer、NLP、深度学习的交流群进行讨论。 59 | > 60 | > 也欢迎关注公众号:![公众号](./docs/resources/AI部落联盟.jpg) 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/.nojekyll -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # 深度学习基础(deeplearningbasics) 2 | > [深度学习基础Github](https://github.com/erenup/deeplearningbasics) 3 | > 4 | > 欢迎来到深度学习基础教程。本教程面向所有**深度学习爱好者/学生/求职人员/算法工程师新手**,希望能从深度学习数学知识、深度学习模型基础、深度学习应用等三个方面对深度学习相关内容进行总结学习。 5 | > 6 | > 笔者在自学深度学习的过程中,发现大部分教程、资料对于深度学习所涉及的数学知识、实践操作讲解并不能让自己完全理解,所以在学习了李沐老师的《动手学深度学习》、斯坦福cs224n、斯坦福231n等各个经典课程之后,笔者将学习过程进行总结,也算是对自己知识体系的一个梳理。 7 | > 8 | > 希望读者在看完本教程之后,能基于高中数学/大学本科一年级数学基础知识和简单的Python编程知识来对深度学习知识进行扎实学习和应用。 9 | > 10 | > 本教程做为交流学习使用,整理了众多资料,由于自己精力有限,暂时无法对所有内容进行重写和图片自创. 本教程参考了北京理工大学毛京中老师的《高等数学》、李沐老师的《动手学深度学习》、斯坦福cs231n、斯坦福224n、各知乎精华问答、各大牛博客知识,如果**涉及侵权请联系我删除**,谢谢! 11 | > 12 | > 如果您在文章中发现错误之处,请帮忙在github提交issue/request,我将及时进行修正,谢谢! 13 | > 14 | 15 | 16 | ## 使用说明 17 | - **深度学习数学基础**从标量、向量、矩阵、张量讲起,然后逐步展开求导、偏导、方向导数、梯度,最后对单层神经网络进行了求梯度演示。 18 | - **深度学习模型基础**希望能够对常用的模型结构(transformer、lstm、cnn、mlp)进行通俗易懂的讲解。 19 | - **深度学习应用**希望能为常见的深度学习任务提供详细的例子,帮助读者一步步读取数据、预处理数据、调用正确的模型、运行模型、后处理模型预测结果、得到接近SOTA的结果。 20 | 21 | ## 主要内容-持续更新中 22 | 23 | * [深度学习基础首页](/) 24 | * [深度学习数学基础-初步完结](./深度学习数学基础/0-前言) 25 | * [1.1 标量、向量、矩阵、张量](./深度学习数学基础/1.1-标量、向量、矩阵和张量.md) 26 | * [1.2 简单的线性代数](./深度学习数学基础/1.2-简单的线性代数.md) 27 | * [2.1-标量:导数的概念](./深度学习数学基础/2.1-标量:导数的概念.md) 28 | * [2.2-标量:链式法则](./深度学习数学基础/2.2-标量:链式法则.md) 29 | * [2.3-标量:求导常用公式](./深度学习数学基础/2.3-标量:求导常用公式.md) 30 | * [2.4-多个标量:多元函数求导、偏导数](./深度学习数学基础/2.4-多个标量:多元函数求导、偏导数.md) 31 | * [2.5-方向导数和梯度](./深度学习数学基础/2.5-方向导数和梯度.md) 32 | * [2.6-向量的梯度和Jacobian矩阵](./深度学习数学基础/2.6-向量的梯度和Jacobian矩阵.md) 33 | * [2.7-矩阵和张量的梯度](./深度学习数学基础/2.7-矩阵和张量的梯度.md) 34 | * [2.8-神经网络中几个实用的梯度计算](./深度学习数学基础/2.8-神经网络中几个实用的梯度计算.md) 35 | * [3.1-神经网络中的反向传播](./深度学习数学基础/3.1-神经网络中的反向传播.md) 36 | * [3.2-单层神经网络梯度计算例子](./深度学习数学基础/3.2-单层神经网络梯度计算例子.md) 37 | * [4.1-Pytorch自动求梯度](./深度学习数学基础/4.1-Pytorch自动求梯度.md) 38 | * [4.2-Tensorflow自动求梯度](./深度学习数学基础/4.2-Tensorflow自动求梯度.md) 39 | * [深度学习模型基础-更新中](./深度学习模型基础/transformer基本原理讲解/0-前言.md) 40 | * [1.1-图解attetion](./深度学习模型基础/transformer基本原理讲解/1.1-图解attetion.md) 41 | * [1.2-图解transformer](./深度学习模型基础/transformer基本原理讲解/1.2-图解transformer.md) 42 | * [1.3-图解BERT](./深度学习模型基础/transformer基本原理讲解/1.3-图解BERT.md) 43 | * [1.4-图解GPT](./深度学习模型基础/transformer基本原理讲解/1.4-图解GPT.md) 44 | * [深度学习应用-更新中](./深度学习应用/前言.md) 45 | * [自然语言处理](./深度学习应用/自然语言处理任务/前言.md) 46 | * [1-语言模型](./深度学习应用/自然语言处理任务/1-language_modeling-语言模型.md) 47 | * [2-机器翻译](./深度学习应用/自然语言处理任务/2-translation-机器翻译.md) 48 | * [3-机器问答](./深度学习应用/自然语言处理任务/3-question_answering-机器问答.md) 49 | * [4-摘要生成](./深度学习应用/自然语言处理任务/4-summarization-摘要生成.md) 50 | * [5-token 分类](./深度学习应用/自然语言处理任务/5-token_classification-词_符号_token级别分类任务.md) 51 | * [计算机视觉](./深度学习应用/计算机视觉任务/前言.md) 52 | * [1-Vit和自监督学习](./深度学习应用/计算机视觉任务/1-Vision%20Transformer使用和facebook自监督学习DINO训练方法.md) 53 | 54 | 55 | 56 | 57 | > 我的知乎是[多多笔记](http://www.zhihu.com/people/nai-ping-46-76) 58 | > 59 | > 可以添加这个微信号联系我:bit_pku_eecs,备注:交流,可以帮拉入transformer、NLP、深度学习的交流群进行讨论。 60 | > 61 | > 也欢迎关注公众号:![公众号](./resources/AI部落联盟.jpg) 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | * [深度学习数学基础-初步完结](./深度学习数学基础/0-前言) 2 | * [1.1 标量、向量、矩阵、张量](./深度学习数学基础/1.1-标量、向量、矩阵和张量) 3 | * [1.2 简单的线性代数](./深度学习数学基础/1.2-简单的线性代数.md) 4 | * [2.1-标量:导数的概念](./深度学习数学基础/2.1-标量:导数的概念.md) 5 | * [2.2-标量:链式法则](./深度学习数学基础/2.2-标量:链式法则.md) 6 | * [2.3-标量:求导常用公式](./深度学习数学基础/2.3-标量:求导常用公式.md) 7 | * [2.4-多个标量:多元函数求导、偏导数](./深度学习数学基础/2.4-多个标量:多元函数求导、偏导数.md) 8 | * [2.5-方向导数和梯度](./深度学习数学基础/2.5-方向导数和梯度.md) 9 | * [2.6-向量的梯度和Jacobian矩阵](./深度学习数学基础/2.6-向量的梯度和Jacobian矩阵.md) 10 | * [2.7-矩阵和张量的梯度](./深度学习数学基础/2.7-矩阵和张量的梯度.md) 11 | * [2.8-神经网络中几个实用的梯度计算](./深度学习数学基础/2.8-神经网络中几个实用的梯度计算.md) 12 | * [3.1-神经网络中的反向传播](./深度学习数学基础/3.1-神经网络中的反向传播.md) 13 | * [3.2-单层神经网络梯度计算例子](./深度学习数学基础/3.2-单层神经网络梯度计算例子.md) 14 | * [4.1-Pytorch自动求梯度](./深度学习数学基础/4.1-Pytorch自动求梯度.md) 15 | * [4.2-Tensorflow自动求梯度](./深度学习数学基础/4.2-Tensorflow自动求梯度.md) 16 | * [深度学习模型基础-更新中](./深度学习模型基础/transformer基本原理讲解/0-前言.md) 17 | * [1.1-图解attetion](./深度学习模型基础/transformer基本原理讲解/1.1-图解attetion.md) 18 | * [1.2-图解transformer](./深度学习模型基础/transformer基本原理讲解/1.2-图解transformer.md) 19 | * [1.3-图解BERT](./深度学习模型基础/transformer基本原理讲解/1.3-图解BERT.md) 20 | * [1.4-图解GPT](./深度学习模型基础/transformer基本原理讲解/1.4-图解GPT.md) 21 | * [深度学习应用-更新中](./深度学习应用/前言.md) 22 | * [自然语言处理](./深度学习应用/自然语言处理任务/前言.md) 23 | * [1-语言模型](./深度学习应用/自然语言处理任务/1-language_modeling-语言模型.md) 24 | * [2-机器翻译](./深度学习应用/自然语言处理任务/2-translation-机器翻译.md) 25 | * [3-机器问答](./深度学习应用/自然语言处理任务/3-question_answering-机器问答.md) 26 | * [4-摘要生成](./深度学习应用/自然语言处理任务/4-summarization-摘要生成.md) 27 | * [5-token 分类](./深度学习应用/自然语言处理任务/5-token_classification-词_符号_token级别分类任务.md) 28 | * [计算机视觉]() 29 | * [1-Vit和自监督学习](./深度学习应用/计算机视觉任务/1-Vision%20Transformer使用和facebook自监督学习DINO训练方法.md) 30 | 31 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 深度学习基础deeplearningbasics 6 | 7 | 8 | 9 | 10 | 11 | 18 | 19 | 20 |
21 | 32 | 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/resources/AI部落联盟.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/resources/AI部落联盟.jpg -------------------------------------------------------------------------------- /docs/深度学习应用/前言.md: -------------------------------------------------------------------------------- 1 | 在这一专题下,我们希望使用深度学习模型来解决一些实际问题。我们将重点使用transformer相关的模型,因为transformer可以帮助我们更轻松拿到最好的结果! 2 | * [深度学习应用-更新中](./深度学习应用/前言.md) 3 | * [自然语言处理](./深度学习应用/自然语言处理任务/前言.md) 4 | * [1-语言模型](./深度学习应用/自然语言处理任务/1-language_modeling-语言模型.md) 5 | * [2-机器翻译](./深度学习应用/自然语言处理任务/2-translation-机器翻译.md) 6 | * [3-机器问答](./深度学习应用/自然语言处理任务/3-question_answering-机器问答.md) 7 | * [4-摘要生成](./深度学习应用/自然语言处理任务/4-summarization-摘要生成.md) 8 | * [5-token 分类](./深度学习应用/自然语言处理任务/5-token_classification-词_符号_token级别分类任务.md) 9 | * [计算机视觉]() 10 | * [1-Vit和自监督学习](./深度学习应用/计算机视觉任务/1-Vision%20Transformer使用和facebook自监督学习DINO训练方法.md) -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/1-language_modeling-语言模型.md: -------------------------------------------------------------------------------- 1 | 点击打开对应的[google colab notebook](https://drive.google.com/file/d/1VIHfCjYP-2NXJhbfhVVhDMvNk2ogvMdJ/view?usp=sharing) 2 | 3 | 如果您在colab上打开这个jupyter笔记本,您需要安装🤗Trasnformers和🤗datasets。具体命令如下(取消注释并运行,如果速度慢请切换国内源,加上第二行的参数)。 4 | 5 | 在运行单元格之前,建议您按照本项目readme中提示,建立一个专门的python环境用于学习。 6 | 7 | 8 | ```python 9 | # ! pip install datasets transformers 10 | # -i https://pypi.tuna.tsinghua.edu.cn/simple 11 | ``` 12 | 13 | 如果您是在本地机器上打开这个jupyter笔记本,请确保您的环境安装了上述库的最新版本。 14 | 15 | 您可以在[这里](https://github.com/huggingface/transformers/tree/master/examples/language-modeling)找到这个jupyter笔记本的具体的python脚本文件,还可以通过分布式的方式使用多个gpu或tpu来微调您的模型。 16 | 17 | # 微调您的语言模型 18 | 19 | 在当前jupyter笔记本中,我们将说明如何使用语言模型任务微调任意[🤗Transformers](https://github.com/huggingface/transformers) 模型。 20 | 21 | 本教程将涵盖两种类型的语言建模任务: 22 | 23 | + 因果语言模型(Causal language modeling,CLM):模型需要预测句子中的下一位置处的字符(类似BERT类模型的decoder和GPT,从左往右输入字符)。为了确保模型不作弊,模型会使用一个注意掩码防止模型看到之后的字符。例如,当模型试图预测句子中的i+1位置处的字符时,这个掩码将阻止它访问i位置之后的字符。 24 | 25 | ![推理表示因果语言建模任务图片](./images/causal_language_modeling.png) 26 | 27 | + 掩蔽语言建模(Masked language modeling,MLM):模型需要恢复输入中被"MASK"掉的一些字符(BERT类模型的预训练任务)。这种方式模型可以看到整个句子,因此模型可以根据“\[MASK\]”标记之前和之后的字符来预测该位置被“\[MASK\]”之前的字符。 28 | 29 | ![Widget inference representing the masked language modeling task](images/masked_language_modeling.png) 30 | 31 | 接下来,我们将说明如何轻松地为每个任务加载和预处理数据集,以及如何使用“Trainer”API对模型进行微调。 32 | 33 | 当然您也可以直接在分布式环境或TPU上运行该jupyter笔记本的python脚本版本,可以在[examples文件夹](https://github.com/huggingface/transformers/tree/master/examples)中找到。 34 | 35 | ## 准备数据 36 | 37 | 在接下来的这些任务中,我们将使用[Wikitext 2](https://huggingface.co/datasets/wikitext#data-instances)数据集作为示例。您可以通过🤗Datasets库加载该数据集: 38 | 39 | 40 | ```python 41 | from datasets import load_dataset 42 | datasets = load_dataset('wikitext', 'wikitext-2-raw-v1') 43 | ``` 44 | 45 | Reusing dataset wikitext (/root/.cache/huggingface/datasets/wikitext/wikitext-2-raw-v1/1.0.0/aa5e094000ec7afeb74c3be92c88313cd6f132d564c7effd961c10fd47c76f20) 46 | 47 | 48 | 如果碰到以下错误: 49 | ![request Error](images/request_error.png) 50 | 51 | 解决方案: 52 | 53 | MAC用户: 在 ```/etc/hosts``` 文件中添加一行 ```199.232.68.133 raw.githubusercontent.com``` 54 | 55 | Windowso用户: 在 ```C:\Windows\System32\drivers\etc\hosts``` 文件中添加一行 ```199.232.68.133 raw.githubusercontent.com``` 56 | 57 | 当然您也可以用公开在[hub](https://huggingface.co/datasets)上的任何数据集替换上面的数据集,或者使用您自己的文件。只需取消注释以下单元格,并将路径替换为将导致您的文件路径: 58 | 59 | 60 | ```python 61 | # datasets = load_dataset("text", data_files={"train": path_to_train.txt, "validation": path_to_validation.txt} 62 | ``` 63 | 64 | 您还可以从csv或JSON文件加载数据集,更多信息请参阅[完整文档](https://huggingface.co/docs/datasets/loading_datasets.html#from-local-files)。 65 | 66 | 要访问一个数据中实际的元素,您需要先选择一个key,然后给出一个索引: 67 | 68 | 69 | ```python 70 | datasets["train"][10] 71 | ``` 72 | 73 | 74 | 75 | 76 | {'text': ' The game \'s battle system , the BliTZ system , is carried over directly from Valkyira Chronicles . During missions , players select each unit using a top @-@ down perspective of the battlefield map : once a character is selected , the player moves the character around the battlefield in third @-@ person . A character can only act once per @-@ turn , but characters can be granted multiple turns at the expense of other characters \' turns . Each character has a field and distance of movement limited by their Action Gauge . Up to nine characters can be assigned to a single mission . During gameplay , characters will call out if something happens to them , such as their health points ( HP ) getting low or being knocked out by enemy attacks . Each character has specific " Potentials " , skills unique to each character . They are divided into " Personal Potential " , which are innate skills that remain unaltered unless otherwise dictated by the story and can either help or impede a character , and " Battle Potentials " , which are grown throughout the game and always grant boons to a character . To learn Battle Potentials , each character has a unique " Masters Table " , a grid @-@ based skill table that can be used to acquire and link different skills . Characters also have Special Abilities that grant them temporary boosts on the battlefield : Kurt can activate " Direct Command " and move around the battlefield without depleting his Action Point gauge , the character Reila can shift into her " Valkyria Form " and become invincible , while Imca can target multiple enemy units with her heavy weapon . \n'} 77 | 78 | 79 | 80 | 为了快速了解数据的结构,下面的函数将显示数据集中随机选取的一些示例。 81 | 82 | 83 | ```python 84 | from datasets import ClassLabel 85 | import random 86 | import pandas as pd 87 | from IPython.display import display, HTML 88 | 89 | def show_random_elements(dataset, num_examples=10): 90 | assert num_examples <= len(dataset), "Can't pick more elements than there are in the dataset." 91 | picks = [] 92 | for _ in range(num_examples): 93 | pick = random.randint(0, len(dataset)-1) 94 | while pick in picks: 95 | pick = random.randint(0, len(dataset)-1) 96 | picks.append(pick) 97 | 98 | df = pd.DataFrame(dataset[picks]) 99 | for column, typ in dataset.features.items(): 100 | if isinstance(typ, ClassLabel): 101 | df[column] = df[column].transform(lambda i: typ.names[i]) 102 | display(HTML(df.to_html())) 103 | ``` 104 | 105 | 106 | ```python 107 | show_random_elements(datasets["train"]) 108 | ``` 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 |
text
0MD 194D is the designation for an unnamed 0 @.@ 02 @-@ mile ( 0 @.@ 032 km ) connector between MD 194 and MD 853E , the old alignment that parallels the northbound direction of the modern highway south of Angell Road . \n
1My sense , as though of hemlock I had drunk , \n
2
3A mimed stage show , Thunderbirds : F.A.B. , has toured internationally and popularised a staccato style of movement known colloquially as the " Thunderbirds walk " . The production has periodically been revived as Thunderbirds : F.A.B. – The Next Generation . \n
4
5
6In his 1998 autobiography For the Love of the Game , Jordan wrote that he had been preparing for retirement as early as the summer of 1992 . The added exhaustion due to the Dream Team run in the 1992 Olympics solidified Jordan 's feelings about the game and his ever @-@ growing celebrity status . Jordan 's announcement sent shock waves throughout the NBA and appeared on the front pages of newspapers around the world . \n
7Research on new wildlife collars may be able to reduce human @-@ animal conflicts by predicting when and where predatory animals hunt . This can not only save human lives and the lives of their pets and livestock but also save these large predatory mammals that are important to the balance of ecosystems . \n
8" Love Me Like You " ( Christmas Mix ) – 3 : 29 \n
9
161 | 162 | 163 | 正如我们所看到的,一些文本是维基百科文章的完整段落,而其他的只是标题或空行。 164 | 165 | ## 因果语言模型(Causal Language Modeling,CLM) 166 | 167 | 对于因果语言模型(CLM),我们首先获取到数据集中的所有文本,并在它们被分词后将它们连接起来。然后,我们将在特定序列长度的例子中拆分它们。通过这种方式,模型将接收如下的连续文本块: 168 | 169 | ``` 170 | 文本1 171 | ``` 172 | 或 173 | ``` 174 | 文本1结尾 [BOS_TOKEN] 文本2开头 175 | ``` 176 | 177 | 取决于它们是否跨越数据集中的几个原始文本。标签将与输入相同,但向左移动。 178 | 179 | 在本例中,我们将使用[`distilgpt2`](https://huggingface.co/distilgpt2) 模型。您同样也可以选择[这里](https://huggingface.co/models?filter=causal-lm)列出的任何一个checkpoint: 180 | 181 | 182 | ```python 183 | model_checkpoint = "distilgpt2" 184 | ``` 185 | 186 | 为了用训练模型时使用的词汇对所有文本进行标记,我们必须下载一个预先训练过的分词器(Tokenizer)。而这些操作都可以由AutoTokenizer类完成: 187 | 188 | 189 | ```python 190 | from transformers import AutoTokenizer 191 | 192 | tokenizer = AutoTokenizer.from_pretrained(model_checkpoint, use_fast=True) 193 | ``` 194 | 195 | 196 | 197 | 198 | 199 | 如果我们现在查看数据集的一个元素,我们会看到文本已经被模型所需的input_ids所取代: 200 | 201 | 202 | ```python 203 | tokenized_datasets["train"][1] 204 | ``` 205 | 206 | 207 | 208 | 209 | {'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1], 210 | 'input_ids': [796, 569, 18354, 7496, 17740, 6711, 796, 220, 198]} 211 | 212 | 213 | 214 | 下一步就有点小困难了:我们需要将所有文本连接在一起,然后将结果分割成特定`block_size`的小块。为此,我们将再次使用`map`方法,并使用选项`batch=True`。这个选项允许我们通过返回不同数量的样本来改变数据集中的样本数量。通过这种方式,我们可以从一批示例中创建新的示例。 215 | 216 | 首先,我们需要获取预训练模型时所使用的最大长度。最大长度在这里设置为128,以防您的显存爆炸💥。 217 | 218 | 219 | ```python 220 | # block_size = tokenizer.model_max_length 221 | block_size = 128 222 | ``` 223 | 224 | 然后我们编写预处理函数来对我们的文本进行分组: 225 | 226 | 227 | ```python 228 | def group_texts(examples): 229 | # 拼接所有文本 230 | concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()} 231 | total_length = len(concatenated_examples[list(examples.keys())[0]]) 232 | # 我们将余数对应的部分去掉。但如果模型支持的话,可以添加padding,您可以根据需要定制此部件。 233 | total_length = (total_length // block_size) * block_size 234 | # 通过max_len进行分割。 235 | result = { 236 | k: [t[i : i + block_size] for i in range(0, total_length, block_size)] 237 | for k, t in concatenated_examples.items() 238 | } 239 | result["labels"] = result["input_ids"].copy() 240 | return result 241 | ``` 242 | 243 | 首先注意,我们复制了标签的输入。 244 | 245 | 这是因为🤗transformer库的模型默认向右移动,所以我们不需要手动操作。 246 | 247 | 还要注意,在默认情况下,`map`方法将发送一批1,000个示例,由预处理函数处理。因此,在这里,我们将删除剩余部分,使连接的标记化文本每1000个示例为`block_size`的倍数。您可以通过传递更高的批处理大小来调整此行为(当然这也会被处理得更慢)。你也可以使用`multiprocessing`来加速预处理: 248 | 249 | 250 | ```python 251 | lm_datasets = tokenized_datasets.map( 252 | group_texts, 253 | batched=True, 254 | batch_size=1000, 255 | num_proc=4, 256 | ) 257 | ``` 258 | 259 | 260 | 261 | 现在我们可以检查数据集是否发生了变化:现在样本包含了`block_size`连续字符块,可能跨越了几个原始文本。 262 | 263 | 264 | ```python 265 | tokenizer.decode(lm_datasets["train"][1]["input_ids"]) 266 | ``` 267 | 268 | 269 | 270 | 271 | ' game and follows the " Nameless ", a penal military unit serving the nation of Gallia during the Second Europan War who perform secret black operations and are pitted against the Imperial unit " Calamaty Raven ". \n The game began development in 2010, carrying over a large portion of the work done on Valkyria Chronicles II. While it retained the standard features of the series, it also underwent multiple adjustments, such as making the game more forgiving for series newcomers. Character designer Raita Honjou and composer Hitoshi Sakimoto both returned from previous entries, along with Valkyria Chronicles II director Takeshi Oz' 272 | 273 | 274 | 275 | 既然数据已经清理完毕,我们就可以实例化我们的训练器了。我们将建立一个模型: 276 | 277 | 278 | ```python 279 | from transformers import AutoModelForCausalLM 280 | model = AutoModelForCausalLM.from_pretrained(model_checkpoint) 281 | ``` 282 | 283 | 284 | 285 | 286 | 检查torch版本 287 | 288 | 289 | ```python 290 | 291 | import importlib.util 292 | import importlib_metadata 293 | a = importlib.util.find_spec("torch") is not None 294 | print(a) 295 | _torch_version = importlib_metadata.version("torch") 296 | print(_torch_version) 297 | ``` 298 | 299 | True 300 | 1.8.1+cu101 301 | 302 | 303 | 和一些`TrainingArguments`: 304 | 305 | 306 | ```python 307 | from transformers import Trainer, TrainingArguments 308 | ``` 309 | 310 | 311 | ```python 312 | training_args = TrainingArguments( 313 | "test-clm", 314 | evaluation_strategy = "epoch", 315 | learning_rate=2e-5, 316 | weight_decay=0.01, 317 | ) 318 | ``` 319 | 320 | 我们把这些都传递给`Trainer`类: 321 | 322 | 323 | ```python 324 | trainer = Trainer( 325 | model=model, 326 | args=training_args, 327 | train_dataset=lm_datasets["train"][:1000], 328 | eval_dataset=lm_datasets["validation"][:1000], 329 | ) 330 | ``` 331 | 332 | 然后就可以训练我们的模型🌶: 333 | 334 | 335 | ```python 336 | trainer.train() 337 | ``` 338 | 339 | 一旦训练完成,我们就可以评估我们的模型,得到它在验证集上的perplexity,如下所示: 340 | 341 | 342 | ```python 343 | import math 344 | eval_results = trainer.evaluate() 345 | print(f"Perplexity: {math.exp(eval_results['eval_loss']):.2f}") 346 | ``` 347 | 348 | ## 掩蔽语言模型(Mask Language Modeling,MLM) 349 | 350 | 掩蔽语言模型(MLM)我们将使用相同的数据集预处理和以前一样用一个额外的步骤: 351 | 352 | 我们将随机"MASK"一些字符(使用"[MASK]"进行替换)以及调整标签为只包含在"[MASK]"位置处的标签(因为我们不需要预测没有被"MASK"的字符)。 353 | 354 | 在本例中,我们将使用[`distilroberta-base`](https://huggingface.co/distilroberta-base)模型。您同样也可以选择[这里](https://huggingface.co/models?filter=causal-lm)列出的任何一个checkpoint: 355 | 356 | 357 | ```python 358 | model_checkpoint = "distilroberta-base" 359 | ``` 360 | 361 | 我们可以像之前一样应用相同的分词器函数,我们只需要更新我们的分词器来使用刚刚选择的checkpoint: 362 | 363 | 364 | ```python 365 | tokenizer = AutoTokenizer.from_pretrained(model_checkpoint, use_fast=True) 366 | tokenized_datasets = datasets.map(tokenize_function, batched=True, num_proc=4, remove_columns=["text"]) 367 | ``` 368 | 369 | 像之前一样,我们把文本分组在一起,并把它们分成长度为`block_size`的样本。如果您的数据集由单独的句子组成,则可以跳过这一步。 370 | 371 | 372 | ```python 373 | lm_datasets = tokenized_datasets.map( 374 | group_texts, 375 | batched=True, 376 | batch_size=1000, 377 | num_proc=4, 378 | ) 379 | ``` 380 | 381 | 剩下的和我们之前的做法非常相似,只有两个例外。首先我们使用一个适合掩蔽语言模型的模型: 382 | 383 | 384 | ```python 385 | from transformers import AutoModelForMaskedLM 386 | model = AutoModelForMaskedLM.from_pretrained(model_checkpoint) 387 | ``` 388 | 389 | 其次,我们使用一个特殊的data_collator。data_collator是一个函数,负责获取样本并将它们批处理成张量。 390 | 391 | 在前面的例子中,我们没有什么特殊的事情要做,所以我们只使用这个参数的默认值。这里我们要做随机"MASK"。 392 | 393 | 我们可以将其作为预处理步骤(`tokenizer`)进行处理,但在每个阶段,字符总是以相同的方式被掩盖。通过在data_collator中执行这一步,我们可以确保每次检查数据时都以新的方式完成随机掩蔽。 394 | 395 | 为了实现掩蔽,`Transformers`为掩蔽语言模型提供了一个`DataCollatorForLanguageModeling`。我们可以调整掩蔽的概率: 396 | 397 | 398 | ```python 399 | from transformers import DataCollatorForLanguageModeling 400 | data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15) 401 | ``` 402 | 403 | 然后我们要把所有的东西交给trainer,然后开始训练: 404 | 405 | 406 | ```python 407 | trainer = Trainer( 408 | model=model, 409 | args=training_args, 410 | train_dataset=lm_datasets["train"][:1000], 411 | eval_dataset=lm_datasets["validation"][:100], 412 | data_collator=data_collator, 413 | ) 414 | ``` 415 | 416 | 417 | ```python 418 | trainer.train() 419 | ``` 420 | 421 | 像以前一样,我们可以在验证集上评估我们的模型。 422 | 423 | 与CLM目标相比,困惑度要低得多,因为对于MLM目标,我们只需要对隐藏的令牌(在这里占总数的15%)进行预测,同时可以访问其余的令牌。 424 | 425 | 因此,对于模型来说,这是一项更容易的任务。 426 | 427 | 428 | ```python 429 | eval_results = trainer.evaluate() 430 | print(f"Perplexity: {math.exp(eval_results['eval_loss']):.2f}") 431 | ``` 432 | 433 | 434 | ```python 435 | 不要忘记将你的模型[上传](https://huggingface.co/transformers/model_sharing.html)到[🤗 模型中心](https://huggingface.co/models)。 436 | 437 | 然后,您可以使用它生成像该笔记本的第一张图片中所示的结果! 438 | ``` 439 | -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/2-translation-机器翻译.md: -------------------------------------------------------------------------------- 1 | [google colab中打开](https://drive.google.com/file/d/1ZEcgBbambJtzRDmGDsRxn3LcqqwHAVHc/view?usp=sharing) 2 | 3 | 如果您正在google的colab中打开这恶搞notebook,您可能需要安装Transformers和🤗Datasets库。将以下命令取消注释即可安装。 4 | 在运行单元格之前,建议您按照本项目readme中提示,建立一个专门的python环境用于学习。 5 | 6 | 7 | ```python 8 | ! pip install datasets transformers sacrebleu sentencepiece 9 | ``` 10 | 11 | 如果您正在本地打开这个notebook,请确保您认真阅读并安装了transformer-quick-start-zh的readme文件中的所有依赖库。您也可以在[这里](https://github.com/huggingface/transformers/tree/master/examples/seq2seq)找到本notebook的多GPU分布式训练版本。 12 | 13 | # Fine-tuning微调transformer模型解决翻译任务 14 | 15 | 在这个notebook中,我们将展示如何使用[🤗 Transformers](https://github.com/huggingface/transformers)代码库中的模型来解决自然语言处理中的翻译任务。我们将会使用[WMT dataset](http://www.statmt.org/wmt16/)数据集。这是翻译任务最常用的数据集之一。 16 | 17 | 下面展示了一个例子: 18 | 19 | ![Widget inference on a translation task](https://github.com/huggingface/notebooks/blob/master/examples/images/translation.png?raw=1) 20 | 21 | 对于翻译任务,我们将展示如何使用简单的加载数据集,同时针对相应的仍无使用transformer中的Trainer接口对模型进行微调。 22 | 23 | 24 | ```python 25 | model_checkpoint = "Helsinki-NLP/opus-mt-en-ro" 26 | # 选择一个模型checkpoint 27 | ``` 28 | 29 | 只要预训练的transformer模型包含seq2seq结构的head层,那么本notebook理论上可以使用各种各样的transformer模型[模型面板](https://huggingface.co/models),解决任何翻译任务。 30 | 31 | 本文我们使用已经训练好的[`Helsinki-NLP/opus-mt-en-ro`](https://huggingface.co/Helsinki-NLP/opus-mt-en-ro) checkpoint来做翻译任务。 32 | 33 | ## 加载数据 34 | 35 | 36 | 我们将会使用🤗 Datasets库来加载数据和对应的评测方式。数据加载和评测方式加载只需要简单使用load_dataset和load_metric即可。我们使用WMT数据集中的English/Romanian双语翻译。 37 | 38 | 39 | 40 | ```python 41 | from datasets import load_dataset, load_metric 42 | 43 | raw_datasets = load_dataset("wmt16", "ro-en") 44 | metric = load_metric("sacrebleu") 45 | ``` 46 | 47 | 这个datasets对象本身是一种[`DatasetDict`](https://huggingface.co/docs/datasets/package_reference/main_classes.html#datasetdict)数据结构. 对于训练集、验证集和测试集,只需要使用对应的key(train,validation,test)即可得到相应的数据。 48 | 49 | 50 | ```python 51 | raw_datasets 52 | ``` 53 | 54 | 55 | 56 | 57 | DatasetDict({ 58 | train: Dataset({ 59 | features: ['translation'], 60 | num_rows: 610320 61 | }) 62 | validation: Dataset({ 63 | features: ['translation'], 64 | num_rows: 1999 65 | }) 66 | test: Dataset({ 67 | features: ['translation'], 68 | num_rows: 1999 69 | }) 70 | }) 71 | 72 | 73 | 74 | 给定一个数据切分的key(train、validation或者test)和下标即可查看数据。 75 | 76 | 77 | ```python 78 | raw_datasets["train"][0] 79 | # 我们可以看到一句英语en对应一句罗马尼亚语言ro 80 | ``` 81 | 82 | 83 | 84 | 85 | {'translation': {'en': 'Membership of Parliament: see Minutes', 86 | 'ro': 'Componenţa Parlamentului: a se vedea procesul-verbal'}} 87 | 88 | 89 | 90 | 为了能够进一步理解数据长什么样子,下面的函数将从数据集里随机选择几个例子进行展示。 91 | 92 | 93 | ```python 94 | import datasets 95 | import random 96 | import pandas as pd 97 | from IPython.display import display, HTML 98 | 99 | def show_random_elements(dataset, num_examples=5): 100 | assert num_examples <= len(dataset), "Can't pick more elements than there are in the dataset." 101 | picks = [] 102 | for _ in range(num_examples): 103 | pick = random.randint(0, len(dataset)-1) 104 | while pick in picks: 105 | pick = random.randint(0, len(dataset)-1) 106 | picks.append(pick) 107 | 108 | df = pd.DataFrame(dataset[picks]) 109 | for column, typ in dataset.features.items(): 110 | if isinstance(typ, datasets.ClassLabel): 111 | df[column] = df[column].transform(lambda i: typ.names[i]) 112 | display(HTML(df.to_html())) 113 | ``` 114 | 115 | 116 | ```python 117 | show_random_elements(raw_datasets["train"]) 118 | ``` 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 |
translation
0{'en': 'The Bulgarian gymnastics team won the gold medal at the traditional Grand Prix series competition in Thiais, France, which wrapped up on Sunday (March 30th).', 'ro': 'Echipa bulgară de gimnastică a câştigat medalia de aur la tradiţionala competiţie Grand Prix din Thiais, Franţa, care s-a încheiat duminică (30 martie).'}
1{'en': 'Being on that committee, however, you will know that this was a very hot topic in negotiations between Norway and some Member States.', 'ro': 'Totuşi, făcând parte din această comisie, ştiţi că acesta a fost un subiect foarte aprins în negocierile dintre Norvegia şi unele state membre.'}
2{'en': 'The overwhelming vote shows just this.', 'ro': 'Ceea ce demonstrează şi votul favorabil.'}
3{'en': '[Photo illustration by Catherine Gurgenidze for Southeast European Times]', 'ro': '[Ilustraţii foto de Catherine Gurgenidze pentru Southeast European Times]'}
4{'en': '(HU) Mr President, today the specific text of the agreement between the Hungarian Government and the European Commission has been formulated.', 'ro': '(HU) Domnule președinte, textul concret al acordului dintre guvernul ungar și Comisia Europeană a fost formulat astăzi.'}
151 | 152 | 153 | metric是[`datasets.Metric`](https://huggingface.co/docs/datasets/package_reference/main_classes.html#datasets.Metric)类的一个实例,查看metric和使用的例子: 154 | 155 | 156 | ```python 157 | metric 158 | ``` 159 | 160 | 161 | 162 | 163 | Metric(name: "sacrebleu", features: {'predictions': Value(dtype='string', id='sequence'), 'references': Sequence(feature=Value(dtype='string', id='sequence'), length=-1, id='references')}, usage: """ 164 | Produces BLEU scores along with its sufficient statistics 165 | from a source against one or more references. 166 | 167 | Args: 168 | predictions: The system stream (a sequence of segments) 169 | references: A list of one or more reference streams (each a sequence of segments) 170 | smooth: The smoothing method to use 171 | smooth_value: For 'floor' smoothing, the floor to use 172 | force: Ignore data that looks already tokenized 173 | lowercase: Lowercase the data 174 | tokenize: The tokenizer to use 175 | Returns: 176 | 'score': BLEU score, 177 | 'counts': Counts, 178 | 'totals': Totals, 179 | 'precisions': Precisions, 180 | 'bp': Brevity penalty, 181 | 'sys_len': predictions length, 182 | 'ref_len': reference length, 183 | Examples: 184 | 185 | >>> predictions = ["hello there general kenobi", "foo bar foobar"] 186 | >>> references = [["hello there general kenobi", "hello there !"], ["foo bar foobar", "foo bar foobar"]] 187 | >>> sacrebleu = datasets.load_metric("sacrebleu") 188 | >>> results = sacrebleu.compute(predictions=predictions, references=references) 189 | >>> print(list(results.keys())) 190 | ['score', 'counts', 'totals', 'precisions', 'bp', 'sys_len', 'ref_len'] 191 | >>> print(round(results["score"], 1)) 192 | 100.0 193 | """, stored examples: 0) 194 | 195 | 196 | 197 | 我们使用`compute`方法来对比predictions和labels,从而计算得分。predictions和labels都需要是一个list。具体格式见下面的例子: 198 | 199 | 200 | ```python 201 | fake_preds = ["hello there", "general kenobi"] 202 | fake_labels = [["hello there"], ["general kenobi"]] 203 | metric.compute(predictions=fake_preds, references=fake_labels) 204 | ``` 205 | 206 | 207 | 208 | 209 | {'bp': 1.0, 210 | 'counts': [4, 2, 0, 0], 211 | 'precisions': [100.0, 100.0, 0.0, 0.0], 212 | 'ref_len': 4, 213 | 'score': 0.0, 214 | 'sys_len': 4, 215 | 'totals': [4, 2, 0, 0]} 216 | 217 | 218 | 219 | ## 数据预处理 220 | 221 | 在将数据喂入模型之前,我们需要对数据进行预处理。预处理的工具叫Tokenizer。Tokenizer首先对输入进行tokenize,然后将tokens转化为预模型中需要对应的token ID,再转化为模型需要的输入格式。 222 | 223 | 为了达到数据预处理的目的,我们使用AutoTokenizer.from_pretrained方法实例化我们的tokenizer,这样可以确保: 224 | 225 | - 我们得到一个与预训练模型一一对应的tokenizer。 226 | - 使用指定的模型checkpoint对应的tokenizer的时候,我们也下载了模型需要的词表库vocabulary,准确来说是tokens vocabulary。 227 | 228 | 229 | 这个被下载的tokens vocabulary会被缓存起来,从而再次使用的时候不会重新下载。 230 | 231 | 232 | ```python 233 | from transformers import AutoTokenizer 234 | # 需要安装`sentencepiece`: pip install sentencepiece 235 | 236 | tokenizer = AutoTokenizer.from_pretrained(model_checkpoint) 237 | ``` 238 | 239 | 以我们使用的mBART模型为例,我们需要正确设置source语言和target语言。如果您要翻译的是其他双语语料,请查看[这里](https://huggingface.co/facebook/mbart-large-cc25)。我们可以检查source和target语言的设置: 240 | 241 | 242 | 243 | ```python 244 | if "mbart" in model_checkpoint: 245 | tokenizer.src_lang = "en-XX" 246 | tokenizer.tgt_lang = "ro-RO" 247 | ``` 248 | 249 | 250 | 251 | tokenizer既可以对单个文本进行预处理,也可以对一对文本进行预处理,tokenizer预处理后得到的数据满足预训练模型输入格式 252 | 253 | 254 | ```python 255 | tokenizer("Hello, this one sentence!") 256 | ``` 257 | 258 | 259 | 260 | 261 | {'input_ids': [125, 778, 3, 63, 141, 9191, 23, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1]} 262 | 263 | 264 | 265 | 上面看到的token IDs也就是input_ids一般来说随着预训练模型名字的不同而有所不同。原因是不同的预训练模型在预训练的时候设定了不同的规则。但只要tokenizer和model的名字一致,那么tokenizer预处理的输入格式就会满足model需求的。关于预处理更多内容参考[这个教程](https://huggingface.co/transformers/preprocessing.html) 266 | 267 | 除了可以tokenize一句话,我们也可以tokenize一个list的句子。 268 | 269 | 270 | ```python 271 | tokenizer(["Hello, this one sentence!", "This is another sentence."]) 272 | ``` 273 | 274 | 275 | 276 | 277 | {'input_ids': [[125, 778, 3, 63, 141, 9191, 23, 0], [187, 32, 716, 9191, 2, 0]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]]} 278 | 279 | 280 | 281 | 注意:为了给模型准备好翻译的targets,我们使用`as_target_tokenizer`来控制targets所对应的特殊token: 282 | 283 | 284 | ```python 285 | with tokenizer.as_target_tokenizer(): 286 | print(tokenizer("Hello, this one sentence!")) 287 | model_input = tokenizer("Hello, this one sentence!") 288 | tokens = tokenizer.convert_ids_to_tokens(model_input['input_ids']) 289 | # 打印看一下special toke 290 | print('tokens: {}'.format(tokens)) 291 | ``` 292 | 293 | {'input_ids': [10334, 1204, 3, 15, 8915, 27, 452, 59, 29579, 581, 23, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]} 294 | tokens: ['▁Hel', 'lo', ',', '▁', 'this', '▁o', 'ne', '▁se', 'nten', 'ce', '!', ''] 295 | 296 | 297 | 如果您使用的是T5预训练模型的checkpoints,需要对特殊的前缀进行检查。T5使用特殊的前缀来告诉模型具体要做的任务,具体前缀例子如下: 298 | 299 | 300 | 301 | ```python 302 | if model_checkpoint in ["t5-small", "t5-base", "t5-larg", "t5-3b", "t5-11b"]: 303 | prefix = "translate English to Romanian: " 304 | else: 305 | prefix = "" 306 | ``` 307 | 308 | 现在我们可以把所有内容放在一起组成我们的预处理函数了。我们对样本进行预处理的时候,我们还会`truncation=True`这个参数来确保我们超长的句子被截断。默认情况下,对与比较短的句子我们会自动padding。 309 | 310 | 311 | ```python 312 | max_input_length = 128 313 | max_target_length = 128 314 | source_lang = "en" 315 | target_lang = "ro" 316 | 317 | def preprocess_function(examples): 318 | inputs = [prefix + ex[source_lang] for ex in examples["translation"]] 319 | targets = [ex[target_lang] for ex in examples["translation"]] 320 | model_inputs = tokenizer(inputs, max_length=max_input_length, truncation=True) 321 | 322 | # Setup the tokenizer for targets 323 | with tokenizer.as_target_tokenizer(): 324 | labels = tokenizer(targets, max_length=max_target_length, truncation=True) 325 | 326 | model_inputs["labels"] = labels["input_ids"] 327 | return model_inputs 328 | ``` 329 | 330 | 以上的预处理函数可以处理一个样本,也可以处理多个样本exapmles。如果是处理多个样本,则返回的是多个样本被预处理之后的结果list。 331 | 332 | 333 | ```python 334 | preprocess_function(raw_datasets['train'][:2]) 335 | ``` 336 | 337 | 338 | 339 | 340 | {'input_ids': [[393, 4462, 14, 1137, 53, 216, 28636, 0], [24385, 14, 28636, 14, 4646, 4622, 53, 216, 28636, 0]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], 'labels': [[42140, 494, 1750, 53, 8, 59, 903, 3543, 9, 15202, 0], [36199, 6612, 9, 15202, 122, 568, 35788, 21549, 53, 8, 59, 903, 3543, 9, 15202, 0]]} 341 | 342 | 343 | 344 | 接下来对数据集datasets里面的所有样本进行预处理,处理的方式是使用map函数,将预处理函数prepare_train_features应用到(map)所有样本上。 345 | 346 | 347 | ```python 348 | tokenized_datasets = raw_datasets.map(preprocess_function, batched=True) 349 | ``` 350 | 351 | 352 | HBox(children=(FloatProgress(value=0.0, max=611.0), HTML(value=''))) 353 | 354 | 355 | 356 | 357 | 358 | 359 | HBox(children=(FloatProgress(value=0.0, max=2.0), HTML(value=''))) 360 | 361 | 362 | 363 | 364 | 365 | 366 | HBox(children=(FloatProgress(value=0.0, max=2.0), HTML(value=''))) 367 | 368 | 369 | 370 | 371 | 372 | 更好的是,返回的结果会自动被缓存,避免下次处理的时候重新计算(但是也要注意,如果输入有改动,可能会被缓存影响!)。datasets库函数会对输入的参数进行检测,判断是否有变化,如果没有变化就使用缓存数据,如果有变化就重新处理。但如果输入参数不变,想改变输入的时候,最好清理调这个缓存。清理的方式是使用`load_from_cache_file=False`参数。另外,上面使用到的`batched=True`这个参数是tokenizer的特点,以为这会使用多线程同时并行对输入进行处理。 373 | 374 | ## Fine-tuning the model微调transformer模型 375 | 376 | 既然数据已经准备好了,现在我们需要下载并加载我们的预训练模型,然后微调预训练模型。既然我们是做seq2seq任务,那么我们需要一个能解决这个任务的模型类。我们使用`AutoModelForSeq2SeqLM`这个类。和tokenizer相似,`from_pretrained`方法同样可以帮助我们下载并加载模型,同时也会对模型进行缓存,就不会重复下载模型啦。 377 | 378 | 379 | ```python 380 | from transformers import AutoModelForSeq2SeqLM, DataCollatorForSeq2Seq, Seq2SeqTrainingArguments, Seq2SeqTrainer 381 | 382 | model = AutoModelForSeq2SeqLM.from_pretrained(model_checkpoint) 383 | ``` 384 | 385 | 386 | HBox(children=(FloatProgress(value=0.0, description='Downloading', max=300887193.0, style=ProgressStyle(descri… 387 | 388 | 389 | 390 | 391 | 392 | 由于我们微调的任务是机器翻译,而我们加载的是预训练的seq2seq模型,所以不会提示我们加载模型的时候扔掉了一些不匹配的神经网络参数(比如:预训练语言模型的神经网络head被扔掉了,同时随机初始化了机器翻译的神经网络head)。 393 | 394 | 395 | 为了能够得到一个`Seq2SeqTrainer`训练工具,我们还需要3个要素,其中最重要的是训练的设定/参数[`Seq2SeqTrainingArguments`](https://huggingface.co/transformers/main_classes/trainer.html#transformers.Seq2SeqTrainingArguments)。这个训练设定包含了能够定义训练过程的所有属性 396 | 397 | 398 | ```python 399 | batch_size = 16 400 | args = Seq2SeqTrainingArguments( 401 | "test-translation", 402 | evaluation_strategy = "epoch", 403 | learning_rate=2e-5, 404 | per_device_train_batch_size=batch_size, 405 | per_device_eval_batch_size=batch_size, 406 | weight_decay=0.01, 407 | save_total_limit=3, 408 | num_train_epochs=1, 409 | predict_with_generate=True, 410 | fp16=False, 411 | ) 412 | ``` 413 | 414 | 上面evaluation_strategy = "epoch"参数告诉训练代码:我们每个epcoh会做一次验证评估。 415 | 416 | 上面batch_size在这个notebook之前定义好了。 417 | 418 | 由于我们的数据集比较大,同时`Seq2SeqTrainer`会不断保存模型,所以我们需要告诉它至多保存`save_total_limit=3`个模型。 419 | 420 | 最后我们需要一个数据收集器data collator,将我们处理好的输入喂给模型。 421 | 422 | 423 | ```python 424 | data_collator = DataCollatorForSeq2Seq(tokenizer, model=model) 425 | ``` 426 | 427 | 设置好`Seq2SeqTrainer`还剩最后一件事情,那就是我们需要定义好评估方法。我们使用`metric`来完成评估。将模型预测送入评估之前,我们也会做一些数据后处理: 428 | 429 | 430 | ```python 431 | import numpy as np 432 | 433 | def postprocess_text(preds, labels): 434 | preds = [pred.strip() for pred in preds] 435 | labels = [[label.strip()] for label in labels] 436 | 437 | return preds, labels 438 | 439 | def compute_metrics(eval_preds): 440 | preds, labels = eval_preds 441 | if isinstance(preds, tuple): 442 | preds = preds[0] 443 | decoded_preds = tokenizer.batch_decode(preds, skip_special_tokens=True) 444 | 445 | # Replace -100 in the labels as we can't decode them. 446 | labels = np.where(labels != -100, labels, tokenizer.pad_token_id) 447 | decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True) 448 | 449 | # Some simple post-processing 450 | decoded_preds, decoded_labels = postprocess_text(decoded_preds, decoded_labels) 451 | 452 | result = metric.compute(predictions=decoded_preds, references=decoded_labels) 453 | result = {"bleu": result["score"]} 454 | 455 | prediction_lens = [np.count_nonzero(pred != tokenizer.pad_token_id) for pred in preds] 456 | result["gen_len"] = np.mean(prediction_lens) 457 | result = {k: round(v, 4) for k, v in result.items()} 458 | return result 459 | ``` 460 | 461 | 最后将所有的参数/数据/模型传给`Seq2SeqTrainer`即可 462 | 463 | 464 | ```python 465 | trainer = Seq2SeqTrainer( 466 | model, 467 | args, 468 | train_dataset=tokenized_datasets["train"], 469 | eval_dataset=tokenized_datasets["validation"], 470 | data_collator=data_collator, 471 | tokenizer=tokenizer, 472 | compute_metrics=compute_metrics 473 | ) 474 | ``` 475 | 476 | 调用`train`方法进行微调训练。 477 | 478 | 479 | ```python 480 | trainer.train() 481 | ``` 482 | 483 | 484 | 485 |
486 | 495 | 496 | 497 | [ 161/38145 44:23 < 176:44:03, 0.06 it/s, Epoch 0.00/1] 498 |
499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 |
EpochTraining LossValidation Loss

510 | 511 | 512 | 513 | 514 |

515 | 524 | 525 | 526 | [ 162/38145 44:38 < 176:37:03, 0.06 it/s, Epoch 0.00/1] 527 |
528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 |
EpochTraining LossValidation Loss

539 | 540 | 541 | 最后别忘了,查看如何上传模型 ,上传模型到](https://huggingface.co/transformers/model_sharing.html) 到[🤗 Model Hub](https://huggingface.co/models)。随后您就可以像这个notebook一开始一样,直接用模型名字就能使用您的模型啦。 542 | 543 | 544 | 545 | ```python 546 | 547 | ``` 548 | -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/images/causal_language_modeling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习应用/自然语言处理任务/images/causal_language_modeling.png -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/images/masked_language_modeling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习应用/自然语言处理任务/images/masked_language_modeling.png -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/images/model_parameters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习应用/自然语言处理任务/images/model_parameters.png -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/images/question_answering.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习应用/自然语言处理任务/images/question_answering.png -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/images/request_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习应用/自然语言处理任务/images/request_error.png -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/images/summarization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习应用/自然语言处理任务/images/summarization.png -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/images/text_classification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习应用/自然语言处理任务/images/text_classification.png -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/images/token_classification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习应用/自然语言处理任务/images/token_classification.png -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/images/translation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习应用/自然语言处理任务/images/translation.png -------------------------------------------------------------------------------- /docs/深度学习应用/自然语言处理任务/前言.md: -------------------------------------------------------------------------------- 1 | 目前主要基于[huggingface/transformer库](https://github.com/huggingface/transformers)对深度学习在自然语言处理任务中的使用进行说明。 2 | 3 | * [1-语言模型](./深度学习应用/自然语言处理任务/1-language_modeling-语言模型.md) 4 | * [2-机器翻译](./深度学习应用/自然语言处理任务/2-translation-机器翻译.md) 5 | * [3-机器问答](./深度学习应用/自然语言处理任务/3-question_answering-机器问答.md) 6 | * [4-摘要生成](./深度学习应用/自然语言处理任务/4-summarization-摘要生成.md) 7 | * [5-token 分类](./深度学习应用/自然语言处理任务/5-token_classification-词_符号_token级别分类任务.md) -------------------------------------------------------------------------------- /docs/深度学习应用/计算机视觉任务/1-Vision Transformer使用和facebook自监督学习DINO训练方法.md: -------------------------------------------------------------------------------- 1 | # 建议在谷歌colab上使用免费的GPU运行本Notebook,少安装很多依赖。 2 | 3 | [google colab中打开](https://drive.google.com/file/d/1Qd4gpc5Vk_YvRVsCd9K7XdV8yxrhBSXA/view?usp=sharing) 4 | 5 | 本文主要内容有: 6 | 1. Facebook基于Vision Transformers的自监督研究DINO相关模型在视频上抽取feature并展示attention map 7 | 2. Huggingface/Transformers中Vision Transformers的基本使用方法。 8 | 9 | 10 | 本文主要参考资料是: 11 | 12 | 13 | * https://gist.github.com/aquadzn/32ac53aa6e485e7c3e09b1a0914f7422 14 | * https://github.com/NielsRogge/Transformers-Tutorials/blob/master/VisionTransformer/Fine_tuning_the_Vision_Transformer_on_CIFAR_10_with_the_%F0%9F%A4%97_Trainer.ipynb 15 | * https://arxiv.org/pdf/2104.14294.pdf 16 | * https://arxiv.org/abs/2010.11929 17 | 18 | 19 | 20 | ## facebook DINO在视频上的尝试尝试 21 | ## 数据/代码准备 22 | 23 | 24 | ```python 25 | # 建议加载自己的google drive方便上传自定义视频进行尝试。 26 | from google.colab import drive 27 | drive.mount('/content/drive') 28 | ``` 29 | 30 | Mounted at /content/drive 31 | 32 | 33 | 34 | ```python 35 | %cd /content/drive/MyDrive/transformer_research 36 | #切换成你的文件夹,colab左边有个向上的箭头,找到/content/目录下你的目录,然后右键复制路径 37 | ``` 38 | 39 | /content/drive/MyDrive/transformer_research 40 | 41 | 42 | 43 | ```python 44 | !pwd 45 | !mkdir input 46 | !mkdir output 47 | ``` 48 | 49 | /content/drive/MyDrive/transformer_research 50 | mkdir: cannot create directory ‘input’: File exists 51 | mkdir: cannot create directory ‘output’: File exists 52 | 53 | 54 | 55 | ```python 56 | !git clone https://github.com/facebookresearch/dino.git 57 | # 下载DINO代码库 58 | ``` 59 | 60 | fatal: destination path 'dino' already exists and is not an empty directory. 61 | 62 | 63 | Download a model, here I used deit small 8 pretrained 64 | 65 | 66 | ```python 67 | !wget https://dl.fbaipublicfiles.com/dino/dino_deitsmall8_pretrain/dino_deitsmall8_pretrain.pth -O dino/dino_deitsmall8_pretrain.pth 68 | #下载模型到当前目录的dino下的dino_deitsmall8_pretrain.pth 69 | ``` 70 | 71 | --2021-05-03 14:24:26-- https://dl.fbaipublicfiles.com/dino/dino_deitsmall8_pretrain/dino_deitsmall8_pretrain.pth 72 | Resolving dl.fbaipublicfiles.com (dl.fbaipublicfiles.com)... 104.22.74.142, 172.67.9.4, 104.22.75.142, ... 73 | Connecting to dl.fbaipublicfiles.com (dl.fbaipublicfiles.com)|104.22.74.142|:443... connected. 74 | HTTP request sent, awaiting response... 200 OK 75 | Length: 86728949 (83M) [application/zip] 76 | Saving to: ‘dino/dino_deitsmall8_pretrain.pth’ 77 | 78 | dino/dino_deitsmall 100%[===================>] 82.71M 14.4MB/s in 6.8s 79 | 80 | 2021-05-03 14:24:34 (12.2 MB/s) - ‘dino/dino_deitsmall8_pretrain.pth’ saved [86728949/86728949] 81 | 82 | 83 | 84 | 找个感兴趣的视频下载下来并上传到这里,假设名字是bilibili_cat.mp4,最好是10s以内,免费的gpu算不了太多。 85 | 这里有个[例子](https://www.pexels.com/fr-fr/video/chien-course-exterieur-journee-ensoleillee-4166347/) 86 | 87 | 然后用ffmpeg将视频转化为jpg,参数是60fps,然后如果是10秒的话,就是600张。 88 | Then you need to extract frames from the video, you can use ffmpeg. 89 | 90 | Video is 60 fps and ~6 sec so you'll get ~360 jpg images 91 | 92 | %03d is from 001 to 999 93 | 94 | 95 | ```python 96 | !ffmpeg -i ./bilibili_cat.mp4 input/img-%03d.jpg 97 | ``` 98 | 99 | 100 | 101 | ```python 102 | %cd dino/ 103 | ``` 104 | 105 | /content/drive/MyDrive/transformer_research/dino 106 | 107 | 108 | 相关代码,来源是:https://gist.github.com/aquadzn/32ac53aa6e485e7c3e09b1a0914f7422 109 | 110 | Requirements: 111 | 112 | 113 | * Opencv 114 | * scikit-image 115 | * maptlotlib 116 | * pytorch 117 | * numpy 118 | * Pillow 119 | 120 | 121 | 122 | 123 | ```python 124 | # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved 125 | import os 126 | import gc 127 | import sys 128 | import argparse 129 | import cv2 130 | import random 131 | import colorsys 132 | import requests 133 | from io import BytesIO 134 | 135 | import skimage.io 136 | from skimage.measure import find_contours 137 | import matplotlib.pyplot as plt 138 | from matplotlib.patches import Polygon 139 | import torch 140 | import torch.nn as nn 141 | import torchvision 142 | from torchvision import transforms as pth_transforms 143 | import numpy as np 144 | from PIL import Image 145 | 146 | import utils 147 | import vision_transformer as vits 148 | ``` 149 | 150 | 注意!!GPU大小有限,如果视频分辨率太高,那么每张图都很大,需要resize一下,这里是resize的512x512,如果OOM跑不了就改小一点。 151 | 152 | 改这里第9行:`pth_transforms.Resize(512)` 153 | 154 | 155 | ```python 156 | def predict_video(args): 157 | for frame in sorted(os.listdir(args.image_path)): 158 | with open(os.path.join(args.image_path, frame), 'rb') as f: 159 | img = Image.open(f) 160 | img = img.convert('RGB') 161 | 162 | transform = pth_transforms.Compose([ 163 | pth_transforms.ToTensor(), 164 | pth_transforms.Resize(512), 165 | pth_transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)), 166 | ]) 167 | img = transform(img) 168 | 169 | # make the image divisible by the patch size 170 | w, h = img.shape[1] - img.shape[1] % args.patch_size, img.shape[2] - img.shape[2] % args.patch_size 171 | img = img[:, :w, :h].unsqueeze(0) 172 | 173 | w_featmap = img.shape[-2] // args.patch_size 174 | h_featmap = img.shape[-1] // args.patch_size 175 | 176 | attentions = model.forward_selfattention(img.cuda()) 177 | 178 | nh = attentions.shape[1] # number of head 179 | 180 | # we keep only the output patch attention 181 | attentions = attentions[0, :, 0, 1:].reshape(nh, -1) 182 | 183 | # we keep only a certain percentage of the mass 184 | val, idx = torch.sort(attentions) 185 | val /= torch.sum(val, dim=1, keepdim=True) 186 | cumval = torch.cumsum(val, dim=1) 187 | th_attn = cumval > (1 - args.threshold) 188 | idx2 = torch.argsort(idx) 189 | for head in range(nh): 190 | th_attn[head] = th_attn[head][idx2[head]] 191 | th_attn = th_attn.reshape(nh, w_featmap, h_featmap).float() 192 | # interpolate 193 | th_attn = nn.functional.interpolate(th_attn.unsqueeze(0), scale_factor=args.patch_size, mode="nearest")[0].cpu().numpy() 194 | 195 | attentions = attentions.reshape(nh, w_featmap, h_featmap) 196 | attentions = nn.functional.interpolate(attentions.unsqueeze(0), scale_factor=args.patch_size, mode="nearest")[0].cpu().numpy() 197 | 198 | # save attentions heatmaps 199 | os.makedirs(args.output_dir, exist_ok=True) 200 | 201 | # Saving only last attention layer 202 | fname = os.path.join(args.output_dir, "attn-" + frame) 203 | plt.imsave( 204 | fname=fname, 205 | arr=sum(attentions[i] * 1/attentions.shape[0] for i in range(attentions.shape[0])), 206 | cmap="inferno", 207 | format="jpg" 208 | ) 209 | print(f"{fname} saved.") 210 | ``` 211 | 212 | 213 | ```python 214 | #@title Args 215 | 216 | pretrained_weights_path = "dino_deitsmall8_pretrain.pth" #@param {type:"string"} 217 | arch = 'deit_small' #@param ["deit_small", "deit_tiny", "vit_base"] 218 | input_path = "../input/" #@param {type:"string"} 219 | output_path = "../output/" #@param {type:"string"} 220 | threshold = 0.6 #@param {type:"number"} 221 | 222 | 223 | parser = argparse.ArgumentParser('Visualize Self-Attention maps') 224 | parser.add_argument('--arch', default='deit_small', type=str, 225 | choices=['deit_tiny', 'deit_small', 'vit_base'], help='Architecture (support only ViT atm).') 226 | parser.add_argument('--patch_size', default=8, type=int, help='Patch resolution of the model.') 227 | parser.add_argument('--pretrained_weights', default='', type=str, 228 | help="Path to pretrained weights to load.") 229 | parser.add_argument("--checkpoint_key", default="teacher", type=str, 230 | help='Key to use in the checkpoint (example: "teacher")') 231 | parser.add_argument("--image_path", default=None, type=str, help="Path of the image to load.") 232 | parser.add_argument('--output_dir', default='.', help='Path where to save visualizations.') 233 | parser.add_argument("--threshold", type=float, default=0.6, help="""We visualize masks 234 | obtained by thresholding the self-attention maps to keep xx% of the mass.""") 235 | 236 | args = parser.parse_args(args=[]) 237 | 238 | args.arch = arch 239 | args.pretrained_weights = pretrained_weights_path 240 | args.image_path = input_path 241 | args.output_dir = output_path 242 | args.threshold = threshold 243 | ``` 244 | 245 | 246 | ```python 247 | model = vits.__dict__[args.arch](patch_size=args.patch_size, num_classes=0) 248 | for p in model.parameters(): 249 | p.requires_grad = False 250 | model.eval() 251 | model.cuda() 252 | if os.path.isfile(args.pretrained_weights): 253 | state_dict = torch.load(args.pretrained_weights, map_location="cpu") 254 | if args.checkpoint_key is not None and args.checkpoint_key in state_dict: 255 | print(f"Take key {args.checkpoint_key} in provided checkpoint dict") 256 | state_dict = state_dict[args.checkpoint_key] 257 | state_dict = {k.replace("module.", ""): v for k, v in state_dict.items()} 258 | msg = model.load_state_dict(state_dict, strict=False) 259 | print('Pretrained weights found at {} and loaded with msg: {}'.format(args.pretrained_weights, msg)) 260 | else: 261 | print("Please use the `--pretrained_weights` argument to indicate the path of the checkpoint to evaluate.") 262 | url = None 263 | if args.arch == "deit_small" and args.patch_size == 16: 264 | url = "dino_deitsmall16_pretrain/dino_deitsmall16_pretrain.pth" 265 | elif args.arch == "deit_small" and args.patch_size == 8: 266 | url = "dino_deitsmall8_300ep_pretrain/dino_deitsmall8_300ep_pretrain.pth" # model used for visualizations in our paper 267 | elif args.arch == "vit_base" and args.patch_size == 16: 268 | url = "dino_vitbase16_pretrain/dino_vitbase16_pretrain.pth" 269 | elif args.arch == "vit_base" and args.patch_size == 8: 270 | url = "dino_vitbase8_pretrain/dino_vitbase8_pretrain.pth" 271 | if url is not None: 272 | print("Since no pretrained weights have been provided, we load the reference pretrained DINO weights.") 273 | state_dict = torch.hub.load_state_dict_from_url(url="https://dl.fbaipublicfiles.com/dino/" + url) 274 | model.load_state_dict(state_dict, strict=True) 275 | else: 276 | print("There is no reference weights available for this model => We use random weights.") 277 | 278 | ``` 279 | 280 | Pretrained weights found at dino_deitsmall8_pretrain.pth and loaded with msg: 281 | 282 | 283 | 284 | ```python 285 | torch.cuda.empty_cache() 286 | gc.collect() 287 | ``` 288 | 289 | 290 | 291 | 292 | 268 293 | 294 | 295 | 296 | ## DINO抽取feature 297 | 使用DINO预训练好的ViT对视频转化之后的图片抽features,如果OOM,把上面的resize参数改小一点。 298 | 299 | 300 | ```python 301 | predict_video(args) 302 | ``` 303 | 304 | ## 输出视频 305 | 306 | 输入视频是60帧每秒,输出也是。 307 | 308 | 309 | ```python 310 | !ffmpeg -framerate 60 -i ../output/attn-img-%03d.jpg ../output.mp4 311 | ``` 312 | 313 | 输入输出对比放一起,输出之后从google drive上下载下来就可以了。 314 | 315 | 316 | ```python 317 | !ffmpeg -i ../bilibili_cat.mp4 -i ../output.mp4 -filter_complex '[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]' -map '[vid]' -c:v libx264 -crf 23 -preset veryfast ../final.mp4 318 | ``` 319 | 320 | 321 | # Huggingface里ViT的基本使用 322 | 323 | ## 在CIFAR-10上微调Fine-tune ViT模型 324 | 主要基于这个[notbook](https://colab.research.google.com/github/NielsRogge/Transformers-Tutorials/blob/master/VisionTransformer/Fine_tuning_the_Vision_Transformer_on_CIFAR_10_with_the_%F0%9F%A4%97_Trainer.ipynb),这个大佬写的https://nielsrogge.github.io/。 325 | 326 | 他原本的本地想直接跑起来其实缺少不少库,需要额外安装下。 327 | 328 | 在这个notebook中我们基于预训练的Vision Transformer在CIFAR-10上做一个分类任务。CIFAR-10数据集包含了60000个32x32的彩色图片,总共10个类别,每个类别6000张图。 329 | 330 | 使用Huggingface的[🤗 datasets](https://github.com/huggingface/datasets)预处理数据,使用[🤗 Trainer](https://huggingface.co/transformers/main_classes/trainer.html)对模型进行训练。 331 | 332 | 333 | ### 简单介绍: Vision Transformer (ViT) by Google Brain 334 | vision Transformer基本上和BERT相同,不同的地方在于用在了图像上。为了能够让transformer用在图像上,它将一张图切分成多个patches(想象成一系列网格即可),然后将所有的patches连接起来看成序列,每个patch对应nlp里的一个token。和NLP相似,直接在patches序列的开头添加一个[CLS] token用来聚合整个图片的信息,每个patch(token)得到一个embedding,同样每个patch也对应了一个position embeding,然后把token 的embedding和位置向量一起送入transformer模型即可。ViT在在图像上取得了很好的效果。 335 | 336 | * Paper: https://arxiv.org/abs/2010.11929 337 | * Official repo (in JAX): https://github.com/google-research/vision_transformer 338 | 339 | 340 | ```python 341 | !pip install -q git+https://github.com/huggingface/transformers datasets 342 | ``` 343 | 344 | Installing build dependencies ... [?25l[?25hdone 345 | Getting requirements to build wheel ... [?25l[?25hdone 346 | Preparing wheel metadata ... [?25l[?25hdone 347 |  |████████████████████████████████| 225kB 21.9MB/s 348 |  |████████████████████████████████| 3.3MB 49.6MB/s 349 |  |████████████████████████████████| 901kB 53.1MB/s 350 |  |████████████████████████████████| 245kB 59.4MB/s 351 |  |████████████████████████████████| 112kB 61.7MB/s 352 | [?25h Building wheel for transformers (PEP 517) ... [?25l[?25hdone 353 | 354 | 355 | ## 数据准备 356 | 357 | 这里只用CIFAR-10数据一部分来作为演示。使用 `ViTFeatureExtractor`抽取图片特征. `ViTFeatureExtractor`会将每个32x32的图片resize成224x224大小,同时对每个channel进行归一化。 358 | 本文主要是演示,想要更好的效果需要更完整数据和更高的图片分辨率进行训练。 359 | 360 | 361 | ```python 362 | from transformers import ViTFeatureExtractor 363 | 364 | feature_extractor = ViTFeatureExtractor.from_pretrained('google/vit-base-patch16-224-in21k') 365 | ``` 366 | 367 | 368 | HBox(children=(FloatProgress(value=0.0, description='Downloading', max=160.0, style=ProgressStyle(description_… 369 | 370 | 371 | 372 | 373 | 374 | 375 | ```python 376 | #加载数据 377 | from datasets import load_dataset 378 | 379 | # load cifar10 (only small portion for demonstration purposes) 380 | train_ds, test_ds = load_dataset('cifar10', split=['train[:5000]', 'test[:1000]']) 381 | # split up training into training + validation 382 | splits = train_ds.train_test_split(test_size=0.1) 383 | train_ds = splits['train'] 384 | val_ds = splits['test'] 385 | ``` 386 | 387 | 388 | ```python 389 | # 数据预处理函数 390 | import numpy as np 391 | 392 | def preprocess_images(examples): 393 | # get batch of images 394 | images = examples['img'] 395 | # convert to list of NumPy arrays of shape (C, H, W) 396 | images = [np.array(image, dtype=np.uint8) for image in images] 397 | images = [np.moveaxis(image, source=-1, destination=0) for image in images] 398 | # preprocess and add pixel_values 399 | inputs = feature_extractor(images=images) 400 | examples['pixel_values'] = inputs['pixel_values'] 401 | 402 | return examples 403 | ``` 404 | 405 | 406 | ```python 407 | # 数据预处理,大概几分钟 408 | from datasets import Features, ClassLabel, Array3D 409 | 410 | # we need to define the features ourselves as both the img and pixel_values have a 3D shape 411 | features = Features({ 412 | 'label': ClassLabel(names=['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']), 413 | 'img': Array3D(dtype="int64", shape=(3,32,32)), 414 | 'pixel_values': Array3D(dtype="float32", shape=(3, 224, 224)), 415 | }) 416 | 417 | preprocessed_train_ds = train_ds.map(preprocess_images, batched=True, features=features) 418 | preprocessed_val_ds = val_ds.map(preprocess_images, batched=True, features=features) 419 | preprocessed_test_ds = test_ds.map(preprocess_images, batched=True, features=features) 420 | ``` 421 | 422 | 423 | 424 | 425 | 426 | 427 | ## 定义模型 428 | 定义一个分类模型,在ViT上面基于CLS token过一个全连接网络即可。 429 | 430 | 431 | ```python 432 | from transformers import ViTModel 433 | from transformers.modeling_outputs import SequenceClassifierOutput 434 | import torch.nn as nn 435 | 436 | class ViTForImageClassification(nn.Module): 437 | def __init__(self, num_labels=10): 438 | super(ViTForImageClassification, self).__init__() 439 | self.vit = ViTModel.from_pretrained('google/vit-base-patch16-224-in21k') 440 | self.dropout = nn.Dropout(0.1) 441 | self.classifier = nn.Linear(self.vit.config.hidden_size, num_labels) 442 | self.num_labels = num_labels 443 | 444 | def forward(self, pixel_values, labels): 445 | outputs = self.vit(pixel_values=pixel_values) 446 | output = self.dropout(outputs.last_hidden_state[:,0]) 447 | logits = self.classifier(output) 448 | 449 | loss = None 450 | if labels is not None: 451 | loss_fct = nn.CrossEntropyLoss() 452 | loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1)) 453 | 454 | return SequenceClassifierOutput( 455 | loss=loss, 456 | logits=logits, 457 | hidden_states=outputs.hidden_states, 458 | attentions=outputs.attentions, 459 | ) 460 | ``` 461 | 462 | 463 | ```python 464 | # 评估方法 465 | from transformers import TrainingArguments, Trainer 466 | 467 | metric_name = "accuracy" 468 | # 训练参数 469 | args = TrainingArguments( 470 | f"test-cifar-10", 471 | evaluation_strategy = "epoch", 472 | learning_rate=2e-5, 473 | per_device_train_batch_size=10, 474 | per_device_eval_batch_size=4, 475 | num_train_epochs=3, 476 | weight_decay=0.01, 477 | load_best_model_at_end=True, 478 | metric_for_best_model=metric_name, 479 | logging_dir='logs', 480 | ) 481 | ``` 482 | 483 | 484 | ```python 485 | from transformers import default_data_collator 486 | 487 | data_collator = default_data_collator 488 | ``` 489 | 490 | 491 | ```python 492 | #定义模型 493 | model = ViTForImageClassification() 494 | ``` 495 | 496 | 497 | ## 训练和分析 498 | 499 | 500 | ```python 501 | # 如何计算分数 502 | from datasets import load_metric 503 | import numpy as np 504 | 505 | metric = load_metric("accuracy") 506 | 507 | def compute_metrics(eval_pred): 508 | predictions, labels = eval_pred 509 | predictions = np.argmax(predictions, axis=1) 510 | return metric.compute(predictions=predictions, references=labels) 511 | ``` 512 | 513 | 514 | HBox(children=(FloatProgress(value=0.0, description='Downloading', max=1362.0, style=ProgressStyle(description… 515 | 516 | 517 | 518 | 519 | 520 | 521 | ```python 522 | # 定义训练框架 523 | trainer = Trainer( 524 | model, 525 | args, 526 | train_dataset=preprocessed_train_ds, 527 | eval_dataset=preprocessed_val_ds, 528 | data_collator=data_collator, 529 | compute_metrics=compute_metrics, 530 | ) 531 | ``` 532 | 533 | 534 | ```python 535 | # Start tensorboard. 536 | %load_ext tensorboard 537 | %tensorboard --logdir logs/ 538 | ``` 539 | 540 | 541 | 542 | 543 | 544 | 545 | ```python 546 | # 开始训练 547 | trainer.train() 548 | ``` 549 | 550 | 551 | 552 |

553 | 554 | 555 | [270/270 02:36, Epoch 3/3] 556 |
557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 |
EpochTraining LossValidation LossAccuracy
1No log1.8511320.920000
2No log1.5238740.950000
3No log1.4077410.960000

587 | 588 | 589 | 590 | 591 | 592 | TrainOutput(global_step=270, training_loss=1.685737779405382, metrics={'train_runtime': 157.1564, 'train_samples_per_second': 1.718, 'total_flos': 0, 'epoch': 3.0, 'init_mem_cpu_alloc_delta': 1325400064, 'init_mem_gpu_alloc_delta': 345588224, 'init_mem_cpu_peaked_delta': 0, 'init_mem_gpu_peaked_delta': 0, 'train_mem_cpu_alloc_delta': 589918208, 'train_mem_gpu_alloc_delta': 1054787072, 'train_mem_cpu_peaked_delta': 50122752, 'train_mem_gpu_peaked_delta': 1691880448}) 593 | 594 | 595 | 596 | 597 | ```python 598 | # 预测 599 | outputs = trainer.predict(preprocessed_test_ds) 600 | ``` 601 | 602 | 603 | 604 |

605 | 606 | 607 | [250/250 00:22] 608 |
609 | 610 | 611 | 612 | 613 | ```python 614 | # 分析 615 | from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay 616 | 617 | y_true = outputs.label_ids 618 | y_pred = outputs.predictions.argmax(1) 619 | 620 | labels = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] 621 | cm = confusion_matrix(y_true, y_pred) 622 | disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=labels) 623 | disp.plot(xticks_rotation=45) 624 | ``` 625 | 626 | 627 | 628 | 629 | 630 | 631 | ![png](Vision%20Transformer%E4%BD%BF%E7%94%A8%E5%92%8Cfacebook%E8%87%AA%E7%9B%91%E7%9D%A3%E5%AD%A6%E4%B9%A0DINO%E8%AE%AD%E7%BB%83%E6%96%B9%E6%B3%95play_files/Vision%20Transformer%E4%BD%BF%E7%94%A8%E5%92%8Cfacebook%E8%87%AA%E7%9B%91%E7%9D%A3%E5%AD%A6%E4%B9%A0DINO%E8%AE%AD%E7%BB%83%E6%96%B9%E6%B3%95play_45_1.png) 632 | 633 | 634 | 635 | 636 | ```python 637 | 638 | ``` 639 | -------------------------------------------------------------------------------- /docs/深度学习应用/计算机视觉任务/前言.md: -------------------------------------------------------------------------------- 1 | 目前主要基于[huggingface/transformer库](https://github.com/huggingface/transformers)对深度学习在计算机视觉任务中的使用进行说明。 2 | 3 | 4 | * [1-Vit和自监督学习](./深度学习应用/计算机视觉任务/1-Vision%20Transformer使用和facebook自监督学习DINO训练方法.md) -------------------------------------------------------------------------------- /docs/深度学习数学基础/0-前言.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 上一篇在公众号写的[神经网络调试Checklist](https://mp.weixin.qq.com/s/Py0NIqPor7i92b7pS5Sw_A)详细地介绍了神经网络调试的步骤和技巧。本文将进一步学习深度学习网络中另一核心内容:**求导和反向传播**。笔者认为,在熟练使用诸如Pytroch/Tensorflow等深度学习工具之外,咱们也有必要对背后的数学知识有所理解。因此,本文将从简单的标量谈起,深入解析神经网络中张量求导和反向传播所涉及的数学计算,希望能成为深度学习初学者的参考资料。 5 | 6 | 提几个问题,读者朋友看下是否可以自如回答: 7 | - 1. 什么是链式法则? 8 | - 2. 什么是Jacobin矩阵,它有什么用处? 9 | - 3. 梯度的定义是什么?方向导数和梯度的关系是什么? 10 | - 4. 神经网络中张量反向传播有什么特点?哪些特性保证了神经网络中高效的梯度计算? 11 | 12 | * [1.1 标量、向量、矩阵、张量](./深度学习数学基础/1.1-标量、向量、矩阵和张量) 13 | * [1.2 简单的线性代数](./深度学习数学基础/1.2-简单的线性代数.md) 14 | * [2.1-标量:导数的概念](./深度学习数学基础/2.1-标量:导数的概念.md) 15 | * [2.2-标量:链式法则](./深度学习数学基础/2.2-标量:链式法则.md) 16 | * [2.3-标量:求导常用公式](./深度学习数学基础/2.3-标量:求导常用公式.md) 17 | * [2.4-多个标量:多元函数求导、偏导数](./深度学习数学基础/2.4-多个标量:多元函数求导、偏导数.md) 18 | * [2.5-方向导数和梯度](./深度学习数学基础/2.5-方向导数和梯度.md) 19 | * [2.6-向量的梯度和Jacobian矩阵](./深度学习数学基础/2.6-向量的梯度和Jacobian矩阵.md) 20 | * [2.7-矩阵和张量的梯度](./深度学习数学基础/2.7-矩阵和张量的梯度.md) 21 | * [2.8-神经网络中几个实用的梯度计算](./深度学习数学基础/2.8-神经网络中几个实用的梯度计算.md) 22 | * [3.1-神经网络中的反向传播](./深度学习数学基础/3.1-神经网络中的反向传播.md) 23 | * [3.2-单层神经网络梯度计算例子](./深度学习数学基础/3.2-单层神经网络梯度计算例子.md) 24 | * [4.1-Pytorch自动求梯度](./深度学习数学基础/4.1-Pytorch自动求梯度.md) 25 | * [4.2-Tensorflow自动求梯度](./深度学习数学基础/4.2-Tensorflow自动求梯度.md) -------------------------------------------------------------------------------- /docs/深度学习数学基础/1.1-标量、向量、矩阵和张量.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 1.1-标量、向量、矩阵、张量 4 | **标量** 简单来说:一个标量就是一个单独的数。 5 | 日常生活的一个例子:我们去超市买了1个冰淇凌,花费了2元,排队结账用了5分钟,其中1、2和5都是标量。 6 | 7 | 对于标量,我们一般不讨论其维度或者形状(shape)的大小(或者说是0维)。 8 | 9 | **向量** 10 | 将多个标量放在一起组成了向量。比如$x=[1,2]$就是一个向量。一个二维平面的点位置有2个特征:横坐标和纵坐标,因此可以用$[x坐标,y坐标]$这样一个二维向量来表示二维平面上的一个点;同理,可以使用[x坐标,y坐标,z坐标]三维向量来表示空间中的一个点所在的位置。日常生活中,我们也可以使用$[身高h,性别s,体重w,肤色f]$这样一个4维向量来表示一个人的特点。更高维的向量可以表达一个物体更多维度的特征。 11 | 12 | 向量的维度通常表达的是向量中标量的个数。$[1,2,3]$的维度为3维。 13 | 14 | **矩阵** 将多个向量排列到一起可以组成矩阵。例如: 15 | $$\begin{bmatrix} 16 | [1 & 2], \\ 17 | [1 & 3] 18 | \end{bmatrix} \tag{1-1-1}$$ 19 | 20 | 如矩阵(1-1-1)所示,矩阵的每一行就是一个向量。 21 | 22 | 矩阵的**形状**:每一列标量的个数 x 每一行标量的个数,矩阵(1-1-1)形状为2x2,维度为2。 23 | 24 | **张量** 25 | 将多个矩阵组合到一起可以形成张量。比如: 26 | $$\begin{bmatrix} 27 | \begin{bmatrix} 28 | [1 & 2] \\ 29 | [1 & 2] 30 | \end{bmatrix}, \\ 31 | \begin{bmatrix} 32 | [2 & 3] \\ 33 | [2 & 3] 34 | \end{bmatrix}, \\ 35 | \begin{bmatrix} 36 | [3 & 3] \\ 37 | [3 & 4] 38 | \end{bmatrix} \\ 39 | \end{bmatrix} \tag{1-1-2}$$ 40 | 因此标量、向量、矩阵都可以看作是维度更少的张量。 41 | 42 | 张量的形状:假设张量A形状为$d_n\times d_{n-1}... \times d_1$,那么表达的含义是:$n$维张量A中包含了$d_{n}$个形状为$d_{n-1} ... \times d_1$的$n-1$维张量B,并以此类推到1维张量。所以张量(1-1-2)的形状是3x2x2维度是3,张量(1-1-1)的形状是是2x2维度是2。 43 | 44 | 注意:由于大家的对矩阵、张量的形状和维度的概念容易混淆,本文在描述张量形状的时候都会使用$\times$符号来区分不同的维度。 45 | 46 | **Pytorch实践** 47 | ``` 48 | import torch 49 | scalar = torch.tensor(5) 50 | vector = torch.tensor([5,5,5]) 51 | matrix = torch.tensor([[5,2],[5,3]]) 52 | tensor = torch.tensor([[[5,2],[5,3]], [[1,2],[2,3]]]) 53 | print("scalar: {}, shape: {}".format(scalar, scalar.shape)) 54 | print("vector: {}, shape: {}".format(vector, vector.shape)) 55 | print("matrix: {}, shape: {}".format(matrix, matrix.shape)) 56 | print("tensor: {}, shape: {}".format(tensor, tensor.shape)) 57 | """ 58 | scalar: 5, shape: torch.Size([]) 59 | vector: tensor([5, 5, 5]), shape: torch.Size([3]) 60 | matrix: tensor([[5, 2], 61 | [5, 3]]), shape: torch.Size([2, 2]) 62 | tensor: tensor([[[5, 2], 63 | [5, 3]], 64 | 65 | [[1, 2], 66 | [2, 3]]]), shape: torch.Size([2, 2, 2]) 67 | """ 68 | ``` -------------------------------------------------------------------------------- /docs/深度学习数学基础/1.2-简单的线性代数.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 1.2-简单的线性代数 4 | 5 | 6 | 1.1章节中我们谈到向量可以延伸到矩阵,然后延伸到张量,因此为了能够更好得对深度学习中的向量/矩阵/张量运算、梯度求解有一个更清晰的理解,我们需要学习一下基本的线性代数知识。由于张量运算过于复杂,一般我们将张量运算交给计算机进行。我们在进行线性代数讲解的时候也尽可能使用特殊而又简单的张量(也就是矩阵和向量)。 7 | 8 | ### 什么是线性代数 9 | 10 | 一般来说,线性代数在是本科一年级的一门必修课。但是本文将不会涉及完整的线性代数体系知识,仅仅将线性代数常用于深度学习的部分知识进行整理。我们将线性代数看作深度学习中的数学计算工具即可:深度学习使用线性代数对张量进行加减乘除等各种运算。 11 | 12 | ### 线性代数能带来什么好处? 13 | 14 | 由于深度学习中需要进行大量的张量运算,而每个张量又包含了多个标量,因此可以想象,如果直接进行标量计算需要大量的$for$循环。但是线性代数的知识,能将复杂而又慢的循环遍历标量计算变得更加优雅、快速、简单。 15 | 16 | ### 例子 17 | ``` 18 | # 将两个向量中的每个元素相乘求和 19 | x = [1,2,3] 20 | y = [2,3,4] 21 | sum = 0.0 22 | for i in range(len(x)): 23 | sum = sum + x[i]*y[i] 24 | # 借助深度学习工具torch,使用点乘直接运算 25 | import torch 26 | x = torch.tensor([1,2,3]) 27 | y = torch.tensor([2,3,4]) 28 | sum = torch.dot(x, y)) 29 | ``` 30 | 31 | ### 深度学习中的应用 32 | 33 | 深度学习中的神经网络包含了大量的参数(也叫做parameters/weights)和参数计算。参数往往以张量的形式储存,线性代数的知识(比如点乘,矩阵运算)能让参数间的计算更加快速(如果是使用GPU进行计算,这种提速会更加明显)。 34 | 35 | ### 标量运算 36 | 37 | 最简单的形式:标量和标量进行加减乘除运算。 38 | 39 | *例子:标量+标量* 40 | 41 | ``` 42 | import torch 43 | a = torch.tensor(2) 44 | b = torch.tensor(3) 45 | c = a + b 46 | print(c) 47 | # tensor(5) 48 | ``` 49 | 50 | ### 向量和标量 51 | 52 | 将向量中的每一个标量都与另一个标量都进行计算([broadcasting/广播](https://pytorch.org/docs/stable/notes/broadcasting.html)的一种)。 53 | 54 | *例子* 55 | 56 | ``` 57 | a = torch.tensor(2) 58 | b = torch.tensor([1,2,3]) 59 | c = a + b 60 | print(c) 61 | # tensor([3, 4, 5]) 62 | ``` 63 | 64 | ### 向量和向量按位置(elementwise)运算 65 | 66 | 向量间同一个位置的元素/标量进行运算。 67 | 68 | *例子* 69 | ``` 70 | a = torch.tensor([2,3,4]) 71 | b = torch.tensor([1,2,3]) 72 | c = a + b 73 | print(c) 74 | # tensor([3, 5, 7]) 75 | # Hadamard product 76 | a = torch.tensor([2,3,4]) 77 | b = torch.tensor([1,2,3]) 78 | c = a * b 79 | print(c) 80 | # tensor([ 2, 6, 12]) 81 | ``` 82 | 83 | ### 点乘 84 | 85 | 向量之间的点乘是深度学习中最普遍也是最常用的一种计算:先按位置做乘法,然后相加求和。 86 | 87 | *例子* 88 | ``` 89 | a = torch.tensor([2,3,4]) 90 | b = torch.tensor([1,2,3]) 91 | c = torch.dot(a, b) 92 | print(c) 93 | # tensor(20) 94 | ``` 95 | 96 | ### 矩阵和标量 97 | 98 | 将矩阵中的每一个标量都与另一个标量都进行计算([broadcasting/广播](https://pytorch.org/docs/stable/notes/broadcasting.html)的一种)。 99 | 100 | *例子* 101 | 102 | ``` 103 | a = torch.tensor(2) 104 | b = torch.tensor([[1,2,3], 105 | [1,2,3]]) 106 | c = a + b 107 | print(c) 108 | # tensor([[3, 4, 5], 109 | # [3, 4, 5]]) 110 | ``` 111 | 112 | ### 矩阵和向量 113 | 114 | 将向量广播成与矩阵相同的维度,然后和矩阵的每一个元素都进行计算([broadcasting/广播](https://pytorch.org/docs/stable/notes/broadcasting.html)的一种)。 115 | 116 | *例子* 117 | 118 | ``` 119 | a = torch.tensor(2) 120 | b = torch.tensor([[1,2,3], 121 | [1,2,3]]) 122 | c = a + b 123 | print(c) 124 | # tensor([[3, 4, 5], 125 | # [3, 4, 5]]) 126 | ``` 127 | 128 | ### 矩阵和矩阵按位置(elementwise)运算 129 | 130 | 向量间同一个位置的元素/标量进行运算。 131 | 132 | *例子* 133 | ``` 134 | a = torch.tensor([[2,3,4], 135 | [2,3,4]]) 136 | b = torch.tensor([[1,2,3]]) 137 | # 现将b变成[[1,2,3], 138 | # [1,2,3]]再计算 139 | c = a + b 140 | print(c) 141 | # tensor([[3, 5, 7], 142 | # [3, 5, 7]]) 143 | # Hadamard product 144 | ``` 145 | 146 | ### 矩阵乘法 147 | 148 | 深度学习中最常用、最重要的计算! 149 | 假设矩阵$a \in \mathbb R ^{n \times m}, b \in \mathbb R^{m \times k}$,那么$c = a \times b \in \mathbb R^{n \times k}$。对于$c$矩阵中的每一个元素计算方式为:$a$的第$i$行向量与$b$的第$j$列向量进行点乘。 150 | 151 | $$c_{ij} = \sum_k {a_{ik}b_{kj}}$$ 152 | 153 | 因此两个矩阵要进行矩阵乘法必须满足:前一个矩阵的列数=后一个矩阵的行数。 154 | 155 | *例子* 156 | ``` 157 | a = torch.tensor([[2,3,4], 158 | [2,3,4]]) 159 | print(a.shape) 160 | # torch.Size([2, 3]) 161 | b = torch.tensor([[1], 162 | [2], 163 | [3]]) 164 | print(b.shape) 165 | # torch.Size([3, 1]) 166 | c = torch.matmul(a, b) 167 | print(c) 168 | #tensor([[20], 169 | # [20]]) 170 | print(c.shape) 171 | # torch.Size([2, 1]) 172 | ``` 173 | ### 转置 174 | 175 | 前面提到了矩阵乘法,因此为了能够让矩阵乘法正常计算,我们常常需要对矩阵进行转置来得到正确的矩阵形状。比如一个$\mathbb R^{2 \times 3}$的矩阵无法和$\mathbb R^{2 \times 3}$直接做乘法,但可以将后一个转置得到$\mathbb R^{3 \times 2}$后便可以进行矩阵乘法了。具体的如何进行转置呢? 176 | 177 | 假设矩阵为 178 | $$M = \begin{bmatrix} 179 | [a& b &c], \\ 180 | [d& e & f] 181 | \end{bmatrix}$$ 182 | 183 | 那么它的转置为 184 | $$M = \begin{bmatrix} 185 | [a& d], \\ 186 | [b& e], \\ 187 | [c&f ] 188 | \end{bmatrix}$$ 189 | 190 | - 先将矩阵$M$逆时针旋转$90^0$ 191 | - 然后每一列顺序反过来即可,比如第一列:$[b,a,c] \to [a,b,c]$ 192 | 193 | ``` 194 | import torch 195 | a = torch.tensor([[2,3,4], 196 | [2,3,4]]) 197 | print(a.shape) 198 | b = torch.tensor([[2,3,4], 199 | [2,3,4]]) 200 | print(b.shape) 201 | c = b.T 202 | print(c.shape) 203 | d = torch.matmul(a, c) 204 | print(d) 205 | # torch.Size([2, 3]) 206 | # torch.Size([2, 3]) 207 | # torch.Size([3, 2]) 208 | # tensor([[29, 29], 209 | # [29, 29]]) 210 | ``` 211 | 212 | 参考文章:[linear-algebra-cheat-sheet-for-deep-learning](https://towardsdatascience.com/linear-algebra-cheat-sheet-for-deep-learning-cd67aba4526c) 213 | -------------------------------------------------------------------------------- /docs/深度学习数学基础/2.1-标量:导数的概念.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 2.1-标量:导数的概念 4 | **导数的定义**:设函数$y=f(x), \mathbb R \to \mathbb R$,将实数$x$映射到实数$y$, 在点$x_0$的某领域内有定义,当自变量在$x_0$处取得增量$\Delta x$时函数取得相应的增量$\Delta y=f(x_0 + \Delta x) - f(x_0)$,如果极限 5 | 6 | $$\lim_{\Delta x \to 0} \frac{\Delta y}{\Delta x} = \lim_{\Delta x \to 0} \frac{f(x_0 + \Delta x) - f(x_0)}{\Delta x} \tag{2.1.1}$$ 7 | 8 | 存在,则称$f(x)$在点$x_0$处可导,通常可以写做$f'(x_0)$, $\frac{dy}{dx} \vert_{x=x_0}$, $\frac{\partial f}{\partial x}$或者$\frac{df}{dx} \vert_{x=x_0}$。 9 | 10 | **注意本文在一元函数导数表示时候也用$\frac{\partial f}{\partial x}$** 11 | 12 | ![图2.1.1 导数示意图,来源:https://www.mathsisfun.com/calculus/derivatives-introduction.html](https://www.mathsisfun.com/calculus/images/slope-dy-dx2.svg) 13 | 14 | 于是,如图2.1.1所示,通俗得讲:对于定义域内的$x$,当$\Delta x$很小的时候,在点$x$处的导数$f'(x)$就是点x处的斜率$\frac{\Delta y}{\Delta x}$(导数的几何意义)。 15 | 16 | **举例**: 计算$f(x)=x^2$的导数,根据定义 17 | 18 | $$\lim_{\Delta x \to 0} = \frac{f(x+\Delta x) -f(x)}{\Delta x} = \frac{2x\Delta x + {\Delta x}^2}{\Delta x} = 2x + {\Delta x} \tag{2.1.2}$$ 19 | 20 | 由于$\Delta x$无限趋近于0,那么可以得到$f'(x)=2x$。 21 | 22 | **读者可继续选修左导数、右导数的定义**。 23 | 24 | 25 | **函数$f(x)$在点$x_0$处可求导的充分必要条件是$f(x)$在点$x_0$处的左、右导数都存在且相等。** 26 | 27 | 观察2.1.1可以继续得到: 28 | 29 | $$f(x+\Delta x) \approx f(x) + \frac{\Delta y}{\Delta x} \Delta x = f(x) + f'(x)\Delta x = f(x) + \frac{\partial f}{\partial x} \Delta x \tag{2.1.3}$$ 30 | 31 | 即:$x$的增量$\Delta x$与$y$的变化量$\Delta y$可以通过导数联系起来,当$x$增加$\Delta x$的时候,$y=f(x)$近似地增加$\frac{\partial y}{\partial x} \Delta x$。 32 | 33 | $$x \to x + \Delta x \Rightarrow y \to \approx y + \frac{\partial y}{\partial x} \Delta x \tag{2.1.4}$$ 34 | -------------------------------------------------------------------------------- /docs/深度学习数学基础/2.2-标量:链式法则.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 2.2-标量:求导链式法则 4 | 一般来说,通过2.1章节导数的定义可以求出导数,但为了计算方便和快捷,我们通常需要知道基本的求导法则和常用公式。 5 | 6 | **函数的和、差、积、商求导法则** 7 | 8 | *定理1* 如果函数$u = u(x), v = v(x)$在点$x$处可导,则$u(x) \pm v(x)$, $Cu(x)(C是常数)$, $u(x)v(x)$, $\frac{u(x)}{v(x)}(当v(x) \neq 0)$都在点$x$处可导,并且: 9 | 10 | $$(u(x) \pm v(x) )' = u'(x) + v'(x) \tag{2.2.1}$$ 11 | $$(Cu(x))' = Cu'(x)$$ 12 | $$(u(x)v(x))' = u'(x)v(x) + u(x)v'(x)$$ 13 | $$(\frac{u(x)}{v(x)})' = \frac{u'(x)v(x) - u(x)v'(x)}{v^2(x)}, 特别地\frac{1}{v(x)} = \frac{-v'(x)}{v^2}$$ 14 | 15 | **复合函数求导:链式法则** 16 | 17 | 根据导数的定义可以知道单个函数$f(x)$的求导方法,当$f(x)$更加复杂时(比如$f(x) = \frac{sinx}{x^2 + cosx}$),直接求导将变得困难。因此,我们希望能将一步复杂的函数拆分成多步简单的函数求导。 18 | 19 | 20 | 21 | *链式法则* 告诉我们如何对一个复杂函数进行多步求导。假设我们有实数函数$z=g(y), y=f(x)$其中$f,g: \mathbb R \to \mathbb R$ 22 | 23 | $$x \overset{f}{\rightarrow} y \overset{g}{\rightarrow} z$$ 24 | *定理2 链式法则*: 25 | $$\frac{\partial z}{\partial x} = \frac{\partial z}{\partial y} \frac{\partial y}{\partial x} \tag{2.2.2}$$ 26 | 27 | 结合公式(2.1.4),我们可以知道: 28 | $$x \to x + \Delta x \Rightarrow y \to \approx y + \frac{\partial y}{\partial x}\Delta x \tag{2.2.3}$$ 29 | 30 | $$y \to y + \Delta y \Rightarrow z \to z + \frac{\partial z}{\partial y}\Delta y$$ 31 | 32 | 从公式(2.2.2)可以看出$x$的增量变化对$z$的影响:如果$x$增加$\Delta x$,$y$增加$\Delta y = \frac{\partial y}{\partial x} \Delta x$;进一步,$y$增加$\Delta y$,$z$增加$\Delta z = \frac{\partial z}{\partial y} \Delta y = \frac{\partial z}{\partial y} \frac{\partial y}{\partial x}$ 33 | 34 | **举例** 35 | $z = e^{2x}$可以写成$z = e^y, y = 2x$,那么 36 | $$\frac{\partial z}{\partial x} = \frac{\partial z}{\partial y} \frac{\partial y}{\partial x} = e^{2x} * 2= 2e^{2x}$$ 37 | -------------------------------------------------------------------------------- /docs/深度学习数学基础/2.3-标量:求导常用公式.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 2.3-标量:求导常用公式 4 | 5 | 6 | **常用求导公式** 7 | $$(C)'=0$$ 8 | $$(x^a)' = ax^{a-1} a为实数$$ 9 | $$(a^x)' = a^x lna, (e^x)' = e^x$$ 10 | $$(log_ax)' = \frac{1}{xlna}, (ln|x|)' = \frac{1}{x}$$ 11 | $$(sinx)' = cosx$$ 12 | $$(cosx)' = -sinx$$ 13 | $$(tanx)' = \frac{1}{cos^2x}$$ 14 | $$(cotx)' = -\frac{1}{sin^2x}$$ 15 | $$(arcsinx)' = \frac{1}{\sqrt{1 - x^2}}$$ 16 | $$(arccosx)' = - \frac{1}{\sqrt{1 - x^2}}$$ 17 | $$(arctanx)' = \frac{1}{1 + x^2}$$ 18 | $$(\frac{e^x + e^{-x}}{2})' = \frac{e^x - e^{-x}}{2}$$ 19 | $$(\frac{e^x - e^{-x}}{2})' = \frac{e^x + e^{-x}}{2}$$ 20 | $$(ln(x + \sqrt{x^2 + 1}))' = \frac{1}{\sqrt{x^2 + 1}}$$ 21 | $$(ln(x + \sqrt{x^2 - 1}))' = \frac{1}{\sqrt{x^2 - 1}}$$ -------------------------------------------------------------------------------- /docs/深度学习数学基础/2.4-多个标量:多元函数求导、偏导数.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 2.4-多个标量:多元函数求导、偏导数 4 | 5 | **一元函数**:一个自变量输入为$x$,一个因变量输出为$y$。 6 | 7 | **多元函数**:多个自变量输入为$x, y$,一个因变量输出为$y$。 8 | 9 | 为了我们能够在多个变量的函数中考虑只有一个自变量变化的变化率,我们需要定义一个叫做**偏导数**的概念。 10 | 11 | *定义* 设函数$z=f(x, y)$在点$(x_0, y_0)$的某领域内有定义,将$y$固定为$y_0$,而$x$在$x_0$处取得增量$\Delta x$ 时,$f(x, y)$所产生的相应增量: 12 | 13 | $$\Delta_x z = f(x_0 + \Delta x, y_0) - f(x_0, y_0) \tag{2.4.1}$$ 14 | 15 | 称为$f(x, y)$关于$x$的偏增量,如果极限: 16 | $$\lim_{\Delta x \to 0} \frac{\Delta_x z}{\Delta x} = \lim_{\Delta x \to 0} \frac{f(x_0 + \Delta x, y_0) - f(x_0, y_0)}{\Delta x} \tag{2.4.2}$$ 17 | 18 | 存在,则称此极限为函数$z=f(x, y)$在点$(x_0, y_0)$处对$x$的偏导数,记做: 19 | $$\frac{\partial z}{ \partial x} \vert_{x_0, y_0}, \frac{\partial f}{ \partial x} \vert_{x_0, y_0}, f'_x(x_0, y_0) \tag{2.4.3}$$ 20 | 21 | 也就是: 22 | $$f'_x(x_0, y_0) = \lim_{\Delta x \to 0} \frac{f(x_0 + \Delta x) - f(x_0)}{ \Delta x}$$ 23 | 24 | 同理,可以得到函数$f(x, y)$对$y$的偏导数: 25 | $$f'_y(x_0, y_0) = \lim_{\Delta y \to 0} \frac{f(y_0 + \Delta y) - f(y_0)}{ \Delta y}$$ 26 | 27 | 如果函数$z=f(x, y)$在区域$D$内每一点$(x,y)$都有对$x$的偏导数$f'_x(x,y)$或对$y$的偏导数$f'_y(x,y)$,且$f'_x(x,y)$和$f'_y(x,y)$仍是$x,y$的函数,我们将其偏导函数(简称偏导数),可以记做: 28 | $$\frac{\partial z}{\partial x},\frac{\partial f}{\partial x} \tag{2.4.5}$$ 29 | $$\frac{\partial z}{\partial y},\frac{\partial f}{\partial y}$$ 30 | 31 | **偏导数的定义可以推广到三元以上函数的情形。根据偏导数的定义,当多元函数表达式已经给出的时候,求他的各个偏导数并不需要新方法,将其他变量固定为常量,对单个变量利用一元函数求导方法求导即可** 32 | 33 | **举例** 34 | 35 | *求$z=5x_0^2 + x_0x_1$在点$(x_0=1,x_1=2)$处的偏导数*. 36 | 37 | 先将$x_1$看作常量,对$x_0$求导得到: 38 | 39 | $$\frac{\partial z}{\partial x_0} = 10x_0 + x_1$$ 40 | 41 | 将$x_0$看成常量,对$x_1$求导得到: 42 | 43 | $$\frac{\partial z}{\partial x_1} = x_0$$ 44 | 45 | 于是带入$x_0=1, x_1 = 2$到上式中得到: 46 | $$\frac{\partial z}{\partial x_0} \vert _{1,2} = 12, \frac{\partial z}{\partial x_1} \vert _{1,2} = 2$$ 47 | 48 | **推广到向量** 49 | 50 | 在章节1.1中我们谈到:将多个标量放在一起可以形成向量。那么,我们重新从向量角度重新看一眼偏导数。我们将$N$个自变量放到一起可以组成一个向量$X=[x_0, x_1,..., x_N]$,输出得到一个标量$y$。于是我们的函数$f(X), \mathbb R^N \to \mathbb R$ 输入是一个向量(多个自变量),输出是一个标量。于是,在任意一点$X \in \mathbb R$, $y$对$X$的偏导数$\frac{\partial y}{\partial X} = [\frac{\partial y}{\partial x_0}, \frac{\partial y}{\partial x_1},..., \frac{\partial y}{\partial x_N}]$. 51 | 52 | **复合函数的偏导数** 53 | 54 | 对于一元函数,我们可以使用链式法则对复合函数进行求导。对于多元函数,由于复合函数的构成可以更加复杂,因此无法针对所有情况给出通用的求导公式,但是可以针对其中一种情况给出求导公式,方便大家发现读者发现其中的求导规律。 55 | 56 | **定理1 如果函数$u=\varphi(x, y), v=\psi(x, y)$ 在点$(x,y)$的各偏导数都存在,$z=f(u, v)在对应点$(u,v)可微,则复合函数$z=f(\varphi(x,y), \psi(x,y))$在点$(x, y)$的偏导数存在,且** 57 | $$\frac{\partial z}{\partial x}= \frac{\partial z}{\partial u} \frac{\partial u}{\partial x} + \frac{\partial z}{\partial v}\frac{\partial v}{\partial x}$$ 58 | $$\frac{\partial z}{\partial y}= \frac{\partial z}{\partial u} \frac{\partial u}{\partial y} + \frac{\partial z}{\partial y}\frac{\partial v}{\partial y} \tag{2.4.6}$$ 59 | 60 | **举例** 61 | 62 | 假设函数$F(x,y,z) = xz + yz,令u(x,z) = xz, v(y,z)=yz,F(u,v) = u + v$那么$F,u,v,x,y,z)之间的计算关系可以如图2.4.1所示,结构图2.4.1显示$z$不仅和u相关,也和v相关,于是我们试着计算一下偏导数 63 | 64 | $$\frac{\partial F}{\partial z} = \frac{\partial F}{\partial u} \frac{\partial u}{\partial z} + \frac{\partial F}{\partial v} \frac{\partial v}{\partial z} = x + y$$ 65 | 66 | ![图2.4.1:多元复合函数求偏导:知乎张敬信](https://pic3.zhimg.com/v2-ab40835bee904e1b508903cc024afb96_b.jpg) 67 | 68 | -------------------------------------------------------------------------------- /docs/深度学习数学基础/2.5-方向导数和梯度.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 2.5-方向导数和梯度 4 | 5 | 学习了偏导数的概念之后,我们可以进一步学习方向导数的概念。 6 | 7 | 在实际问题中,我们通常要研究函数在某一点处沿着某一方向的变化率(之前学习的对$x,y,z$的偏导数其实是沿着$x,y,z$方向的导数),例如在大气气象的研究中,我们就需要研究温度、气压沿着不同方向的变化率,方向导数便可以用来描述这类变化率。 8 | 9 | ![图2.5.1 方向导数示意图](https://pic3.zhimg.com/v2-66d67c93ad6cc6ae6bbc2f707fb3ef52_b.jpg) 10 | 11 | 设函数$z=f(x,y)$在点$P(x,y)$的某领域内有定义,如图2.5.1所示,从点$P$出发在$xOy$平面上引出一条射线$l$,并且$e$是射线$l$上的单位向量。假设$e$与$x$轴和$y$轴的夹脚分别为$\alpha, \beta$,从而单位向量$e=(cos\alpha, cos \beta)$,在射线上另外再取一个点$P'(x+\Delta x, y+ \Delta y)$,记: 12 | $$\rho = |PP'|=\sqrt{\Delta x^2 + \Delta y^2} \tag{2.5.1}$$ 13 | $$\Delta_l z = f(P') - f(P) = f(x+\Delta x, y+ \Delta y) - f(x,y)$$ 14 | 15 | 那么当$\rho$较小的时候,$\frac{\Delta_l z}{\rho}$可以近似地反应函数$z=f(x,y)$在点$P$处沿着射线$l$方向的变化情况,而其极限可以精确地描述这个变化情况,因此有如下定义: 16 | 17 | **定义 在上面所给出的假设下,如果极限** 18 | 19 | $$\lim_{\rho \to 0} \frac{\Delta_l z}{\rho} = \lim_{\rho \to 0} \frac{f(x+\Delta x, y+ \Delta y) - f(x,y)}{\rho} \tag{2.5.2}$$ 20 | 21 | **存在,则称此极限为函数$z=f(x,y)$在点点$P$处沿着方向$l或者e$的方向导数,记做$\frac{\partial z}{\partial l}或者\frac{\partial f}{\partial l}$**. 22 | 23 | 方向导数$\frac{\partial z}{\partial l}$反映了沿着射线$l$方向变量$z$的变化情况。 24 | 25 | **偏导数与方向导数的关系:**如果$i$表示$x$轴的方向,那么根据方向函数的定义,当$e=i$的时候,由于$\Delta_l z = \Delta_x z, \rho=\Delta x$,从而: 26 | 27 | $$\frac{\partial z}{\partial l} = \lim_{\rho \to 0} \frac{\Delta_l z}{\rho} = \lim_{\Delta x \to 0} \frac{\Delta_x z}{\Delta x} = \frac{\partial z}{\partial x} \tag{2.5.3}$$ 28 | 29 | 同理,如果$j$表示$y$轴的方向,那么根据方向函数的定义,当$e=j$的时候,由于$\Delta_l z = \Delta_y z, \rho=\Delta y$,从而: 30 | 31 | $$\frac{\partial z}{\partial l} = \lim_{\rho \to 0} \frac{\Delta_l z}{\rho} = \lim_{\Delta y \to 0} \frac{\Delta_y z}{\Delta y} = \frac{\partial z}{\partial y} \tag{2.5.3}$$ 32 | 33 | 多元函数的方向导数可以类比二元函数进行定义。 34 | 35 | **定理** 如果函数$z=f(x,y)$在点$P(x,y)$可微,且在点$P(x,y)$处$f(x,y)$沿着任何方向$l$的方向导数都存在,并且$e=(cos\alpha, cos \beta)为l$上的单位向量,那么有: 36 | 37 | $$\frac{\partial z}{\partial l} = \frac{\partial z}{\partial x} cos \alpha + \frac{\partial z}{\partial y} cos \beta$$ 38 | 39 | **定理** 如果函数$u=f(x,yz)$在点$P(x,y,z)$可微,且在点$P(x,y,z)$处$f(x,y,z)$沿着任何方向$l$的方向导数都存在,并且$e=(cos\alpha, cos \beta, cos\gamma)为l$上的单位向量,那么有: 40 | 41 | $$\frac{\partial u}{\partial l} = \frac{\partial u}{\partial x} cos \alpha + \frac{\partial u}{\partial y} cos \beta + \frac{\partial u}{\partial z} cos \gamma \tag{2.5.3}$$ 42 | 43 | 多元函数同样可以类比二元和三元函数建立方向导数和偏导数之间的联系。 44 | 45 | ### 偏导数、方向导数、梯度的关系 46 | 47 | 式子(2.5.3)可以进一步写成向量点乘的形式: 48 | 49 | $$\frac{\partial u}{\partial l} = (\frac{\partial u}{\partial x}, \frac{\partial u}{\partial y}, \frac{\partial u}{\partial z}) \cdot (cos \alpha, cos \beta, cos \gamma) \tag{2.5.4}$$ 50 | 51 | 记$g=(\frac{\partial u}{\partial x}, \frac{\partial u}{\partial y}, \frac{\partial u}{\partial z}), e=(cos \alpha, cos \beta, cos \gamma)$ 52 | 53 | 则$\frac{\partial u}{\partial l} = g \cdot e = |g|cos(g,e)$,因此可以知道当向量$e$与向量$g$方向一致时候取得最大值,即函数$u(x,y,z)$沿着此时方向$g$的方向导数取得最大值,且这个最大值为: 54 | 55 | $$|g| = \sqrt{(\frac{\partial u}{\partial x})^2 + \frac{\partial u}{\partial y})^2+ \frac{\partial u}{\partial z})^2} \tag{2.5.5}$$ 56 | 57 | 因此对于此时的$g$我们给出如下定义: 58 | 59 | ### 梯度的定义 60 | 61 | **向量$(\frac{\partial u}{\partial x}, \frac{\partial u}{\partial y}, \frac{\partial u}{\partial z})$称为函数$u(x,y,z)在点P(x,y,z)处的梯度,记为\mathbf{grad} u$**,也就是: 62 | 63 | $$\mathbf{grad} u =(\frac{\partial u}{\partial x}, \frac{\partial u}{\partial y}, \frac{\partial u}{\partial z}) \tag{2.5.6} $$ 64 | 65 | ### 梯度的意义 66 | 67 | 根据上面的讨论,函数$u(x,y,z)$的梯度的意义在于:假设$P(x,y,z)$是空间中一点,那么从点$P$所引出的所有射线方向中,沿着方向$\mathbf{grad} u$的方向导数最大,并且这个最大的方向导数值为$|\mathbf{grad} u|$ 68 | 69 | $$max\frac{\partial u}{\partial l} = |\mathbf{grad} u| = \sqrt{(\frac{\partial u}{\partial x})^2 + (\frac{\partial u}{\partial y})^2+ (\frac{\partial u}{\partial z})^2} \tag{2.5.7}$$ 70 | 71 | **举个例子** 72 | 73 | 假设$u(x,y,z)=x^2y + xy^2z$,求$\mathbf{grad} u(2,1,0)$. 74 | 75 | $$\frac{\partial u}{\partial x} = 2xy + y^2z, \frac{\partial u}{\partial y} = x^2 + 2xyz, \frac{\partial u}{\partial z} = xy^2$$ 76 | 77 | 在点(2,1,0)带入可以得到$\mathbf{grad} u(2,1,0) = 4i + 4j + 2k, i,j,k为沿着x,y,z的单位向量$ -------------------------------------------------------------------------------- /docs/深度学习数学基础/2.6-向量的梯度和Jacobian矩阵.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 2.6-向量的梯度和Jacobian矩阵 4 | 上一章节我们学习了三元函数中梯度的定义和例子。对于三元函数$f(x,y,z)$,我们同样可以从向量的角度进行理解:函数$f: \mathbb R^3 \to R$的输入是一个3维的向量(我们具体表示成了$x,y,z$),输出是一个标量。同样的对于$N$元函数可以理解为:$f: \mathbb R^N \to R$,输入是一个$N$维的向量,输出是一个标量。 5 | 6 | 对于函数$f: 输入x=[x_1, x_2,...,x_N] \in \mathbb R^N,输出y$,结合方向导数的定义和梯度的定义,我们可以得到如下等式: 7 | $$\lim_{\rho \to 0} \frac{\Delta_l y}{\rho} = \bigtriangledown_x y = \lim_{\rho \to 0} \frac{f(x_1+\Delta x_1,..., x_N+ \Delta x_N) - f(x_1,..., x_N)}{\rho} \tag{2.7.1}$$ 8 | $$\bigtriangledown_x y = [\frac{\partial y}{\partial x_1}, \frac{\partial y}{\partial x_2},..., \frac{\partial y}{\partial x_N}] \tag{2.7.2}$$ 9 | $$\rho = \sqrt{(\frac{\partial y}{\partial x_1})^2 + (\frac{\partial y}{\partial x_2})^2+,...,+ (\frac{\partial y}{\partial x_N})^2} \tag{2.7.3}$$ 10 | 11 | 现在我们用符号$\bigtriangledown_x y \in \mathbb R^N$表示标量$y$对向量$x$的梯度,也是一个向量。和标量的梯度类似,我们可以得到: 12 | $$x \to x + \Delta x \Rightarrow y \to \approx y + \bigtriangledown_x y \cdot \Delta x $$ 13 | 14 | 与标量章节有所不同,我们从考虑标量自变量变化到考虑向量自变量$x \in \mathbb R^N$和自变量的变化$\Delta x \in \mathbb R^N$,因此得到对应的梯度/方向导数是向量$\bigtriangledown_x y \in \mathbb R^N$,最后我们将$\bigtriangledown_x y \in \mathbb R^N 点乘法 \Delta x $来反应因变量$y$的变化。$y$的变化受到$x$中每一维度变化的影响。 15 | 16 | 接下来继续考虑**输入输出都是向量**的情况: 17 | 18 | 现在,假设我们的函数$f: \mathbb R^N \to \mathbb R^M$的输入是一个$N$维的向量,输出是一个$M$维的向量。那么,函数$y=f(x) \in \mathbb R^M$对于输入$x \in \mathbb R^N$每一维标量的偏导数可以写成: 19 | 20 | $$\frac{\partial y}{\partial x} = \begin{bmatrix} 21 | \frac{\partial y_1}{\partial x_1}& ... & \frac{\partial y_1}{\partial x_N}\\ 22 | .& ... &. \\ 23 | \frac{\partial y_M}{\partial x_1}& ... & \frac{\partial y_M}{\partial x_N} 24 | \end{bmatrix} \tag{2.7.4}$$ 25 | 26 | 式子(2.7.4)右边$M \times N$的偏导数矩阵又叫做Jacobian,我们也可以将上式理解为$M个标量y$对向量$x$求偏导。。Jacobian矩阵中连接了输入$x$和输出$y$中的每一个元素:Jacobian中的$(i,j)$个偏导$\frac{\partial y_i}{\partial x_j}$反应了$x_j$变化对$y_i$的影响。因此$y$向量与$x$向量的变化关系可以表达为: 27 | 28 | $$x \to x + \Delta x \Rightarrow y \to \approx y + \frac{\partial y}{\partial x} \Delta x$$ 29 | 30 | $\frac{\partial y}{\partial x}$是一个$M \times N$的矩阵,$\Delta x$是一个N维的向量,所以根据矩阵乘法得到的 31 | $\frac{\partial y}{\partial x} \cdot \Delta x$是一个$M$维的向量,每一位对应着$M$维$y$的改变。 32 | 33 | 使用jacobian矩阵可以将标量中的链式法则拓展到向量计算中。假设函数$f: \mathbb R^N \to \mathbb R^M$和函数$g: \mathbb R^M \to \mathbb R^K$,输入$x \in \mathbb R^N$,经过函数$y=f(x)$输出中间变量$y \in \mathbb R^M$,再经过函数$z = g(y)$输出$z \in \mathbb R^K$: 34 | 35 | $$x \overset{f} \to y \overset{g} \to z $$ 36 | 37 | **链式法则**和标量时候一样: 38 | 39 | $$\frac{\partial z}{\partial x} = \frac{\partial z}{\partial y} \frac{\partial y}{\partial x}$$ 40 | 41 | 只不过此时的$\frac{\partial z}{\partial x} \in \mathbb R^{K \times N}$, $\frac{\partial z}{\partial y} \in \mathbb R^{K \times M}$, $\frac{\partial y}{\partial x} \in \mathbb R^{M \times N}$,进行的是矩阵乘法运算。 -------------------------------------------------------------------------------- /docs/深度学习数学基础/2.7-矩阵和张量的梯度.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 2.7-矩阵和张量的梯度 4 | 5 | 标量组成向量,向量进一步可以组成矩阵,矩阵再进一步组成了张量。所以现在我们进一步学习矩阵、张量的梯度(每一个位置求偏导)。 6 | 7 | 由于深度学习中的大部分运算的输入输出都是张量(tensor),比如输入的一张图像通常是$3 \times 宽度 \times 高度$,所以我们需要能够明白张量和张量之间的梯度是如何计算的。 8 | 9 | 类比输入输出都是向量的情况,假设函数$f: \mathbb R^{N_1 \times N_2 ... \times N_{D_x}} \to \mathbb R^{M_1 \times M_2 ... \times M_{D_y}}$的输入是一个$D_x$维的向量,形状是$N_1 \times N_2 ... \times N_{D_x}$,输出是$D_y$维度的向量$M_1 \times M_2 ... \times M_{D_y}$,对于这样的$y=f(x)$,**generalized Jacobian** $\frac{\partial y}{\partial x}$的形状是: 10 | $$(M_1 \times M_2 ... \times M_{D_y}) \times (M_1 \times M_2 ... \times M_{D_y})$$ 11 | 12 | 注意:我们将Jacobian矩阵的维度分成了两组:第一组是输出$y$的维度,第二组是输入$x$的形状。这样分组之后,我们可以将**generalized Jacobian**矩阵看成一个“假二维”的矩阵便于理解。这个“假二维”矩阵的每一行的形状与$x$相同,每一列的形状与$y$相同。 13 | 14 | 假设$i \in \mathbb Z ^{D_y}, j \in \mathbb Z ^{D_x}$ 是“假矩阵”的下标(下标不再是标量,而是一个向量来指明位置),我们有: 15 | 16 | $$(\frac{\partial y}{\partial x})_{i,j} = \frac{\partial y_i}{\partial x_j} \tag{2.8.1}$$ 17 | 18 | 式子(2.8.1)中的$y_i, x_j$都是标量,但$i,j是向量,表示具体的y和x在张量中的位置$, 因此$\frac{\partial y_i}{\partial x_j}$依旧是一个标量。有了上面的式子,我们进一步可以得到输入和输出的关系为: 19 | 20 | $$x \to x + \Delta x \Rightarrow y \to \approx y + \frac{\partial y}{\partial x} \Delta x \tag{2.8.2}$$ 21 | 22 | 只不过此时$\Delta x$的维度是$N_1 \times N_2 ... \times N_{D_x}$, $$\frac{\partial y_i}{\partial x_j}的维度是: $(M_1 \times M_2 ... \times M_{D_y}) \times (M_1 \times M_2 ... \times M_{D_y})$, $\frac{\partial y}{\partial x} \Delta x$的维度是:$M_1 \times M_2 ... \times M_{D_y}$。 23 | 24 | 式子(2.8.2)中的矩阵乘法和1.2章节中的矩阵乘法法则一样,暂且称之为**generalized matrix multiply**: 25 | 26 | $$(\frac{\partial y}{\partial x} \Delta x)_j = \sum_i (\frac{\partial y}{\partial x} )_{i,j} (\Delta x)_i = (\frac{\partial y}{\partial x} )_{j, :} \cdot \Delta x$$ 27 | 28 | 和普通矩阵乘法唯一的不同就是下标$i,j$不再是标量,而是下标向量。$(\frac{\partial y}{\partial x} )_{j, :}$可以看作矩阵$\frac{\partial y}{\partial x}$的第$j$行,该行形状与$x$相同,因此直接和$\Delta x$进行elementwise乘法。 29 | 30 | 于是对于张量,我们同样有**链式法则**:假设$y=f(x), z=g(y)$, $x,y$形状如上,$z$的形状是$K_1,...K_{D_z}$,我们可以将张量链式法则写成: 31 | 32 | $$\frac{\partial z}{\partial x} = \frac{\partial z}{\partial y} \frac{\partial y}{\partial x}$$ 33 | 34 | 区别在于$\frac{\partial z}{\partial x}$的维度是$(K_1 \times K_2 ... \times K_{D_z}) \times (N_1 \times N_2 ... \times N_{D_x})$,$\frac{\partial z}{\partial y}$的维度是$(K_1 \times K_2 ... \times K_{D_z}) \times (M_1 \times M_2 ... \times M_{D_y})$,$\frac{\partial y}{\partial x}$的维度是$(M_1 \times M_2 ... \times M_{D_y}) \times (N_1 \times N_2 ... \times N_{D_x})$。 35 | 36 | 37 | 从**generalized matrix multiply**:角度,我们可以得到: 38 | $$(\frac{\partial y}{\partial x})_{i,j} = \sum_k (\frac{\partial y}{\partial x} )_{i,k} (\frac{\partial y}{\partial x})_i = (\frac{\partial z}{\partial y} )_{i, :} \cdot (\frac{\partial y}{\partial x} )_{:, j}$$ -------------------------------------------------------------------------------- /docs/深度学习数学基础/2.8-神经网络中几个实用的梯度计算.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 2.8-神经网络中几个实用的梯度计算 4 | 5 | 2.8章节我们知道了张量求梯度的方法以及张量中的链式法则,这一章节我们结合Jacobian矩阵继续学习神经网络中几个非常使用的梯度计算。 6 | 7 | ### 2.8.1 $z = Wx$矩阵$W \in \mathbb R^{n \times m}$乘以列向量$x \in \mathbb R^m$求$\frac{\partial z}{\partial x}$ 8 | 9 | 可以看作函数将输入$x \in \mathbb R^m$ 经过$W \in \mathbb R^{n \times m}$变换得到输出$z \in \mathbb R^n$,那么Jacobian矩阵$\frac{\partial z}{\partial x} \in \mathbb R^{n \times m}$ 10 | 11 | $$z_i = \sum^{m}_k W_{ik}x_k$$ 12 | 13 | 那么 14 | $$(\frac{\partial z}{\partial x})_{i,j} = \frac{\partial z_i}{\partial x_j} = \frac{\partial {\sum^{m}_k W_{ik}x_k}}{\partial x} = \sum^{m}_k W_{ik} \frac{\partial x_k}{\partial x_j} = W_{ij}$$ 15 | 16 | 由于$\frac{\partial x_k}{\partial x_j} = 1$ if $k = j$ else 0, 所以有$\frac{\partial z}{\partial x} = W$ 17 | 18 | ### 2.8.2 $z=xW, \frac{\partial z}{\partial x} = W^T$ 19 | 20 | ### 2.8.3 $z=x$向量等于自身,求$\frac{\partial z}{\partial x}$ 21 | 22 | 因为$z_i = x_i$ 所以 23 | $$(\frac{\partial z}{\partial x})_{i,j} = \frac{\partial z_i}{\partial x_j} = \frac{\partial x_i}{\partial x_j} = \{^{1, i=j}_{0, otherwise}$$ 24 | 25 | 所以$\frac{\partial z}{\partial x} = I$,将其放在链式法则中进行矩阵乘法时候不会改变其他矩阵。 26 | 27 | ### 2.8.4 $z = f(x)$ 对向量$x$中每个元素进行变换, 求$\frac{\partial z}{\partial x}$ 28 | 由于$z_i = f(x_i)$所以 29 | $$(\frac{\partial z}{\partial x})_{i,j} = \frac{\partial z_i}{\partial x_j} = \frac{\partial f(x_i)}{\partial x_j} = \{^{f'(x_i), i=j}_{0, otherwise}$$ 30 | 31 | 所以$\frac{\partial z}{\partial x}$是一个diagonal matrix 且$\frac{\partial z}{\partial x} = diag(f'(x))$ 32 | 33 | 矩阵乘以一个diagonal矩阵也就是每个元素进行幅度变换,因此链式法则中的矩阵乘以$diag(f'(x))$相当于和$f'(x)$做elementwise 乘法。 34 | 35 | ### 2.8.5 $z = Wx, \delta = \frac{\partial J}{\partial z}$,求$\frac{\partial J}{\partial W}=\frac{\partial J}{\partial z} \frac{\partial z}{\partial W}=\delta \frac{\partial z}{\partial W}$ 36 | 37 | 我们开始引入更复杂的情况,因为神经网络中往往包含多次链式法则的引用,这里我们假设已经知道$\delta = \frac{\partial J}{\partial z}$,直接求$\frac{\partial J}{\partial W}$。 38 | 39 | 假设神经网络的损失函数$J$是标量,我们想计算的是损失函数对参数$W \in \mathbb R^{n \times m}$的梯度。我们可以想象神经网络这个函数输入是一个$n \times m$形状的参数,输出是一个标量,结合上一章节Jacobian知识我们可以知道$\frac{\partial J}{\partial W} \in \mathbb R^{(1) \times (n \times m)}$形状和$W$一样,所以在神经网络训练的时候可以将参数减轻去参数的梯度乘以学习率。 40 | 41 | 根据链式法则,我们需要求出$\frac{\partial z}{\partial W} \in \mathbb R^{(n) \times (n \times m)}$。这个三维的张量不方便表示且十分复杂,因此我们先只看对$W_{i,j}$求导$\frac{\partial z}{\partial W_{i,j}} \in \mathbb R^{(n) \times (1)}$。 42 | 43 | $$z_k = \sum^m_{l=1} W_{kl}x_l$$ 44 | $$\frac{\partial z}{\partial W_{ij}} = \sum^m_{l=1}x_l \frac{\partial W_{kl}}{\partial W_{ij}}$$ 45 | 46 | $$\frac{\partial W_{kl}}{\partial W_{ij}} = \{^{1, i=k, j=l}_0$$ 47 | 48 | 所以只有$i=k, j=l$时候非零 49 | $$\frac{\partial J}{\partial W_{ij}} = \begin{bmatrix} 50 | 0\\ 51 | .\\ 52 | x_j\\ 53 | .\\ 54 | 0 55 | \end{bmatrix} \leftarrow ith element, j=l$$ 56 | 57 | 所以 58 | $$\frac{\partial J}{\partial W_{ij}} = \frac{\partial J}{\partial z}\frac{\partial z}{\partial W_{ij}} = \delta \frac{\partial z}{\partial W_{ij}} = \delta_i x_j$$ 59 | 60 | 所以得到 61 | $$\frac{\partial J}{\partial W} = \delta^T x^T $$ 62 | 63 | ### 2.8.6 $z=xW, \delta = \frac{\partial J}{\partial z}, \frac{\partial J}{\partial W} =x^T\delta$ 64 | 65 | ### 2.8.7 7. $\hat{y} = softmax(\Theta), J=Cross-entropy(y,\hat{y}), \frac{\partial J}{\partial \Theta } = \hat{y} - y$ 66 | 67 | 假设神经网络到达softmax之前的输出为$\Theta = [\theta_1, \theta_2, ..., \theta_n]$,$n$为分类数量,那么 68 | $$\hat{y} = softmax(\Theta), \theta_i = \frac{e^{\theta_i}}{\sum^n_k e^{\theta_k}}$$ 69 | $$J = \sum^n_{i=1}y_ilog(\hat{y_i})$$ 70 | $$\frac{\partial J}{\partial{\hat{y_i}}} = \frac{y_i}{\hat{y_i}}$$ 71 | $$\frac{\partial \hat{y_i}}{\partial \theta_i} = \{^{\hat{y_i}(1-\hat{y_k}), i=k}_{-\hat{y_i}\hat{y_k}, i \neq k}$$ 72 | 73 | $$\frac{\partial J}{\partial{\theta_i}} = \frac{\partial J}{\hat{y}} \frac{\partial \hat{y}}{\partial{\theta_i}}, 形状为1 \times n, n \times 1$$ 74 | 75 | $$\frac{\partial J}{\partial{\theta_i}} = \sum^n_{k=1}{\frac{\partial J}{\hat{y_k}} \frac{\partial \hat{y_k}}{\partial{\theta_i}}} (k=i, k\neq i)$$ 76 | 77 | $$\frac{\partial J}{\partial{\partial{\theta_i}}} = \frac{\partial J}{\hat{y_i}} \frac{\partial \hat{y_i}}{\partial \theta_i} + \sum^n_{k \neq i}{\frac{\partial J}{\hat{y_k}} \frac{\partial \hat{y_k}}{\theta_i}} (k=i, k\neq i)$$ 78 | 79 | $$\frac{\partial J}{\partial{\theta_i}} = y_i(1- \hat{y_i}) + \sum_{k neq i} {y_k \hat{y_i}}$$ 80 | 81 | $$\frac{\partial J}{\partial{\theta_i}} = -y_i(1- \hat{y_i}) + \sum_{k neq i} {y_k \hat{y_i}}$$ 82 | 83 | $$\frac{\partial J}{\partial{\theta_i}} = -y_i + \hat{y_i} \sum {y_k} $$ 84 | 85 | $$\frac{\partial J}{\partial{\theta_i}} = \hat{y_i} -y_i $$ 86 | 87 | 所以 88 | $$\frac{\partial J}{\partial{\theta_i}} = \hat{y} -y \in \mathbb R^{n} $$ -------------------------------------------------------------------------------- /docs/深度学习数学基础/3.1-神经网络中的反向传播.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 3.1神经网络中的反向传播 4 | 5 | 神经网络可以理解为输入张量$x$和权重张量$W$的一个巨大函数$y=f(x, W)$。函数的输出在和标注(正确答案)比较得到一个标量的损失函数$J$。因此我们反向传播的目的是求$\frac{\partial J}{\partial x }, \frac{\partial J}{\partial W }$,根据链式法则: 6 | $$\frac{\partial J}{\partial x } = \frac{\partial J}{\partial y }\frac{\partial y}{\partial x }, \frac{\partial J}{\partial W } = \frac{\partial J}{\partial y } \frac{\partial y}{\partial W }$$ 7 | 8 | 在求得参数$W$的梯度之后,将参数根据学习率和梯度进行迭代更新 $W = W - \alpha \frac{\partial y}{\partial W }$寻找最佳参数。 -------------------------------------------------------------------------------- /docs/深度学习数学基础/3.2-单层神经网络梯度计算例子.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 3.2-单层神经网络的梯度计算例子 4 | 在本章节,我们来对一个单层神经网路求梯度验证我们对导数、矩阵运算的学习效果。为了能够对神经网络复杂的计算求导,我们将神经网络的步步拆开成下面的表达式来看。单层神经网络可以表示为: 5 | $$x = input \in \mathbb R^{D_x \times 1}$$ 6 | $$z = Wx + b_1 \in \mathbb R^{D_h \times 1}$$ 7 | $$h = ReLU(z) \in \mathbb R^{D_x \times 1}$$ 8 | $$\Theta = Uh + b_2 \in \mathbb R^{N_c \times 1}$$ 9 | $$\hat{y} = softmax(\Theta ) \in \mathbb R^{N_c \times 1}$$ 10 | $$J = cross-entropy(y, \hat{y} \in \mathbb R^{1}$$ 11 | 其中 12 | $$x \in \mathbb R^{D_x \times 1}, b_1 \in \mathbb R^{D_h \times 1}, W \in \mathbb R^{D_h \times D_x}, b_2 \in \mathbb R^{N_c \times 1}, U \in \mathbb R^{N_c \times D_h}$$ 13 | 14 | $D_x, D_h$分别是输入和hidden layer的大小,$N_c$是分类的类别数量。 15 | 16 | 我们想计算的是损失函数对参数$U,W, b_1, b_2$的梯度,我们可以计算的梯度有: 17 | $$\frac{\partial J}{\partial U}, \frac{\partial J}{\partial b_2}, \frac{\partial J}{\partial W}, \frac{\partial J}{\partial b_1}, \frac{\partial J}{\partial x}$$ 18 | 19 | 另外我们需要知道$ReLu(x) = max(x, 0)$,他的导数: 20 | $$ReLU'(x) = \{^{1, x>0}_{0} = sgn(ReLu(x))$$ 21 | 22 | sgn是符号函数(输入大于0为输出1,输入小于等于0输出0)。 23 | 24 | 假设我们要求$U, b_2$的梯度,我们可以写出链式法则: 25 | $$\frac{\partial J}{\partial U} = \frac{\partial J}{\partial \hat{y}} \frac{\partial \hat{y}}{\partial \Theta} \frac{\partial \Theta}{\partial U}$$ 26 | $$\frac{\partial J}{\partial b_2} = \frac{\partial J}{\partial \hat{y}} \frac{\partial \hat{y}}{\partial \Theta} \frac{\partial \Theta}{\partial b_2}$$ 27 | 28 | 从上面的两个式子可以看出$\frac{\partial J}{\partial \hat{y}} \frac{\partial \hat{y}}{\partial \Theta}$被用了两遍,所以我们再定义一个中间变量: 29 | $$\delta_1 = \frac{\partial J}{\partial \hat{y}} \frac{\partial \hat{y}}{\partial \Theta} = \frac{\partial J}{\partial \Theta}$$ 30 | 31 | 根据2.9.7的推到可以得到 32 | $$\delta_1 = \frac{\partial J}{\partial \hat{y}} \frac{\partial \hat{y}}{\partial \Theta} = \frac{\partial J}{\partial \Theta} = (\hat{y} - y)^T \mathbb R^{1 \times N_c}$$ 33 | 34 | 进一步对$z$求梯度: 35 | 36 | $$\frac{\partial J}{\partial z} = \frac{\partial J}{\partial \Theta} \frac{\partial \Theta}{\partial h} \frac{\partial h}{\partial z}$$ 37 | 38 | $$\frac{\partial J}{\partial z} = \delta_1 \frac{\partial \Theta}{\partial h} \frac{\partial h}{\partial z}, 带入\delta_1$$ 39 | 40 | $$\frac{\partial J}{\partial z} = \delta_1 U \frac{\partial h}{\partial z}, 根据2.9.1$$ 41 | 42 | $$\frac{\partial J}{\partial z} = \delta_1 U \odot ReLu'(z), 根据2.9.4, \odot代表elementwise乘法$$ 43 | 44 | $$\frac{\partial J}{\partial z} = \delta_1 U \odot sgn(h)$$ 45 | 46 | 最后进行一下形状检查 47 | $$\frac{\partial J}{\partial z} (1 \times D_h) = \delta_1(1 \times N_c)乘以 U (N_c \times D_h)\odot sgn(h) (D_h)$$ 48 | -------------------------------------------------------------------------------- /docs/深度学习数学基础/4.1-Pytorch自动求梯度.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 4.1-Pytorch自动求梯度 4 | 5 | ``` 6 | import torch 7 | 8 | x = torch.arange(4.0) 9 | print(x) #tensor([0., 1., 2., 3.]) 10 | x.requires_grad_(True) # 设定求梯度 11 | print(x.grad) # 默认值是None 12 | y = 5 * torch.dot(x, x) #计算输出 13 | print(y) #tensor(150., grad_fn=) 14 | 15 | y.backward() #反向传播 16 | print(x.grad) # tensor([ 0., 10., 20., 30., 40.]) 17 | print(x.grad == 10 * x) # tensor([True, True, True, True, True]) -------------------------------------------------------------------------------- /docs/深度学习数学基础/4.2-Tensorflow自动求梯度.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 4.2-Tensorflow自动求梯度 4 | ``` 5 | import tensorflow as tf 6 | 7 | x = tf.range(4, dtype=tf.float32) 8 | print(x) #tf.Tensor([0. 1. 2. 3.], shape=(4,), dtype=float32) 9 | x = tf.Variable(x) 10 | 11 | with tf.GradientTape() as t: 12 | y = 5 * tf.tensordot(x, x, axes=1) 13 | x_grad = t.gradient(y, x) 14 | x_grad 15 | print(y) #tf.Tensor(70.0, shape=(), dtype=float32) 16 | print(x_grad == 10 * x) #tf.Tensor([ True True True True], shape=(4,), dtype=bool) 17 | ``` -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/0-前言.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | 希望能在这里将深度学习模型基础进行通俗易懂的整理和讲解。 4 | * [1.1-图解attetion](./深度学习模型基础/transformer基本原理讲解/1.1-图解attetion.md) 5 | * [1.2-图解transformer](./深度学习模型基础/transformer基本原理讲解/1.2-图解transformer.md) 6 | * [1.3-图解BERT](./深度学习模型基础/transformer基本原理讲解/1.3-图解BERT.md) 7 | * [1.4-图解GPT](./深度学习模型基础/transformer基本原理讲解/1.4-图解GPT.md) -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/1.1-图解attetion.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 致谢 4 | 主要由哈尔滨工业大学张贤同学翻译(经原作者 [@JayAlammmar](https://twitter.com/JayAlammar) 授权)撰写,由本项目同学组织和整理。 5 | 6 | ## 图解Attention 7 | ## seq2seq模型 8 | 序列到序列(seq2seq)模型是一种深度学习模型,在很多任务上都取得了成功,如:机器翻译、文本摘要、图像描述生成。谷歌翻译在 2016 年年末开始使用这种模型。有2篇开创性的论文:[Sutskever等2014年发表的Sequence to Sequence Learning 9 | with Neural Networks](https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf)和[Cho等2014年发表的Learning Phrase Representations using RNN Encoder–Decoder 10 | for Statistical Machine Translation](http://emnlp2014.org/papers/pdf/EMNLP2014179.pdf)都对这些模型进行了解释。 11 | 12 | 然而,我发现,想要充分理解模型并实现它,需要拆解一系列概念,而这些概念是层层递进的。我认为,如果能够把这些概念进行可视化,会更加容易理解。这就是这篇文章的目标。你需要先了解一些深度学习的知识,才能读完这篇文章。我希望这篇文章,可以对你阅读上面提到的 2 篇论文有帮助。 13 | 14 | 一个序列到序列(seq2seq)模型,接收的输入是一个输入的(单词、字母、图像特征)序列,输出是另外一个序列。一个训练好的模型如下图所示: 15 | 16 | 17 | ![seq2seq](./pictures/1-seq2seq.gif)动态图:seq2seq 18 | 19 | 在神经机器翻译中,一个序列是指一连串的单词。类似地,输出也是一连串单词。 20 | ![translation](./pictures/1-2-translation.gif)动态图:translation 21 | 22 | ### 进一步理解细节 23 | 模型是由编码器(Encoder)和解码器(Decoder)组成的。其中,编码器会处理输入序列中的每个元素,把这些信息转换为一个向量(称为上下文(context))。当我们处理完整个输入序列后,编码器把上下文(context)发送给解码器,解码器开始逐项生成输出序列中的元素。 24 | 25 | ![encoder-decode](./pictures/1-3-encoder-decoder.gif)动态图:encoder-decoder 26 | 27 | ![encoder-decoder](./pictures/1-3-encoder-decoder.gif)动态图:encoder-decoder 28 | 29 | 这种机制,同样适用于机器翻译。 30 | 31 | 在机器翻译任务中,上下文(context)是一个向量(基本上是一个数字数组)。编码器和解码器一般都是循环神经网络,一定要看看 [Luis Serrano写的一篇关于循环神经网络](https://www.youtube.com/watch?v=UNmqTiOnRfg)的精彩介绍. 32 | 33 | ![上下文是一个浮点数向量。在下文中,我们会可视化这些向量,使用更明亮的色彩来表示更高的值](./pictures/1-4-context-example.png)上下文是一个浮点数向量。在下文中,我们会可视化这些向量,使用更明亮的色彩来表示更高的值 34 | 35 | 你可以在设置模型的时候设置上下文向量的长度。这个长度是基于编码器 RNN 的隐藏层神经元的数量。上图展示了长度为 4 的向量,但在实际应用中,上下文向量的长度可能是 256,512 或者 1024。 36 | 37 | 根据设计,RNN 在每个时间步接受 2 个输入: 38 | - 输入序列中的一个元素(在解码器的例子中,输入是指句子中的一个单词) 39 | - 一个 hidden state(隐藏层状态) 40 | 41 | 然而每个单词都需要表示为一个向量。为了把一个词转换为一个向量,我们使用一类称为 "word embedding" 的方法。这类方法把单词转换到一个向量空间,这种表示能够捕捉大量的单词的语义信息(例如,king - man + woman = queen[例子来源](http://p.migdal.pl/2017/01/06/king-man-woman-queen-why.html))。 42 | 43 | ![我们在处理单词之前,需要把他们转换为向量。这个转换是使用 word embedding 算法来完成的。我们可以使用预训练好的 embeddings,或者在我们的数据集上训练自己的 embedding。通常 embedding 向量大小是 200 或者 300,为了简单起见,我们这里展示的向量长度是4](./pictures/1-5-word-vector.png)我们在处理单词之前,需要把他们转换为向量。这个转换是使用 word embedding 算法来完成的。我们可以使用预训练好的 embeddings,或者在我们的数据集上训练自己的 embedding。通常 embedding 向量大小是 200 或者 300,为了简单起见,我们这里展示的向量长度是4 44 | 45 | 现在,我们已经介绍完了向量/张量的基础知识,让我们回顾一下 RNN 的机制,并可视化这些 RNN 模型: 46 | 47 | ![rnn](./pictures/1-6-rnn.png)rnn 48 | 49 | RNN 在第 2 个时间步,采用第 1 个时间步的 hidden state(隐藏层状态) 和第 2 个时间步的输入向量,来得到输出。在下文,我们会使用类似这种动画,来描述神经机器翻译模型里的所有向量。 50 | 51 | 在下面的可视化图形中,编码器和解码器在每个时间步处理输入,并得到输出。由于编码器和解码器都是 RNN,RNN 会根据当前时间步的输入,和前一个时间步的 hidden state(隐藏层状态),更新当前时间步的 hidden state(隐藏层状态)。 52 | 53 | 让我们看下编码器的 hidden state(隐藏层状态)。注意,最后一个 hidden state(隐藏层状态)实际上是我们传给解码器的上下文(context)。 54 | 55 | 解码器也持有 hidden state(隐藏层状态),而且也需要把 hidden state(隐藏层状态)从一个时间步传递到下一个时间步。我们没有在上图中可视化解码器的 hidden state,是因为这个过程和解码器是类似的,我们现在关注的是 RNN 的主要处理过程。 56 | 现在让我们用另一种方式来可视化序列到序列(seq2seq)模型。下面的动画会让我们更加容易理解模型。这种方法称为展开视图。其中,我们不只是显示一个解码器,而是在时间上展开,每个时间步都显示一个解码器。通过这种方式,我们可以看到每个时间步的输入和输出。 57 | 58 | ## Attention 讲解 59 | 事实证明,上下文向量是这类模型的瓶颈。这使得模型在处理长文本时面临非常大的挑战。 60 | 61 | 在 Bahdanau等2014发布的[Neural Machine Translation by Jointly Learning to Align and Translate](https://arxiv.org/abs/1409.0473) 和 Luong等2015年发布的[Effective Approaches to Attention-based Neural Machine Translation 62 | ](https://arxiv.org/abs/1508.04025)两篇论文中,提出了一种解决方法。这 2 篇论文提出并改进了一种叫做注意力**attetion**的技术,它极大地提高了机器翻译的质量。注意力使得模型可以根据需要,关注到输入序列的相关部分。 63 | 64 | ![在第 7 个时间步,注意力机制使得解码器在产生英语翻译之前,可以将注意力集中在 "student" 这个词(在发育里,是 "student" 的意思)。这种从输入序列放大相关信号的能力,使得注意力模型,比没有注意力的模型,产生更好的结果。](./pictures/1-7-attetion.png)在第 7 个时间步,注意力机制使得解码器在产生英语翻译之前,可以将注意力集中在 "student" 这个词(在发育里,是 "student" 的意思)。这种从输入序列放大相关信号的能力,使得注意力模型,比没有注意力的模型,产生更好的结果。 65 | 66 | 让我们继续从高层次来理解注意力模型。一个注意力模型不同于经典的序列到序列(seq2seq)模型,主要体现在 2 个方面: 67 | 68 | 首先,编码器会把更多的数据传递给解码器。编码器把所有时间步的 hidden state(隐藏层状态)传递给解码器,而不是只传递最后一个 hidden state(隐藏层状态)。 69 | 70 | 第二,注意力模型的解码器在产生输出之前,做了一个额外的处理。为了把注意力集中在与该时间步相关的输入部分。解码器做了如下的处理: 71 | 72 | 1. 查看所有接收到的编码器的 hidden state(隐藏层状态)。其中,编码器中每个 hidden state(隐藏层状态)都对应到输入句子中一个单词。 73 | 2. 给每个 hidden state(隐藏层状态)一个分数(我们先忽略这个分数的计算过程)。 74 | 3. 将每个 hidden state(隐藏层状态)乘以经过 softmax 的对应的分数,从而,高分对应的 hidden state(隐藏层状态)会被放大,而低分对应的 hidden state(隐藏层状态)会被缩小。 75 | 76 | 这个加权平均的步骤是在解码器的每个时间步做的。 77 | 现在,让我们把所有内容都融合到下面的图中,来看看注意力模型的整个过程: 78 | 79 | 1. 注意力模型的解码器 RNN 的输入包括:一个embedding 向量,和一个初始化好的解码器 hidden state(隐藏层状态)。 80 | 2. RNN 处理上述的 2 个输入,产生一个输出和一个新的 hidden state(隐藏层状态 h4 向量),其中输出会被忽略。 81 | 3. 注意力的步骤:我们使用编码器的 hidden state(隐藏层状态)和 h4 向量来计算这个时间步的上下文向量(C4)。 82 | 4. 我们把 h4 和 C4 拼接起来,得到一个向量。 83 | 5. 我们把这个向量输入一个前馈神经网络(这个网络是和整个模型一起训练的)。 84 | 6. 前馈神经网络的输出的输出表示这个时间步输出的单词。 85 | 7. 在下一个时间步重复这个步骤。 86 | 87 | 下图,我们使用另一种方式来可视化注意力,看看在每个解码的时间步中关注输入句子的哪些部分: 88 | 89 | 90 | 请注意,注意力模型不是无意识地把输出的第一个单词对应到输入的第一个单词。实际上,它从训练阶段学习到了如何在两种语言中对应单词的关系(在我们的例子中,是法语和英语)。下图展示了注意力机制的准确程度(图片来自于上面提到的论文): 91 | ![你可以看到模型在输出 "European Economic Area" 时,注意力分布情况。在法语中,这些单词的顺序,相对于英语,是颠倒的("européenne économique zone")。而其他词的顺序是类似的。](./pictures/1-8-attention-vis.png) 92 | 93 | 如果你觉得你准备好了学习注意力机制的代码实现,一定要看看基于 TensorFlow 的 神经机器翻译 (seq2seq) [指南](https://github.com/tensorflow/nmt)。 94 | 95 | 期待您的反馈。 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/1.2-图解transformer.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 致谢 4 | 主要由哈尔滨工业大学张贤同学翻译撰写,由本项目同学组织和整理。 5 | 6 | 7 | ## 图解transformer 8 | ![结构总览](./pictures/2-transformer-stru.png)图: 9 | 10 | ## 前言 11 | 12 | 本文翻译自[illustrated-transformer](http://jalammar.github.io/illustrated-transformer),是笔者看过的把 Transformer 讲解得最好的文章。这篇文章从输入开始,一步一步演示了数据在 Transformer 中的流动过程。由于看过一些中文翻译的文章,感觉不够好,所以我自己翻译了一个版本,在一些难以直译的地方,我加入了一些原文没有的文字说明,来更好地解释概念。另外,我添加了一些简单的代码,实现了一个基本的 Self Attention 以及 multi-head attention 的矩阵运算。 13 | 14 | Transformer 依赖于 Self Attention 的知识。Attention 是一种在深度学习中广泛使用的方法,Attention的思想提升了机器翻译的效果。如果你还没学习 Attention,请查看这篇 Attention 的精彩讲解:[知乎讲解](https://zhuanlan.zhihu.com/p/265182368)。 15 | 16 | 2017 年,Google 提出了 Transformer 模型,用 Self Attention 的结构,取代了以往 NLP 任务中的 RNN 网络结构,在 WMT 2014 Englishto-German 和 WMT 2014 English-to-French两个机器翻译任务上都取得了当时 SOTA 的效果。 17 | 18 | 这个模型的其中一个优点,就是使得模型训练过程能够并行计算。在 RNN 中,每一个 time step 的计算都依赖于上一个 time step 的输出,这就使得所有的 time step 必须串行化,无法并行计算,如下图所示。 19 | 20 | ![机器翻译示意图](./pictures/2-translation.png)图:机器翻译示意图 21 | 22 | 而在 Transformer 中,所有 time step 的数据,都是经过 Self Attention 计算,使得整个运算过程可以并行化计算。 23 | 24 | 这篇文章的目的是从上到下,一步一步拆解 Transformer 的各种概念,希望有助于初学者更加容易地理解 Transformer 到底是什么。 25 | 26 | Transformer 使用了 Seq2Seq任务中常用的结构——包括两个部分:Encoder 和 Decoder。一般的结构图,都是像下面这样。 27 | 28 | ![transformer](./pictures/2-transformer.png)图:transformer 29 | 30 | 如果你看到上图不知所措,不要担心,下面我们来一步步拆解 Transformer。 31 | 32 | ## 从整体宏观来理解 Transformer 33 | 34 | 首先,我们将整个模型视为黑盒。在机器翻译任务中,接收一种语言的句子作为输入,然后将其翻译成其他语言输出。 35 | 36 | ![input-output](./pictures/2-input-output.png)图:input-output 37 | 38 | 中间部分的 Transformer 可以拆分为 2 部分:左边是编码部分(encoding component),右边是解码部分(decoding component)。 39 | ![encoder-decoder](./pictures/2-encoder-decoder.png)图:encoder-decoder 40 | 41 | 其中编码部分是多层的编码器(Encoder)组成(Transformer 的论文中使用了 6 层编码器,这里的层数 6 并不是固定的,你也可以根据实验效果来修改层数)。同理,解码部分也是由多层的解码器(Decoder)组成(论文里也使用了 6 层的解码器)。 42 | ![翻译例子](./pictures/2-encoder-decoder.png)图:翻译例子 43 | 44 | 每一个编码器 在结构上都是一样的,但它们的权重参数是不同的。每一个编码器里面,可以分为 2 层 45 | - Self-Attention Layer 46 | - Feed Forward Neural Network(前馈神经网络,缩写为 FFNN) 47 | 48 | ![encoder](./pictures/2-encoder.png)图:encoder 49 | 50 | 输入编码器的文本数据,首先会经过一个 Self Attention 层,这个层处理一个词的时候,不仅会使用这个词本身的信息,也会使用句子中其他词的信息(你可以类比为:当我们翻译一个词的时候,不仅会只关注当前的词,也会关注这个词的上下文的其他词的信息)。本文后面将会详细介绍 Self Attention 的内部结构。 51 | 52 | 接下来,Self Attention 层的输出会经过前馈神经网络。 53 | 54 | 同理,解码器也具有这两层,但是这两层中间还插入了一个 Encoder-Decoder Attention 层,这个层能帮助解码器聚焦于输入句子的相关部分(类似于 seq2seq 模型 中的 Attention)。 55 | 56 | ![decoder](./pictures/2-decoder.webp)图:decoder 57 | 58 | ## 从细节来理解 Transformer 59 | 60 | 上面,我们从宏观理解了 Transformer 的主要部分。下面,我们来看输入的张量数据,在 Transformer 中运算最终得到输出的过程。 61 | ### Transformer 的输入 62 | 和通常的 NLP 任务一样,我们首先会使用词嵌入算法(embedding algorithm),将每个词转换为一个词向量。实际中向量一般是 256 或者 512 维。为了简化起见,这里将每个词的转换为一个 4 维的词向量。 63 | 64 | 那么整个输入的句子是一个向量列表,其中有 3 个词向量。在实际中,每个句子的长度不一样,我们会取一个适当的值,作为向量列表的长度。如果一个句子达不到这个长度,那么就填充全为 0 的词向量;如果句子超出这个长度,则做截断。句子长度是一个超参数,通常是训练集中的句子的最大长度,你可以尝试不同长度的效果。 65 | 66 | ![ 个词向量](./pictures/2-x.png)图:个词向量 67 | 68 | 编码器(Encoder)接收的输入都是一个向量列表,输出也是大小同样的向量列表,然后接着输入下一个编码器。 69 | 70 | 第一个编码器的输入是词向量,*而后面的编码器的输入是上一个编码器的输出*。 71 | 72 | 下面,我们来看这个向量列表在编码器里面是如何流动的。 73 | 74 | ![输入encoder](./pictures/2-x-encoder.png)图:输入encoder 75 | 76 | 77 | 这里我们可以注意到 Transformer 的一个重要特性:每个位置的词向量经过编码器都有自己单独的路径。具体来说,在 Self Attention 层中,这些路径之间是有依赖关系的;而在 Feed Forward (前馈神经网络)层中,这些路径之间是没有依赖关系的。因此这些词向量在经过 Feed Forward 层中可以并行计算(*这句话会造成困扰,我认为在 Self Attention 层中,也能并行计算,没有必要单独说 Feed Forward 层也可以并行计算*)。 78 | 79 | 下面我们用一个更短的句子,来说明数据在编码器的编码过程。 80 | 81 | ### Encoder(编码器) 82 | 上面我们提到,一个编码器接收的输入是一个向量列表,它会把向量列表输入到 Self Attention 层,然后经过 feed-forward neural network (前馈神经网络)层,最后得到输出,传入下一个编码器。 83 | 84 | ![一层传一层](./pictures/2-multi-encoder.webp)图:一层传一层 85 | 86 | 每个位置的词都经过 Self Attention 层,得到的每个输出向量都单独经过前馈神经网络层,每个向量经过的前馈神经网络都是一样的 87 | 88 | ### Self-Attention 整体理解 89 | 90 | 别被“Self-Attention”这么高大上的词给唬住了,乍一听好像每个人都应该对这个词熟悉一样。但我在读论文《Attention is All You Need》 之前就没有听过这个词。下面来分析 Self-Attention 的具体机制。 91 | 92 | 假设我们想要翻译的句子是: 93 | ``` 94 | The animal didn't cross the street because it was too tired 95 | ``` 96 | 这个句子中的 *it* 是一个指代词,那么 *it* 指的是什么呢?它是指 *animal* 还是*street*?这个问题对人来说,是很简单的,但是对算法来说并不是那么容易。 97 | 98 | 当模型在处理(翻译)it 的时候,*Self Attention*机制能够让模型把it和animal关联起来。 99 | 100 | 同理,当模型处理句子中的每个词时,*Self Attentio*n机制使得模型不仅能够关注这个位置的词,而且能够关注句子中其他位置的词,作为辅助线索,进而可以更好地编码当前位置的词。 101 | 102 | 如果你熟悉 RNN,回忆一下:RNN 在处理一个词时,会考虑前面传过来的*hidden state*,而*hidden state*就包含了前面的词的信息。而 Transformer 使用*Self Attention*机制,会把其他单词的理解融入处理当前的单词。 103 | 104 | ![一个词和其他词的attention](./pictures/2-attention-word.png)图:一个词和其他词的attention 105 | 106 | 当我们在第五层编码器中(编码部分中的最后一层编码器)编码“it”时,有一部分注意力集中在“The animal”上,并且把这两个词的信息融合到了"it"这个单词中。 107 | 108 | 你可以查看 【Tensor2Tensor notebook】。在这个 notebook 里,你可以加载 Transformer 模型,并通过交互式的可视化,来理解 Self Attention。 109 | 110 | ## Self-Attention 的细节 111 | ### 计算Query 向量,Key 向量,Value 向量 112 | 113 | 下面我们先看下如何使用向量来计算 Self Attention,然后再看下如何使用矩阵来实现 Self Attention。(矩阵运算的方式,使得 Self Attention 的计算能够并行化,这也是 Self Attention 最终的实现方式)。 114 | 115 | 计算 Self Attention 的第 1 步是:对输入编码器的每个词向量,都创建 3 个向量,分别是:Query 向量,Key 向量,Value 向量。这 3 个向量是词向量分别和 3 个矩阵相乘得到的,而这个矩阵是我们要学习的参数。 116 | 117 | 注意,这 3 个新得到的向量一般比原来的词向量的长度更小。假设这 3 个向量的长度是$d_{key}$,而原始的词向量或者最终输出的向量的长度是 512(这 3 个向量的长度,和最终输出的向量长度,是有倍数关系的)。关于 Multi-head Attention,后面会给出实际代码。这里为了简化,假设只有一个 head 的 Self-Attention。 118 | 119 | ![Q,K,V](./pictures/2-qkv.png)图:Q,K,V 120 | 121 | 上图中,有两个词向量:Thinking 的词向量 x1 和 Machines 的词向量 x2。以 x1 为例,X1 乘以 WQ 得到 q1,q1 就是 X1 对应的 Query 向量。同理,X1 乘以 WK 得到 k1,k1 是 X1 对应的 Key 向量;X1 乘以 WV 得到 v1,v1 是 X1 对应的 Value 向量。 122 | 123 | Query 向量,Key 向量,Value 向量是什么含义呢? 124 | 125 | 其实它们就是 3 个向量,给它们加上一个名称,可以让我们更好地理解 Self-Attention 的计算过程和逻辑含义。继续往下读,你会知道 attention 是如何计算出来的,Query 向量,Key 向量,Value 向量又分别扮演了什么角色。 126 | 127 | ### 计算 Attention Score(注意力分数) 128 | 129 | 第 2 步,是计算 Attention Score(注意力分数)。假设我们现在计算第一个词 *Thinking* 的 Attention Score(注意力分数),需要根据 *Thinking* 这个词,对句子中的其他每个词都计算一个分数。这些分数决定了我们在编码*Thinking*这个词时,需要对句子中其他位置的每个词放置多少的注意力。 130 | 131 | 这些分数,是通过计算 "*Thinking*" 对应的 Query 向量和其他位置的每个词的 Key 向量的点积,而得到的。如果我们计算句子中第一个位置单词的 Attention Score(注意力分数),那么第一个分数就是 q1 和 k1 的内积,第二个分数就是 q1 和 k2 的点积。 132 | 133 | ![Thinking计算](./pictures/2-think.png)图:Thinking计算 134 | 135 | 第 3 步就是把每个分数除以 $\sqrt(d_{key})$ ($d_{key}$是 Key 向量的长度)。你也可以除以其他数,除以一个数是为了在反向传播时,求取梯度更加稳定。 136 | 137 | 第 4 步,接着把这些分数经过一个 Softmax 层,Softmax可以将分数归一化,这样使得分数都是正数并且加起来等于 1。 138 | 139 | ![Thinking计算](./pictures/2-think2.png)图:Thinking计算 140 | 141 | 这些分数决定了在编码当前位置(这里的例子是第一个位置)的词时,对所有位置的词分别有多少的注意力。很明显,在上图的例子中,当前位置(这里的例子是第一个位置)的词会有最高的分数,但有时,关注到其他位置上相关的词也很有用。 142 | 143 | 第 5 步,得到每个位置的分数后,将每个分数分别与每个 Value 向量相乘。这种做法背后的直觉理解就是:对于分数高的位置,相乘后的值就越大,我们把更多的注意力放到了它们身上;对于分数低的位置,相乘后的值就越小,这些位置的词可能是相关性不大的,这样我们就忽略了这些位置的词。 144 | 145 | 第 6 步是把上一步得到的向量相加,就得到了 Self Attention 层在这个位置(这里的例子是第一个位置)的输出。 146 | 147 | ![Think计算](./pictures/2-sum.png)图:Think计算 148 | 149 | 150 | 上面这张图,包含了 Self Attention 的全过程,最终得到的当前位置(这里的例子是第一个位置)的向量会输入到前馈神经网络。但这样每次只能计算一个位置的输出向量,在实际的代码实现中,Self Attention 的计算过程是使用矩阵来实现的,这样可以加速计算,一次就得到所有位置的输出向量。下面让我们来看,如何使用矩阵来计算所有位置的输出向量。 151 | 152 | ## 使用矩阵计算 Self-Attention 153 | 154 | 第一步是计算 Query,Key,Value 的矩阵。首先,我们把所有词向量放到一个矩阵 X 中,然后分别和3 个权重矩阵$W^Q, W^K W^V$ 相乘,得到 Q,K,V 矩阵。 155 | 156 | ![](./pictures/2-qkv-multi.png)图:QKV矩阵乘法 157 | 158 | 矩阵 X 中的每一行,表示句子中的每一个词的词向量,长度是 512。Q,K,V 矩阵中的每一行表示 Query 向量,Key 向量,Value 向量,向量长度是 64。 159 | 160 | 接着,由于我们使用了矩阵来计算,我们可以把上面的第 2 步到第 6 步压缩为一步,直接得到 Self Attention 的输出。 161 | 162 | ![输出](./pictures/2-attention-output.webp)图:输出 163 | 164 | ## 多头注意力机制(multi-head attention) 165 | 166 | Transformer 的论文通过增加多头注意力机制(一组注意力称为一个 attention head),进一步完善了 Self Attention 层。这种机制从如下两个方面增强了 attention 层的能力: 167 | 168 | - 它扩展了模型关注不同位置的能力。在上面的例子中,第一个位置的输出 z1 包含了句子中其他每个位置的很小一部分信息,但 z1 可能主要是由第一个位置的信息决定的。当我们翻译句子:`The animal didn’t cross the street because it was too tired`时,我们想让机器知道其中的it指代的是什么。这时,多头注意力机制会有帮助。 169 | - 多头注意力机制赋予 attention 层多个“子表示空间”。下面我们会看到,多头注意力机制会有多组$W^Q, W^K W^V$ 的权重矩阵(在 Transformer 的论文中,使用了 8 组注意力(attention heads)。因此,接下来我也是用 8 组注意力头 (attention heads))。每一组注意力的 的权重矩阵都是随机初始化的。经过训练之后,每一组注意力$W^Q, W^K W^V$ 可以看作是把输入的向量映射到一个”子表示空间“。 170 | 171 | ![多头注意力机制](./pictures/2-multi-head.png)图:多头注意力机制 172 | 173 | 在多头注意力机制中,我们为每组注意力维护单独的 WQ, WK, WV 权重矩阵。将输入 X 和每组注意力的WQ, WK, WV 相乘,得到 8 组 Q, K, V 矩阵。 174 | 175 | 接着,我们把每组 K, Q, V 计算得到每组的 Z 矩阵,就得到 8 个 Z 矩阵。 176 | 177 | ![8 个 Z 矩阵](./pictures/2-8z.webp)图:8 个 Z 矩阵 178 | 179 | 接下来就有点麻烦了,因为前馈神经网络层接收的是 1 个矩阵(其中每行的向量表示一个词),而不是 8 个矩阵。所以我们需要一种方法,把 8 个矩阵整合为一个矩阵。 180 | 181 | 怎么才能做到呢?我们把矩阵拼接起来,然后和另一个权重矩阵$W^Q$相乘。 182 | 183 | ![整合矩阵](./pictures/2-to1.webp)图:整合矩阵 184 | 185 | 1. 把 8 个矩阵 {Z0,Z1...,Z7} 拼接起来 186 | 2. 把拼接后的矩阵和 WO 权重矩阵相乘 187 | 3. 得到最终的矩阵 Z,这个矩阵包含了所有 attention heads(注意力头) 的信息。这个矩阵会输入到 FFNN (Feed Forward Neural Network)层。 188 | 189 | 这就是多头注意力的全部内容。我知道,在上面的讲解中,出现了相当多的矩阵。下面我把所有的内容都放到一张图中,这样你可以总揽全局,在这张图中看到所有的内容。 190 | 191 | ![放在一起](./pictures/2-put-together.webp)图:放在一起 192 | 193 | 既然我们已经谈到了多头注意力,现在让我们重新回顾之前的翻译例子,看下当我们编码单词it时,不同的 attention heads (注意力头)关注的是什么部分。 194 | 195 | ![`it`的attention](./pictures/2-it-attention.webp)图:`it`的attention 196 | 197 | 当我们编码单词"it"时,其中一个 attention head (注意力头)最关注的是"the animal",另外一个 attention head 关注的是"tired"。因此在某种意义上,"it"在模型中的表示,融合了"animal"和"word"的部分表达。 198 | 199 | 然而,当我们把所有 attention heads(注意力头) 都在图上画出来时,多头注意力又变得难以解释了。 200 | 201 | ![所有注意力heads](./pictures/2-all-att.png)图:所有注意力heads 202 | 203 | ## 代码实现矩阵计算 Attention 204 | 下面我们是用代码来演示,如何使用矩阵计算 attention。首先使用 PyTorch 库提供的函数实现,然后自己再实现。 205 | 206 | ### 207 | PyTorch 提供了 MultiheadAttention 来实现 attention 的计算。 208 | ``` 209 | torch.nn.MultiheadAttention(embed_dim, num_heads, dropout=0.0, bias=True, add_bias_kv=False, add_zero_attn=False, kdim=None, vdim=None) 210 | ``` 211 | 参数说明如下: 212 | 213 | - embed_dim:最终输出的 K、Q、V 矩阵的维度,这个维度需要和词向量的维度一样 214 | 215 | - num_heads:设置多头注意力的数量。如果设置为 1,那么只使用一组注意力。如果设置为其他数值,那么 - - num_heads 的值需要能够被 embed_dim 整除 216 | 217 | - dropout:这个 dropout 加在 attention score 后面 218 | 219 | 现在来解释一下,为什么 num_heads 的值需要能够被 embed_dim 整除。这是为了把词的隐向量长度平分到每一组,这样多组注意力也能够放到一个矩阵里,从而并行计算多头注意力。 220 | 221 | 例如,我们前面说到,8 组注意力可以得到 8 组 Z 矩阵,然后把这些矩阵拼接起来,得到最终的输出。如果最终输出的每个词的向量维度是 512,那么每组注意力的向量维度应该是64 。 222 | 223 | 如果不能够整除,那么这些向量的长度就无法平均分配。 224 | 225 | 下面的会有代码示例,如何使用矩阵实现多组注意力的并行计算。 226 | 227 | 定义 `MultiheadAttention` 的对象后,调用时传入的参数如下。 228 | ``` 229 | forward(query, key, value, key_padding_mask=None, need_weights=True, attn_mask=None) 230 | ``` 231 | 232 | - query:对应于 Key 矩阵,形状是 (L,N,E) 。其中 L 是输出序列长度,N 是 batch size,E 是词向量的维度 233 | 234 | - key:对应于 Key 矩阵,形状是 (S,N,E) 。其中 S 是输入序列长度,N 是 batch size,E 是词向量的维度 235 | 236 | - value:对应于 Value 矩阵,形状是 (S,N,E) 。其中 S 是输入序列长度,N 是 batch size,E 是词向量的维度 237 | 238 | - key_padding_mask:如果提供了这个参数,那么计算 attention score 时,忽略 Key 矩阵中某些 padding 元素,不参与计算 attention。形状是 (N,S)。其中 N 是 batch size,S 是输入序列长度。 239 | 240 | - - 如果 key_padding_mask 是 ByteTensor,那么非 0 元素对应的位置会被忽略 241 | - - 如果 key_padding_mask 是 BoolTensor,那么 True 对应的位置会被忽略 242 | - attn_mask:计算输出时,忽略某些位置。形状可以是 2D (L,S),或者 3D (N∗numheads,L,S)。其中 L 是输出序列长度,S 是输入序列长度,N 是 batch size。 243 | 244 | - - 如果 attn_mask 是 ByteTensor,那么非 0 元素对应的位置会被忽略 245 | - - 如果 attn_mask 是 BoolTensor,那么 True 对应的位置会被忽略 246 | 247 | 需要注意的是:在前面的讲解中,我们的 K、Q、V 矩阵的序列长度都是一样的。但是在实际中,K、V 矩阵的序列长度是一样的,而 Q 矩阵的序列长度可以不一样。 248 | 249 | 这种情况发生在:在解码器部分的Encoder-Decoder Attention层中,Q 矩阵是来自解码器下层,而 K、V 矩阵则是来自编码器的输出。 250 | 251 | ![encoder-decoder动态图](./pictures/2-encoder-decoder.gif)动态图:encoder-decoder动态图 252 | 253 | 254 | 在完成了编码(encoding)阶段之后,我们开始解码(decoding)阶段。解码(decoding )阶段的每一个时间步都输出一个翻译后的单词(这里的例子是英语翻译)。 255 | 256 | 输出是: 257 | 258 | - attn_output:形状是 (L,N,E) 259 | - attn_output_weights:形状是 (N,L,S) 260 | 代码示例如下: 261 | 262 | ``` 263 | ## nn.MultiheadAttention 输入第0维为length 264 | # batch_size 为 64,有 12 个词,每个词的 Query 向量是 300 维 265 | query = torch.rand(12,64,300) 266 | # batch_size 为 64,有 10 个词,每个词的 Key 向量是 300 维 267 | key = torch.rand(10,64,300) 268 | # batch_size 为 64,有 10 个词,每个词的 Value 向量是 300 维 269 | value= torch.rand(10,64,300) 270 | 271 | embed_dim = 299 272 | num_heads = 1 273 | # 输出是 (attn_output, attn_output_weights) 274 | multihead_attn = nn.MultiheadAttention(embed_dim, num_heads) 275 | attn_output = multihead_attn(query, key, value)[0] 276 | # output: torch.Size([12, 64, 300]) 277 | # batch_size 为 64,有 12 个词,每个词的向量是 300 维 278 | print(attn_output.shape) 279 | ``` 280 | ### 手动实现计算 Attention 281 | 282 | 在 PyTorch 提供的 MultiheadAttention 中,第 1 维是句子长度,第 2 维是 batch size。这里我们的代码实现中,第 1 维是 batch size,第 2 维是句子长度。代码里也包括:如何用矩阵实现多组注意力的并行计算。代码中已经有详细注释和说明。 283 | 284 | ``` 285 | class MultiheadAttention(nn.Module): 286 | # n_heads:多头注意力的数量 287 | # hid_dim:每个词输出的向量维度 288 | def __init__(self, hid_dim, n_heads, dropout): 289 | super(MultiheadAttention, self).__init__() 290 | self.hid_dim = hid_dim 291 | self.n_heads = n_heads 292 | 293 | # 强制 hid_dim 必须整除 h 294 | assert hid_dim % n_heads == 0 295 | # 定义 W_q 矩阵 296 | self.w_q = nn.Linear(hid_dim, hid_dim) 297 | # 定义 W_k 矩阵 298 | self.w_k = nn.Linear(hid_dim, hid_dim) 299 | # 定义 W_v 矩阵 300 | self.w_v = nn.Linear(hid_dim, hid_dim) 301 | self.fc = nn.Linear(hid_dim, hid_dim) 302 | self.do = nn.Dropout(dropout) 303 | # 缩放 304 | self.scale = torch.sqrt(torch.FloatTensor([hid_dim // n_heads])) 305 | 306 | def forward(self, query, key, value, mask=None): 307 | # K: [64,10,300], batch_size 为 64,有 12 个词,每个词的 Query 向量是 300 维 308 | # V: [64,10,300], batch_size 为 64,有 10 个词,每个词的 Query 向量是 300 维 309 | # Q: [64,12,300], batch_size 为 64,有 10 个词,每个词的 Query 向量是 300 维 310 | bsz = query.shape[0] 311 | Q = self.w_q(query) 312 | K = self.w_k(key) 313 | V = self.w_v(value) 314 | # 这里把 K Q V 矩阵拆分为多组注意力,变成了一个 4 维的矩阵 315 | # 最后一维就是是用 self.hid_dim // self.n_heads 来得到的,表示每组注意力的向量长度, 每个 head 的向量长度是:300/6=50 316 | # 64 表示 batch size,6 表示有 6组注意力,10 表示有 10 词,50 表示每组注意力的词的向量长度 317 | # K: [64,10,300] 拆分多组注意力 -> [64,10,6,50] 转置得到 -> [64,6,10,50] 318 | # V: [64,10,300] 拆分多组注意力 -> [64,10,6,50] 转置得到 -> [64,6,10,50] 319 | # Q: [64,12,300] 拆分多组注意力 -> [64,12,6,50] 转置得到 -> [64,6,12,50] 320 | # 转置是为了把注意力的数量 6 放到前面,把 10 和 50 放到后面,方便下面计算 321 | Q = Q.view(bsz, -1, self.n_heads, self.hid_dim // 322 | self.n_heads).permute(0, 2, 1, 3) 323 | K = K.view(bsz, -1, self.n_heads, self.hid_dim // 324 | self.n_heads).permute(0, 2, 1, 3) 325 | V = V.view(bsz, -1, self.n_heads, self.hid_dim // 326 | self.n_heads).permute(0, 2, 1, 3) 327 | 328 | # 第 1 步:Q 乘以 K的转置,除以scale 329 | # [64,6,12,50] * [64,6,50,10] = [64,6,12,10] 330 | # attention:[64,6,12,10] 331 | attention = torch.matmul(Q, K.permute(0, 1, 3, 2)) / self.scale 332 | 333 | # 把 mask 不为空,那么就把 mask 为 0 的位置的 attention 分数设置为 -1e10 334 | if mask isnotNone: 335 | attention = attention.masked_fill(mask == 0, -1e10) 336 | 337 | # 第 2 步:计算上一步结果的 softmax,再经过 dropout,得到 attention。 338 | # 注意,这里是对最后一维做 softmax,也就是在输入序列的维度做 softmax 339 | # attention: [64,6,12,10] 340 | attention = self.do(torch.softmax(attention, dim=-1)) 341 | 342 | # 第三步,attention结果与V相乘,得到多头注意力的结果 343 | # [64,6,12,10] * [64,6,10,50] = [64,6,12,50] 344 | # x: [64,6,12,50] 345 | x = torch.matmul(attention, V) 346 | 347 | # 因为 query 有 12 个词,所以把 12 放到前面,把 5 和 60 放到后面,方便下面拼接多组的结果 348 | # x: [64,6,12,50] 转置-> [64,12,6,50] 349 | x = x.permute(0, 2, 1, 3).contiguous() 350 | # 这里的矩阵转换就是:把多组注意力的结果拼接起来 351 | # 最终结果就是 [64,12,300] 352 | # x: [64,12,6,50] -> [64,12,300] 353 | x = x.view(bsz, -1, self.n_heads * (self.hid_dim // self.n_heads)) 354 | x = self.fc(x) 355 | return x 356 | 357 | 358 | # batch_size 为 64,有 12 个词,每个词的 Query 向量是 300 维 359 | query = torch.rand(64, 12, 300) 360 | # batch_size 为 64,有 12 个词,每个词的 Key 向量是 300 维 361 | key = torch.rand(64, 10, 300) 362 | # batch_size 为 64,有 10 个词,每个词的 Value 向量是 300 维 363 | value = torch.rand(64, 10, 300) 364 | attention = MultiheadAttention(hid_dim=300, n_heads=6, dropout=0.1) 365 | output = attention(query, key, value) 366 | ## output: torch.Size([64, 12, 300]) 367 | print(output.shape) 368 | 369 | ``` 370 | ### 关键代码 371 | 372 | 其中用矩阵实现多头注意力的关键代码如下所示, K、Q、V 矩阵拆分为多组注意力,变成了一个 4 维的矩阵。 373 | 374 | ``` 375 | # 这里把 K Q V 矩阵拆分为多组注意力,变成了一个 4 维的矩阵 376 | # 最后一维就是是用 self.hid_dim // self.n_heads 来得到的,表示每组注意力的向量长度, 每个 head 的向量长度是:300/6=50 377 | # 64 表示 batch size,6 表示有 6组注意力,10 表示有 10 个词,50 表示每组注意力的词的向量长度 378 | # K: [64,10,300] 拆分多组注意力 -> [64,10,6,50] 转置得到 -> [64,6,10,50] 379 | # V: [64,10,300] 拆分多组注意力 -> [64,10,6,50] 转置得到 -> [64,6,10,50] 380 | # Q: [64,12,300] 拆分多组注意力 -> [64,12,6,50] 转置得到 -> [64,6,12,50] 381 | # 转置是为了把注意力的数量 6 放到前面,把 10 和 50 放到后面,方便下面计算 382 | Q = Q.view(bsz, -1, self.n_heads, self.hid_dim // 383 | self.n_heads).permute(0, 2, 1, 3) 384 | K = K.view(bsz, -1, self.n_heads, self.hid_dim // 385 | self.n_heads).permute(0, 2, 1, 3) 386 | V = V.view(bsz, -1, self.n_heads, self.hid_dim // 387 | self.n_heads).permute(0, 2, 1, 3) 388 | 经过 attention 计算得到 x 的形状是 `[64,12,6,50]`,64 表示 batch size,6 表示有 6组注意力,10 表示有 10 个词,50 表示每组注意力的词的向量长度。把这个矩阵转换为 `[64,12,300]`的矩阵,就是相当于把多组注意力的结果拼接起来。 389 | e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e ee 390 | 391 | 这里的矩阵转换就是:把多组注意力的结果拼接起来,最终结果就是 [64,12,300],x: [64,12,6,50] -> [64,12,300] 392 | x = x.view(bsz, -1, self.n_heads * (self.hid_dim // self.n_heads)) 393 | ``` 394 | 395 | ## 使用位置编码来表示序列的顺序 396 | 397 | 到目前为止,我们阐述的模型中缺失了一个东西,那就是表示序列中单词顺序的方法。 398 | 399 | 为了解决这个问题,Transformer 模型对每个输入的向量都添加了一个向量。这些向量遵循模型学习到的特定模式,有助于确定每个单词的位置,或者句子中不同单词之间的距离。这种做法背后的直觉是:将这些表示位置的向量添加到词向量中,得到了新的向量,这些新向量映射到 Q/K/V,然后计算点积得到 attention 时,可以提供有意义的信息。 400 | 401 | ![位置编码](./pictures/2-position.png)图:位置编码 402 | 403 | 为了让模型了解单词的顺序,我们添加了带有位置编码的向量--这些向量的值遵循特定的模式。 404 | 如果我们假设词向量的维度是 4,那么带有位置编码的向量可能如下所示: 405 | 406 | ![位置编码](./pictures/2-position2.png)图:位置编码 407 | 408 | 上图为带有位置编码的向量长度为 4 的例子。 409 | 那么带有位置编码的向量到底遵循什么模式? 410 | 411 | 在下图中,每一行表示一个带有位置编码的向量。所以,第一行对应于序列中第一个单词的位置编码向量。每一行都包含 512 个值,每个值的范围在 -1 和 1 之间。我对这些向量进行了涂色可视化,你可以从中看到向量遵循的模式。 412 | ![位置编码图示](./pictures/2-position3.png)图:位置编码图示 413 | 414 | 这是一个真实的例子,包含了 20 个词,每个词向量的维度是 512。你可以看到,它看起来像从中间一分为二。这是因为左半部分的值是由 sine 函数产生的,而右半部分的值是由 cosine 函数产生的,然后将他们拼接起来,得到每个位置编码向量。 415 | 416 | 你可以在get_timing_signal_1d()上查看生成位置编码的代码。这种方法来自于`Tranformer2Transformer` 的实现。 417 | 418 | 而论文中的方法和上面图中的稍有不同,它不是直接拼接两个向量,而是将两个向量交织在一起。如下图所示。 419 | 420 | ![位置编码交织](./pictures/2-positin4.png)图:位置编码交织 421 | 422 | 此为生成位置编码的公式,在 Transformer 论文的 3.5 节中有详细说明。 423 | 424 | 425 | 这不是唯一一种生成位置编码的方法。但这种方法的优点是:可以扩展到未知的序列长度。例如:当我们的模型需要翻译一个句子,而这个句子的长度大于训练集中所有句子的长度,这时,这种位置编码的方法也可以生成一样长的位置编码向量。 426 | 427 | ## 残差连接 428 | 429 | 在我们继续讲解之前,编码器结构中有一个需要注意的细节是:编码器的每个子层(Self Attention 层和 FFNN)都有一个残差连接和层标准化(layer-normalization)。 430 | 431 | ![残差连接](./pictures/2-resnet.png)图:残差连接 432 | 将 Self-Attention 层的层标准化(layer-normalization)和向量都进行可视化,如下所示: 433 | 434 | ![标准化](./pictures/2-lyn.png)图:标准化 435 | 436 | 在解码器的子层里面也有层标准化(layer-normalization)。假设一个 Transformer 是由 2 层编码器和两层解码器组成的,如下图所示。 437 | 438 | 439 | ![2层示意图](./pictures/2-2layer.png)图:2层示意图 440 | 441 | ## Decoder(解码器) 442 | 443 | 现在我们已经介绍了解码器中的大部分概念,我们也基本知道了解码器的原理。现在让我们来看下, 编码器和解码器是如何协同工作的。 444 | 445 | 上面说了,编码器一般有多层,第一个编码器的输入是一个序列,最后一个编码器输出是一组注意力向量 K 和 V。这些注意力向量将会输入到每个解码器的Encoder-Decoder Attention层,这有助于解码器把注意力集中中输入序列的合适位置。 446 | 447 | 在完成了编码(encoding)阶段之后,我们开始解码(decoding)阶段。解码(decoding )阶段的每一个时间步都输出一个翻译后的单词(这里的例子是英语翻译)。 448 | 449 | 接下来会重复这个过程,直到输出一个结束符,Transformer 就完成了所有的输出。每一步的输出都会在下一个时间步输入到下面的第一个解码器。Decoder 就像 Encoder 那样,从下往上一层一层地输出结果。正对如编码器的输入所做的处理,我们把解码器的输入向量,也加上位置编码向量,来指示每个词的位置。 450 | 451 | ![decoder动态图](./pictures/2-decoder.gif)动态图:decoder动态图 452 | 453 | 解码器中的 Self Attention 层,和编码器中的 Self Attention 层不太一样:在解码器里,Self Attention 层只允许关注到输出序列中早于当前位置之前的单词。具体做法是:在 Self Attention 分数经过 Softmax 层之前,屏蔽当前位置之后的那些位置。 454 | 455 | Encoder-Decoder Attention层的原理和多头注意力(multiheaded Self Attention)机制类似,不同之处是:Encoder-Decoder Attention层是使用前一层的输出来构造 Query 矩阵,而 Key 矩阵和 Value 矩阵来自于解码器最终的输出。 456 | 457 | ## 最后的线性层和 Softmax 层 458 | 459 | Decoder 最终的输出是一个向量,其中每个元素是浮点数。我们怎么把这个向量转换为单词呢?这是由 Softmax 层后面的线性层来完成的。 460 | 461 | 线性层就是一个普通的全连接神经网络,可以把解码器输出的向量,映射到一个更长的向量,这个向量称为 logits 向量。 462 | 463 | 现在假设我们的模型有 10000 个英语单词(模型的输出词汇表),这些单词是从训练集中学到的。因此 logits 向量有 10000 个数字,每个数表示一个单词的分数。我们就是这样去理解线性层的输出。 464 | 465 | 然后,Softmax 层会把这些分数转换为概率(把所有的分数转换为正数,并且加起来等于 1)。然后选择最高概率的那个数字对应的词,就是这个时间步的输出单词。 466 | 467 | ![线性层](./pictures/2-linear.png)图:线性层 468 | 469 | 在上图中,最下面的向量,就是编码器的输出,这个向量输入到线性层和 Softmax 层,最终得到输出的词。 470 | 471 | ## Transformer 的训练过程 472 | 473 | 现在我们已经了解了 Transformer 的前向传播过程,下面讲讲 Transformer 的训练过程,这也是非常有用的知识。 474 | 475 | 在训练过程中,模型会经过上面讲的所有前向传播的步骤。但是,当我们在一个标注好的数据集上训练这个模型的时候,我们可以对比模型的输出和真实的标签。 476 | 477 | 为了可视化这个对比,让我们假设输出词汇表只包含 6 个单词(“a”, “am”, “i”, “thanks”, “student”, and “\”(“\”表示句子末尾))。 478 | 479 | ![6个词](./pictures/2-6words.webp)图:6个词 480 | 481 | 我们模型的输出词汇表,是在训练之前的数据预处理阶段构造的。当我们确定了输出词汇表,我们可以用向量来表示词汇表中的每个单词。这个表示方法也称为 one-hot encoding。例如,我们可以把单词 “am” 用下面的向量来表示: 482 | 483 | 484 | ![am向量](./pictures/2-am.webp)图:am向量 485 | 486 | 介绍了训练过程,我们接着讨论模型的损失函数,这我们在训练时需要优化的目标,通过优化这个目标来得到一个训练好的、非常精确的模型。 487 | 488 | ## 损失函数 489 | 490 | 用一个简单的例子来说明训练过程,比如:把“merci”翻译为“thanks”。 491 | 492 | 这意味着我们希望模型最终输出的概率分布,会指向单词 ”thanks“(在“thanks”这个词的概率最高)。但模型还没训练好,它输出的概率分布可能和我们希望的概率分布相差甚远。 493 | 494 | ![概率分布](./pictures/2-loss.webp)图:概率分布 495 | 496 | 由于模型的参数都是随机初始化的。模型在每个词输出的概率都是随机的。我们可以把这个概率和正确的输出概率做对比,然后使用反向传播来调整模型的权重,使得输出的概率分布更加接近震数输出。 497 | 498 | 那我们要怎么比较两个概率分布呢?我们可以简单地用一个概率分布减去另一个概率分布。关于更多细节,你可以查看交叉熵(cross-entropy)]和KL 散度(Kullback–Leibler divergence)的相关概念。 499 | 500 | 但上面的例子是经过简化的,因为我们的句子只有一个单词。在实际中,我们使用的句子不只有一个单词。例如--输入是:“je suis étudiant” ,输出是:“i am a student”。这意味着,我们的模型需要输出多个概率分布,满足如下条件: 501 | 502 | - 每个概率分布都是一个向量,长度是 vocab_size(我们的例子中,向量长度是 6,但实际中更可能是 30000 或者 50000) 503 | - 第一个概率分布中,最高概率对应的单词是 “i” 504 | - 第二个概率分布中,最高概率对应的单词是 “am” 505 | - 以此类推,直到第 5 个概率分布中,最高概率对应的单词是 “”,表示没有下一个单词了 506 | 507 | 508 | ![概率分布](./pictures/2-target.png)图:概率分布 509 | 510 | 我们用例子中的句子训练模型,希望产生图中所示的概率分布 511 | 我们的模型在一个足够大的数据集上,经过足够长时间的训练后,希望输出的概率分布如下图所示: 512 | 513 | ![训练后概率分布](./pictures/2-trained.webp)图:训练后概率分布 514 | 515 | 希望经过训练,模型会输出我们希望的正确翻译。当然,如果你要翻译的句子是训练集中的一部分,那输出的结果并不能说明什么。我们希望的是模型在没见过的句子上也能够准确翻译。需要注意的是:概率分布向量中,每个位置都会有一点概率,即使这个位置不是输出对应的单词--这是 Softmax 中一个很有用的特性,有助于帮助训练过程。 516 | 517 | 现在,由于模型每个时间步只产生一个输出,我们可以认为:模型是从概率分布中选择概率最大的词,并且丢弃其他词。这种方法叫做贪婪解码(greedy decoding)。另一种方法是每个时间步保留两个最高概率的输出词,然后在下一个时间步,重复执行这个过程:假设第一个位置概率最高的两个输出的词是”I“和”a“,这两个词都保留,然后根据第一个词计算第二个位置的词的概率分布,再取出 2 个概率最高的词,对于第二个位置和第三个位置,我们也重复这个过程。这种方法称为集束搜索(beam search),在我们的例子中,beam_size 的值是 2(含义是:在所有时间步,我们保留两个最高概率),top_beams 的值也是 2(表示我们最终会返回两个翻译的结果)。beam_size 和 top_beams 都是你可以在实验中尝试的超参数。 518 | 519 | ## 更进一步理解 520 | 521 | 我希望上面讲的内容,可以帮助你理解 Transformer 中的主要概念。如果你想更深一步地理解,我建议你可以参考下面这些: 522 | 523 | - 阅读 Transformer 的论文: 524 | 《Attention Is All You Need》 525 | 链接地址:https://arxiv.org/abs/1706.03762 526 | - 阅读Transformer 的博客文章: 527 | 《Transformer: A Novel Neural Network Architecture for Language Understanding》 528 | 链接地址:https://ai.googleblog.com/2017/08/transformer-novel-neural-network.html 529 | 阅读《Tensor2Tensor announcement》 530 | - 链接地址:https://ai.googleblog.com/2017/06/accelerating-deep-learning-research.html 531 | - 观看视频 【Łukasz Kaiser’s talk】来理解模型和其中的细节 532 | 链接地址:https://www.youtube.com/watch?v=rBCqOTEfxvg 533 | 运行这份代码:【Jupyter Notebook provided as part of the Tensor2Tensor repo】 534 | - 链接地址:https://colab.research.google.com/github/tensorflow/tensor2tensor/blob/master/tensor2tensor/notebooks/hello_t2t.ipynb。 535 | - 查看这个项目:【Tensor2Tensor repo】 536 | 链接地址:https://github.com/tensorflow/tensor2tensor 537 | 538 | 539 | -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/1.3-图解BERT.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 致谢 4 | 主要由哈尔滨工业大学张贤同学翻译(经过原作者授权)撰写,由本项目同学组织和整理。感谢Jacob Devlin、Matt Gardner、Kenton Lee、Mark Neumann 和 [Matthew Peters](https://twitter.com/mattthemathman) 为这篇文章的早期版本提供了反馈 5 | 6 | ## 图解BERT 7 | 8 | ![结构总览](./pictures/3-stru.png)图:结构总览 9 | 10 | ## 前言 11 | 2018 年是机器学习模型处理文本(或者更准确地说,自然语言处理或 NLP)的转折点。我们对这些方面的理解正在迅速发展:如何最好地表示单词和句子,从而最好地捕捉基本语义和关系?此外,NLP 社区已经发布了非常强大的组件,你可以免费下载,并在自己的模型和 pipeline 中使用(今年可以说是 NLP 的 ImageNet 时刻,这句话指的是多年前类似的发展也加速了 机器学习在计算机视觉任务中的应用)。 12 | 13 | ![BERT-ELMo-ULM-FIT](./pictures/3-bert-elmo.png)图:BERT-ELMo-ULM-FIT 14 | 15 | ULM-FiT 与 Cookie Monster(饼干怪兽)无关。但我想不出别的了... 16 | 17 | BERT的发布是这个领域发展的最新的里程碑之一,这个事件标志着NLP 新时代的开始。BERT模型打破了基于语言处理的任务的几个记录。在 BERT 的论文发布后不久,这个团队还公开了模型的代码,并提供了模型的下载版本,这些模型已经在大规模数据集上进行了预训练。这是一个重大的发展,因为它使得任何一个构建构建机器学习模型来处理语言的人,都可以将这个强大的功能作为一个现成的组件来使用,从而节省了从零开始训练语言处理模型所需要的时间、精力、知识和资源。 18 | 19 | ![BERT训练和微调](./pictures/3-bert.webp)图:BERT训练和微调 20 | 21 | BERT 开发的两个步骤:第 1 步,你可以下载预训练好的模型(这个模型是在无标注的数据上训练的)。然后在第 2 步只需要关心模型微调即可。 22 | 23 | 你需要注意一些事情,才能理解 BERT 是什么。因此,在介绍模型本身涉及的概念之前,让我们先看看如何使用 BERT。 24 | 25 | ## 句子分类 26 | 27 | 使用 BERT 最直接的方法就是对一个句子进行分类。这个模型如下所示: 28 | 29 | ![BERT句子分类](./pictures/3-bert-cls.png)图:BERT句子分类 30 | 31 | 为了训练这样一个模型,你主要需要训练分类器(上图中的 Classifier),在训练过程中 几乎不用改动BERT模型。这个训练过程称为微调,它起源于Semi-supervised Sequence Learning 和 ULMFiT。 32 | 33 | 由于我们在讨论分类器,这属于机器学习的监督学习领域。这意味着我们需要一个带有标签的数据集来训练这样一个模型。例如,在下面这个垃圾邮件分类器的例子中,带有标签的数据集包括一个邮件内容列表和对应的标签(每个邮件是“垃圾邮件”或者“非垃圾邮件”)。 34 | 35 | ![垃圾邮件分类](./pictures/3-trash.png)图:垃圾邮件分类 36 | 37 | 其他一些例子包括: 38 | 39 | 1) 语义分析 40 | 41 | - - 输入:电影或者产品的评价。输出:判断这个评价是正面的还是负面的。 42 | 数据集示例:SST (https://nlp.stanford.edu/sentiment) 43 | 2)Fact-checking 44 | 45 | - 输入:一个句子。输出:这个句子是不是一个断言 46 | - 参考视频:https://www.youtube.com/watch?v=ddf0lgPCoSo 47 | 48 | ## 模型架构 49 | 50 | 现在你已经通过上面的例子,了解了如何使用 BERT,接下来让我们更深入地了解一下它的工作原理。 51 | 52 | ![BERT base和large](./pictures/3-bert-bl.webp)图:BERT base和large 53 | 54 | 论文里介绍了两种不同模型大小的 BERT: 55 | 56 | - BERT BASE - 与 OpenAI 的 Transformer 大小相当,以便比较性能 57 | - BERT LARGE - 一个非常巨大的模型,它取得了最先进的结果 58 | 59 | BERT 基本上是一个训练好的 Transformer 的 encoder 的栈。关于 Transformer 的介绍,可以阅读之前的文章[《 图解Transformer(完整版)!》](https://github.com/datawhalechina/transformers-quick-start-zh/blob/main/transformer%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86%E8%AE%B2%E8%A7%A3/2-%E5%9B%BE%E8%A7%A3transformer.md),这里主要介绍 Transformer 模型,这是 BERT 中的一个基本概念。此外,我们还会介绍其他一些概念。 60 | 61 | 2 种不同大小规模的 BERT 模型都有大量的 Encoder 层(论文里把这些层称为 Transformer Blocks)- BASE 版本由 12 层 Encoder,Large 版本有 20 层 Encoder。同时,这些 BERT 模型也有更大的前馈神经网络(分别有 768 个和 1024 个隐藏层单元)和更多的 attention heads(分别有 12 个和 16 个),超过了原始 Transformer 论文中的默认配置参数(原论文中有 6 个 Encoder 层, 512 个隐藏层单元和 8 个 attention heads)。 62 | 63 | ## 模型输入 64 | 65 | ![模型输入](./pictures/3-bert-input.png)图:模型输入 66 | 67 | 第一个输入的 token 是特殊的 [CLS],它 的含义是分类(class的缩写)。 68 | 69 | 就像 Transformer 中普通的 Encoder 一样,BERT 将一串单词作为输入,这些单词在 Encoder 的栈中不断向上流动。每一层都会经过 Self Attention 层,并通过一个前馈神经网络,然后将结果传给下一个 Encoder。 70 | 71 | ![BERT encoder](./pictures/3-bert-encoder.webp)图:BERT encoder 72 | 73 | 在模型架构方面,到目前为止,和 Transformer 是相同的(除了模型大小,因为这是我们可以改变的参数)。我们会在下面看到,BERT 和 Transformer 在模型的输出上有一些不同。 74 | 75 | ## 模型输出 76 | 77 | 每个位置输出一个大小为 hidden_size(在 BERT Base 中是 768)的向量。对于上面提到的句子分类的例子,我们只关注第一个位置的输出(输入是 [CLS] 的那个位置)。 78 | 79 | ![BERT output](./pictures/3-bert-output.png)图:BERT output 80 | 81 | 这个输出的向量现在可以作为后面分类器的输入。论文里用单层神经网络作为分类器,取得了很好的效果。 82 | 83 | ![BERT 接分类器](./pictures/3-bert-clss.webp)图:BERT 接分类器 84 | 85 | 如果你有更多标签(例如你是一个电子邮件服务,需要将邮件标记为 “垃圾邮件”、“非垃圾邮件”、“社交”、“推广”),你只需要调整分类器的神经网络,增加输出的神经元个数,然后经过 softmax 即可。 86 | 87 | 88 | ## 与卷积神经网络进行对比 89 | 90 | 对于那些有计算机视觉背景的人来说,这个向量传递过程,会让人联想到 VGGNet 等网络的卷积部分,和网络最后的全连接分类部分之间的过程。 91 | 92 | ![CNN](./pictures/3-cnn.png)图:CNN 93 | 94 | ## 词嵌入(Embedding)的新时代 95 | 96 | 上面提到的这些新发展带来了文本编码方式的新转变。到目前为止,词嵌入一直是 NLP 模型处理语言的主要表示方法。像 Word2Vec 和 Glove 这样的方法已经被广泛应用于此类任务。在我们讨论新的方法之前,让我们回顾一下它们是如何应用的。 97 | 98 | ### 回顾词嵌入 99 | 100 | 单词不能直接输入机器学习模型,而需要某种数值表示形式,以便模型能够在计算中使用。通过 Word2Vec,我们可以使用一个向量(一组数字)来恰当地表示单词,并捕捉单词的语义以及单词和单词之间的关系(例如,判断单词是否相似或者相反,或者像 "Stockholm" 和 "Sweden" 这样的一对词,与 "Cairo" 和 "Egypt"这一对词,是否有同样的关系)以及句法、语法关系(例如,"had" 和 "has" 之间的关系与 "was" 和 "is" 之间的关系相同)。 101 | 102 | 人们很快意识到,相比于在小规模数据集上和模型一起训练词嵌入,更好的一种做法是,在大规模文本数据上预训练好词嵌入,然后拿来使用。因此,我们可以下载由 Word2Vec 和 GloVe 预训练好的单词列表,及其词嵌入。下面是单词 "stick" 的 Glove 词嵌入向量的例子(词嵌入向量长度是 200)。 103 | 104 | ![wrod vector](./pictures/3-wordvector.webp)图: wrod vector 105 | 106 | 107 | 单词 "stick" 的 Glove 词嵌入 - 一个由200个浮点数组成的向量(四舍五入到小数点后两位)。 108 | 109 | 由于这些向量都很长,且全部是数字,所以在文章中我使用以下基本形状来表示向量: 110 | 111 | ![vector](./pictures/3-single-vector.png)图:vector 112 | 113 | ### 语境问题 114 | 115 | 如果我们使用 Glove 的词嵌入表示方法,那么不管上下文是什么,单词 "stick" 都只表示为同一个向量。一些研究人员指出,像 "stick" 这样的词有多种含义。为什么不能根据它使用的上下文来学习对应的词嵌入呢?这样既能捕捉单词的语义信息,又能捕捉上下文的语义信息。于是,语境化的词嵌入模型应运而生。 116 | 117 | ![ELMO](./pictures/3-elmo.webp)图:ELMO 118 | 119 | 语境化的词嵌入,可以根据单词在句子语境中的含义,赋予不同的词嵌入。你可以查看这个视频 RIP Robin Williams(https://zhuanlan.zhihu.com/RIP Robin Williams) 120 | 121 | ELMo 没有对每个单词使用固定的词嵌入,而是在为每个词分配词嵌入之前,查看整个句子,融合上下文信息。它使用在特定任务上经过训练的双向 LSTM 来创建这些词嵌入。 122 | 123 | ![ELMO embedding](./pictures/3-elmo-emb.png)图: ELMO embedding 124 | 125 | ELMo 在语境化的预训练这条道路上迈出了重要的一步。ELMo LSTM 会在一个大规模的数据集上进行训练,然后我们可以将它作为其他语言处理模型的一个部分,来处理自然语言任务。 126 | 127 | 那么 ELMo 的秘密是什么呢? 128 | 129 | ELMo 通过训练,预测单词序列中的下一个词,从而获得了语言理解能力,这项任务被称为语言建模。要实现 ELMo 很方便,因为我们有大量文本数据,模型可以从这些数据中学习,而不需要额外的标签。 130 | 131 | 132 | ![ELMO 训练](./pictures/3-elmo-pre.webp)图: ELMO 训练 133 | 134 | ELMo 预训练过程的其中一个步骤:以 "Let’s stick to" 作为输入,预测下一个最有可能的单词。这是一个语言建模任务。当我们在大规模数据集上训练时,模型开始学习语言的模式。例如,在 "hang" 这样的词之后,模型将会赋予 "out" 更高的概率(因为 "hang out" 是一个词组),而不是 "camera"。 135 | 136 | 在上图中,我们可以看到 ELMo 头部上方展示了 LSTM 的每一步的隐藏层状态向量。在这个预训练过程完成后,这些隐藏层状态在词嵌入过程中派上用场。 137 | 138 | ![ELMO 训练 stick](./pictures/3-elmo-pre1.png)图:ELMO 训练 139 | 140 | ELMo 通过将隐藏层状态(以及初始化的词嵌入)以某种方式(向量拼接之后加权求和)结合在一起,实现了带有语境化的词嵌入。 141 | 142 | ![ELMO 训练 stick](./pictures/3-elmo-pre2.webp)图:ELMO 训练 143 | 144 | ### ULM-FiT:NLP 领域的迁移学习 145 | 146 | ULM-FiT 提出了一些方法来有效地利用模型在预训练期间学习到的东西 - 这些东西不仅仅是词嵌入,还有语境化的词嵌入。ULM-FiT 提出了一个语言模型和一套流程,可以有效地为各种任务微调这个语言模型。 147 | 148 | 现在,NLP 可能终于找到了好的方法,可以像计算机视觉那样进行迁移学习了。 149 | 150 | ### Transformer:超越 LSTM 151 | 152 | Transformer 论文和代码的发布,以及它在机器翻译等任务上取得的成果,开始让人们认为它是 LSTM 的替代品。这是因为 Transformer 可以比 LSTM 更好地处理长期依赖。 153 | 154 | Transformer 的 Encoder-Decoder 结构使得它非常适合机器翻译。但你怎么才能用它来做文本分类呢?你怎么才能使用它来预训练一个语言模型,并能够在其他任务上进行微调(下游任务是指那些能够利用预训练模型的监督学习任务)? 155 | 156 | ### OpenAI Transformer:预训练一个 Transformer Decoder 来进行语言建模 157 | 158 | 事实证明,我们不需要一个完整的 Transformer 来进行迁移学习和微调。我们只需要 Transformer 的 Decoder 就可以了。Decoder 是一个很好的选择,用它来做语言建模(预测下一个词)是很自然的,因为它可以屏蔽后来的词 。当你使用它进行逐词翻译时,这是个很有用的特性。 159 | 160 | ![open ai模型](./pictures/3-openai.webp)图: open ai模型 161 | 162 | OpenAI Transformer 是由 Transformer 的 Decoder 堆叠而成的 163 | 164 | 这个模型包括 12 个 Decoder 层。因为在这种设计中没有 Encoder,这些 Decoder 层不会像普通的 Transformer 中的 Decoder 层那样有 Encoder-Decoder Attention 子层。不过,它仍然会有 Self Attention 层(这些层使用了 mask,因此不会看到句子后来的 token)。 165 | 166 | 有了这个结构,我们可以继续在同样的语言建模任务上训练这个模型:使用大规模未标记的数据来预测下一个词。只需要把 7000 本书的文字扔给模型 ,然后让它学习。书籍非常适合这种任务,因为书籍的数据可以使得模型学习到相关联的信息。如果你使用 tweets 或者文章来训练,模型是得不到这些信息的。 167 | 168 | ![open ai模型预测下一个词](./pictures/3-openai-next.webp)图: open ai模型预测下一个词 169 | 170 | 上图表示:OpenAI Transformer 在 7000 本书的组成的数据集中预测下一个单词。 171 | 172 | ### 下游任务的迁移学习 173 | 174 | 现在,OpenAI Transformer 已经经过了预训练,它的网络层经过调整,可以很好地处理文本语言,我们可以开始使用它来处理下游任务。让我们先看下句子分类任务(把电子邮件分类为 ”垃圾邮件“ 或者 ”非垃圾邮件“): 175 | 176 | ![open ai模型下游任务](./pictures/3-openai-down.png)图: open ai模型下游任务 177 | 178 | OpenAI 的论文列出了一些列输入变换方法,来处理不同任务类型的输入。下面这张图片来源于论文,展示了执行不同任务的模型结构和对应输入变换。这些都是非常很巧妙的做法。 179 | 180 | ![open ai微调](./pictures/3-openai-method.webp)图: open ai微调 181 | 182 | ## BERT:从 Decoder 到 Encoder 183 | 184 | OpenAI Transformer 为我们提供了一个基于 Transformer 的可以微调的预训练网络。但是在把 LSTM 换成 Transformer 的过程中,有些东西丢失了。ELMo 的语言模型是双向的,但 OpenAI Transformer 只训练了一个前向的语言模型。我们是否可以构建一个基于 Transformer 的语言模型,它既向前看,又向后看(用技术术语来说 - 融合上文和下文的信息)。 185 | 186 | 187 | 188 | ### Masked Language Model(MLM 语言模型) 189 | 190 | 那么如何才能像 LSTM 那样,融合上文和下文的双向信息呢? 191 | 192 | 一种直观的想法是使用 Transformer 的 Encoder。但是 Encoder 的 Self Attention 层,每个 token 会把大部分注意力集中到自己身上,那么这样将容易预测到每个 token,模型学不到有用的信息。BERT 提出使用 mask,把需要预测的词屏蔽掉。 193 | 194 | 下面这段风趣的对话是博客原文的。 195 | 196 | 197 | ``` 198 | BERT 说,“我们要用 Transformer 的 Encoder”。 199 | 200 | Ernie 说,”这没什么用,因为每个 token 都会在多层的双向上下文中看到自己“。 201 | 202 | BERT 自信地说,”我们会使用 mask“。 203 | ``` 204 | ![BERT mask](./pictures/3-bert-mask.webp)图: BERT mask 205 | 206 | BERT 在语言建模任务中,巧妙地屏蔽了输入中 15% 的单词,并让模型预测这些屏蔽位置的单词。 207 | 208 | 找到合适的任务来训练一个 Transformer 的 Encoder 是一个复杂的问题,BERT 通过使用早期文献中的 "masked language model" 概念(在这里被称为完形填空)来解决这个问题。 209 | 210 | 除了屏蔽输入中 15% 的单词外, BERT 还混合使用了其他的一些技巧,来改进模型的微调方式。例如,有时它会随机地用一个词替换另一个词,然后让模型预测这个位置原来的实际单词。 211 | 212 | 213 | ### 两个句子的任务 214 | 215 | 如果你回顾 OpenAI Transformer 在处理不同任务时所做的输入变换,你会注意到有些任务需要模型对两个句子的信息做一些处理(例如,判断它们是不是同一句话的不同解释。将一个维基百科条目作为输入,再将一个相关的问题作为另一个输入,模型判断是否可以回答这个问题)。 216 | 217 | 为了让 BERT 更好地处理多个句子之间的关系,预训练过程还包括一个额外的任务:给出两个句子(A 和 B),判断 B 是否是 A 后面的相邻句子。 218 | 219 | ![2个句子任务](./pictures/3-bert-2sent.webp)图: 2个句子任务 220 | 221 | BERT 预训练的第 2 个任务是两个句子的分类任务。在上图中,tokenization 这一步被简化了,因为 BERT 实际上使用了 WordPieces 作为 token,而不是使用单词本身。在 WordPiece 中,有些词会被拆分成更小的部分。 222 | 223 | 224 | ### BERT 在不同任务上的应用 225 | 226 | BERT 的论文展示了 BERT 在多种任务上的应用。 227 | 228 | 229 | ![BERT应用](./pictures/3-bert-app.png)图: BERT应用 230 | 231 | ### 将 BERT 用于特征提取 232 | 233 | 使用 BERT 并不是只有微调这一种方法。就像 ELMo 一样,你可以使用预训练的 BERT 来创建语境化的词嵌入。然后你可以把这些词嵌入用到你现有的模型中。论文里也提到,这种方法在命名实体识别任务中的效果,接近于微调 BERT 模型的效果。 234 | 235 | 236 | ![BERT特征提取](./pictures/3-bert-feature.png)图: BERT特征提取 237 | 238 | 那么哪种向量最适合作为上下文词嵌入?我认为这取决于任务。论文里验证了 6 种选择(与微调后的 96.4 分的模型相比): 239 | 240 | ![BERT特征选择](./pictures/3-bert-fea.webp)图: BERT特征选择 241 | 242 | 243 | ### 如何使用 BERT 244 | 245 | 尝试 BERT 的最佳方式是通过托管在 Google Colab 上的 BERT FineTuning with Cloud TPUs。如果你之前从来没有使用过 Cloud TPU,那这也是一个很好的尝试开端,因为 BERT 代码可以运行在 TPU、CPU 和 GPU。 246 | 247 | 下一步是查看 BERT 仓库 中的代码: 248 | 249 | - 模型是在 modeling.py(class BertModel)中定义的,和普通的 Transformer encoder 完全相同。 250 | - run_classifier.py 是微调网络的一个示例。它还构建了监督模型分类层。如果你想构建自己的- 分类器,请查看这个文件中的 create_model() 方法。 251 | - 可以下载一些预训练好的模型。这些模型包括 BERT Base、BERT Large,以及英语、中文和包括 102 种语言的多语言模型,这些模型都是在维基百科的数据上进行训练的。 252 | - BERT 不会将单词作为 token。相反,它关注的是 WordPiece。tokenization.py 就是 tokenizer,它会将你的单词转换为适合 BERT 的 wordPiece。 253 | 254 | -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/1.4-图解GPT.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ## 致谢 6 | 主要由哈尔滨工业大学张贤同学翻译(经过原作者授权)撰写,由本项目同学组织和整理。 7 | 8 | 9 | ## 图解GPT 10 | 11 | ![结构总览](./pictures/4-stru.webp)图: 结构总览 12 | 13 | ## 前言 14 | 15 | 这篇文章翻译自http://jalammar.github.io/illustrated-gpt2/。多图详细解释当今最为强大的人工智能 GPT-2(截至 2019 年 8 月 12 日)。 16 | 17 | 今年,我们看到了机器学习在许多场景的广泛应用。OpenAI GPT-2(https://openai.com/blog/better-language-models/)表现出了令人印象深刻的能力,它能够写出连贯而充满激情的文章,这超出了我们当前对语言模型的预期效果。GPT-2 不是一个特别新颖的架构,而是一种与 Transformer 解码器非常类似的架构。不过 GPT-2 是一个巨大的、基于 Transformer 的语言模型,它是在一个巨大的数据集上训练的。在这篇文章,我们会分析它的结构,以及这种结构产生的作用。我们会深入了解 Self Attention 层的细节。然后我们会再了解一下这种只有 Decoder 的 Transformer 在语言建模之外的应用。 18 | 19 | 这篇文章可以看作是之前文章[《图解Transformer(完整版)!》](https://github.com/datawhalechina/transformers-quick-start-zh/blob/main/transformer%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86%E8%AE%B2%E8%A7%A3/2-%E5%9B%BE%E8%A7%A3transformer.md)的补充。图解 Transformer 的文章使用了更多的图来解释 Transformer 的内部工作原理,以及它们是如何从原始论文一步一步进化的。我希望这种可视化的方式能够更加容易解释基于 Transformer 的模型内部原理和进化。 20 | 21 | ## GPT2 和语言模型 22 | 23 | 首先,我们来看看什么是语言模型。 24 | 25 | ### 什么是语言模型 26 | 27 | 在 图解 Word2Vec(https://jalammar.github.io/illustrated-word2vec/) 中,我们了解到语言模型基本上是一个机器学习模型,它可以根据句子的一部分预测下一个词。最著名的语言模型就是手机键盘,它可以根据你输入的内容,提示下一个单词。 28 | 29 | ![词之间的关系](./pictures/4-word2vec.webp)图:词之间的关系 30 | 31 | 从这个意义上讲,GPT-2 基本上就是键盘应用程序中预测下一个词的功能,但 GPT-2 比你手机上的键盘 app 更大更复杂。GPT-2 是在一个 40 GB 的名为 WebText 的数据集上训练的,OpenAI 的研究人员从互联网上爬取了这个数据集,作为研究工作的一部分。从存储空间大小方面来比较,我使用的键盘应用程序 SwiftKey,占用了 78 MB 的空间。而最小的 GPT-2 变种,需要 500 MB 的空间来存储它的所有参数。最大的 GPT-2 模型变种是其大小的 13 倍,因此占用的空间可能超过 6.5 GB。 32 | ![GPT发展](./pictures/4-gpt-his.webp)图:GPT发展 33 | 34 | 对 GPT-2 进行实验的一个很好的方法是使用 AllenAI GPT-2 Explorer(https://gpt2.apps.allenai.org/?text=Joel is)。它使用 GPT-2 来显示下一个单词的 10 种预测(包括每种预测的分数)。你可以选择一个单词,然后就能看到下一个单词的预测列表,从而生成一篇文章。 35 | 36 | ### 语言模型的 Transformer 37 | 38 | 正如我们在图解 Transformer中看到的,原始的 Transformer 模型是由 Encoder 和 Decoder 组成的,它们都是由 Transformer 堆叠而成的。这种架构是合适的,因为这个模型是用于处理机器翻译的。在机器翻译问题中,Encoder-Decoder 的架构已经在过去成功应用了。 39 | 40 | ![transformer](./pictures/4-transformer.webp)图:transformer 41 | 42 | 在随后的许多研究工作中,只使用 Transformer 中的一部分,要么去掉 Encoder,要么去掉 Decoder,并且将它们堆得尽可能高。使用大量的训练文本,并投入大量的计算(数十万美元用于训练这些模型,在 AlphaStar 的例子中可能是数百万美元)。 43 | ![gpt-bert](./pictures/4-gpt-bert.webp)图:gpt-bert 44 | 45 | 46 | 我们可以将这些模块堆得多高呢?事实证明,这是区分不同的 GPT-2 的主要因素之一。 47 | 48 | ![gpt区分](./pictures/4-gpt-his2.webp)图:gpt区分 49 | 50 | ### 与 BERT 的一个不同之处 51 | 52 | ``` 53 | 机器人第一定律: 54 | 55 | 机器人不得伤害人类,也不能因不作为而使人类受到伤害。 56 | ``` 57 | 58 | GPT-2 是使用 Transformer 的 Decoder 模块构建的。另一方面,BERT 是使用 Transformer 的 Encoder 模块构建的。我们将在下一节中研究这种差异。但它们之间的一个重要差异是,GPT-2 和传统的语言模型一样,一次输出一个 token。例如,让一个训练好的 GPT-2 背诵机器人第一定律: 59 | 60 | ![gpt2 output](./pictures/4-gpt2-output.webp)图: gpt2 output 61 | 62 | 这些模型的实际工作方式是,在产生每个 token 之后,将这个 token 添加到输入的序列中,形成一个新序列。然后这个新序列成为模型在下一个时间步的输入。这是一种叫“自回归(auto-regression)”的思想。这种做法可以使得 RNN 非常有效。 63 | 64 | ![gpt2 output](./pictures/4-gpt2-output2.webp)图: gpt2 output 65 | 66 | GPT-2,和后来的一些模型如 TransformerXL 和 XLNet,本质上都是自回归的模型。但 BERT 不是自回归模型。这是一种权衡。去掉了自回归后,BERT 能够整合左右两边的上下文,从而获得更好的结果。XLNet 重新使用了 自回归,同时也找到一种方法能够结合两边的上下文。 67 | 68 | 69 | ### Transformer 模块的进化 70 | 71 | Transformer 原始论文(https://arxiv.org/abs/1706.03762) 介绍了两种模块: 72 | 73 | Encoder 模块 74 | 75 | 首先是 Encoder 模块。 76 | 77 | 78 | ![encoder](./pictures/4-encoder.webp)图: encoder 79 | 80 | 原始的 Transformer 论文中的 Encoder 模块接受特定长度的输入(如 512 个 token)。如果一个输入序列比这个限制短,我们可以填充序列的其余部分。 81 | 82 | Decoder 模块 83 | 84 | 其次是 Decoder。与 Encoder 相比,它在结构上有一个很小的差异:它有一个层,使得它可以关注来自 Encoder 特定的段。 85 | 86 | ![decoder](./pictures/4-decoder.webp)图: decoder 87 | 88 | 这里的 Self Attention 层的一个关注差异是,它会屏蔽未来的 token。具体来说,它不像 BERT 那样将单词改为mask,而是通过改变 Self Attention 的计算,阻止来自被计算位置右边的 token。 89 | 90 | 例如,我们想要计算位置 4,我们可以看到只允许处理以前和现在的 token。 91 | 92 | ![decoder只能看到以前和现在的token](./pictures/4-decoder1.webp)图: decoder只能看到以前和现在的token 93 | 94 | 很重要的一点是,(BERT 使用的)Self Attention 和 (GPT-2 使用的)masked Self Attention 有明确的区别。一个正常的 Self Attention 模块允许一个位置关注到它右边的部分。而 masked Self Attention 阻止了这种情况的发生: 95 | 96 | ![mask attention](./pictures/4-mask.png)图: mask attention 97 | 98 | 只有 Decoder 的模块 99 | 100 | 在 Transformer 原始论文发布之后,Generating Wikipedia by Summarizing Long Sequences(https://arxiv.org/pdf/1801.10198.pdf) 提出了另一种能够进行语言建模的 Transformer 模块的布局。这个模型丢弃了 Transformer 的 Encoder。因此,我们可以把这个模型称为 Transformer-Decoder。这种早期的基于 Transformer 的语言模型由 6 个 Decoder 模块组成。 101 | 102 | ![transformer-decoder](./pictures/4-trans-decoder.webp)图: transformer-decoder 103 | 104 | 这些 Decoder 模块都是相同的。我已经展开了第一个 Decoder,因此你可以看到它的 Self Attention 层是 masked 的。注意,现在这个模型可以处理多达 4000 个 token--是对原始论文中 512 个 token 的一个大升级。 105 | 106 | 这些模块和原始的 Decoder 模块非常类似,只是它们去掉了第二个 Self Attention 层。在 Character-Level Language Modeling with Deeper Self-Attention(https://arxiv.org/pdf/1808.04444.pdf) 中使用了类似的结构,来创建一次一个字母/字符的语言模型。 107 | 108 | OpenAI 的 GPT-2 使用了这些 Decoder 模块。 109 | 110 | ### 语言模型入门:了解 GPT2 111 | 112 | 让我们拆解一个训练好的 GPT-2,看看它是如何工作的。 113 | 114 | ![拆解GPT2](./pictures/4-gpt2-1.png)图:拆解GPT2 115 | 116 | GPT-2 能够处理 1024 个 token。每个 token 沿着自己的路径经过所有的 Decoder 模块 117 | 118 | 运行一个训练好的 GPT-2 模型的最简单的方法是让它自己生成文本(这在技术上称为 生成无条件样本)。或者,我们可以给它一个提示,让它谈论某个主题(即生成交互式条件样本)。在漫无目的情况下,我们可以简单地给它输入初始 token,并让它开始生成单词(训练好的模型使用 <|endoftext|> 作为初始的 token。我们称之为 \)。 119 | 120 | 121 | ![拆解GPT2初始token](./pictures/4-gpt2-start.webp)图:拆解GPT2初始token 122 | 123 | 模型只有一个输入的 token,因此只有一条活跃路径。token 在所有层中依次被处理,然后沿着该路径生成一个向量。这个向量可以根据模型的词汇表计算出一个分数(模型知道所有的 单词,在 GPT-2 中是 5000 个词)。在这个例子中,我们选择了概率最高的 the。但我们可以把事情搞混--你知道如果一直在键盘 app 中选择建议的单词,它有时候会陷入重复的循环中,唯一的出路就是点击第二个或者第三个建议的单词。同样的事情也会发生在这里,GPT-2 有一个 top-k 参数,我们可以使用这个参数,让模型考虑第一个词(top-k =1)之外的其他词。 124 | 125 | 下一步,我们把第一步的输出添加到我们的输入序列,然后让模型做下一个预测。 126 | 127 | 128 | ![拆解GPT2](./pictures/4-gpt2-the.gif)动态图:拆解GPT2 129 | 130 | 请注意,第二条路径是此计算中唯一活动的路径。GPT-2 的每一层都保留了它自己对第一个 token 的解释,而且会在处理第二个 token 时使用它(我们会在接下来关于 Self Attention 的章节中对此进行更详细的介绍)。GPT-2 不会根据第二个 token 重新计算第一个 token。 131 | 132 | 133 | ### 深入理解 GPT2 的更多细节 134 | **输入编码** 135 | 136 | 让我们更深入地了解模型。首先从输入开始。与之前我们讨论的其他 NLP 模型一样,GPT-2 在嵌入矩阵中查找输入的单词的对应的 embedding 向量--这是我们从训练好的模型中得到的组件之一。 137 | 138 | ![token embedding](./pictures/4-gpt-token.png)图:token embedding 139 | 140 | 每一行都是词的 embedding:这是一个数字列表,可以表示一个词并捕获一些含义。这个列表的大小在不同的 GPT-2 模型中是不同的。最小的模型使用的 embedding 大小是 768 141 | 142 | 因此在开始时,我们会在嵌入矩阵查找第一个 token \ 的 embedding。在把这个 embedding 传给模型的第一个模块之前,我们需要融入位置编码,这个位置编码能够指示单词在序列中的顺序。训练好的模型中,有一部分是一个矩阵,这个矩阵包括了 1024 个位置中每个位置的位置编码向量。 143 | 144 | ![位置编码](./pictures/4-gpt-pos.webp)图:位置编码 145 | 146 | 在这里,我们讨论了输入单词在传递到第一个 Transformer 模块之前,是如何被处理的。我们还知道,训练好的 GPT-2 包括两个权重矩阵。 147 | ![token+position](./pictures/4-gpt-token-pos.png)图: token+position 148 | 149 | 把一个单词输入到 Transformer 的第一个模块,意味着寻找这个单词的 embedding,并且添加第一个位置的位置编码向量 150 | 151 | **在这些层中向上流动** 152 | 153 | 第一个模块现在可以处理 token,首先通过 Self Attention 层,然后通过神经网络层。一旦 Transformer 的第一个模块处理了 token,会得到一个结果向量,这个结果向量会被发送到堆栈的下一个模块处理。每个模块的处理过程都是相同的,不过每个模块都有自己的 Self Attention 和神经网络层。 154 | 155 | ![向上流动](./pictures/4-gpt-fllow.webp)图:向上流动 156 | 157 | **回顾 Self-Attention** 158 | 159 | 语言严重依赖于上下文。例如,看看下面的第二定律: 160 | 161 | ``` 162 | 机器人第二定律 163 | 164 | 机器人必须服从人给予 它 的命令,当 该命令 与 第一定律 冲突时例外。 165 | ``` 166 | 167 | 我在句子中高亮了 3 个部分,这些部分的词是用于指代其他的词。如果不结合它们所指的上下文,就无法理解或者处理这些词。当一个模型处理这个句子,它必须能够知道: 168 | 169 | - 它 指的是机器人 170 | - 该命令 指的是这个定律的前面部分,也就是 人给予 它 的命令 171 | - 第一定律 指的是机器人第一定律 172 | 173 | 这就是 Self Attention 所做的事。它在处理某个词之前,将模型对这个词的相关词和关联词的理解融合起来(并输入到一个神经网络)。它通过对句子片段中每个词的相关性打分,并将这些词的表示向量加权求和。 174 | 175 | 举个例子,下图顶部模块中的 Self Attention 层在处理单词 `it` 的时候关注到` a robot`。它传递给神经网络的向量,是 3 个单词和它们各自分数相乘再相加的和。 176 | 177 | 178 | ![it的attention](./pictures/4-gpt-it.webp)图:it的attention 179 | 180 | **Self-Attention 过程** 181 | 182 | Self-Attention 沿着句子中每个 token 的路径进行处理,主要组成部分包括 3 个向量。 183 | 184 | - Query:Query 向量是当前单词的表示,用于对其他所有单词(使用这些单词的 key 向量)进行评分。我们只关注当前正在处理的 token 的 query 向量。 185 | - Key:Key 向量就像句子中所有单词的标签。它们就是我们在搜索单词时所要匹配的。 186 | - Value:Value 向量是实际的单词表示,一旦我们对每个词的相关性进行了评分,我们需要对这些向量进行加权求和,从而表示当前的词。 187 | 188 | ![query](./pictures/4-gpt-query.webp)图: query 189 | 一个粗略的类比是把它看作是在一个文件柜里面搜索,Query 向量是一个便签,上面写着你正在研究的主题,而 Key 向量就像是柜子里的文件夹的标签。当你将便签与标签匹配时,我们取出匹配的那些文件夹的内容,这些内容就是 Value 向量。但是你不仅仅是寻找一个 Value 向量,而是在一系列文件夹里寻找一系列 Value 向量。 190 | 191 | 将 Value 向量与每个文件夹的 Key 向量相乘,会为每个文件夹产生一个分数(从技术上来讲:就是点积后面跟着 softmax)。 192 | 193 | ![score](./pictures/4-gpt-score.webp)图: score 194 | 195 | 我们将每个 Value 向量乘以对应的分数,然后求和,得到 Self Attention 的输出。 196 | 197 | ![Self Attention 的输出](./pictures/4-gpt-out.webp)图:Self Attention 的输出 198 | 199 | 这些加权的 Value 向量会得到一个向量,它将 50% 的注意力放到单词 robot 上,将 30% 的注意力放到单词 a,将 19% 的注意力放到单词 it。在下文中,我们会更加深入 Self Attention,但现在,首先让我们继续在模型中往上走,直到模型的输出。 200 | 201 | **模型输出** 202 | 203 | 当模型顶部的模块产生输出向量时(这个向量是经过 Self Attention 层和神经网络层得到的),模型会将这个向量乘以嵌入矩阵。 204 | 205 | ![顶部的模块产生输出](./pictures/4-gpt-out1.webp)图:顶部的模块产生输出 206 | 207 | 回忆一下,嵌入矩阵中的每一行都对应于模型词汇表中的一个词。这个相乘的结果,被解释为模型词汇表中每个词的分数。 208 | 209 | ![token概率](./pictures/4-gpt-out3.webp)图:token概率 210 | 211 | 我们可以选择最高分数的 token(top_k=1)。但如果模型可以同时考虑其他词,那么可以得到更好的结果。所以一个更好的策略是把分数作为单词的概率,从整个列表中选择一个单词(这样分数越高的单词,被选中的几率就越高)。一个折中的选择是把 top_k 设置为 40,让模型考虑得分最高的 40 个词。 212 | 213 | ![top k选择输出](./pictures/4-gpt-out4.webp)图:top k选择输出 214 | 215 | 这样,模型就完成了一次迭代,输出一个单词。模型会继续迭代,直到所有的上下文都已经生成(1024 个 token),或者直到输出了表示句子末尾的 token。 216 | 217 | ### GPT2 总结 218 | 219 | 现在我们基本知道了 GPT-2 是如何工作的。如果你想知道 Self Attention 层里面到底发生了什么,那么文章接下来的额外部分就是为你准备的,我添加这个额外的部分,来使用更多可视化解释 Self Attention,以便更加容易讲解后面的 Transformer 模型(TransformerXL 和 XLNet)。 220 | 221 | 我想在这里指出文中一些过于简化的说法: 222 | 223 | - 我在文中交替使用 token 和 词。但实际上,GPT-2 使用 Byte Pair Encoding 在词汇表中创建 token。这意味着 token 通常是词的一部分。 224 | - 我们展示的例子是在推理模式下运行。这就是为什么它一次只处理一个 token。在训练时,模型将会针对更长的文本序列进行训练,并且同时处理多个 token。同样,在训练时,模型会处理更大的 batch size,而不是推理时使用的大小为 1 的 batch size。 225 | - 为了更加方便地说明原理,我在本文的图片中一般会使用行向量。但有些向量实际上是列向量。在代码实现中,你需要注意这些向量的形式。 226 | - Transformer 使用了大量的层归一化(layer normalization),这一点是很重要的。我们在图解Transformer中已经提及到了一部分这点,但在这篇文章,我们会更加关注 Self Attention。 227 | - 有时我需要更多的框来表示一个向量,例如下面这幅图: 228 | 229 | ![输入与输出维度](./pictures/4-gpt-sum.webp)图:输入与输出维度 230 | 231 | ## 可视化 Self-Attention 232 | 233 | 在这篇文章的前面,我们使用了这张图片来展示,如何在一个层中使用 Self Attention,这个层正在处理单词 `it`。 234 | 235 | ![it的attention](./pictures/4-att-it.png)图:it的attention 236 | 237 | 在这一节,我们会详细介绍如何实现这一点。请注意,我们会讲解清楚每个单词都发生了什么。这就是为什么我们会展示大量的单个向量。而实际的代码实现,是通过巨大的矩阵相乘来完成的。但我想把重点放在词汇层面上。 238 | 239 | ### Self-Attention 240 | 让我们先看看原始的 Self Attention,它被用在 Encoder 模块中进行计算。让我们看看一个玩具 Transformer,它一次只能处理 4 个 token。 241 | 242 | Self-Attention 主要通过 3 个步骤来实现: 243 | 244 | - 为每个路径创建 Query、Key、Value 矩阵。 245 | - 对于每个输入的 token,使用它的 Query 向量为所有其他的 Key 向量进行打分。 246 | - 将 Value 向量乘以它们对应的分数后求和。 247 | 248 | ![3步](./pictures/4-att-3.webp)图:3步 249 | 250 | (1) 创建 Query、Key 和 Value 向量 251 | 252 | 让我们关注第一条路径。我们会使用它的 Query 向量,并比较所有的 Key 向量。这会为每个 Key 向量产生一个分数。Self Attention 的第一步是为每个 token 的路径计算 3 个向量。 253 | 254 | ![第1步](./pictures/4-att-31.webp)图:第1步 255 | 256 | (2) 计算分数 257 | 258 | 现在我们有了这些向量,我们只对步骤 2 使用 Query 向量和 Value 向量。因为我们关注的是第一个 token 的向量,我们将第一个 token 的 Query 向量和其他所有的 token 的 Key 向量相乘,得到 4 个 token 的分数。 259 | 260 | ![第2步](./pictures/4-att-32.webp)图:第2步 261 | 262 | (3) 计算和 263 | 264 | 我们现在可以将这些分数和 Value 向量相乘。在我们将它们相加后,一个具有高分数的 Value 向量会占据结果向量的很大一部分。 265 | 266 | ![第3步](./pictures/4-att-33.webp)图:第3步 267 | 268 | 分数越低,Value 向量就越透明。这是为了说明,乘以一个小的数值会稀释 Value 向量。 269 | 270 | 如果我们对每个路径都执行相同的操作,我们会得到一个向量,可以表示每个 token,其中包含每个 token 合适的上下文信息。这些向量会输入到 Transformer 模块的下一个子层(前馈神经网络)。 271 | 272 | ![汇总](./pictures/4-att-34.webp)图:汇总 273 | 274 | 275 | ### 图解 Masked Self_attention 276 | 277 | 现在,我们已经了解了 Transformer 的 Self Attention 步骤,现在让我们继续研究 masked Self Attention。Masked Self Attention 和 Self Attention 是相同的,除了第 2 个步骤。假设模型只有 2 个 token 作为输入,我们正在观察(处理)第二个 token。在这种情况下,最后 2 个 token 是被屏蔽(masked)的。所以模型会干扰评分的步骤。它基本上总是把未来的 token 评分为 0,因此模型不能看到未来的词: 278 | 279 | ![masked self attention](./pictures/4-mask.webp)图:masked self attention 280 | 281 | 这个屏蔽(masking)经常用一个矩阵来实现,称为 attention mask。想象一下有 4 个单词的序列(例如,机器人必须遵守命令)。在一个语言建模场景中,这个序列会分为 4 个步骤处理--每个步骤处理一个词(假设现在每个词是一个 token)。由于这些模型是以 batch size 的形式工作的,我们可以假设这个玩具模型的 batch size 为 4,它会将整个序列作(包括 4 个步骤)为一个 batch 处理。 282 | 283 | ![masked 矩阵](./pictures/4-mask-matrix.webp)图:masked 矩阵 284 | 285 | 在矩阵的形式中,我们把 Query 矩阵和 Key 矩阵相乘来计算分数。让我们将其可视化如下,不同的是,我们不使用单词,而是使用与格子中单词对应的 Query 矩阵(或者 Key 矩阵)。 286 | 287 | ![Query矩阵](./pictures/4-mask-q.webp)图:Query矩阵 288 | 289 | 在做完乘法之后,我们加上三角形的 attention mask。它将我们想要屏蔽的单元格设置为负无穷大或者一个非常大的负数(例如 GPT-2 中的 负十亿): 290 | 291 | ![加上attetnion的mask](./pictures/4-mask-s.webp)图:加上attetnion的mask 292 | 293 | 然后对每一行应用 softmax,会产生实际的分数,我们会将这些分数用于 Self Attention。 294 | 295 | ![softmax](./pictures/4-mask-soft.webp)图:softmax 296 | 297 | 这个分数表的含义如下: 298 | 299 | - 当模型处理数据集中的第 1 个数据(第 1 行),其中只包含着一个单词 (robot),它将 100% 的注意力集中在这个单词上。 300 | - 当模型处理数据集中的第 2 个数据(第 2 行),其中包含着单词(robot must)。当模型处理单词 must,它将 48% 的注意力集中在 robot,将 52% 的注意力集中在 must。 301 | - 诸如此类,继续处理后面的单词。 302 | 303 | 304 | ### GPT2 的 Self-Attention 305 | 306 | 让我们更详细地了解 GPT-2 的 masked attention。 307 | 308 | *评价模型:每次处理一个 token* 309 | 310 | 我们可以让 GPT-2 像 mask Self Attention 一样工作。但是在评价评价模型时,当我们的模型在每次迭代后只添加一个新词,那么对于已经处理过的 token 来说,沿着之前的路径重新计算 Self Attention 是低效的。 311 | 312 | 在这种情况下,我们处理第一个 token(现在暂时忽略 \)。 313 | 314 | ![gpt2第一个token](./pictures/4-gpt2-self.png)图:gpt2第一个token 315 | 316 | GPT-2 保存 token `a` 的 Key 向量和 Value 向量。每个 Self Attention 层都持有这个 token 对应的 Key 向量和 Value 向量: 317 | 318 | ![gpt2的词a](./pictures/4-gpt2-a.png)图:gpt2的词a 319 | 320 | 现在在下一个迭代,当模型处理单词 robot,它不需要生成 token a 的 Query、Value 以及 Key 向量。它只需要重新使用第一次迭代中保存的对应向量: 321 | 322 | ![gpt2的词robot](./pictures/4-gpt2-r.png)图:gpt2的词robot 323 | 324 | `(1) 创建 Query、Key 和 Value 矩阵` 325 | 326 | 让我们假设模型正在处理单词 `it`。如果我们讨论最下面的模块(对于最下面的模块来说),这个 token 对应的输入就是 `it` 的 embedding 加上第 9 个位置的位置编码: 327 | 328 | ![处理it](./pictures/4-gpt2-it.webp)图:处理it 329 | 330 | Transformer 中每个模块都有它自己的权重(在后文中会拆解展示)。我们首先遇到的权重矩阵是用于创建 Query、Key、和 Value 向量的。 331 | 332 | ![处理it](./pictures/4-gpt2-it1.webp)图:处理it 333 | 334 | Self-Attention 将它的输入乘以权重矩阵(并添加一个 bias 向量,此处没有画出) 335 | 336 | 这个相乘会得到一个向量,这个向量基本上是 Query、Key 和 Value 向量的拼接。 337 | ![处理it](./pictures/4-gpt2-it2.webp)图:处理it 338 | 339 | 340 | 将输入向量与 attention 权重向量相乘(并加上一个 bias 向量)得到这个 token 的 Key、Value 和 Query 向量拆分为 attention heads。 341 | 342 | 在之前的例子中,我们只关注了 Self Attention,忽略了 multi-head 的部分。现在对这个概念做一些讲解是非常有帮助的。Self-attention 在 Q、K、V 向量的不同部分进行了多次计算。拆分 attention heads 只是把一个长向量变为矩阵。小的 GPT-2 有 12 个 attention heads,因此这将是变换后的矩阵的第一个维度: 343 | 344 | ![处理it](./pictures/4-gpt2-it3.png)图:处理it 345 | 346 | 在之前的例子中,我们研究了一个 attention head 的内部发生了什么。理解多个 attention-heads 的一种方法,是像下面这样(如果我们只可视化 12 个 attention heads 中的 3 个): 347 | 348 | 349 | ![处理it](./pictures/4-gpt2-it4.webp)图:处理it 350 | 351 | `(2) 评分` 352 | 353 | 我们现在可以继续进行评分,这里我们只关注一个 attention head(其他的 attention head 也是在进行类似的操作)。 354 | 355 | ![](./pictures/4-gpt2-it5.webp)图:处理it 356 | 357 | 现在,这个 token 可以根据其他所有 token 的 Key 向量进行评分(这些 Key 向量是在前面一个迭代中的第一个 attention head 计算得到的): 358 | 359 | ![](./pictures/4-gpt2-it6.webp)图: 360 | 361 | `(3) 求和` 362 | 363 | 正如我们之前所看的那样,我们现在将每个 Value 向量乘以对应的分数,然后加起来求和,得到第一个 attention head 的 Self Attention 结果: 364 | 365 | ![处理it](./pictures/4-gpt2-it7.webp)图: 366 | 367 | `合并 attention heads` 368 | 369 | 我们处理各种注意力的方法是首先把它们连接成一个向量: 370 | 371 | ![处理it](./pictures/4-gpt2-it8.webp)图:处理it 372 | 373 | 但这个向量还没有准备好发送到下一个子层(向量的长度不对)。我们首先需要把这个隐层状态的巨大向量转换为同质的表示。 374 | 375 | `(4) 映射(投影)` 376 | 377 | 我们将让模型学习如何将拼接好的 Self Attention 结果转换为前馈神经网络能够处理的形状。在这里,我们使用第二个巨大的权重矩阵,将 attention heads 的结果映射到 Self Attention 子层的输出向量: 378 | 379 | ![映射](./pictures/4-project.png)图:映射 380 | 381 | 通过这个,我们产生了一个向量,我们可以把这个向量传给下一层: 382 | 383 | ![传给下一层](./pictures/4-vector.webp)图:传给下一层 384 | 385 | ### GPT-2 全连接神经网络 386 | 387 | `第 1 层` 388 | 389 | 全连接神经网络是用于处理 Self Attention 层的输出,这个输出的表示包含了合适的上下文。全连接神经网络由两层组成。第一层是模型大小的 4 倍(由于 GPT-2 small 是 768,因此这个网络会有 个神经元)。为什么是四倍?这只是因为这是原始 Transformer 的大小(如果模型的维度是 512,那么全连接神经网络中第一个层的维度是 2048)。这似乎给了 Transformer 足够的表达能力,来处理目前的任务。 390 | 391 | 392 | ![全连接层](./pictures/4-full.gif)动态图:全连接层 393 | 394 | 没有展示 bias 向量 395 | 396 | `第 2 层. 把向量映射到模型的维度` 397 | 398 | 第 2 层把第一层得到的结果映射回模型的维度(在 GPT-2 small 中是 768)。这个相乘的结果是 Transformer 对这个 token 的输出。 399 | 400 | ![全连接层](./pictures/4-full.webp)图:全连接层 401 | 402 | 没有展示 bias 向量 403 | 404 | 你完成了! 405 | 406 | 这就是我们讨论的 Transformer 的最详细的版本!现在,你几乎已经了解了 Transformer 语言模型内部发生了什么。总结一下,我们的输入会遇到下面这些权重矩阵: 407 | 408 | ![总结](./pictures/4-sum.png)图: 409 | 410 | 每个模块都有它自己的权重。另一方面,模型只有一个 token embedding 矩阵和一个位置编码矩阵。 411 | 412 | 413 | ![总结](./pictures/4-sum1.png)图:总结 414 | 415 | 如果你想查看模型的所有参数,我在这里对它们进行了统计: 416 | 417 | ![总结](./pictures/4-sum2.png)图:总结 418 | 由于某些原因,它们加起来是 124 M,而不是 117 M。我不确定这是为什么,但这个就是在发布的代码中展示的大小(如果我错了,请纠正我)。 419 | 420 | ## 语言模型之外 421 | 422 | 只有 Decoder 的 Transformer 在语言模型之外一直展现出不错的应用。它已经被成功应用在了许多应用中,我们可以用类似上面的可视化来描述这些成功应用。让我们看看这些应用,作为这篇文章的结尾。 423 | 424 | ### 机器翻译 425 | 426 | 进行机器翻译时,Encoder 不是必须的。我们可以用只有 Decoder 的 Transformer 来解决同样的任务: 427 | 428 | ![翻译](./pictures/4-trans.png)图:翻译 429 | 430 | ### 生成摘要 431 | 432 | 这是第一个只使用 Decoder 的 Transformer 来训练的任务。它被训练用于阅读一篇维基百科的文章(目录前面去掉了开头部分),然后生成摘要。文章的实际开头部分用作训练数据的标签: 433 | ![摘要](./pictures/4-wiki.png)图: 434 | 435 | 论文里针对维基百科的文章对模型进行了训练,因此这个模型能够总结文章,生成摘要: 436 | 437 | ![摘要](./pictures/4-wiki1.webp)图:摘要 438 | 439 | ### 迁移学习 440 | 441 | 在 Sample Efficient Text Summarization Using a Single Pre-Trained Transformer(https://arxiv.org/abs/1905.08836) 中,一个只有 Decoder 的 Transformer 首先在语言模型上进行预训练,然后微调进行生成摘要。结果表明,在数据量有限制时,它比预训练的 Encoder-Decoder Transformer 能够获得更好的结果。 442 | 443 | GPT-2 的论文也展示了在语言模型进行预训练的生成摘要的结果。 444 | 445 | ### 音乐生成 446 | 447 | Music Transformer(https://magenta.tensorflow.org/music-transformer) 论文使用了只有 Decoder 的 Transformer 来生成具有表现力的时序和动态性的音乐。音乐建模 就像语言建模一样,只需要让模型以无监督的方式学习音乐,然后让它采样输出(前面我们称这个为 漫步)。 448 | 449 | 你可能会好奇在这个场景中,音乐是如何表现的。请记住,语言建模可以把字符、单词、或者单词的一部分(token),表示为向量。在音乐表演中(让我们考虑一下钢琴),我们不仅要表示音符,还要表示速度--衡量钢琴键被按下的力度。 450 | 451 | ![音乐生成](./pictures/4-music.webp)图:音乐生成 452 | 453 | 一场表演就是一系列的 one-hot 向量。一个 midi 文件可以转换为下面这种格式。论文里使用了下面这种输入序列作为例子: 454 | 455 | ![音乐生成](./pictures/4-music1.png)图:音乐生成 456 | 457 | 458 | 这个输入系列的 one-hot 向量表示如下: 459 | 460 | ![音乐生成](./pictures/4-music2.png)图:音乐生成 461 | 462 | 我喜欢论文中的音乐 Transformer 展示的一个 Self Attention 的可视化。我在这基础之上添加了一些注释: 463 | 464 | ![音乐生成](./pictures/4-music3.png)图:音乐生成 465 | 466 | 这段音乐有一个反复出现的三角形轮廓。Query 矩阵位于后面的一个峰值,它注意到前面所有峰值的高音符,以知道音乐的开头。这幅图展示了一个 Query 向量(所有 attention 线的来源)和前面被关注的记忆(那些受到更大的softmax 概率的高亮音符)。attention 线的颜色对应不同的 attention heads,宽度对应于 softmax 概率的权重。 467 | 468 | ## 总结 469 | 470 | 现在,我们结束了 GPT-2 的旅程,以及对其父模型(只有 Decoder 的 Transformer)的探索。我希望你看完这篇文章后,能对 Self Attention 有一个更好的理解,也希望你能对 Transformer 内部发生的事情有更多的理解。 471 | 472 | -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/1-2-translation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/1-2-translation.gif -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/1-3-encoder-decoder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/1-3-encoder-decoder.gif -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/1-4-context-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/1-4-context-example.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/1-5-word-vector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/1-5-word-vector.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/1-6-rnn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/1-6-rnn.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/1-7-attetion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/1-7-attetion.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/1-8-attention-vis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/1-8-attention-vis.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/1-seq2seq.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/1-seq2seq.gif -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-2layer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-2layer.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-6words.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-6words.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-8z.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-8z.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-all-att.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-all-att.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-am.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-am.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-attention-output.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-attention-output.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-attention-word.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-attention-word.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-decoder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-decoder.gif -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-decoder.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-decoder.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-encoder-decoder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-encoder-decoder.gif -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-encoder-decoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-encoder-decoder.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-encoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-encoder.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-input-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-input-output.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-it-attention.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-it-attention.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-linear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-linear.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-loss.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-loss.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-lyn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-lyn.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-multi-encoder.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-multi-encoder.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-multi-head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-multi-head.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-positin4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-positin4.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-position.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-position.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-position2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-position2.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-position3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-position3.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-put-together.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-put-together.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-qkv-multi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-qkv-multi.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-qkv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-qkv.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-resnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-resnet.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-sum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-sum.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-target.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-think.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-think.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-think2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-think2.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-to1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-to1.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-trained.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-trained.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-trans-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-trans-example.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-transformer-stru.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-transformer-stru.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-transformer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-transformer.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-translation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-translation.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-x-encoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-x-encoder.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/2-x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/2-x.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-2sent.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-2sent.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-app.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-bl.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-bl.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-cls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-cls.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-clss.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-clss.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-elmo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-elmo.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-encoder.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-encoder.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-fea.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-fea.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-feature.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-input.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-mask.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-mask.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert-output.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-bert.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-cnn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-cnn.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo-emb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo-emb.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo-pre.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo-pre.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo-pre1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo-pre1.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo-pre2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo-pre2.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-elmo.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-openai-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-openai-down.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-openai-method.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-openai-method.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-openai-next.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-openai-next.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-openai.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-openai.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-single-vector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-single-vector.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-stru.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-stru.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-trash.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/3-wordvector.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/3-wordvector.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-3.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-31.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-31.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-32.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-32.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-33.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-33.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-34.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-34.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-it.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-att-it.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-decoder.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-decoder.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-decoder1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-decoder1.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-encoder.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-encoder.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-full.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-full.gif -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-full.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-full.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-bert.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-bert.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-fllow.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-fllow.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-his.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-his.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-his2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-his2.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-it.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-it.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-out.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-out.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-out1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-out1.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-out3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-out3.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-out4.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-out4.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-pos.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-pos.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-query.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-query.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-score.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-score.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-sum.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-sum.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-token-pos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-token-pos.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt-token.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-1.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-a.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it1.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it2.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it3.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it4.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it4.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it5.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it5.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it6.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it6.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it7.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it7.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it8.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-it8.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-output.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-output.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-output2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-output2.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-r.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-self.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-self.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-start.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-start.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-the.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-gpt2-the.gif -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask-matrix.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask-matrix.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask-q.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask-q.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask-s.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask-s.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask-soft.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask-soft.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-mask.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-music.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-music.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-music1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-music1.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-music2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-music2.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-music3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-music3.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-project.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-stru.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-stru.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-sum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-sum.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-sum1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-sum1.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-sum2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-sum2.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-trans-decoder.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-trans-decoder.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-trans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-trans.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-transformer.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-transformer.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-vector.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-vector.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-wiki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-wiki.png -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-wiki1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-wiki1.webp -------------------------------------------------------------------------------- /docs/深度学习模型基础/transformer基本原理讲解/pictures/4-word2vec.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erenup/deeplearningbasics/a51fee97bb3b1e52b4f8303fabf3efe598065e62/docs/深度学习模型基础/transformer基本原理讲解/pictures/4-word2vec.webp --------------------------------------------------------------------------------