我正在尝试通过一些旧的教程,并发现它刺激保持在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 Tensor部分。只是为了好玩,我添加了另一个图层并乘以另一个线程建议的一个,但这并没有改变错误。
Keras的工作方式与tensorflow略有不同,因为必须将输入(通常为x_train)和输出(通常为y_train)作为已知数据传递。
Keras的损失必然是一个能够获取地面实况值和预测(输出)值的函数:function(y_true, y_pred)
。
通过查看你的代码,似乎损失是crossentropy,其中p(y_true)是reward
而q(y_pred)是responsible_weight
。
因此,我们可以重新制作它,好像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()
关于log为零的风险,您可以稍微改变损失函数以避免零预测:
def loss(y_true, y_pred):
return - K.log(y_pred + K.epsilon())*(y_true + K.epsilon())