为什么我们在深度强化学习中需要与均匀分布进行比较来选择动作,而策略函数已经完成了这个任务?

在由Karpathy编写的以下代码中,为什么我们需要这行代码(为什么我们在策略函数已经完成这个任务的情况下,还需要与均匀分布进行比较来选择动作)

  # 前向传播策略网络并从返回的概率中抽样一个动作  aprob, h = policy_forward(x)  action = 2 if np.random.uniform() < aprob else 3 # 掷骰子!

而不是直接使用

 # 前向传播策略网络并从返回的概率中抽样一个动作  aprob, h = policy_forward(x)  action = 2 if 0.5 < aprob else 3 # 掷骰子!

….Karpathy的完整代码来自 : https://gist.github.com/karpathy/a4166c7fe253700972fcbc77e4ea32c5

""" 使用(随机)策略梯度在Pong上训练一个智能体。使用OpenAI Gym。 """import numpy as npimport cPickle as pickleimport gym# 超参数H = 200 # 隐藏层神经元的数量batch_size = 10 # 每隔多少个回合进行一次参数更新?learning_rate = 1e-4gamma = 0.99 # 奖励的折扣因子decay_rate = 0.99 # RMSProp中梯度平方和的衰减因子resume = False # 从之前的检查点恢复?render = False# 模型初始化D = 80 * 80 # 输入维度:80x80网格if resume:  model = pickle.load(open('save.p', 'rb'))else:  model = {}  model['W1'] = np.random.randn(H,D) / np.sqrt(D) # "Xavier"初始化  model['W2'] = np.random.randn(H) / np.sqrt(H)  grad_buffer = { k : np.zeros_like(v) for k,v in model.iteritems() } # 更新缓冲区,用于在批次中累加梯度rmsprop_cache = { k : np.zeros_like(v) for k,v in model.iteritems() } # rmsprop内存def sigmoid(x):   return 1.0 / (1.0 + np.exp(-x)) # sigmoid "压缩"函数到区间[0,1]def prepro(I):  """ 将210x160x3 uint8的帧预处理成6400(80x80)的1D浮点向量 """  I = I[35:195] # 裁剪  I = I[::2,::2,0] # 按2的因子降采样  I[I == 144] = 0 # 擦除背景(背景类型1)  I[I == 109] = 0 # 擦除背景(背景类型2)  I[I != 0] = 1 # 其他一切(球拍,球)都设置为1  return I.astype(np.float).ravel()def discount_rewards(r):  """ 接受一个奖励的1D浮点数组并计算折扣后的奖励 """  discounted_r = np.zeros_like(r)  running_add = 0  for t in reversed(xrange(0, r.size)):    if r[t] != 0: running_add = 0 # 重置总和,因为这是一个游戏边界(Pong特定!)    running_add = running_add * gamma + r[t]    discounted_r[t] = running_add  return discounted_rdef policy_forward(x):  h = np.dot(model['W1'], x)  h[h<0] = 0 # ReLU非线性  logp = np.dot(model['W2'], h)  p = sigmoid(logp)  return p, h # 返回采取动作2的概率和隐藏状态def policy_backward(eph, epdlogp):  """ 反向传播。(eph是中间隐藏状态的数组) """  dW2 = np.dot(eph.T, epdlogp).ravel()  dh = np.outer(epdlogp, model['W2'])  dh[eph <= 0] = 0 # 反向传播ReLU  dW1 = np.dot(dh.T, epx)  return {'W1':dW1, 'W2':dW2}env = gym.make("Pong-v0")observation = env.reset()prev_x = None # 用于计算差异帧xs,hs,dlogps,drs = [],[],[],[]running_reward = Nonereward_sum = 0episode_number = 0while True:  if render: env.render()  # 预处理观察,将网络的输入设置为差异图像  cur_x = prepro(observation)  x = cur_x - prev_x if prev_x is not None else np.zeros(D)  prev_x = cur_x  # 前向传播策略网络并从返回的概率中抽样一个动作  aprob, h = policy_forward(x)  action = 2 if np.random.uniform() < aprob else 3 # 掷骰子!  # 记录各种中间结果(稍后用于反向传播)  xs.append(x) # 观察  hs.append(h) # 隐藏状态  y = 1 if action == 2 else 0 # 一个“假标签”  dlogps.append(y - aprob) # 鼓励采取已采取动作的梯度(如果感到困惑,请参阅http://cs231n.github.io/neural-networks-2/#losses)  # 步进环境并获取新测量值  observation, reward, done, info = env.step(action)  reward_sum += reward  drs.append(reward) # 记录奖励(必须在调用step()后进行,以获取前一个动作的奖励)  if done: # 一个回合结束    episode_number += 1    # 将本回合的所有输入、隐藏状态、动作梯度和奖励堆叠在一起    epx = np.vstack(xs)    eph = np.vstack(hs)    epdlogp = np.vstack(dlogps)    epr = np.vstack(drs)    xs,hs,dlogps,drs = [],[],[],[] # 重置数组内存    # 通过时间向后计算折扣后的奖励    discounted_epr = discount_rewards(epr)    # 将奖励标准化为单位正态分布(有助于控制梯度估计器的方差)    discounted_epr -= np.mean(discounted_epr)    discounted_epr /= np.std(discounted_epr)    epdlogp *= discounted_epr # 用优势调制梯度(策略梯度的魔法在这里发生)    grad = policy_backward(eph, epdlogp)    for k in model: grad_buffer[k] += grad[k] # 在批次中累积梯度    # 每batch_size个回合执行一次rmsprop参数更新    if episode_number % batch_size == 0:      for k,v in model.iteritems():        g = grad_buffer[k] # 梯度        rmsprop_cache[k] = decay_rate * rmsprop_cache[k] + (1 - decay_rate) * g**2        model[k] += learning_rate * g / (np.sqrt(rmsprop_cache[k]) + 1e-5)        grad_buffer[k] = np.zeros_like(v) # 重置批次梯度缓冲区    # 无聊的记录工作    running_reward = reward_sum if running_reward is None else running_reward * 0.99 + reward_sum * 0.01    print '重置环境。本回合总奖励为%f。运行平均值:%f' % (reward_sum, running_reward)    if episode_number % 100 == 0: pickle.dump(model, open('save.p', 'wb'))    reward_sum = 0    observation = env.reset() # 重置环境    prev_x = None  if reward != 0: # Pong在游戏结束时有+1或-1的奖励。    print ('回合%d:游戏结束,奖励:%f' % (episode_number, reward)) + ('' if reward == -1 else ' !!!!!!!!')

回答:

如果没有与均匀分布的比较,策略将是确定性的。对于任何给定的状态,policy_forward函数将返回相同的输出,因此每次都会采取相同的动作。所以,如果使用您提出的方法,就不会有任何探索。均匀分布为动作选择引入了一些随机性,这鼓励了探索。没有探索,基本上不可能发现最优策略。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注