配合阅读:python
笔者在[深度概念]·Attention机制概念学习笔记博文中,讲解了Attention机制的概念与技术细节,本篇内容配合讲解,使用Keras实现Self-Attention文本分类,来让你们更加深刻理解Attention机制。bash
做为对比,能够访问[TensorFlow深度学习深刻]实战三·分别使用DNN,CNN与RNN(LSTM)作文本情感分析,查看不一样网络区别与联系。网络
了解了模型大体原理,咱们能够详细的看一下究竟Self-Attention结构是怎样的。其基本结构以下app
对于self-attention来说,Q(Query), K(Key), V(Value)三个矩阵均来自同一输入,首先咱们要计算Q与K之间的点乘,而后为了防止其结果过大,会除以一个尺度标度 学习
这里可能比较抽象,咱们来看一个具体的例子(图片来源于https://jalammar.github.io/illustrated-transformer/,该博客讲解的极其清晰,强烈推荐),假如咱们要翻译一个词组Thinking Machines,其中Thinking的输入的embedding vector用 ui
当咱们处理Thinking这个词时,咱们须要计算句子中全部词与它的Attention Score,这就像将当前词做为搜索的query,去和句子中全部词(包含该词自己)的key去匹配,看看相关度有多高。咱们用 spa
显然,当前单词与其自身的attention score通常最大,其余单词根据与当前单词重要程度有相应的score。而后咱们在用这些attention score与value vector相乘,获得加权的向量。.net
若是将输入的全部向量合并为矩阵形式,则全部query, key, value向量也能够合并为矩阵形式表示
其中
笔者使用Keras来实现对于Self_Attention模型的搭建,因为网络中间参数量比较多,这里采用自定义网络层的方法构建Self_Attention,关于如何自定义Keras能够参看这里:编写你本身的 Keras 层
Keras实现自定义网络层。须要实现如下三个方法:(注意input_shape是包含batch_size项的
)
build(input_shape)
: 这是你定义权重的地方。这个方法必须设 self.built = True
,能够经过调用 super([Layer], self).build()
完成。call(x)
: 这里是编写层的功能逻辑的地方。你只须要关注传入 call
的第一个参数:输入张量,除非你但愿你的层支持masking。compute_output_shape(input_shape)
: 若是你的层更改了输入张量的形状,你应该在这里定义形状变化的逻辑,这让Keras可以自动推断各层的形状。实现代码以下:
这里能够对照一中的概念讲解来理解代码
若是将输入的全部向量合并为矩阵形式,则全部query, key, value向量也能够合并为矩阵形式表示
上述内容对应
其中
上述内容对应(为何使用batch_dot呢?这是因为input_shape是包含batch_size项的
)
这里 QK = QK / (64**0.5) 是除以一个归一化系数,(64**0.5)是笔者本身定义的,其余文章可能会采用不一样的方法。
项目完整代码以下,这里使用的是Keras自带的imdb影评数据集