元学习—神经图灵机
1 神经图灵机
神经图灵机(NTM)是一类能够从内存中存储和恢复信息的一个算法。神经图灵机的基本思路在额外的内存空间中增加神经网络,而不是通过增加隐藏单元 ,NTM使用一个额外的内存来存储和恢复信息。NTM的整体结构如下图所示:
1.1 NTM的基本组成
控制器: 这是一个基础的前馈神经网络或者递归神经网络,其主要负责从内存中读取信息或者想内存中写入信息。
内存: 内存通常以内存矩阵或者内存池的形式进行展现。我们将在内存中存储信息。一般情况下,内存是通过两个维度的矩阵所构成,矩阵中的每一个元素是一个内存细胞。整个内存矩阵包括N行M列。通过使用控制器,我们可以从内存中获取信息,因此,控制器可以从额外的环境中接受内容,并且能够通过与内存矩阵的交互来做出反应。
读头和写头: 读头和写头是包含内存地址的两个指针,内存地址指的是需要读取的地址和需要写入的地址。
在了解了基本结构之后,我们首先来思考第一个问题,控制器应该以什么样的策略来从内存中获取相关的信息?
最简单的策略是通过记录内存矩阵中行和列的地址来位置index,进而通过索引来访问和写入到内存矩阵。当时这样存在一个问题,由于我们不能通过一个索引来执行梯度下降算法,所以我们利用这种方式就无法利用梯度下降算法来更新参数。所以NTM的作者就定义了基于读头和写头的模糊操作。这种模糊操作和内存中的部分信息进行交互。该操作的核心在于利用Attention机制来重点关注于内存的局部那些对于读写重要的信息,而忽略内存中的其他位置。因此,我们可以使用一个特殊的读和写操作来决定那些区域需要进行关注。
1.2 NTM中的读操作
在上一小节中我们提到了,我们需要定义一种特殊的读操作来从内存中选择相对比较重要的信息,那么具体应该如何选择呢?
首先,我们给出一个能够决定内存信息重要性的 权重向量,这里记为
w
t
w_t
wt,
w
t
w_t
wt是一个0到1的概率分布,通过具体的概率值,我们可以判断内存对应位置信息的重要性。即:
∑
i
w
t
(
i
)
=
1
0
<
w
t
(
i
)
<
1
∑_iw_t(i)=1\ \ \ \ \ 0<w_t(i)<1
i∑wt(i)=1 0<wt(i)<1
其中i表示的权重向量
w
t
w_t
wt的索引。我们的内存包含了N行M列,进一步,我们将我们的内存矩阵表示为
M
t
M_t
Mt。如下图所示:
现在,我们拥有了表示重要性的权重向量,同时也拥有了表示内存的原始的内存矩阵,我们下一步要做的就是将二者做一个简单的线性组合。具体如下图所示:
进一步,我们用公式表达一下:
r
t
=
∑
i
w
t
(
i
)
M
t
(
i
)
r_t=∑_iw_t(i)M_t(i)
rt=i∑wt(i)Mt(i)
不难发现,内存矩阵的维度为N行M列,那么我们的读取矩阵就定义为一个维度为N的向量。最后我们可以得到一个列向量。例如,根据上图所示,我们可以定义权重向量为:
1.3 NTM中的写操作
与读取操作不同的是,NTM中的写操作中具体定义了两个操作,一个是擦除操作,另外一个是写入的操作。两个操作分别负责擦除就得信息和写入新的信息。
1.3.1 擦除操作
我们使用擦除操作从内存中移除不在需要的数据。在执行完擦除操作之后。我们将会有一个新的的更新之后的内存矩阵。其中某些数据已经被擦除。下面,我们来介绍如何擦除内存区域的数据。
首先,我们定义一个用于控制擦除特定区域的数据的向量 e t e_t et,该向量的维度和权重向量 w t w_t wt的维度相同。擦除向量 e t e_t et中的元素值非0即1。
下一步,我们定义内存矩阵的更新公式为:
M
t
∗
(
i
)
=
(
1
−
w
t
(
i
)
e
t
)
M
t
−
1
(
i
)
M_t^*(i)=(1-w_t(i)e_t)M_{t-1}(i)
Mt∗(i)=(1−wt(i)et)Mt−1(i)
简单的解释一下,首先,我们先计算的是
w
t
(
i
)
e
t
w_t(i)e_t
wt(i)et,举个例子来说:
下面,我们计算
1
−
(
w
t
(
i
)
e
t
)
1-(w_t(i)e_t)
1−(wt(i)et)
计算完这一步之后,结果中非零的值极为需要保留的值。下一步,将该结果和上一个时刻的矩阵相乘,即可获得下一个时刻的结果:
1.3.2 写入操作
在完成擦除操作之后,我们就可以获得更新之后的结果矩阵。矩阵中的某些元素被擦除,下一步,我们就将新的数据写入到矩阵中去。我们来介绍具体的步骤。
- 首先,我们将定义一个写入向量
a
t
a_t
at,其值将被写入到内存矩阵中去。其写入公式为:
M t ( i ) = M t ∗ ( i ) + w t ( i ) a t M_t(i)=M_t^*(i)+w_t(i)a_t Mt(i)=Mt∗(i)+wt(i)at
1.4 NTM的寻址机制
在上面的介绍中,我们介绍了如何利用权重向量
w
t
w_t
wt来进行读写操作,那么下面我们来具体介绍权重向量的生成过程,实际上,我们利用Attention机制和不同的寻址机制来进行计算。
而NTM的寻址机制包括两种情况,分别为:
- 基于内容的寻址
- 基于局部的寻址
1.4.1 基于内容的寻址机制
在基于内容的寻址机制中,我们利用的是内存的相似性来进行计算的。此时,控制器中给定一个关键向量,称为
k
t
k_t
kt,我们利用这个向量
k
t
k_t
kt来和内存矩阵
M
t
M_t
Mt中的每一行进行比较,为了计算相似性,这里我们使用的是consine相似度的计算机制。其具体表示为:
c
o
n
s
i
n
e
[
k
t
,
M
t
]
=
k
t
⋅
M
t
∣
k
t
∣
⋅
∣
M
t
∣
consine[k_t,M_t]=\frac{k_t·M_t}{|k_t|·|M_t|}
consine[kt,Mt]=∣kt∣⋅∣Mt∣kt⋅Mt
下一步,我们引入一个新的参数β,称为关键长度,这个参数决定了如何压缩权重向量。基于参数β的值,我们增加或者减少注意力,这样可以可以将我们的注意力转移到关键的区域之上。当参数β的值比较小,我们均衡的关注这些局部区域,当参数β的值比较大的时候,我们将更加关注于某一个局部区域。
因此,我们的权重向量的计算公式为:
w
t
c
=
β
t
c
o
n
s
i
n
e
[
k
t
,
M
t
(
i
)
]
w_t^c=β_tconsine[k_t,M_t(i)]
wtc=βtconsine[kt,Mt(i)]
然后,我们基于这个结果来计算cosine相似度:
在上述公式中,c表示的是基于内容的权重向量。
1.4.2 基于位置的寻址
在基于位置的寻址中,我们一共需要三个步骤:
- 插入 Interpolation
- 卷积移位 Convolution shift
- 锐化 sharpening
首先,插入操作决定了是否我们应该使用上一个时刻获取的权重向量
w
t
−
1
w_{t-1}
wt−1,或者是使用基于当前时刻基于内容获取的权重向量
w
t
c
w_t^c
wtc,为了完成这种选择,我们引入一个新的标量参数
g
t
g_t
gt,该值被用来对两种权重向量的选择,其取值非0即1。其计算公式为:
w
t
g
=
g
t
w
t
c
+
(
1
−
g
t
)
w
t
−
1
w_t^g=g_tw^c_t+(1-g_t)w_{t-1}
wtg=gtwtc+(1−gt)wt−1
当
g
t
g_t
gt的值为0的时候,我们取值为
w
t
−
1
w_{t-1}
wt−1,当前
g
t
g_t
gt的取值为1的时候,我们的取值为
w
t
c
w_t^c
wtc。即
g
t
g_t
gt起到了一个门控机制。
然后,是卷积转移操作,这一步的操作被用于移动头部位置。进而将注意力从一个位置移动到另外一个位置。每一个头部发送一个参数称为转移权重
s
t
s_t
st,这个权重给定了我们一个用于执行哪些整数移位。例如,我们定义的转移值为-1到1。此时,我们可以得到转移向量
s
t
s_t
st为
s
t
=
[
−
1
,
0
,
1
]
s_t=[-1,0,1]
st=[−1,0,1]。其中转移-1表示我们将对向量
w
t
g
w_t^g
wtg从左向右转移。而转移0表示这个元素的位置不动,而+1则表示元素从右向左移动。例如下面的例子:
再比如下面的例子:
通过上述的转移方式,我们可以计算出如下的公式:
w
t
∗
(
i
)
=
∑
j
=
0
N
−
1
w
t
g
s
t
(
i
−
j
)
w_t^*(i)=∑_{j=0}^{N-1}w_t^gs_t(i-j)
wt∗(i)=j=0∑N−1wtgst(i−j)
最后的一步被称为锐化,在卷积移位中,我们获取的了权重向量
w
t
∗
w_t^*
wt∗,同时,因为位移的缘故,原本集中在某一个位置的权重将会被转移分散到其他的位置,为了解决这个问题,使用了锐化这一步骤,我们定义一个新的参数
γ
t
γ_t
γt,其负责对于权重向量的锐化,该参数的取值在1或者1以上。锐化的具体公式如下:
w
t
(
i
)
=
w
t
∗
(
i
)
γ
t
∑
j
w
t
∗
(
j
)
t
γ
w_t(i)=\frac{w^*_t(i)^{γ_t}}{∑_jw_t^*(j)^γ_t}
wt(i)=∑jwt∗(j)tγwt∗(i)γt
1.5 总结
在上述中,我们重点介绍了神经图灵机的基本构造,以及读写头的执行方式,寻址确定权重向量的方式等等。
2 记忆增强神经网络(MANN)
在神经图灵机的基础之上,我们又来引申出神经图灵机的一个变体。称为MANN,其对于ont-shot学习比较有效。MANN相比于NTM在one-shot的学习上更为的有效,于NTM相比,MANN中仅保留了基于content寻址,来确定权重向量的方式。
在MANN中,定义了一个称为最近最少使用的原则。顾名思义,其写入的位置将是最近最少使用的位置。我们选择写入到这个位置的原因在于这个位置是通过读取操作确定,并且通过基于内容寻址的读取操作。因此,我们基本上执行基于内容的寻址,以读取和写入最近最少使用的位置。
2.1 MANN中的读操作
与NTM不同的是,我们使用两种权重向量来执行读和写的操作,在MANN的读取操作与NTM中相同。因此我们可以知道,在MANN中,我们将执行基于内容相似性的读取操作,我们通过比较由控制器发射的关键向量
k
t
k_t
kt和内存矩阵的每一行,来学习相似性。我们使用的是cosine相似性来计算相似性的结果,其基本公式定义如下:
c
o
s
i
n
e
[
k
t
,
M
t
]
=
k
t
⋅
M
t
∣
k
t
∣
⋅
∣
M
t
∣
cosine[k_t,M_t]=\frac{k_t·M_t}{|k_t|·|M_t|}
cosine[kt,Mt]=∣kt∣⋅∣Mt∣kt⋅Mt
因此,我们的权重向量称为如下的形式:
w
t
r
=
c
o
s
i
n
e
[
k
t
,
M
t
(
i
)
]
w^r_t=cosine[k_t,M_t(i)]
wtr=cosine[kt,Mt(i)]
这里值得注意的是,我们没有用到NTM中的β参数,并且公式中的r表示的是读取的权重向量。最后,我们将读取的权重向量转换成概率分布的形式,即执行softmax的操作。
最后,我们计算出来的读取结果如下图所示:
r
t
=
∑
i
R
w
t
r
(
i
)
M
t
(
i
)
r_t=∑_{i}^Rw_t^r(i)M_t(i)
rt=i∑Rwtr(i)Mt(i)
2.2 MANN中的写操作
在执行MANN的写操作之前,我们需要去发现最近最少使用的内存位置,为了寻找这个位置,我们现实定义一个新的使用向量,表示为
w
t
u
w_t^u
wtu。在每一次读写之后,向量将会被更新。即
w
t
u
>
w
t
r
+
w
t
r
w_t^u>w_t^r+w_t^r
wtu>wtr+wtr
随着读写向量的添加,我们将更新我们的使用向量,通过使用前一个时刻的衰减的权重向量
w
t
−
1
u
w_{t-1}^u
wt−1u。这里我们引入一个衰减系数γ,其表示的是前一个使用向量的衰减程度。则其具体的计算公式为:
w
t
u
=
γ
w
t
−
1
u
+
w
t
r
+
w
t
w
w_t^u=γw_{t-1}^u+w_t^r+w_t^w
wtu=γwt−1u+wtr+wtw
在计算出当前时刻的使用向量之后,我们下面要计算的就是最近最少使用的位置,这里我们在引入一个新的向量,称为最近使用的向量,
w
t
l
u
w_t^{lu}
wtlu。
我们通过使用向量来计算最近使用的向量,其计算方式比较简单,将使用向量中的最小值设置为1,其他的值设置为0,即意味着在使用向量中的最小值表示最近最少使用它。比如下面的例子:
下一步,我们已经计算好最近最少使用的向量基础上,我们来计算写入权重向量
w
t
w
w_t^w
wtw,这里我们在计算写入权重向量的时候使用一个门限机制,该门限机制将被用于控制前一个时刻的读取向量和前一个时刻最近最少使用向量的凸组合。计算公式如下:
w
t
w
=
σ
(
α
)
w
t
−
1
r
+
(
1
−
σ
(
α
)
)
w
t
−
1
l
u
w_t^w=σ(α)w_{t-1}^r+(1-σ(α))w_{t-1}^{lu}
wtw=σ(α)wt−1r+(1−σ(α))wt−1lu
最后,我们来更新内存矩阵:
M
t
(
i
)
=
M
t
−
1
(
i
)
+
w
t
w
(
i
)
k
t
M_t(i)=M_{t-1}(i)+w_t^w(i)k_t
Mt(i)=Mt−1(i)+wtw(i)kt
2.3 小结
在MANN中,选择了NTM中基于内容寻址的方式,并且引入了读取向量,写入向量,使用向量,最近最少使用向量的概念。相比于NTM,MANN拥有更好的基于小样本的学习能力。