#P5312. 第3题-模域双向循环注意力网络前向计算
-
1000ms
Tried: 378
Accepted: 152
Difficulty: 8
所属公司 :
华为
时间 :2026年8月26日-AI方向
第3题-模域双向循环注意力网络前向计算
解题思路
本题没有复杂的模型训练过程,只需要严格按照题目给出的公式完成一次前向计算,整体采用模拟算法和矩阵乘法。
首先处理 S 层双向循环网络。对于每一层,正向状态按照 1→N 的顺序递推,反向状态按照 N→1 的顺序递推。每个位置分别计算输入向量与输入权重的乘积、上一状态与循环权重的乘积,再加上偏置并对 MOD 取模,最后将正向和反向状态拼接,作为下一层的输入。
完成 S 层编码后得到每个位置的 2R 维向量 et。
接着计算 A 个注意力头。对于每个头,先由 et 分别计算查询向量、键向量和值向量,再枚举位置 t 和 s,通过点积得到注意力分数,并使用该分数对所有值向量进行加权求和。题目明确不需要使用缩放、softmax 或 mask,因此直接按照公式计算并取模即可。
题目内容
需要在模 MOD 的整数域中,完成一个由多层双向循环神经网络和多头自注意力组成的网络的一次前向计算。
输入序列共有 N 个位置,位置 t 的原始输入向量记为 xt,其维度为 F。网络先经过 S 层双向 RNN 编码,再进行包含 A 个注意力头的多头自注意力计算,之后通过残差连接,最后使用线性输出层得到 C 维向量 yt。
所有向量均视为行向量,矩阵乘法均采用“行向量乘矩阵”的方式。所有输入参数均为满足 0≤x<MOD 的非负整数。每次完成向量加法、点积或矩阵乘法后,都需要将结果对 MOD 取模。
- 多层双向 RNN 编码
对于双向 RNN 的第 l 层,位置 t 的输入记为 at(l)。第一层直接使用原始输入,即 at(1)=xt。
每一层的输入维度记作 dl,其中 dl={F,2R,l=1l>1。
这里,R 是单个方向的隐藏状态维度。因此,一层双向 RNN 在每个位置都会分别产生一个 R 维正向状态和一个 R 维反向状态。
第 l 层正向计算所使用的参数为 Uf(l)、Vf(l)、cf(l),其规模依次为 dl×R、R×R、1×R。该方向的给定初始状态为 p0(l),规模为 1×R。
正向状态从位置 1 开始,按照 1,2,…,N 的顺序计算。对于每个 t,有 pt(l)=(at(l)Uf(l)+pt−1(l)Vf(l)+cf(l))modMOD。
同一层的反向计算使用 Ub(l)、Vb(l)、cb(l),规模分别为 dl×R、R×R、1×R。反向方向的给定初始状态为 rN+1(l),其规模为 1×R。
反向状态的计算次序与正向相反,从位置 N 开始依次处理到位置 1。对于每个 t,有 rt(l)=(at(l)Ub(l)+rt+1(l)Vb(l)+cb(l))modMOD。
当第 l 层的两个方向均计算完成后,把同一位置上的正向状态放在前、反向状态放在后进行拼接。若 l<S,该结果作为下一层对应位置的输入,即 at(l+1)=[pt(l)∥rt(l)]。
因此,从第 2 层开始,每个 at(l) 的维度均为 2R。
经过全部 S 层双向 RNN 后,取最后一层在位置 t 的两个方向状态,并定义 et=[pt(S)∥rt(S)]。
此时 et∈ZMOD2R,它将作为后续多头自注意力部分的输入。
- 多头自注意力
多头自注意力共有 A 个注意力头,注意力头编号为 h=0,1,…,A−1,每个头的维度为 Q。
本题使用未归一化的点积注意力,不进行缩放、不使用 softmax,也不存在 mask。
对于任意注意力头 h,均给定三个规模为 2R×Q 的矩阵 Qh、Kh、Vh。在位置 t,分别计算 qt(h)=etQhmodMOD、kt(h)=etKhmodMOD、vt(h)=etVhmodMOD。
上述三个向量均为 Q 维,即 qt(h),kt(h),vt(h)∈ZMODQ。
接下来,对于位置 t 和位置 s,利用 qt(h) 与 ks(h) 的点积计算第 h 个注意力头的注意力分数:
βt,s(h)=(∑j=0Q−1qt(h)[j]⋅ks(h)[j])modMOD。
得到位置 t 对所有位置的注意力分数后,对每个分量 j=0,1,…,Q−1 计算:
ct(h)[j]=(∑s=1Nβt,s(h)⋅vs(h)[j])modMOD。
由此得到第 h 个注意力头在位置 t 的 Q 维输出 ct(h)。
对于同一个位置 t,将各注意力头的结果按照编号 0,1,…,A−1 的顺序拼接,得到 ct=[ct(0)∥ct(1)∥⋯∥ct(A−1)]。
拼接后的向量满足 ct∈ZMODAQ。
- 残差连接
多头自注意力产生的 AQ 维向量 ct 需要通过投影矩阵 Wp 映射到 2R 维。
其中,Wp 的规模为 AQ×2R,偏置 cp 的规模为 1×2R。
投影结果与同一位置的编码结果 et 进行残差相加,得到 ut=(ctWp+cp+et)modMOD。
- 输出层
残差连接后的 ut 通过最后的线性层得到位置 t 的输出。
输出层包含规模为 2R×C 的矩阵 Wy 和规模为 1×C 的偏置 cy,计算方式为 yt=(utWy+cy)modMOD。
最终得到 yt∈ZMODC。需要计算输入序列全部 N 个位置对应的最终输出向量。
输入描述
第一行给出 8 个整数 N、F、R、C、S、A、Q、MOD,分别表示序列长度、输入维度、单向隐藏状态维度、输出维度、双向 RNN 层数、注意力头数量、每个注意力头的维度以及模数。
数据范围为:
1≤N≤10, 1≤F≤5, 1≤R≤5。
1≤C≤5, 1≤S≤3, 1≤A≤4, 1≤Q≤4。
2≤MOD≤97。
随后给出原始输入序列,共 N 行。第 t 行包含 F 个整数,表示位置 t 的向量 xt。
原始输入之后是 S 层双向 RNN 的参数,各层按照 l=1,2,…,S 的顺序给出。对于当前层 l,输入维度为 dl={F,2R,l=1l>1。
每一层内部的参数输入顺序固定如下:
- Uf(l):输入 dl 行,每行包含 R 个整数;
- Vf(l):输入 R 行,每行包含 R 个整数;
- cf(l):输入 1 行,包含 R 个整数;
- Ub(l):输入 dl 行,每行包含 R 个整数;
- Vb(l):输入 R 行,每行包含 R 个整数;
- cb(l):输入 1 行,包含 R 个整数;
- p0(l):输入 1 行,包含 R 个整数;
- rN+1(l):输入 1 行,包含 R 个整数。
全部 S 层双向 RNN 参数之后,依次给出 A 个注意力头的参数。注意力头按照 h=0,1,…,A−1 的编号顺序输入,每个头依次包含:
- Qh:输入 2R 行,每行包含 Q 个整数;
- Kh:输入 2R 行,每行包含 Q 个整数;
- Vh:输入 2R 行,每行包含 Q 个整数。
所有注意力头的参数结束后,剩余参数按照 Wp、cp、Wy、cy 的顺序给出:
- Wp:输入 AQ 行,每行包含 2R 个整数;
- cp:输入 1 行,包含 2R 个整数;
- Wy:输入 2R 行,每行包含 C 个整数;
- cy:输入 1 行,包含 C 个整数。
所有输入矩阵均按照从上到下、逐行的顺序给出。
输出描述
按照位置 1,2,…,N 的顺序输出计算结果,共输出 N 行。
第 t 行包含 C 个非负整数,依次表示最终输出向量 yt 的各个分量,相邻整数之间使用一个空格分隔。
样例1
输入
1 1 1 1 1 1 1 5
2
3
4
1
2
1
3
4
0
1
0
0
1
4
3
1 4
2 1
2
1
0
输出
1
说明
由于 N=1,只需计算位置 1。第 1 层正向隐藏状态为
p1(1)=(2⋅3+4⋅4+1)mod5=23mod5=3。
反向隐藏状态为
r1(1)=(2⋅2+0⋅1+3)mod5=7mod5=2。
因此编码器输出 e1=[3,2]。
注意力头中: q1=e1Q0=3⋅1+2⋅0=3, k1=e1K0=3⋅0+2⋅1=2, v1=e1V0=(3⋅4+2⋅3)mod5=18mod5=3。 注意力分数 β1,1=q1k1mod5=6mod5=1,因此注意力输出 c1=1⋅3mod5=3。
投影层中 c1Wp=[3⋅1,3⋅4]mod5=[3,2]。 残差连接后 u1=([3,2]+[2,1]+[3,2])mod5=[3,0]。 输出层计算 y1=(3⋅2+0⋅1+0)mod5=6mod5=1。
最终输出为 1。
样例2
输入
2 1 1 2 1 1 1 5
1
2
1
0
0
1
0
0
0
0
1
0
0
1
1
0
1 1
0 0
1 0
0 1
0 0
输出
1 1
2 2
说明
第 1 层中正向和反向都只使用当前输入,因此
pt(1)=xt,rt(1)=xt。
于是位置 1 的编码器输出为 e1=[1,1],位置 2 的编码器输出为 e2=[2,2]。
注意力头参数将 qt 取为 et 的第 1 个分量,kt 取为 et 的第 2 个分量,vt 取为 et 的第 1 个分量。
所以 q1=1,q2=2,k1=1,k2=2,v1=1,v2=2。
对于位置 1,注意力分数为
β1,1=1⋅1mod5=1,
β1,2=1⋅2mod5=2。
注意力输出为
c1=(1⋅1+2⋅2)mod5=5mod5=0。
对于位置 2,注意力分数为
β2,1=2⋅1mod5=2,
β2,2=2⋅2mod5=4。
注意力输出为
c2=(2⋅1+4⋅2)mod5=10mod5=0。
所以两个位置的注意力输出均为 0。残差后 ut=et,输出层使用单位矩阵,因此最终输出为位置 1 的 [1,1] 和位置 2 的 [2,2]。
样例3
输入
1 1 1 1 1 2 1 5
2
3
4
1
2
1
3
4
0
1
0
0
1
4
3
0
1
1
2
1
4
1 0
0 1
0 0
1
1
0
输出
2
说明
由于 N=1,仍只需计算位置 1。第 1 层正向隐藏状态为
p1(1)=(2⋅3+4⋅4+1)mod5=3。
反向隐藏状态为
r1(1)=(2⋅2+0⋅1+3)mod5=2。
因此编码器输出 e1=[3,2]。
第 0 个头中:
q1(0)=3⋅1+2⋅0=3,
k1(0)=3⋅0+2⋅1=2,
v1(0)=(3⋅4+2⋅3)mod5=3。
注意力分数
β1,1(0)=3⋅2mod5=6mod5=1,
因此该头输出 c1(0)=1⋅3=3。
第 1 个头中:
q1(1)=3⋅0+2⋅1=2,
k1(1)=(3⋅1+2⋅2)mod5=7mod5=2,
v1(1)=(3⋅1+2⋅4)mod5=11mod5=1。
注意力分数
β1,1(1)=2⋅2mod5=4,
因此该头输出 c1(1)=4⋅1=4。
拼接后注意力输出为 c1=[3,4]。投影矩阵是单位矩阵,所以残差后 u1=([3,4]+[0,0]+[3,2])mod5=[1,1]。 输出层计算 y1=(1⋅1+1⋅1+0)mod5=2。
最终输出为 2。