我正在尝试使用tensorflow.js和node创建一个用于玩井字游戏的策略网络代理。
当我在游戏结束时运行我的训练步骤时,我得到了以下错误:
错误:无法找到任何变量与损失函数结果之间的连接 y=f(x)。请确保使用变量的操作在传递给minimize()的函数f内部。
class NNModel { constructor(learning_rate = 0.01){ this.learning_rate = learning_rate this.model = this.createModel() } train(actions, rewards, boards) { const optimizer = tf.train.rmsprop(this.learning_rate, 0.99) optimizer.minimize(() => { const oneHotLabels = tf.oneHot(actions, BOARD_SIZE).dataSync() const logits = this.model.predict(tf.tensor(boards)).dataSync() const crossEntropies = tf.losses.softmaxCrossEntropy(oneHotLabels, logits).asScalar() const loss = tf.tensor(rewards).mul(crossEntropies) return loss }) } createModel() { const model = tf.sequential() model.add( tf.layers.dense({ units: BOARD_SIZE * 3 * 9, activation: 'relu', inputShape: [BOARD_SIZE * 3] }) ) model.add( tf.layers.dense({ units: BOARD_SIZE, }) ) return model }}
在我的SimplePolicyAgent中,每次移动步骤我都会将棋盘状态保存到日志中,使用模型选择移动并也保存到日志中。
在游戏结束时,我会得到结果,并根据游戏结果创建一个与移动日志长度相同的奖励列表。
然后我调用train函数,传入动作、奖励和棋盘状态。
我期望这一步骤能更新模型权重,使得模型在给定的棋盘状态下更可能选择获胜的移动。
我正在尝试模仿以下Python实现:
#losscross_entropies tf.losses.softmax_cross_entropy(one_hot_labels=tf.one_hot(actions, 7), logits=Ylogits)loss = tf.reduce_sum(rewards * cross_entropies)#training opoptimizer = tf.train.RMSPropOptimizer(learning_rate=0.001, decay=0.99)train_op = optimizer.minimize(loss)
谢谢阅读我的问题
回答:
train(actions, rewards, boards) { const optimizer = tf.train.rmsprop(this.learning_rate, 0.99) return optimizer.minimize(() => { const oneHotLabels = tf.oneHot(actions, BOARD_SIZE) const logits = this.model.predict(tf.tensor(boards)) const crossEntropies = tf.losses.softmaxCrossEntropy(oneHotLabels, logits) const loss = tf.sum(tf.tensor(rewards).mul(crossEntropies)).asScalar() return loss }) }
这段代码现在可以运行而不会出现错误,我之前错误地在oneHotLabels
和logits
上添加了.dataSync()
,这使得变量对minimize函数不可见。