00:00
大家好,今天大家讲一个attention机制,以及结合机器翻译这样的任务,呃,讲一下它的拍错实现,OK,首先我先说一下天讯机制的原理吧,这大概会花十呃十分钟左右,嗯,行,那么首先啊,我们先看这是一个encoder结构啊,我我现在有一个任务,比方说我要用英文翻译啊,我要用德语翻译成英文,然后呢,我现在这边输入是德语的每一个单词,呃,输入之后呢,这个比方说这个网络,这个coder,它可能是个LSTM啊,或者是G,或者是普通的RN都可以,呃,我输入之后呢,它会得到一个输出,就是得到了每个时刻它都会有个输出,那么我把每个时刻最后一层隐藏层的输出就是I奇艺,一直到。
01:00
啊,HM我给它称作为output,在我代码当中我也是定义为output,而最后一个时刻,最后一层,呃,听清楚我说的话,就是说最后一个时刻就是这个,这个时刻最后一层就是这个HM,它我定义为呃,我就把它记作S0 S0的值在值上和HM是相等的,只不过我给它换个别名而已,叫做S0,就是传呃,在传统的to sequ当中,我就直接把S0作为输入,作为encoder的初始时,初始时刻的一个隐藏层输入了,但是sequence to sequence不是的。接下来呢,我会用S0对每一个H,就这里S0,我会对所有的hi去做一个函数,计算出一个值,那么这个函数我可以认为它是计算它们之间的相似度,比方说或者是叫相关性吧。
02:00
平号可以这么理解,比方说我用S0我去计算啊,我跟H1它们之间相关性有多少,那么计算出它相关性是阿尔法一,或者叫A1,我在代码当中我是用A来表示了,不是用阿尔法,然后呢,所以我这里也念作A吧,就不念阿尔法了,然后呢,S0我再去计算一下和H2它们之间的相关程度是多少,比方说是A2,算起来是A2,然后一直到HM,它们俩之间相关程度算出来是am。呃,算出来这个度之后呢,它这些,呃,就算出来这些值啊,它其实是一个权重,这个权重要分别和它对应的这个隐藏,隐藏变量,隐藏层的这个输出的变量相乘,再相加,就是R啊,我先把它擦一下,就是说这里啊啊A1乘以H1一直加到am乘以HM这个contest,就是说呃,上下文变量或者说环境变量吧,它等于什么呢?AI从一到MA这里写上A吧,AI乘以h hi,它其实就是一个加全平均,呃,这里的M啊呃,我想这里M应该没什么说的吧,就是说你一共一句话里面有多少个单词,比方说我有什么德语,比方说什么那种乱七八糟的,那我就比方说有十个单词,那么M肯定是十。
03:33
那么它就等于什么呢?等于sourceless sourceless指的就是说source原就是原句子,目标句子是我要翻译的成的英语,原句子是德语,就是原句子的长度就是十,就是M啊这个地方稍微说一下,因为后面代码会提到OK,那我呃算出来这个环境变量就是说环境向量C0就是输入式和C0,这里这前面大家应该都理解了,那么我得到环境变量之后呢?啊,我肯定要用到这个环境变量,对吧?就是说这个东西它这个注意力了啊,我可以给大家解释一下,首先大家想一下,假如说我用S0去和它们每一个H去算出来一个相似度之后呢,我假设H2的相似度是整个相似度当中最大的,然后它可能是0.8或者零点几,那么它和这个H2相乘是不是就特别大,就或者说就是说它那么整个C0啊,它是不是价钱平均,它是不是就有很大一部分。
04:33
本是来自于HR的,因为A2它是很大的嘛,所以它就C里会有很大有可能来自HR,我就可以看作是什么呢?看作是我在读这一句话的时候啊,我特别看重X2这个单词,这就是注意力集聚着,就是说我把注意力放在这个第二个时刻,这个单词OK,那么得到这个环境变量之后呢,我肯定要用到这个环境变量,所以我要把环境变量,然后以及初始的,呃,就是说S0这两个东西啊,以及它这个时刻的输入deco,它第一个时刻的输入。
05:10
那么就是我现有C0。X0 x11撇,X11撇就是Co input。Input就是第一时刻的输入去做一个拼接,或者说叫整合吧。的整合打引号,至于怎么整合,等会我再讲,你大家可以认为就是说把它们糅合在一起,糅合成一个新的变量,然后呢,通过这样一个隐隐藏层,对吧,这这是个LSTM啊或者什么东西,大家可以这么理解。啊,那么最后得到个S1,这里大家应该都理解了,那么接下来怎么做呢?接下来也一样的,我再用S1去计算一下呃,H1它们之间的相似程度,得到一个阿尔法一,A1,再用H1去和H2计算一下相似程度,得到A21直到H1和HM计算一个相似程度,得到am,然后呢,再把这些东西去做一个相乘,就这个相乘,这些相乘,然后把这个东西相乘完了,相加加上这个,加上这个一起加,那它又得到一个加权平均。
06:23
做完这个价权平均之后呢,我得到什么?得到的就是C1,这里就是C1这个问号,这里就是C1啊,我现在有C1,然后有了下一个时刻的输入,还有S1,那我就可以用C1。S一下一刻的输入,再去做一个整合,再通过一个。呃,LSTM,或者怎么样,又得到一个什么呢?得到一个S2。然后接下来还是一样的,我用S2去计算一下它们的相似度,然后再相乘的相加,所以在已经得到一个C2,然后我再用C2。S2以及下一时刻输入X31撇做一个整合。
07:10
通过一个R,呃,RLSTM,然后得到一个S3,那后面就不用我多说了,再去继续这样做对吧?那么就是右边这张图,这里的话大然我讲的应该够清楚吧,这个就是呃的原理大概是这样,呃就是说呃,不不不就是attention它的原理就是说attention它的呃工作流程大概是这样子的,那么其中有些细节啊,首先第一。这个函数我一思都说计算它们相似度对吧?那怎么去计算它们相似度,这个函数没有什么公式呢,公式在这里,首先我把S0或者说S1,反正各个时刻的S,然后然后呢去和hi去做一个拼接,拼接完了之后呢,通再乘一个权重,再用一个摊点H做激活,那么整个这个。
08:04
实际上是什么呢?我们可以通过一个 Nn.liar来完成,对吧,因为它实际上就是一个维度的变化嘛,然后后面用一个点H做一个激活,这没什么难度,然后再通过一个再乘以一个V这个向量,那实际上比比我举个例子啊。比方说,嗯,先把它擦了,稍等一下。比方说我通过这个之后,通过这个里我得到一个变量,我叫做W吧。然后呢,W通过13DH,比方说我得到一个叫做T。那么我T再乘以一个这样的向量,那其实就是一个NN点。把气进去嘛,对吧。没问题吧,就是说这样的。那么得到这个变量叫阿尔法啊,叫A。当然此时还不是A,此时是一个A的大,我先擦掉,此时是个A的估计值,大家看上来有波浪线,为什么呢?因为你这个时候得到的A啊,就说呃,这些AIA1 a21到am,它们的和并不是一,我想让他们的和变成一,所以我需要把它们全部进行一个soft ma soft ma呢,呃,原来大的值还是很大,原来小的值还是很小,但是此时它们的和就变为一了,它们加起来呢,它们加起来和变成一了,这个地方大家也应该都,嗯,也可以理解对吧?好,那么这里也过了啊,首先是这个函数怎么设计,我也给大家讲完了,我先把它擦了啊,等会再藏了啊,讲完之后呢,然后我第二个问题就是说如何做整合,其实就是把这三个变量传入,然后呢,做一个就是乘以个A撇,再加上个B,就是一个,怎么说呢?呃,仿射变换吧,然后再乘,再用一个三点就做。
09:57
激活,那么这里其实不是一个简单的拼接这么一个就完了,在这里的话,我等会儿从代码上会给大家讲这是怎么做的,大家可以先理,就是感性的理解一下,如果简单来做的话,就是做一个拼接,但其实代码不是这样做的,OK,那么首先这就是完整的一个腾讯的一个流程,包括里面一些呃细节部分我也给大家讲了,那么接下来我就去讲一下代码吧,呃,因为就是说我觉得呃,我想讲那个条例的话,所以我还是对着这篇文章去讲,而不要空讲,空讲的话很容易讲的比较乱。首先啊,数据预处理部分,这个地方大家用的不同,用自己的数据,或者说在呃,实际工作中,或者实际应用当中用的是不同的数据,所以数据预处理的代码是没有办法,大家呃,肯定都写的不一样的,那这里的话我就不贴代码,而且数据预处理我调用的各种库很麻烦,大家如果不理,没见过这些库的话,都会觉得。
10:57
的这些代码不好不好不好读,所以我就给大家讲一下,你需要把数据处理成什么样子就可以了,所以大家如果有自己的代码的话,呃,有自己的数据,你就把数据处理成和我一样就OK了。首先呢,你的数据要处理成什么样呢?你要处理成首先第一啊,我是一个德语翻译成英语的一个问题,对吧?首先你要把每个就不管是德语还是英语每一句话你都需要用呃,Start of sequence end of sequence以及pad去填充,那么填充的规则就是说,首先你一句话的开头用star seence去,呃,就是说插入这样一个开始标,每句的结尾要插入这样一个结束标志。
11:41
如果说这个句子不够长,你需要在结束标志后面加上pad,就这样子就可以了,当然有的人可能会说,为什么不在,为什么不先加pad,然后再加结束标志,这样也都是可以的,其实都可以没有什么固定要求,OK,就这样子。那么还有一点就是说。
12:00
呃,句子的长度不一样怎么办?这个解决我是这样子做的,就是说大家可以看到我这有很多BY对吧,那么每一个BY,比方说这第一个BY,第一个BY里面左边这个是就是德语句子的那个呃呃,Shape,然后右边是英语句子shape,首先德语和英语它们的长度。第一个维度是句子的长度,第二个维度是这个BA有多少个样本,那么首先大家可以看这第一个BA,德语它有38啊,就是说一个句子每个句子都是38个单词,而英语37个单词,所以说第一你的德语和英语的那个句子的长度不一样,没关系,没有任何限制。第二。在同一个BY学里面,不管是德语还是英语,同一个BY学里面,这你看这个这个BY学里面,它128个样本,对吧,每一个样本就是每一句话。它单词的长,它的句子的长度必须都是相同的,然后这句话里面有128个句子,那么每一个句子的长度都是38,不够的怎么办?不够的加派的。
13:03
而不同BY之间,你的句子的长度没有任何限制,比方说第一个BY你是38,第二个BY你是31,你看这两个就没有任何关系,包括后面它们全部都是不一样的,没有关系,你只要保证在同一个best里面,你的句子的长度必须得是相同的就OK,不管是等于还是英语,这是这是第一加封装,第二呃,你的be,第三就是。你德语和英语要分开建词库,就vocabulary,呃,这个也很好理解吧,就是说你德语你要分词,用空格作为分词之后,然后你构建词库,英语也构建一个词库,要构建两个词库,不能说把它们俩全部放到同一个词库里面,然后用索引去编号,不行,不可以这样,OK,那么这就是三个要求,大家去理解一下就行了。
14:00
呃,当然还有一点就说,就从这里可以看,大家可以看出我输入的形式。哎呀,我这声音有点大。就是我输入的形式啊,它的shape,首先第一个维度不是by size,是句子的长度,第二个维度才是by size,那么大家这里处理一下就可以了,就调换一下维度嘛。好,那么我首先讲一下inco,呃,Coder的部分的代码吧,我coder部分呢,用的是单层的双向GRU。啊,想想。呃,双向GU那么OK哦,我看看什么时候,就是说双向GU的隐藏状态是由隐藏状态的输出是由两个向量拼接而成的,怎么理解呢?首先啊,大家可以看一下这个绿色的所有这个绿色这个这个这个这个这。
15:08
这是呃,绿色的,它是正向的一个输入。就是把这个句子正向输入一遍,然后呢,得到的H1H2H3H4OK没有问题,这个蓝色的呢。后面这个蓝色的是把这个句子反向输入一遍,就是说先输入us,再输入这个,再输入这个,再输入这个,得到的一个反向的输出,这个H1 h2 h3 H4,那么整个真正的它的输出是什么呢?就是说output。Output,就是我刚这里讲的这个东西。就是后面这个用红框框起来的这一部分。它其实就是。啊,其实首先我把这两个拼接在一起,因为他们都同一个时刻的。对吧,那么到同一个时刻,那么我就定义为H1吧,那等于什么呢?等于H1这个拼接上H4这个。
16:08
然后呢,H2它等于什么呢?它等于就是这两个拼接在一起,就是H2过去在拼接上,H3反向的,那么后面以此类推,我就不说了,那么output其实就是H1在拼接上,H2在,哦,不是拼接是就是放进去H1H2。H3。其四。OK,就是这样子啊,那么这个就是output,就是说整个这个就是H1就是H2。这H3。这是H4。那么就是刚刚这个图里面的这个东西,一直到HM。这个是它会,就是说你调用呃RN,或者说呃调用什么呃G,它会返回给你的,那么同时它还会返回一个什么呢?它这个output我用中文解释一下,就是说所有时刻的最后一层。
17:00
隐藏层的输出,大家看到吗?每一个时刻对吧,所有时刻最后一层就是最后一层嘛,假如说这是多层的,这里面还有。哎。哦。假如说这里面还有一层。这个输入,然后这个输入,然后就输入输入。假设这有两层的话,那么我还是只要最后一层,呃,还有它会返回什么呢?它会返回一个黑的。黑的是什么呢?我用中文解释一遍,就是说最后。一个时刻。最后一个时刻的所有隐藏层。所有隐藏层的输出,比方说啊,我在这里画个图。这是最后一个时刻,就是T时刻。它的。
18:01
这是70,这是input,就是说这个东西,然后它会输入什么呢?它会首先它会这是一个正向的输入。然后这是一个反向的一个输入。就这两个东西,然后它会输出一个东西,他也会输出一个东西。然后他在。如果是两层的话,它是这样子,他在输出,它再输出,哎,我把这个叫做什么呢?这个东西,这这这条线啊,它的输出我给他记做啥呢。给他记作 Ht1,就是说第一层T10克的输出,而这个的输出呢?我给他去做H11。一为什么呢?因为它是反向时刻的第一个时刻的输入,呃,输入对吧,那你看嘛。大家可以看这啊,像这个时候,这是最后一个时刻嘛,但它反向的话,它是作为第一个时刻的。然后这里呢,他的输出我记住什么我记住。HT2。
19:00
因为是T时刻第二层的一个输出,那这里我记一就说第一最后一层,就说第二层,它第一个时的输出。那么黑的你指的是啥呢?黑的啊。指的就是。啊,首先我这样吧。我把这个拼接起来,那么H1就是第一层的隐藏层的输出等于什么呢?等于H71,拼接上H1,然后第二层隐藏层的输出等于什么呢?等于H72,拼接上H12。那么黑的。它就等于H1H2。这样的东西。但他假如说我有三层。假如我有三层,那岂不是H3?我有四层,那就是H4。
20:03
那后面S3S4也是依次类推对吧。但是呢,我这里刚刚也给大家解释过,我一开始就说,我说这个HM它是最后一层,最后一个时刻的输出,对吧,隐藏他的输出,那我这里黑它并不是它是。它是最后一个时刻所有隐藏层的输出,但我现在要求的黑钻是什么呢?我要的是最后一层,最后一个时刻的输出,那是什么呢?比方说我现在就两层对吧,我现在就两层,那我要的就是这个HR。但是这个H2,我把这个H1写开吧,H1写开是啥呢?就是 Ht1,然后冒分号H1,然后逗号。H72H12,哎,我要的其实就是这两个东西,那我现在怎么取呢?我如果是用Python的话,我就这么取,我呃,通过GU,它返回出来是个这么个东西,返回回来一个黑的对吧,然后我通过黑盾,然后负一冒号,冒号因为它是个三维的,负一指的就是这个东西,而黑的。
21:12
负二,冒号冒号。它指的就是这个东西,我现在获得这两个东西了,我再把他们俩拼接起来,拼接起来记做S0,不就和这个对应上了吗?对吧?这个就是最后一层,最后一个时刻的输出,这个是啊,负一的话,它是啊,这个是反向的,这个是正向的,呃,这反向输入的,这正向输入的,把它俩拼接起来就是S0啊,这里讲的实在是太太慢了,OK,就是这样一个东西。啊,大家可以看到,就是大家如果我没讲懂的话,大家可以看一下这里文字解释可能会更好理解一点,OK,那么我现在推一下它的维度啊。首先这个黑的啊,它的维度是什么呢。
22:00
哎,这里不查了吧。我们可以看一下这个黑它的维度什么,首先它的维度,呃,肯定是就是number of layers。就是你有多少层,这里我就写上一吧,因为我就一层,我就是个单层的,然后后面是by size,然后后面是啥呢?后面是coder的hidden。Dimension就是encounter,你设置为你隐藏成的维度是多少?乘以二那种是乘以二呢?因为你是一个正向和反向双向,反向的一个拼接就是乘以二。然后我给它取出来之后呢,那么这个东西它的维度,首先它就很明显少了一个啊第呃,它就少了个第一维,那它就是一个普通的bit,然后Co。黑的。Dimension。哦等等,呃,我我想对于这个问题来说啊,假如说我现在有两层对吧,那这里其实是二嘛,对吧,就是二,那我取了负一之后,它就它就这里就没有了,它就Co size,然后它就是个二维的,然后这个呢,也是一样的,这也是by size,然后Co。
23:06
Hidden dimension。OK对吧,然后把它的拼接,拼接的话,肯定不是按照半起来拼接,肯定是按照这个来拼接的,那么S0最终的维度就是by side啊等等。啊,对对对,是对了size,然后in。Hidden dimension。乘以二没有问题吧,这这就对了吧,OK,那么大家可以看到S0的维度就是byside,然后in黑白线乘以二。啊OK,那么现在还还有一个问题就是说,哎,假如说我没有腾讯机制啊,我现在就得到这么一个HM,然后呢,我把它记,呃,用一个新的变量名,起起个新的变量名叫S0,它们俩维度和那个什么,它们俩维度和值都是一模一样的。我现在如果说没有attention,我就直接把它输入作为那个什么,呃,Decoder的一个隐藏,初始隐藏成的。
24:08
一个初始向量作为输入它的维度也是不对的,因为你encoder decoder,你要求的是什么呢?底coder。你的H0就是说初始的隐藏的向量,它要求的维,呃,它要求的维度是什么呢?首先第一它肯定是个三维的,第二你这里最后一个维度啊,就不对,最后一个维度你啊,我先写第一个维度吧,第一个维度是什么?Be size啊,不对,Size是在后面吧。哦,对,你需要的是。认识。然后size,然后decoder。Deco hidden dimension。大家可以对比一下啊,这个source我刚才讲了,就是说你圆。句子。
25:02
长度。OK,这里我就不说了先,大家可以看一下这里这个地方有什么不一样的。首先。这个你这个两个维度就不一样,第二你这是个两维的,我都是三维的,那么这个东西怎么解决呢?呃,首先这个东西好解决,就是说两维和三维我直接S0点。Iried。在零这个维度上加一个,那么它就变成,它就变成一,然后size,然后dimension对吧,乘以二。它就会变成这样子,然后我再repeat一下,就重复一遍。那么就会重复,呃,Source这么多,那么这里就变成source,然后后面都匹配上,就唯独是这个地方没匹配上,就乘二以根,咱们选乘以二,这里没有匹配上,但是也没匹配上,怎么办呢?啊,我先我说了两维变成三三维这个事很好解决,那么最后再解决,我先把这个不好解决解决了,那么这个不好解决怎么办呢?我通过我直接把S0啊。
26:02
通过一个。全连接神经网络就通过一个单层的一个神经网络。把它维度转换一下不就完了吗?转换成BY,然后decoder hidden dimension。就可以了,对吧,所以说啊,大家可以看到,首先要做的就是说将这个维度啊,你首先要做的就是说将它转为,所以说这里要将S0通过一个网络进行维转换,然后下面是代码。再把手给大家解释一把,就是就是说呃,你传输进来的一个原始数据,德语它的维度什么呢?Source,然后by side。那么我先进行一个word inbedding。就先把这个维度变一下,转换过来,就一下将零维和一维它们俩的位置调换一下,变成be size,然后然后呢,通过bedding。那么这个东西之后,经过这个我框起来这块代码,它的维度就变成了sizeding,然后呢,我再给。
27:04
它就会变成by size,把by size又放到中间去了,为什么要这样做呢?因为呃,RN,就是不管什么RNRN啊,GRSTEM他们的输入都需要这样的条件,就说BY不放在第一,不放在第零呃维度的第零个位置上,而放在第一个位置上是这样子,OK,然后呢,我通呃把这个东西输入一个RN,当然这里我只输入了输入,没有输入那个初始的隐藏层向量,如果你没有输输入的话,那么它初始的这个H0啊,没有给的话,它就会设置为全零的默认为全零,大家这里可以不用担心,不,没有少参数。然后它会返回两个东西,一个Co output,一个Co hiddenco output指的就是我这里说的这个东西,最后所有时刻,最后一一层隐藏层的输出,它的维度我这里写了source,然后BY,然后hidden乘以number of direction,因为我是一个双向,所以说number directions是二。
28:05
然后它会返回include hidden dimension哦,Include hiddenco hidden呢?它是什么意思?这里我也写了,就是number of lays乘以number of directions,然后by size,然后human dimension哦,这里我我说错了,不好意思,这里的话,这里不是不是这里,二是这儿。这里的话就应该是四,其实因为我是两层,然后呢,我的是双向的,所以乘以二,那么它就变成四。所以这里写错了,OK,然后我会获得这样的东西,然后呢,我现在要取出的是最后一个时刻,最后一层它的输出,隐藏层的输出,那我就取出这两个东西,为什么取出两个东西呢?因为我有一个正向,一个反向。好把他们俩取出来之后呢,进行个contact,他俩取出来之后,他们的的维度啊,我也写了,是一个两维的一个向量,就这。
29:02
Contact在哪个位置上进行contact呢?在一,这是零,这是一,在一位置上进行一个contact拼接,拼接完了之后呢?通过一个fully connected layer,它会变成什么呢?它就会变成by size了啊,稍等我喝口水。好,那么der讲完了。接下来给大家讲,就说腾讯的部分。呃,腾讯的话就是三个公式嘛,那么这三个公式,首先维度它是比较难推的,所以我在这里给大家推一下它的维度,我反过来推维度。呃,首先这个at它的维度是什么呢?它的维度应该是by side,为什么?
30:03
大概看这里。因为你要和这个啊它们相乘,那么这个它的维度是什么呢?这个hi,它的维度肯定是by side在前面。然后呢,哎。呃,大家可以先看一下吧,就说by side,然后为什么要说呢?就是为什么要这个句子的长度呢?因为你要有,就是你要和它对应,它有一个隐藏的,就是说你有一个输入,你就有一个阿尔法,你有多少个输入呢?你有多少个单词,我有source这么多单词,那你就有要有source这么多个权重,所以它是BY,然后是毋庸置疑的,然后呢,它是这个维度,所以说你通过soft max是不改变维度的,所以说它也是这个维度。那么这个估计值也是这个维度啊,估计值是这个维度之后呢。哎,硅值这个维度也或者是它是个三维的,但是某个值某个维度的值是一,那么它就可以通过S柜,它就可以变成两维的,那为什么?那我这里假设啊,假设这个维度是这个三维的,为什么要这样假设,我等会再说啊,我们继续往上推,它是个三维的,并且维度是这样子的。
31:16
然后它是由这两个东西做乘法,或者或者说这个V,它不是一个乘法,它是一个诶。大家可以看一下这个V,或者我刚也解释了,这个V不是一个乘普通乘法,它其实就是一个N点。对吧,就是变换维度的一个作用,那么就是说啊,我要怎么样变换维度才能变换成乘以呃一对吧。那么我,呃。一对吧,我要变成这个维度,因为没有没有关系的,不用管它,然后呢,那我前面是什么东西乘以什么东西才会变成这样子,那首先最后这个维度肯定是一对吧,那我这里我先不知道。
32:10
对吧,这里只要这两个东西相等就可以了。然后最后这个是一,那么前面这里肯定是。所以说那么这个东西啊,它就是N就是V,就是V的维度就是N点。而这个东西呢,它就是一期的维度。哎,当然大家可以看,大家可能会看到说这里面顺序反了,无所谓的,因为这个东西只是一个,就是只是一个linear,你你怎么设计都可以的,只是个点LINEAR1层,你怎么设计都可以,所以说这个E它就是这样的一个维度,但是E呢,它前面还有个by size,对吧,我说了有个size size。你和一个二维的东西去做一个,就说经过一个全经网络是没有关系的,所说BY维度也出来了,就是BY,呃,E的维度也出来了,就是by size,然后问号。
33:02
啊,那么大家可以看到E对吧,E维度就是by sideness问号,然后V的维度是问号一没,呃,这里大家应该理解了,好,那么继续往上推,E的维度有了BY问号,然后加HH,它是不改变维度的,而这个东西呢,也是一个就是N点,大家概刚刚还记得吧,这个东西不就是通过一个linear嘛,对吧。那么现在我已知HH是啥?H不是这个吗?把所有的hi,所有的 hih1 h21直到HM统称为,就是说全部整在一起就变成一个大H,那么它的维度是什么呢?就是那么就是这个东西,就是output,这个大H啊,就是我的output变量,就是这个东西。这output就是大H,那么outp它的维度是什么呢?它是length by size,然后乘以二,所以说这里H的维度也是by size黑乘以二,然后ST减一就是S0的维度,S0的维度在这里嘛,S0就是这个S,它的维度什么呢?BY黑,所以S0的维度就是by size抵扣到黑上面去,然后这两个我要做一个拼接,大家可以看到这里吗?
34:21
我要做个拼接,然后送这个全连接神经网络,那么我现在拼接就有问题,因为这个东西反正它是个三维,它是个两维的,并且他们维度还不太一样,所以我要怎么做拼接呢?那么我要首先将ST减一它的维度啊变成这个样子。变成这个样子了。你看那看这H,这是S0,这两个BY相同了吧,相同了吧,那么只要我能够在定义参数的时候,就是我定义它呃,Encoder和decoder他们俩的隐藏层的参数的时候,我只要能够报,只要能够要求,比方说我呃只要能够要求decoder它的隐藏层的维度是等于什么呢?等于enco尔隐藏层的维度乘以二这样的关系,那么这两个就天然的就相等了,Co尔和边乘以二就等于Co两边,那这两个就可以直接拼接了,对吧?好,那么我然假设我等会义,我就这么义,那么就把它们拼接,拼接完了之后呢们维度就变成了,然后以二加上这个东西们呃就可以了。
35:26
呃,那么这样的话,它的输出输入输出也有啊,就是说它就是一个Li尼尔函数连接函数,那么他们输,呃输入的维度什么呢?是这个维度。它加它就是这里嘛,然后输出维度是问号,为什么是问号呢?因为你你一踢它就是这样的维度,By side问号,所以你需要得到一个问号,那么到此为止,除了问号以外,其他所有的我现在也都已经推导出来了啊,我们现在再回过头思考一下,这个问号应该设置为多少?其实我们发现啊,这个问号没有任何的限制,这问号设可以设计为任何的值。
36:03
因此我在代码中我就把问号设置为,比方设置为一百两百都可以,当然你偷懒,你想写一下,随便写个抵扣分权也是可以的,你写上in扣黑版选代选乘以二,乘以十,乘以百都可以,无所谓的设置为任何值都可以,只要你问号地方相同就行了。好,那么attention的细节就是这么多,那么我下面给出代码。哦,对了,这里我刚刚口误了,我这里写错了,其实Co和成线乘以二和这个地方它们俩的值没有任何要求。没有任何要求,这里我先修改一下,不好意思。呃,我找一下。OK,这样拼接之后,我就变成了这个东西。
37:01
他们俩的没有任何要求的,你不需要要求都可以拼接,是的。OK,然后他俩拼接就这样,OK,呃,OK,那么attention的代码我就给大家讲一下,首先by size,我要获取这个S啊,就是S0这个output。S就是这个东西,Output就是这个东西。然后获取,获取完了之后呢啊BY然后我都有了,然后s.S柜子一。因为S它的维度是这样子的,我在这里一的话,那么它就变成by size1逗号,然后扣分形,然后repeat这么多次,那么它就会变成了什么呢?变成by size在中间这个地方,那么S变成size这样的维度,然后呢,P。我给他调换一下维度。那么它就变成了by size south这样一个维度,然后它俩那by size对上了,Social也对上了,最后把这两个地方拼接在一起,那tor k这两个东西拼接在一起,维度咱们选是在第二维上,012在这个维度上拼接,拼接上之后呢,通过一个函数,这里attention就是n.linear。
38:17
转换成什么维度呢?转换成我这里说的问号这个维度,问号这个维度我代码当中设置的是deco,就这里,然后呢,通过一个参加作为激活,最后再通过一个列点函数这个V,那么它就是这样的一个维度,Deco,然后呢,一,那么得到一之后呢,它就会变成这样的一个维度,就是呃,这样的一个by size1 by size1对吧,然后我再用I squeeze,哦,Squeeze把二去掉,那么就是说这个一就没了,那就只剩下,那就最终得到这个阿尔法,那就是说at的估计值,那么它的维度就是,然后通过soft ma就得到还是这个维度,所以大家可以看一下f.soft ma这样子就OK了。
39:05
这是整个腾代码还是比较复杂的,其实然后下面呢,我讲一下sequence sequence啊啊,就是我整个代码是有四个类构成的,一个是coder。De。然后呢?Attention。Have seconds to seconds。呃。而这个sequence to sequ,它算是一个特别大的类,因为这个sequence to sequence里面,它调它去调用了coder,调用coder调用调用attention,而在这个decoder里面,它是调用调用了这个attention的,而encoder啊,它就是一个普通encoder,它谁也没调用,所以说可以这么说吧,就是说呃,Second sequence里面调用了这三个。
40:03
而decoder调用了attention,而encoder啥都没调用,是这样的一个逻辑。OK,那么呃,我先讲一下sequence to sequence是这样的,呃,传统sequence to sequence的呢,我是将句子连续不断的输入,而我引入了attention机制的时候呢,我需要人为的控制一个词一个词的输入,因为你在每一个词进入到decoder的时候,我要去调用一次attention,去计算一次,然后再去跟你这个词去做一些运算。所以我要慢慢的一个词一个词去输入,就我要用,所以大家可以在代码中看到我用了for循环。那么循环了这么多次,这个TRG嫩啊TRG。就是target target什么呢?就是英语,也就是同一个BY里面英语句子的长度。一句英语,它有多少个单词,就是target,就是这里。
41:05
就这S1 S2S31直到XN撇。就是这个东西,那么N其实就是他给的N,为什么循环N减一次呢?为什么只需要减一呢?因为我开头的SOS是我手动输入的,所以说它就循环少一次,等会代码再说吧,呃,然后呢,并且训练过程中我使用了一种叫的机制。这个机制是什么呢?这个的话就要讲很多了。这个机制的话是这样子的,大家可以想一下,在decoder是这个decoder。这是我的失误,在训练的过程中,这只针对训练,测试的时候是没得说的,就是那种测试方法,没有用teacher说的方法。
42:03
然后他会得到一个输出,然后他会得到一个输出,他得到一个输出。它得到一个输出,OK,比方说这里我输的是SOS,然后是I like。You。哦对,差不多,然后这里呢,输出的是I,然后这里是like。然后这里是,然后这里是EOS。OK,那么首先对于我有两种训练方法,第一种训练方法呢,我是说就是我首先输入SOS嘛,然后再输入他们前面传过来的S0,让我得到I,那么此时就有一个选项了,你接下来这个地方呢,比方说我这里输出的不是I啊,因为我可能一开始学的训练它效果没那么好,那训练时候乱七八糟的词,比方说比方输出一个but。哎,那我现在就有问题了,我在这个时刻,我是应该继续按照我原来句子当中的规定输入I,还是说把这个but传过来呢?这两个其实是完全不同的训练方式,对于第一种来说,第一种方式就是不管什么情况,不管你输出啥。
43:13
我都按照原来的呃进程,我就输出来,然后不管你这里输出,比方说这里输出呃,Me OK,然后你输出but me,然后把你全部下来but me,然后比如说还输入but,输出but,然后这里也输出but,然后计算一下他们跟真实的I like you。Us。他们之间loss计算较多呢,这是第一种方式,不管你输入输出什么,我都还是按照原来的规定去进行输入。第二种方式呢,是。是一个自回归的方式,也就是测试当中会用到的方式。就是你输出你上一个时刻的输出,一定会作为这一个时刻的输入,比方说你输入SOS,你输出的我本来想要得到的是I like you。
44:04
E,但是呢,你输出but OK,那那那没办法,那你只能把butt再作为输入,然后butt输出,我希望他能够这个时候希望能够输出like了,可惜因为你but本来就是个错的,你再输入的话,他就会更错,可能输出密了。然后你再把密作为输入。这就不说了。你你希望哎,你前面都两个都错了,这里应该对了吧,可惜你前面两个都是错的,这里对的可能性更小了,就它又是又是一个错的,比方他又输出一个but。那你就错的越来越离谱,你就这样子慢慢训练,这样训练有什么好处呢?就是通过第二种方式训练啊。你通过这种方式训练,因为你测试的时候也是这样子的,你测试的时候也是这样的一个流程,你训练的时候如果设置为这样流程,首先第一什么好处,好处就是当你测试的时候,你的效果肯定会更好一些。因为你就是说相当于你没有看答案,你就让他自己去搞,也能搞出来那么好的效果,那确实了不起,但他有问题,他的缺点就是说他肯定。
45:09
因为你不看答案,或者说不看怎么样,你让他自己去搞,那很难很难收敛的,这是它的缺陷,而对于第一种方式来说,他的优点就是说收敛肯定很快,因为你输出是错的,但是我讲这个时刻立马给你纠正过来,我我要输入爱,然后你又输了错的,我还我还是不管你,你输入是错就错吧,然后我还继续按照我的正确的输入输入,那么你肯定训练的时候收敛会很快,但是缺点就是。呃,缺点的话就是你这个太有点矫,真的太狠了,不太好。那么teacher讲了这么多之后呢,我就说一下teacher是个什么样的机制,呃,字面意义上来说就是用老师来校正你,呃,可以理解为一种方式,但他其实是介于第一种和第二种时间的方式,就是我测的一个概率,然后我设置0.5 OK,我现在去一下。
46:02
Random random。我计算一个概率值,如果这个概率值小于0.5,哎,那我就用第一种方式,如果说概率值大于零大于等于0.5,那我就用第二种方式这样的个意思,让它在训练的过程中呢,他啊有有可能一会儿是那样子,一会儿是这样子,这样的话就还同时能够看到第一,呃第一种方式优点,也能看到第二种方式优点,同时也避免了第二种方式他这种训练越来越跑偏的缺陷。这就是提取的训练方法。如果大家没没搞懂的话,可以看一下我这篇文章。我会那么。就是讲teacher讲了这么久。那我们思考一下,For循环应该做哪些事情呢?在sequence sequence啊,我们首先要将变量传入de,对吧?那么哪些变量要传入呢?因为我前面说了,Attention的计算就是de里面会调用attention的。
47:02
所以说你attention,那么我首先要把attention计算的一些材料丢进去,也要把deco的材料丢进去,Deco的材料有哪些呢?其实也就是一个输入,对吧。所所以说我首先把抵扣表里面传入抵扣input传进去,抵扣的input就这个嘛,然后呢,我还要传什么呢?我要传入attention需要计算注意力的材料,那么它需要的材料有哪些呢?有S。以及inco put。就这两个东西。首先是这个以及这个都要传进去,所以说这三个东西都进去了。然后呢,OK,那么我们先看一下,首先第一。这个TRG指的就是呃,英语,就是说我需要翻译成英语的句子,那么我首先取出所有的BA的第零个词。啊不不就是说在这个里面,我取出这个里面所有样本的个词,那么词肯定都是SOS嘛,就说first input to is SOS token,那么就是SOS。
48:07
那我会把这个传进去,传进去之后它会返回两个东西出来,它会返回,就说呃抵扣它可能返回两个东西嘛,底扣它会返回什么呢?它也是个呃循环神经网络嘛,所以它会返回一个。抵扣的output对吧,抵扣的output以及新的S对吧?新呃,新计算出来的S。那么此时我需要把所有的output全部都记录下来,所以说我用一个变量这里output。我喜欢用全灵来初始化,初始化之后呢,我把迪库奥特的每次输出的都放进去,放70克,70克就是说。嗯,就是说你T时刻的一个输出嘛,对吧,然后呢,我这就是t random random,如果它小于这个东西的话,怎么样,那么就啊,OK,这个是啊,我预测得到的值阿一就是我预测得到的值,那我此时到底要预测得到的值呢,还是真正的这个时刻的值呢?那就看teacher for怎么选了,看它的概率到底是true还是false,如果是true呢,那我就用真正的值,如果是false呢,我就用我预测的到值作为下一个时刻,这扣段已input这里看到没循环上了,在这个循环里面。
49:25
这里就连接上了,OK,就是这样子的,然后呢,我sequence to sequence就是整个模型了,整个模型最后返回到就是我输出最后的一些单词,就OK把传去行,这里就是讲解了,那么下面就是最后一个部分de了,Co讲完就真的没了,所以还是挺复杂的。我讲的是真的嘞,呃,那么抵扣的呢,我肯定是用的单层单向的那么多,呃,多少层大家可以随意,反正一定要是单向的,单向的G用,因为你输出嘛,你你怎么双向啊。
50:02
那么底扣呢,其实也就三个公式对吧?呃,首先我看一下。这里。的话,就是把这些东西整合一下,然后传入扣嘛,那么就三个公式,首先权重就是W,就是weight,权重等于啥呢?等于你的,哦不不不,那个不是权重,这个不是权重,这个是那个什么。这个是context CC等于什么呢?等于权重乘以每一个der的hidden,得到一个呃上下文向量C,呃,得到一个上下文向量W,然后呢,我现在要把什么呢?我要把通过变呃,Word embedding之后的词。以及我的contest,以及我上一个时刻的。T减一全部搜输入。这里说什么呢?说加U。啊,输入GU之后呢,啊,当然然后呢,我得到这么这么一个XST,然后我还要用这个ST呢,去做一个n.Li这个主要是为了转换维度,转换多少维呢,转换成我最后输出的那个分类。
51:13
就我分成哪哪个单词哪一类,我是一个分类问题,所以就是要通过一个FN点。那么这里也说了,H指的是encounter的变量Co put,然后呢,呃,这个是指的将Co input,呃。呃,这条话写错了,应该是。不好意思,我稍微写,修改一下,是将input。这里是张decoded的input。世交。Deta input经过world inding之后得到的一个结果。
52:00
然后F实际上是因为需要输出大小是这个是呃,目标句子它的的大,所以说啊,它这里要转换为度,那其中有个细节啊,就是说GRU。本身G它其实只有两个参数的,一个就是输入,还有一个是隐藏层的初始的输入,但是上面的公式它有三个变量。所以我们应该挑选一个。作为隐藏层输入,另外两个整合一下作为输入。就是说一个作为隐藏层的初始输入,另外两个整合一下作为隐藏层的作作为输入。那么首先我们正推每一个变量的维度是什么东西?首先啊,这个。上俩要相乘啊,并且要保留by size。
53:00
所以说我要将,而且它它是个三维,它是个二维的,所以我先将这个权重扩展一维,然后调换一下这个顺序,把BY放前面去,然后用BMM这个函数按照Bach相乘,就是同一个BA内的矩阵去相乘,OK,我们先看一下这个为代码,首先是将AI底下在一这个维度上,I,那么它就变成这个维度,变成这个维度之后呢,H一下,它就变成这个维度,那你看。这里by size对应上了,然后这里是一,然后这里然后乘以二,那么这两项用BA multiple呃去相乘,就按照一个BA,那么对于第一个BA来说,那么就是这样的一个维度,这个H对于第一个BA来说就是这样的维度,这两个维度相乘,那它就会变成一,然后Co乘以二,然后所有的BA都这样子计算完之后拼接起来,那么就就会变成一个by size,其实它还是个三维的。OK,然后前面我们也说了,GRU是不需要三个变量的,所以我需要将这个W,这个inbedding h啊,这个东西,还有这个东西整合一下,而这个YT啊,实际上是sequence to sequence当中的啊,这写错了口。
54:24
哎。抵扣变量。而扣它的变量,它的维度是什么?是为什么是这个维度,因为我每次只传入来一个词,对吧?我只传入来一个词,然后每个词有多少个呢?呃,有BY赛这么多个,说它的维度就是一维的,所以我先将它拓展一个维度,拓展一个维度它会变成什么呢?它会变成。它会变成by side1,那就是说啊,这个意思是说每一个BY里面都只有一个句子啊,不是就是说呃,一个BI棋里面有有BI赛这么多个样本,每个样本都是由一个单词构成的,就这样子,所以我先将它拓展一个维度呢,然后再通过word in bedding,这样它就变成BY1,然后in bedding dimension,这里大家应该能理解,然后最后我就对WT和这个东西进行一个,大家可以看一下,先que一下,然后通过一个in bed,就是word in bedding,那就变成这样维度,这样维度之后呢,可以看一下这里WT什么维度,WT是这个维度,By size1in hidden选二,然后这里是by size1inding hidden hidden dimension,它俩一拼接就会变成这里后面维度就相加了,而ST减一,它的维度是by size乘以扣的hidden dimension。
55:57
啊,前面我这里也说,在Co的部分,Co这里S它不就是by sizeco们选吗?
56:04
啊,在哪呢?啊,这里所以说我要先将它拓展一个维度,因为通过gru的全是三维的,没有两位的,所以说啊。哎,哦,对,R input就是说输入啊,我现在有输,我我现在输入什么东西呢?输入其实就是有bed y和W去这一个整合,整合之后得到了这种东西叫做呃,底扣的一个输入,那么底扣的隐藏层的输入我就用STST减一了,将拓展一个维度。但是呢,首先我在此之前,因为通过GRU的或者是ITM的,他们都是by size在中间的,所以我先将它transport一下,把by size放到中间,OK,然后S拓展一个SIZE1,然后抵。这样的。然后就将他们传入就OK了,传它会返回两个东西,一个是deco output,一个是deco hidden,它的维度我写我也写在上面了。
57:07
同时呢,这个decode hidden。其实就是新的S。它不是原来的S了,它是新的S,就是说它们,它和原来S的作用是一模一样的,都是用来呃去。就说得到这么一个,呃,注意力的,而它的和原来是不一样的,就是的hidden OK,就是第二个公式,那么第三个公式呢,我就将这三个东西整合一下,然后通过一个全连接升经网络就可以了。好,最后一个公式,我需要将这三个变量全部拼接在一起,然后通过一个全连接升经网络。首先我们先分析一下三个变量的维度啊,这个维度它是这个W的维度是这个ST的维度是这个东西。是1BY size de。因此我们将它们全部拼接起来,因为他们全部都是呃。
58:10
我先将他们全部都去掉一个维度,然后再拼接起来,先看啊。哎,这里写错了吧,这应该是S贵,不是安sque。哦,不好意思。这里应该是squeeze啊,不好意思,我这里写的写错的地方有点多,没办法,当时我这篇文章是两个小时,就我流水一直写写写,中间没停过,就一直写下来的,然后中间会有很多呃细节写错,这是很很正常的,希望大家能理解,然后把他们呃去掉一个一这个维度之后呢,它就变成这样子,这样子之后拼接,拼接之后就按照第一个维度去拼接,那么这三个东西拼接一起,那就变成by size,然后两边选加上in,两边乘二加上选,然后再通过一个全连接神经网络。
59:03
啊,通过一个全限神经网络,全限神经网络我这就没写了,直接下面了,那你看一下,呃,拼接之后呢,然后通过一个FC out FC out其就是个N点,好,咱们下面看一下这个代码吧,这个是代码,代码里面是调用了attention的,首先input我先给它拓展一个维度,按照就上面说了,上上面说过了,我就不说了,好吧,然后继续往下。这里就是说通过attention把S和include output传入attention,它会返回一个权重出来。然后返回这个权重呢,我用BA multiple,就是说按照BA去相乘,去和Co output相乘,得到这样的一个CC,就是这个东西。啊,就是这个C02 C12C2这样东西,然后再传入R,呃,R,再去把这两个东西整合一下,定义为rn input,定义为r input之后呢,再去把这些东西传进去,传入呃,Deco deco也是一个GU。
60:08
那它就会返回这两个东西,有两个东西返回这两个东西之后呢,再把他们去整合一下,通过一个linear得到这样的一个结果,得到一个predict。然后把把这个东西传出来。啊,这里的话大家可以看一下deco黑塔没选啊decoder黑。Decode hidden就是我说的那个S,但是它先呃压缩一个维度,为什么呢?你看decode hidden是这里它是个单向的,所以说而且是单层的,所以说这里是一,这里是一,那么就是一,这里都是一,把它们把它压缩掉,那么底下by size,然后底CL咱们选了就是S,所以这里也对应上了,在这里,在sequence to sequence这里S。抵扣的output就是这里。Predict和SK。
61:00
那么整个就基本上讲完了,下面之后就定义模型就可以了。定义模型的话,一些参数,然后去定义一下。然后最后model是second two second,把这三个都传进来,OK就可以了,嗯,那么最后这里呢,有一个细节啊,就是cross two,这里我是有一个参数ignore index。等于这个东西,这个东西是什么呢?就是说当我在输入的时候啊。这里我不是加了pad嘛,后面加了很多pad嘛,然后我不希望计算这个pad这个类别它的loss,因为我觉得没有什么意义,因为pad本来就没什么用,它只是为了拓展长度的,所以说这里这个参数作用什么呢?忽略某一类别,忽略哪个类别呢?忽略trg pad index这类别,而这个东西它是这个tr vocabulary里面的S,就是three to index。那么这个string,什么t r pad token这个东西。就忽略这个类别,然后补计算器loss。
62:02
就是这样的东西啊,但是要注意就是说忽略的是真实值当中的类别,例如这个代码,然后这个是真实值,这是预测值,我真实值呃呃,类别是一,类别是从零开始的,012只有三类对吧,0123类,然后你看我现在预测值是零,有有三类,我现在预测值全部都认为是第二类,因为是0.60.8,然后0.9嘛。而我的真实值,它的它的标签是全面是第一类,而我要忽略的是什么呢?我要忽略就是第一类是它最后算出来loss等于零,但是如果说我真实值全是第一类,而我预测时全是第二类,然后呢,我在这里写上我忽略的是第二类,还会是零吗?不会,因为它忽略的,它只是忽略真实值里面的东西,它不会忽略预测值里面的是你二,然后预测值里面全是二,这这个也是二二类,这个也是二类,这也是第二类。
63:00
他会是零吗?不会,它还是会有一个损失在里面的。这个是要注意的地方。好,那么啊,代码的话,最后就可以看这里。啊,这这就是我说的,然后呢,呃。如果说你没有那个的话,那你就去get up上面看在这里。这里,Sequence to sequence attention。好吃。在这里可以看到。那么感谢大家收看这期视频,后面的话,这里面有些写的不太好的地方,有些bug,我等会儿结束了,我会下去修改一下。好,谢谢大家。
我来说两句