【问题标题】:multi-armed bandit agent in KerasKeras 中的多臂强盗特工
【发布时间】:2018-12-28 22:02:59
【问题描述】:

我正在尝试学习一些旧教程,并发现将所有内容保留在 Keras 中会很刺激。不过,当我用 Tensorflow 编写一个极其简单的事情时,我遇到了麻烦。这是教程中的 tf 代理代码。

tf.reset_default_graph()

weights = tf.Variable(tf.ones([num_bandits]))
chosen_action = tf.argmax(weights,0)

reward_holder = tf.placeholder(shape=[1],dtype=tf.float32)
action_holder = tf.placeholder(shape=[1],dtype=tf.int32)
responsible_weight = tf.slice(weights,action_holder,[1])
loss = -(tf.log(responsible_weight)*reward_holder)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
update = optimizer.minimize(loss)

这是一个简单的多臂强盗。 到目前为止,我尝试将代理转换为 Keras 的工作是;

size = 4
weights = K.variable(K.ones(shape=(size), dtype='float32'))
best_action = Lambda(lambda x: K.cast(K.argmax(x), dtype=K.floatx()))(weights)

reward = Input(shape=(1,), dtype='float32')
action = Input(shape=(1,), dtype='int32')

responsible_weight = K.slice(weights, action[-1], [1])

custom_loss = -(K.log(responsible_weight) * reward)
opti = SGD(lr=0.001)
model = Model(inputs=[reward, action], outputs=best_action)
model.compile(optimizer=opti, loss=custom_loss)

挑战似乎是输入张量必须来自输入层(至少来自其他练习)。

任何人都可以在这里看到明显的错误吗?当我到达 model=Model() 行时,attributeError 告诉我

'NoneType' object has no attribute '_inbound_nodes'

我的“输出”已经包含在一个 Lambda 函数中,该函数部分地按照潜在重复的建议处理 Keras 张量部分。只是为了好玩,我添加了另一层并按照另一个线程的建议乘以一个,但这并没有改变错误。

【问题讨论】:

标签: python-3.x tensorflow keras


【解决方案1】:

Keras 的工作方式与 tensorflow 略有不同,因为它必须将输入(通常是 x_train)和输出(通常是 y_train)作为已知数据传递。

Keras 中的损失必须是一个接受地面真值和预测(输出)值的函数:function(y_true, y_pred)

通过查看您的代码,损失似乎是 crossentropy 其中 p (y_true) 是 rewardq (y_pred) 是 @987654324 @。

因此,我们可以将其重新制作为reward 是输出(y_train 或 y_true),action_holder 是输入(x_train)。

def loss(y_true,y_pred):
    return - K.log(y_pred)*y_true

另外,action_holder 只不过是采用单行权重,这完全符合 Embedding 层的想法,其大小为 1,词汇表为 num_bandits

也就是说,我们可以开始建模了:

#because of the log, let's also add a non negative constraint to the weights
from keras.constraints import NonNeg

input_action = Input((1,))
responsible_weight = Embedding(num_bandits, 
                               1, 
                               name='weights', 
                               embeddings_initializer='ones',
                               embeddings_constraint=NonNeg())(input_action)

model = Model(input_action, responsible_weight)
model.compile(optimizer=anyOptimizer, loss=loss)

对于训练,使用:

model.fit(data_for_action_holder, data_for_reward, ...)

输入和输出数据都必须整形为(examples, 1)


关于最佳动作或选择的动作,它根本不参与训练。要获得它,您需要获取嵌入权重并获取其最大值:

weights = model.get_layer('weights').get_weights()[0].max()

关于日志为零的风险,您可以稍微更改损失函数以避免零预测:

def loss(y_true, y_pred):
    return - K.log(y_pred + K.epsilon())*(y_true + K.epsilon())

【讨论】:

  • 感谢您的解释。我认为它会解决问题,但仍然对损失函数感到困惑。 (其实这就是练习的目的,回过头来了解强化学习中损失和奖励的关系)。
  • 我得先看看,待会儿接受。
猜你喜欢
  • 2018-09-12
  • 2017-01-25
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 2023-01-03
  • 1970-01-01
  • 2023-03-11
  • 2019-06-13
相关资源
最近更新 更多