点击上方,选择星标置顶,每天给你送干货!


来自:CS的陋室

近期我会一连几篇谈谈bert中的关键细节,这个position encoding是我看到的bert(实质上是transformer中提出的)中最为惊喜的但是却被很多人忽略(可以理解为媒体鼓吹最少的)一个细节,这里给大家谈谈。

什么是position encoding

顾名思义,就是基于位置的一套词嵌入方法,说得简单点,就是对于一个句子,都有对应的一个向量。

position encoding的收益

我感觉要做一个事情,首先还是要看他的出发点和收益,说白了就是优点是啥,做这个的目标是啥,这样我们才知道怎么做。

回头看看CNN结构、RNN甚至是transformer的self-attention,其实都没有特别关注位置信息,而实际上,我们却是需要去关注的,毕竟作为一门语言,他大都有比较严谨的语法结构,特定词汇还真的会出现在特定位置,这是非常有意思的,来看看例子(来源于知乎):

I like this movie because it doesn't have an overhead history. I don't like this movie because it has an overhead history.

从情感上,上面是正面,下面是负面,这个非常显而易见,因为这个否定句,从实体提取的角度都有movie和history,无论是哪个任务,都可以看到一个语法结构中存在的位置信息。

对CNN,只能考虑到固定前后的局部信息,RNN能考虑稍微长期的信息,LSTM是有重点的记录,Transformer只能考虑到全局的信息,尤其在bert中,只用了transformer encoder,模型上就完全丧失对位置信息的描述了,因此引入基于位置的特征就可能在特定任务中产生收益。

换个角度再看一个例子:

I believe I can be the best.

对于self attention,如果没有positional encoding,两个i的输出将会一样,但是我们知道,这两个i是存在区别的,不是在指代上,而是含义上,第一个i是观点的发出者,“不要你觉得,我要我觉得”,第二个i是观点的对象,“认为我会是最棒的,不是别人”,所以从语义上两者就有所区别了,权重向量完全一样可就有问题了吧。这也是缺少位置信息的缺憾。

position embedding怎么做

首先,最简单的模式就是对词向量矩阵直接加一层全连接层,就是全连接层。就真的是这么简单!

对于每个位置的词向量,都稳定的乘以一个稳定的向量,就如上面所示,第1个位置一定对应positonal embedding的第一个向量,那这组向量抽出来,不是positional embedding是啥。

但当然的,这里就有很大的问题,那就是这只是绝对位置,看上面第一个例子(我再搬运一遍):

I like this movie because it doesn't have an overhead history. I don't like this movie because it has an overhead history.

这里的like 和 don't like可就不是一个位置了吧,所以绝对位置肯定是有问题的,那么就要引入相对位置的概念了。来看看transformer论文里面是怎么说的(我把解释也给大家搬过来了):

这里用的是两种三角函数,可以说是非常巧妙了,我们来慢慢分析。上代码!

import matplotlib.pyplot as plt
import math
def positional_enc(i,pos):
return math.sin(pos /10000**(i/100))
x = []
for idx in range(10):tmp_x = list(range(1,100))tmp_y = [positional_enc(i, idx) for i in tmp_x]plt.plot(tmp_x,tmp_y,label=str(idx))
plt.legend(loc = 'upper right')
plt.show()

代码跑出来是这样的:

横坐标是维数上的每个值,纵坐标是对应的sin值,图例对应句子中的每个位置。

首先看维数位置-sin值之间的关系,很明显,我们没有发现周期性,最终往0处收敛,我们也可以知道了,在这种emcoding下,其实维数没必要太高了。

而对于位置-sini值之间的关系,可以整个曲线是会朝着右边移动的,从权重角度看,实质上就是每一个维度都会有一个比较看重的句子位置,其他位置说白了就是不看了,而前面的甚至可能为负,主要原因是要抛弃以前的信息,这样多个维度就能把多个位置都当做了重点来看。

周期性去了哪里呢,其实在这里,再来上代码:

import matplotlib.pyplot as plt
import math
def positional_emb(i,pos):
return math.sin(pos /10000**(i/100))
tmp_x = list(range(20))
tmp_y = [positional_emb(10, i) for i in tmp_x]
plt.plot(tmp_x,tmp_y)
plt.show()

得到了有周期性的图。

周期性只体现在位置和整个函数结果的关系,而具体的波长,其实是由positional encoding向量决定的。

不得不说,这个函数的设计可谓是对现实场景有了十分充分的理解,抽象非常精准。

预测效果

首先来看看两种positional encoding的具体效果,来自transformer的对比。

主要看E、base和big。其实可以看到posiitional emb本身的效果其实还行,与base相当,说明还是有不小收益的。

来看看源码

原理是看完了,来看看源码吧。

def positional_encoding(inputs,maxlen,masking=True,scope="positional_encoding"):
'''Sinusoidal Positional_Encoding. See 3.5inputs: 3d tensor. (N, T, E)maxlen: scalar. Must be >= Tmasking: Boolean. If True, padding positions are set to zeros.scope: Optional scope for `variable_scope`.returns3d tensor that has the same shape as inputs.'''E = inputs.get_shape().as_list()[-1] # staticN, T = tf.shape(inputs)[0], tf.shape(inputs)[1] # dynamic
with tf.variable_scope(scope, reuse=tf.AUTO_REUSE):
# position indicesposition_ind = tf.tile(tf.expand_dims(tf.range(T), 0), [N, 1]) # (N, T)
# First part of the PE function: sin and cos argumentposition_enc = np.array([
[pos / np.power(10000, (i-i%2)/E) for i in range(E)]
for pos in range(maxlen)])
# Second part, apply the cosine to even columns and sin to odds.position_enc[:, 0::2] = np.sin(position_enc[:, 0::2])  # dim 2iposition_enc[:, 1::2] = np.cos(position_enc[:, 1::2])  # dim 2i+1position_enc = tf.convert_to_tensor(position_enc, tf.float32) # (maxlen, E)
# lookupoutputs = tf.nn.embedding_lookup(position_enc, position_ind)
# masks
if masking:outputs = tf.where(tf.equal(inputs, 0), inputs, outputs)
return tf.to_float(outputs)

本身公式上没有想象的复杂,但是这里面其实展现了很多python相关的技巧。

  • 这里的计算并非全都使用的tf,对positionenc,前面用numpy进行计算,然后用embeddinglookup的方式引入。

  • position_enc[:,0::2]和 position_enc[:,1::2]来自numpy语法,避免了写循环和条件语句就能够完成奇数偶数计算。

  • 另外是有很多可能在各种教材或者教程中没有的函数工具,大家可以多看看学学。

    • tf.AUTO_REUSE:批量化共享变量作用域的方法。

    • tf.tile():张量扩展,对当前张量内的数据进行一定规则的复制,保证输出张量维度不变。

说个正事哈

由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:

(1)点击页面最上方深度学习自然语言处理”,进入公众号主页。

(2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。

感谢支持,比心

投稿或交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。

方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等。

记得备注呦

推荐两个专辑给大家:

专辑 | 李宏毅人类语言处理2020笔记

专辑 | NLP论文解读

专辑 | 情感分析


整理不易,还望给个在看!

bert之我见 - positional encoding相关推荐

  1. positional encoding位置编码详解:绝对位置与相对位置编码对比

    目录 前言 Why What 绝对位置编码 相对位置编码 Sinusoidal Position Encoding Complex embedding How 前言 相信熟悉BERT的小伙伴对posi ...

  2. 【AI理论学习】对Transformer中Positional Encoding的理解

    对Transformer中Positional Encoding的理解 1. 什么是Positional Encoding?为什么Transformer需要使用Positional Encoding? ...

  3. transformer:self-attention,muti-head attention,positional encoding

    文章目录 transformer和RNN.LSTM相比 seq2seq 编码器-解码器架构 What is Input? What is Output? N-N:each vector has a l ...

  4. 基于Transformer的文本情感分析编程实践(Encoder编码器-Decoder解码器框架 + Attention注意力机制 + Positional Encoding位置编码)

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) Encoder编码器-Decoder解码器框架 + Atten ...

  5. 如何理解Transformer论文中的positional encoding,和三角函数有什么关系?

    https://www.zhihu.com/question/347678607/answer/864217252

  6. 陋室快报 | BERT学习指导-20211026

    [陋室推荐] 陋室快报是对陋室推荐栏目更新优化后的版本,更快更准的给大家推荐优质信息,频率预计是一周一次.敬请关注. 近期,我再次总结了我的历史文章,累积起来有50w字,百余篇文章了,有兴趣可以拿来看 ...

  7. 【研一小白的白话理解】BERT

    BERT 上一篇博客通过一篇论文已经介绍了迁移学习和计算机视觉,然而迁移学习在自然语言处理(NLP)同样很强.通过迁移学习训练出来的模型叫做预训练模型,预训练模型首先要针对数据丰富的任务进行预训练,然 ...

  8. NLP领域近期有哪些值得读的开源论文?(附下载)

    来源:PaperWeekly 本文约3300字,建议阅读8分钟. 本文为你分享10篇值得读的NLP论文,带源代码的那种~ @paperweekly 推荐 #Relation Extraction 本文 ...

  9. NLP领域近期有哪些值得读的开源论文?

    在碎片化阅读充斥眼球的时代,越来越少的人会去关注每篇论文背后的探索和思考. 在这个栏目里,你会快速 get 每篇精选论文的亮点和痛点,时刻紧跟 AI 前沿成果. 点击本文底部的「阅读原文」即刻加入社区 ...

  10. 史上最小白之Transformer详解

    1.前言 博客分为上下两篇,您现在阅读的是下篇史上最小白之Transformer详解,在阅读该篇博客之前最好你能够先明白Encoder-Decoder,Attention机制,self-Attenti ...

最新文章

  1. 奥卡姆剃刀是什么?机器学习实践中那些学习模型或者那些评估指标践行了这一理论?
  2. python中国地图热力图是什么意思_python实现输入的数据在地图上生成热力图效果...
  3. 团队作业5-测试与发布(AIpha版本)
  4. 自己做的一个小程序 可采集、导出、模板、配置
  5. CodeFrist基础_迁移更新数据
  6. Mac OS安装octave出现的问题-'error:terminal type set to 'unknown'的解决'
  7. Android之在linux终端执行shell脚本文件(通过aapt)得到apk包名
  8. 【转载】4412开发板、PC、ubuntu通过网线连接
  9. .Net Framework System.Collections 集合类
  10. 十大程序员最实用的技术社区网站
  11. 反思:安全需要新体系
  12. 老毛桃装机版制作启动U盘图文教程
  13. 昆明理工大学知道计算机答案,昆明理工大学 计算机基础教材参考答案(1-6章)
  14. [Error] expected declaration or statement at end of input
  15. 单源路径分支界限java_java实现单源最短路径
  16. HTTP 调用 WebService、CXF 动态调用 WebService
  17. 【渝粤教育】广东开放大学 大学英语2 形成性考核 (39)
  18. 看美国人竟然是这样教育小学生的
  19. 二进制除法教程计算机基础,计算机应用基础第四章《二进制的学习》课件.ppt...
  20. Node.js | 全栈开发必经之路

热门文章

  1. solr学习篇(三) solr7.4 连接MySQL数据库
  2. 一张表搞懂各种 Docker 监控方案 - 每天5分钟玩转 Docker 容器技术(86)
  3. RuntimeException
  4. EntityFramework Code-First 简易教程(八)-------一对一
  5. Tomcat部署记事
  6. 【C语言】为什么指明数组的列数?
  7. android 异步加载图片缩略图
  8. C#捕获控制台(console)关闭事件
  9. C# 0xC0000005 捕获
  10. 微信开发之调起摄像头、本地展示图片、上传下载图片