利用预测答案与标签的f1分数作为奖励
相关论文
- Reinforced Mnemonic Reader for Machine Reading Comprehension
- DCN+: MIXED OBJECTIVE AND DEEP RESIDUAL
COATTENTION FOR QUESTION ANSWERING
在抽取式阅读理解任务当中,模型最终的预测是答案的起始位置和终止位置。
损失函数是预测的起始位置和标签的起始位置的交叉熵+预测的终止位置和标签的终止位置的交叉熵
这就有一个问题:过于严格
因为假设答案是“重力作用”,而预测的答案是"重力",显然是可以接受的答案,但是对于交叉熵损失来说,这就是错误的,因为终止位置不对。
为了让模型不去惩罚这个预测的答案,就要告诉模型这个答案是好的,所以可以利用预测答案与标签的f1分数作为奖励。
最常用的做法就是REINFORCE算法:
REINFORCE
强化学习的目标是尽可能获得最多的累计奖励,因此一个好的策略应当能够反应强化学习的目标,所以策略的目标函数可以写成
J
(
θ
)
=
E
π
θ
(
a
∣
s
)
[
R
(
s
,
a
)
]
J(\theta)=\underset{\pi_\theta(a|s)}{\mathbb{E}}[R(s,a)]
J(θ)=πθ(a∣s)E[R(s,a)]
上式的含义就是,对于所有可能的状态 s s s,在策略 π θ \pi_\theta πθ下产生的所有可能的行为 a a a,我们希望得到的奖励 R ( s , a ) R(s,a) R(s,a)最大。(策略 π θ ( a ∣ s ) \pi_\theta(a|s) πθ(a∣s)是行为空间上的概率密度函数)
Policy Gradient
目标函数对参数
θ
\theta
θ的导数叫做策略梯度(policy gradient)
J
(
θ
)
=
E
π
θ
(
a
∣
s
)
[
R
(
s
,
a
)
]
=
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
R
(
s
,
a
)
∂
J
(
θ
)
∂
θ
=
∑
(
s
,
a
)
∈
D
∂
π
θ
(
a
∣
s
)
∂
θ
R
(
s
,
a
)
∂
J
(
θ
)
∂
θ
=
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
1
π
θ
(
a
∣
s
)
∂
π
θ
(
a
∣
s
)
∂
θ
R
(
s
,
a
)
∂
J
(
θ
)
∂
θ
=
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
∂
J
(
θ
)
∂
θ
=
E
π
θ
(
a
∣
s
)
[
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
]
\begin{aligned} J(\theta)&=\underset{\pi_\theta(a|s)}{\mathbb{E}}[R(s,a)] \\ &= \sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)R(s,a) \\ \frac{\partial J(\theta)}{\partial\theta}&= \sum_{(s,a)\in \mathcal{D}}\frac{\partial\pi_\theta(a|s)}{\partial \theta}R(s,a)\\ \frac{\partial J(\theta)}{\partial\theta}&= \sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)\frac{1}{\pi_\theta(a|s)}\frac{\partial\pi_\theta(a|s)}{\partial \theta}R(s,a)\\ \frac{\partial J(\theta)}{\partial\theta}&= \sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)\nabla_\theta \log \pi_\theta(a|s)R(s,a)\\ \frac{\partial J(\theta)}{\partial\theta}&=\underset{\pi_\theta(a|s)}{\mathbb{E}}[\nabla_\theta\log \pi_\theta(a|s)R(s,a)] \end{aligned}
J(θ)∂θ∂J(θ)∂θ∂J(θ)∂θ∂J(θ)∂θ∂J(θ)=πθ(a∣s)E[R(s,a)]=(s,a)∈D∑πθ(a∣s)R(s,a)=(s,a)∈D∑∂θ∂πθ(a∣s)R(s,a)=(s,a)∈D∑πθ(a∣s)πθ(a∣s)1∂θ∂πθ(a∣s)R(s,a)=(s,a)∈D∑πθ(a∣s)∇θlogπθ(a∣s)R(s,a)=πθ(a∣s)E[∇θlogπθ(a∣s)R(s,a)]
上面就是策略梯度的推导过程,最后一行就是常用的策略梯度的形式,通常我们不会去求这个期望,而是仅仅利用一个或者多个样本来近似。
也就是说:
当给定一个状态
s
s
s,输出一个行为
a
a
a之后,就利用当前得到的奖励
R
(
s
,
a
)
R(s,a)
R(s,a)乘以
∇
θ
log
π
θ
(
a
∣
s
)
\nabla_\theta\log\pi_\theta(a|s)
∇θlogπθ(a∣s)作为策略梯度,其中
log
π
θ
(
a
∣
s
)
\log\pi_\theta(a|s)
logπθ(a∣s)就是log_softmax(logits)
这就是DCN+: MIXED OBJECTIVE AND DEEP RESIDUAL
COATTENTION FOR QUESTION ANSWERING论文中的公式
这里的状态就是最后一层的输出,它是两个长度为seq_length的向量,编程时习惯取名字start_logits和end_logits,可以理解为未归一化的softmax概率,start_logits每一个值对应的是当前的word是起始位置的分数,end_logits每一个值对应的是当前的word是终止位置的分数。
这里的行为自然是将要预测的答案位置,对应的是logits中的最大值所在的下标。
现在就差这个奖励怎么定义,前面我们说过,利用预测答案与标签的f1分数作为奖励,这个预测的答案是在logits上进行采样(也就是sample,而不是argmax),然后得到预测的答案位置。
除此之外,DCN+这篇论文又在奖励的基础上减去了一个baseline,这个baseline的定义是在当前的logits上做贪婪求解(也就是argmax)得到的预测答案与标签的f1分数.
下面我们证明在奖励上减去一个baseline可以减小策略梯度的方差同时保证策略梯度的期望不变
添加baseline可以减小策略梯度的方差且保持期望不变
证明添加baseline对策略梯度是不变的,前提是baseline与动作无关
推导过程:
E
π
θ
(
a
∣
s
)
[
∇
θ
log
π
θ
(
a
∣
s
)
∗
b
]
=
b
∗
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
∇
θ
log
π
θ
(
a
∣
s
)
=
b
∗
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
1
π
θ
(
a
∣
s
)
∂
π
θ
(
a
∣
s
)
∂
θ
=
b
∗
∑
(
s
,
a
)
∈
D
∂
π
θ
(
a
∣
s
)
∂
θ
=
b
∗
∂
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
∂
θ
=
b
∗
∂
1
∂
θ
=
0
\begin{aligned} \underset{\pi_\theta(a|s)}{\mathbb{E}}[\nabla_{\theta}\log \pi_\theta(a|s)*b] &=b*\sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)\nabla_{\theta}\log \pi_\theta(a|s) \\ &= b*\sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)\frac{1}{\pi_\theta(a|s)}\frac{\partial \pi_\theta(a|s)}{\partial \theta}\\ &= b*\sum_{(s,a)\in \mathcal{D}} \frac{\partial \pi_\theta(a|s)}{\partial \theta}\\ &= b*\frac{\partial \sum_{(s,a)\in \mathcal{D}} \pi_\theta(a|s)}{\partial \theta}\\ &= b*\frac{\partial 1}{\partial \theta} \\ &= 0 \end{aligned}
πθ(a∣s)E[∇θlogπθ(a∣s)∗b]=b∗(s,a)∈D∑πθ(a∣s)∇θlogπθ(a∣s)=b∗(s,a)∈D∑πθ(a∣s)πθ(a∣s)1∂θ∂πθ(a∣s)=b∗(s,a)∈D∑∂θ∂πθ(a∣s)=b∗∂θ∂∑(s,a)∈Dπθ(a∣s)=b∗∂θ∂1=0
需要注意的是:
- 求导和求和是可以互换的
- baseline b是与动作无关的,绝对不能是关于动作的函数
知道了上面的计算过程,下面就容易了,我们来看策略梯度:
E
π
θ
(
a
∣
s
)
[
∇
θ
log
π
θ
(
a
∣
s
)
(
R
(
s
,
a
)
−
b
)
]
=
E
π
θ
(
a
∣
s
)
[
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
]
−
E
π
θ
(
a
∣
s
)
[
∇
θ
log
π
θ
(
a
∣
s
)
b
]
=
E
π
θ
(
a
∣
s
)
[
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
]
]
\begin{aligned} \underset{\pi_\theta(a|s)}{\mathbb{E}}[\nabla_{\theta}\log \pi_\theta(a|s)(R(s,a)-b)]&=\underset{\pi_\theta(a|s)}{\mathbb{E}}[\nabla_{\theta}\log \pi_\theta(a|s)R(s,a)]-\underset{\pi_\theta(a|s)}{\mathbb{E}}[\nabla_{\theta}\log \pi_\theta(a|s)b] \\ &=\underset{\pi_\theta(a|s)}{\mathbb{E}}[\nabla_{\theta}\log \pi_\theta(a|s)R(s,a)]] \end{aligned}
πθ(a∣s)E[∇θlogπθ(a∣s)(R(s,a)−b)]=πθ(a∣s)E[∇θlogπθ(a∣s)R(s,a)]−πθ(a∣s)E[∇θlogπθ(a∣s)b]=πθ(a∣s)E[∇θlogπθ(a∣s)R(s,a)]]
所以说添加个与动作无关的baseline是不改变策略梯度值的。
证明合适的baseline可以减小策略梯度的方差
我们需要知道方差的定义是 Var [ x ] = E [ x 2 ] − E 2 [ x ] \text{Var}[x]=\mathbb{E}[x^2]-\mathbb{E}^2[x] Var[x]=E[x2]−E2[x]
所以策略梯度的方差:
V
a
r
[
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
]
=
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
)
2
]
−
E
π
θ
(
a
∣
s
)
2
[
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
]
Var[\nabla_{\theta}\log \pi_\theta(a|s)R(s,a)]=\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s)R(s,a))^2]-\underset{\pi_\theta(a|s)}{\mathbb{E}}^2[\nabla_{\theta}\log \pi_\theta(a|s)R(s,a)]
Var[∇θlogπθ(a∣s)R(s,a)]=πθ(a∣s)E[(∇θlogπθ(a∣s)R(s,a))2]−πθ(a∣s)E2[∇θlogπθ(a∣s)R(s,a)]
减去baselin后的方差:
V
a
r
[
∇
θ
log
π
θ
(
a
∣
s
)
(
R
(
s
,
a
)
−
b
)
]
=
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
(
R
(
s
,
a
)
−
b
)
)
2
]
−
E
π
θ
(
a
∣
s
)
2
[
∇
θ
log
π
θ
(
a
∣
s
)
(
R
(
s
,
a
)
−
b
)
]
Var[\nabla_{\theta}\log \pi_\theta(a|s)(R(s,a)-b)]=\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s)(R(s,a)-b))^2]-\underset{\pi_\theta(a|s)}{\mathbb{E}}^2[\nabla_{\theta}\log \pi_\theta(a|s)(R(s,a)-b)]
Var[∇θlogπθ(a∣s)(R(s,a)−b)]=πθ(a∣s)E[(∇θlogπθ(a∣s)(R(s,a)−b))2]−πθ(a∣s)E2[∇θlogπθ(a∣s)(R(s,a)−b)]
第二项我们不需要考虑,因为我们已经推导出它和
E
π
θ
(
a
∣
s
)
2
[
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
]
\underset{\pi_\theta(a|s)}{\mathbb{E}}^2[\nabla_{\theta}\log \pi_\theta(a|s)R(s,a)]
πθ(a∣s)E2[∇θlogπθ(a∣s)R(s,a)]一样的。
我们主要看第一项,如果第一项可以小于
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
)
2
]
\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s)R(s,a))^2]
πθ(a∣s)E[(∇θlogπθ(a∣s)R(s,a))2],那么我们就证明出来添加了baseline后减小了策略梯度的方差。
推导过程:
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
(
R
(
s
,
a
)
−
b
)
)
2
]
=
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
)
2
(
R
(
s
,
a
)
−
b
)
2
]
\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s)(R(s,a)-b))^2]=\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s))^2(R(s,a)-b)^2]
πθ(a∣s)E[(∇θlogπθ(a∣s)(R(s,a)−b))2]=πθ(a∣s)E[(∇θlogπθ(a∣s))2(R(s,a)−b)2]
我们假设变量无关性,即
∇
θ
log
π
θ
(
a
∣
s
)
\nabla_{\theta}\log \pi_\theta(a|s)
∇θlogπθ(a∣s)与
R
(
s
,
a
)
−
b
R(s,a)-b
R(s,a)−b是相互独立的。那么
E
(
x
y
)
=
E
(
x
)
E
(
y
)
\mathbb{E}(xy)=\mathbb{E}(x)\mathbb{E}(y)
E(xy)=E(x)E(y)当
x
x
x与
y
y
y相互独立时。
所以我们有:
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
)
2
(
R
(
s
,
a
)
−
b
)
2
]
=
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
)
2
]
E
π
θ
(
a
∣
s
)
[
(
R
(
s
,
a
)
−
b
)
2
]
\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s))^2(R(s,a)-b)^2]=\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s))^2]\underset{\pi_\theta(a|s)}{\mathbb{E}}[(R(s,a)-b)^2]
πθ(a∣s)E[(∇θlogπθ(a∣s))2(R(s,a)−b)2]=πθ(a∣s)E[(∇θlogπθ(a∣s))2]πθ(a∣s)E[(R(s,a)−b)2]
同样的思路:
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
R
(
s
,
a
)
)
2
]
=
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
)
2
(
R
(
s
,
a
)
)
2
]
=
E
π
θ
(
a
∣
s
)
[
(
∇
θ
log
π
θ
(
a
∣
s
)
)
2
]
E
π
θ
(
a
∣
s
)
[
(
R
(
s
,
a
)
)
2
]
\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s)R(s,a))^2]=\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s))^2(R(s,a))^2]=\underset{\pi_\theta(a|s)}{\mathbb{E}}[(\nabla_{\theta}\log \pi_\theta(a|s))^2]\underset{\pi_\theta(a|s)}{\mathbb{E}}[(R(s,a))^2]
πθ(a∣s)E[(∇θlogπθ(a∣s)R(s,a))2]=πθ(a∣s)E[(∇θlogπθ(a∣s))2(R(s,a))2]=πθ(a∣s)E[(∇θlogπθ(a∣s))2]πθ(a∣s)E[(R(s,a))2]
所以我们主要看第二项 E π θ ( a ∣ s ) [ ( R ( s , a ) − b ) 2 ] \underset{\pi_\theta(a|s)}{\mathbb{E}}[(R(s,a)-b)^2] πθ(a∣s)E[(R(s,a)−b)2],看看 b b b取什么值的时候它可以小于 E π θ ( a ∣ s ) [ ( R ( s , a ) ) 2 ] \underset{\pi_\theta(a|s)}{\mathbb{E}}[(R(s,a))^2] πθ(a∣s)E[(R(s,a))2]
我们把第二项看成是关于 b b b的函数(比如 ( 1 − b ) 2 (1-b)^2 (1−b)2),然后对 b b b求导,导数为0的点就是函数的极小值点(这里说明下,按理来说导数为0的点有可能是极大值,但是我们知道第二项关于 b b b的二阶导数是2,二阶导数值大于0,那么我们知道该点一定是极小值点)
推导过程:
step1 将期望用展开:
E
π
θ
(
a
∣
s
)
[
(
R
(
s
,
a
)
−
b
)
2
]
=
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
(
R
(
s
,
a
)
−
b
)
2
\underset{\pi_\theta(a|s)}{\mathbb{E}}[(R(s,a)-b)^2]=\sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)(R(s,a)-b)^2
πθ(a∣s)E[(R(s,a)−b)2]=(s,a)∈D∑πθ(a∣s)(R(s,a)−b)2
step2 对b求导:
d
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
(
R
(
s
,
a
)
−
b
)
2
d
b
=
−
2
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
(
R
(
s
,
a
)
−
b
)
\frac{d\sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)(R(s,a)-b)^2}{db}=-2\sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)(R(s,a)-b)
dbd∑(s,a)∈Dπθ(a∣s)(R(s,a)−b)2=−2(s,a)∈D∑πθ(a∣s)(R(s,a)−b)
step3 令导数为:
−
2
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
(
R
(
s
,
a
)
−
b
)
=
0
-2\sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)(R(s,a)-b)=0
−2(s,a)∈D∑πθ(a∣s)(R(s,a)−b)=0
step4 整理得:
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
R
(
s
,
a
)
=
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
b
\sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)R(s,a)=\sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)b
(s,a)∈D∑πθ(a∣s)R(s,a)=(s,a)∈D∑πθ(a∣s)b
step5 ,由于策略
π
θ
(
a
∣
s
)
\pi_\theta(a|s)
πθ(a∣s)是行为空间上的概率密度函数,而且baseline b与行为无关,所以:
b
=
∑
(
s
,
a
)
∈
D
π
θ
(
a
∣
s
)
R
(
s
,
a
)
=
E
π
θ
(
a
∣
s
)
[
R
(
s
,
a
)
]
b=\sum_{(s,a)\in \mathcal{D}}\pi_\theta(a|s)R(s,a)=\underset{\pi_\theta(a|s)}{\mathbb{E}}[R(s,a)]
b=(s,a)∈D∑πθ(a∣s)R(s,a)=πθ(a∣s)E[R(s,a)]
**我们最终推导出来当 b = E π θ ( a ∣ s ) [ R ( s , a ) ] b=\underset{\pi_\theta(a|s)}{\mathbb{E}}[R(s,a)] b=πθ(a∣s)E[R(s,a)]时,上式的 E π θ ( a ∣ s ) [ ( R ( s , a ) − b ) 2 ] \underset{\pi_\theta(a|s)}{\mathbb{E}}[(R(s,a)-b)^2] πθ(a∣s)E[(R(s,a)−b)2]函数值最小,且一定小于 E π θ ( a ∣ s ) [ ( R ( s , a ) ) 2 ] \underset{\pi_\theta(a|s)}{\mathbb{E}}[(R(s,a))^2] πθ(a∣s)E[(R(s,a))2]。而且我们发现 E π θ ( a ∣ s ) [ R ( s , a ) ] \underset{\pi_\theta(a|s)}{\mathbb{E}}[R(s,a)] πθ(a∣s)E[R(s,a)]其实就是所有的奖励的期望值。
但是我们是不可能求出来所有的奖励的,只能用一个或者多个奖励值近似期望。
DCN+这篇论文的奖励值采取的是在当前的logits上做贪婪求解(也就是argmax)得到的预测答案与标签的f1分数.
下面我们用代码重复一遍
代码部分
定义相关变量
import torch
seq_length=10
start_positions=torch.LongTensor([0,0,0,1,0,0,0,0,0,0])
end_positions =torch.LongTensor([0,0,0,0,0,0,0,0,0,1])
start_logits=torch.randn(seq_length)
end_logits=torch.randn(seq_length)
需要注意一点,end_logits的最大值的下标要大于start_logits的最大值的下标才可以
构造贪婪策略下模型做出的行为
greedy_start_predictions=torch.zeros(seq_length).long().scatter(index=torch.argmax(start_logits),dim=0,value=1)
greedy_end_predictions=torch.zeros(seq_length).long().scatter(index=torch.argmax(end_logits),dim=0,value=1)
print(greedy_start_predictions)
print(greedy_end_predictions)
以上两个就是模型在贪婪策略下做出的行为,也就是预测第七个单词作为起始位置,第八个单词作为终止位置
构造采样策略下模型做出的行为
sample_start_predictions=torch.zeros(seq_length).long().scatter(index=torch.multinomial(torch.softmax(start_logits,dim=0),1),dim=0,value=1)
sample_end_predictions=torch.zeros(seq_length).long().scatter(index=torch.multinomial(torch.softmax(end_logits,dim=0),1),dim=0,value=1)
print(sample_start_predictions)
print(sample_end_predictions)
计算之间的单词重叠
target_text_span=torch.cumsum(start_positions,dim=0)-torch.cumsum(end_positions,dim=0)+end_positions
greedy_text_span=torch.cumsum(greedy_start_predictions,dim=0)-torch.cumsum(greedy_end_predictions,dim=0)+greedy_end_predictions
sample_text_span=torch.cumsum(sample_start_predictions,dim=0)-torch.cumsum(sample_end_predictions,dim=0)+sample_end_predictions
print(target_text_span)
print(greedy_text_span)
print(sample_text_span)
- 第一行是标签答案的跨度
- 第二行是贪婪策略下做出的行为预测的答案跨度
- 第三行是随机采样策略下做出的行为预测的答案跨度
计算贪婪策略下的f1分数,作为baseline
union1=torch.clamp(target_text_span+greedy_text_span,0,1)#tensor([0, 0, 0, 1, 1, 1, 1, 1, 1, 1])
diff1=torch.abs(target_text_span-greedy_text_span)#tensor([0, 0, 0, 1, 1, 1, 0, 0, 0, 1])
num_same1=torch.sum(union1)-torch.sum(diff1)#3,表明有三个位置是重合的
greedy_precision=num_same1.item()/torch.sum(greedy_text_span).item()#重合的位置长度/预测的文本长度
greedy_recall=num_same1.item()/torch.sum(target_text_span).item()#重合的长度/标签的文本长度
greedy_f1=2*greedy_precision*greedy_recall/(greedy_precision+greedy_recall)
print(greedy_precision,greedy_recall,greedy_f1)
0.6就是baseline
计算采样策略下的f1分数
union1=torch.clamp(target_text_span+sample_text_span,0,1)#tensor([0, 0, 0, 1, 1, 1, 1, 1, 1, 1])
diff1=torch.abs(target_text_span-sample_text_span)#tensor([0, 0, 0, 1, 1, 1, 0, 0, 0, 1])
num_same1=torch.sum(union1)-torch.sum(diff1)#3,表明有三个位置是重合的
sample_precision=num_same1.item()/torch.sum(sample_text_span).item()#重合的位置长度/预测的文本长度
sample_recall=num_same1.item()/torch.sum(target_text_span).item()#重合的长度/标签的文本长度
sample_f1=2*sample_precision*sample_recall/(sample_precision+sample_recall)
print(sample_precision,sample_recall,sample_f1)
采样做出的行为才被认为模型真正做出的行为
计算交叉熵loss
start_loss=-torch.sum(sample_start_predictions*torch.log_softmax(start_logits,dim=0))
print(start_loss)
end_loss=-torch.sum(sample_end_predictions*torch.log_softmax(end_logits,dim=0))
print(end_loss)
千万注意,我们是在求强化学习的loss,此时的标签是随机采样出来的那些位置,而不是真正的标签,真正的标签只有在计算奖励的时候才会用到
计算奖励reward
with torch.no_grad():
reward=sample_f1-greedy_f1#将贪婪策略下的f1分数作为baseline
得到强化学习的loss:
print(reward)
rl_loss=reward*(start_loss+end_loss)
print(rl_loss)
最终只需要loss.backward()。
上述的baseline有个问题
我们已经清楚的了解到,DCN+模型是将随机采样做出的行为获得的奖励作为指导模型的真正的奖励,利用贪心策略做出的行为得到的奖励作为baseline。
然而存在的问题就是当随机采样做出的行为不如贪心策略做出的行为好的时候,那么随机采样做出的行为就会受到抑制。
以上面的例子为例,贪心策略下的f1分数大于随机采样的f1分数,导致奖励为负数-0.15,那么即使此时的随机采样做出的行为已经有两个单词和标准答案重合,但是模型仍然不鼓励做出这种行为。
为了解决这个问题,RMR模型(Reinforced Mnemonic Reader for Machine Reading Comprehension)提出一种动态的决定奖励和baseline的方法。
思想是这样的:
将随机采样策略和贪心策略看成两个不同的策略,随机采样策略鼓励探索(exploration),贪心策略鼓励利用(exploitation)。并不总是将贪心策略获得的奖励看成baseline。
而是视情况而定:
- 当随机采样做出的行为获得的奖励(F1分数)大于贪心策略做出的行为获得的分数时,就将贪心策略的奖励作为baseline
- 反之亦然
这样就保证了获得的奖励始终是正的。
所以我们就可以写出代码了:
接着上面的过程:
with torch.no_grad():
reward_sample=sample_f1-greedy_f1
sample_start_loss=-torch.sum(sample_start_predictions*torch.log_softmax(start_logits,dim=0))
sample_end_loss=-torch.sum(sample_end_predictions*torch.log_softmax(end_logits,dim=0))
with torch.no_grad():
reward_greedy=greedy_f1-sample_f1
greedy_start_loss=-torch.sum(greedy_start_predictions*torch.log_softmax(start_logits,dim=0))
greedy_end_loss=-torch.sum(greedy_end_predictions*torch.log_softmax(end_logits,dim=0))
rl_loss=torch.mean(reward_sample*(sample_start_loss+sample_end_loss)+reward_greedy*(greedy_start_loss+greedy_end_loss))
我们来分析一下:
由于当前情况下随机采样的奖励不如贪心策略的高,所以我们可以看到reward_sample是负数,此时不鼓励随机采样策略,相反,模型会鼓励贪心策略,因为奖励是正的。