我正在尝试了解Python中Karpathy的pong代码,解释如下:karpathy pong
# forward the policy network and sample an action from the returned probability
#########action 2 is up and 3 is down
aprob, h = policy_forward(x)
print("aprob\n {}\n h\n {}\n".format(aprob, h))
#2 is up, 3 is down
action = 2 if np.random.uniform() < aprob else 3 # roll the dice!
print("action\n {}\n".format(action))
# record various intermediates (needed later for backprop)
xs.append(x) # observation, ie. the difference frame?
#print("xs {}".format(xs))
hs.append(h) # hidden state obtained from forward pass
#print("hs {}".format(hs))
#if action is up, y = 1, else 0
y = 1 if action == 2 else 0 # a "fake label"
print("y \n{}\n".format(y))
dlogps.append(y - aprob) # grad that encourages the action that was taken to be taken (see http://cs231n.github.io/neural-networks-2/#losses if confused)
print("dlogps\n {}\n".format(dlogps))
# step the environment and get new measurements
observation, reward, done, info = env.step(action)
print("observation\n {}\n reward\n {}\n done\n {}\n ".format(observation, reward, done))
reward_sum += reward
print("reward_sum\n {}\n".format(reward_sum))
drs.append(reward) # record reward (has to be done after we call step() to get reward for previous action)
print("drs\n {}\n".format(drs))
if done: # an episode finished
episode_number += 1
在上面的代码段中,我不太理解为什么需要假标签以及这意味着什么:
dlogps.append(y - aprob)# grad that encourages the action that was taken to be taken (see http://cs231n.github.io/neural-networks-2/#losses if confused)
为什么假标签y
减去aprob
?
我的理解是,网络输出“向上移动”的“对数概率”,但随后的解释似乎表明,标签实际上应该是采取该操作而获得的奖励,然后鼓励情节中的所有操作(如果是)赢得一个。因此,我不知道1或0的假标签有什么帮助。
在前向通过功能中,没有对数运算,那么它的对数概率如何?
#forward pass, how is logp a logp without any log operation?????
def policy_forward(x):
h = np.dot(model['W1'], x)
h[h<0] = 0 # ReLU nonlinearity
logp = np.dot(model['W2'], h)
p = sigmoid(logp)
#print("p\n {}\n and h\n {}\n".format(p, h))
return p, h # return probability of taking action 2 (up), and hidden state
编辑:
我使用打印语句查看幕后情况,并发现由于y=0
导致行动失败,(y - aprob)
将导致行动失败。他利用优势epdlogp *= discounted_epr
调制梯度的公式仍然以指示向下移动是否良好(即)结束。负数或差,即。一个正数。
对于行动起来,当应用公式时反之亦然。即。 epdlogp *= discounted_epr
的正数表示操作良好,而负数表示操作不好。
因此,这似乎是一种非常整洁的实现方式,但是我仍然不明白从前进通道返回的aprob
是对数概率,因为向控制台的输出看起来像这样:
aprob
0.5
action
3
aprob
0.5010495775824385
action
2
aprob
0.5023498477623756
action
2
aprob
0.5051575154468827
action
2
这些看起来像是介于0到1之间的概率。那么将y - aprob
用作“对数概率”仅仅是经过数月和数年实践发展而来的一种直觉吗?如果是这样,这些黑客是通过反复试验发现的吗?
编辑:由于汤米(Tommy)的出色解释,我知道在我的Udacity深度学习课程视频中可以找到哪里,以重新了解对数概率和交叉熵:https://www.youtube.com/watch?time_continue=94&v=iREoPUrpXvE
此外,该备忘单还有助于:https://ml-cheatsheet.readthedocs.io/en/latest/loss_functions.html
答案 0 :(得分:1)
我对他如何到达(y-aprob)的解释:
当他向前通过网时,最后一步是将S型S(x)应用于最后一个神经元的输出。
S(x) = 1 / (1+e^-x)
及其渐变
grad S(x) = S(x)(1-S(X))
要增加/减少您采取行动的可能性,您必须计算“标签”概率的日志
L = log p(y|x)
要对此进行反向传播,您必须计算似然度L的梯度
grad L = grad log p(y|x)
由于在输出中应用了S型函数p = S(y),因此您可以实际计算
grad L = grad log S(y)
grad L = 1 / S(y) * S(y)(1-(S(y))
grad L = (1-S(y))
**grad L = (1-p)**
这实际上只是对数损失/交叉熵。 更笼统的公式是:
L = - (y log p + (1-y)log(1-p))
grad L = y-p with y either 0 or 1
由于安德烈(Andrej)在他的示例中未使用Tensorflow或PyTorch之类的框架,因此他在那里进行了一些反向传播。
一开始我也很困惑,我花了一些时间弄清楚到底发生了什么魔术。也许他可以在那儿变得更清楚一些,并给出一些提示。
至少那是我对他的代码的谦卑理解:)