不断采取行动来加强力量

时间:2019-07-08 02:11:46

标签: python tensorflow machine-learning reinforcement-learning

我正在尝试为连续动作空间实现REINFORCE算法。我创建了一个玩具单状态MDP,其中奖励是所选择的操作与目标值之间的绝对差的负值。最佳策略是使动作与目标值相同。可能的操作范围是-inf到inf。例如,如果目标值为5且代理采取行动2.2,则奖励为-2.8 = -abs(2.2-5),情节终止。具有单个线性神经元的神经网络可预测高斯分布的均值,该高斯分布具有固定的标准偏差,代理可以从中取样其作用。 MDP状态的特征向量仅为[1.0]。

当标准偏差小(例如0.05)时,网络将很好地收敛。但是,当标准偏差较大(例如0.5)时,网络的预测会在与目标值相反的方向上发散。

代码如下:

import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp

tf.enable_eager_execution()

if __name__ == '__main__':
    mean_input_layer = tf.keras.Input(shape=(1,))
    mean_output_layer = tf.keras.layers.Dense(
                                1, activation='linear')(mean_input_layer)
    mean_model = tf.keras.Model(inputs=mean_input_layer, 
                                outputs=mean_output_layer)
    optimizer = tf.keras.optimizers.SGD(learning_rate=0.001)

    target_mean = 5
    standard_deviation = 0.05 # Works
    # standard_deviation = 0.5 # Diverges

    for t in range(10000):
        with tf.GradientTape() as tape:
            mean = mean_model(np.array([[1]]), training=True)
            stdev = np.array([[standard_deviation]], dtype=np.float32)
            dist = tfp.distributions.Normal(loc=mean, scale=stdev)
            samp = dist.sample()
            ascent = -(dist.log_prob(samp)*(-tf.math.abs(samp-target_mean)))
            mean_grads = tape.gradient(ascent, mean_model.trainable_variables) 
            optimizer.apply_gradients(
                zip(mean_grads, mean_model.trainable_variables))
            print('#' + str(t) 
                   + ' Sample: ' + str(samp.numpy()[0]) 
                   + ' Mean: ' + str(mean.numpy()[0]))

变量“ ascent”为负,目的是执行梯度上升而不是下降。

这是一个示例,目标值为5,标准差为0.05:

#0样本:[-0.3368746]均值:[-0.400553]

#1样本:[-0.35207522]均值:[-0.3980214]

#2样本:[-0.39965397]均值:[-0.3947122]

#3样本:[-0.3883655]均值:[-0.39056838]

...

#2460样本:[5.0231776]均值:[4.9940543]

#2461样本:[5.030905]均值:[4.99024]

#2462样本:[4.853626]均值:[4.9867477]

#2463样本:[4.8647094]均值:[4.983813]

#2464样本:[4.9929175]均值:[4.982292]

它收敛。

这是一个示例,目标值为5,标准差为0.5:

#1样本:[0.6297094]均值:[1.4340767]

#2样本:[0.75481075]均值:[1.4310371]

#3样本:[0.9269088]均值:[1.4287564]

#4样本:[1.2933123]均值:[1.4272974]

...

#3210样本:[-3.4329443]均值:[-3.322072]

#3211样本:[-3.755511]均值:[-3.3225727]

#3212样本:[-3.6817236]均值:[-3.3237739]

#3213样本:[-3.4897459]均值:[-3.324738]

...

#9996样本:[-13.280873]均值:[-13.032175]

#9997样本:[-13.879341]均值:[-13.032874]

#9998样本:[-12.796365]均值:[-13.036192]

#9999样本:[-13.04003]均值:[-13.036874]

它在与目标值相反的方向上发散。 这里发生了什么?我的实现中有错误吗?感谢您的帮助。

更新:如果我将“ samp = dist.sample()”替换为均匀分布的样本,该样本的均值为中心,均值的宽度为+-2标准差,则标准差为0.5收敛。具体而言,“ samp = tf.constant([[mean.numpy()[0]-2 * standard_deviation + 4 * standard_deviation * np.random.random(random()]]))”。显然,这不是解决问题的真正方法,但可能为试图找出问题所在的人提供一些见识。我还在寻找解决方案。

更新2:作为难题的另一部分,如果我翻转上升变量的符号,则0.5个标准偏差的情况会收敛,而0.05个标准偏差的情况会发散。

0 个答案:

没有答案