我正在尝试为流行的葡萄牙纸牌游戏设计强化学习项目。我有工作的环境。该代码可以使用随机选择独立运行n轮。
为便于快速说明,该游戏类似于《红心大战》。它在2个团队中有4位球员。每个玩家有10张牌,在可能的情况下按照以下顺序进行游戏,直到没有纸牌。每个技巧都可以赢得积分,经过10个技巧之后,得分超过60的团队将赢得一轮胜利。
首先,我对如何“编码”卡片/卡座有些疑问。我要把桌上的纸牌,手上的纸牌和已经打过的纸牌传递给模型。我一口气编码了套牌,4套西服,10个数字/数字。我还必须包括王牌(从回合开始时采取)。例如,一张卡片看起来像:[0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],其中前四个数字是西装,以及最后一个是王牌(布尔值),其余为什么牌(2、3、4、5、6,j,q,k,7,a)。我要传递每只手,桌子和所有游戏的牌组,因此40 * 3,每个都有15个特征(展平时为1800个特征)。可能这不是最好的方法,如果有人可以对此建议的话。
使用此数据,我将1个玩家设置为AI代理。轮到AI时,状态为手中的纸牌,桌上的纸牌,已玩的纸牌。对于下一个状态,我将使用相同类型的数据结束提示。该技巧的奖励是累积值(最高120分)。当我运行代码时,损失会像第一次一样输出初始值,然后显示NaN。因此,预测也将以NaN的形式出现(我手头有10张输出,每张纸牌有1张。对此也有一些疑问,因为它们以10张卡开始,但是随着游戏的进行和纸牌的使用,该数字将变为零。)
这是培训的代码:
async expReplay() {
console.debug('Training...')
const minibatch = await this.memory.concat().sort(() => .5 - Math.random()).slice(0, this.batchSize)
for (let i = 0; i < minibatch.length - 1; i++) {
let [state, action, reward, next_state, done] = minibatch[i]
state = await tf.concat(state).flatten().reshape([1, this.stateSize])
next_state = await tf.concat(next_state).flatten().reshape([1, this.stateSize])
let target = reward
if (!done) {
let predictNext = await this.model.predict(next_state)
target = reward + this.gamma * predictNext.argMax().dataSync()[0]
}
let target_f = await this.model.predict(state).dataSync()
target_f[action] = target
target_f = await tf.tensor2d(target_f, [1, this.actionSize])
await this.model.fit(state, target_f, {
epochs: 1,
verbose: 1,
callbacks: {
onEpochEnd: (epoch, logs) => {
process.stdout.write(`${logs.loss} ${logs.acc} \r`)
}
}
})
await state.dispose()
await next_state.dispose()
await target_f.dispose()
}
if (this.epsilon > this.epsilonMin) {
this.epsilon *= this.epsilonDecay
}
return 'Training... stop!'
}
这个循环,我之前已经在DQN上使用过,也用于我正在尝试的比特币交易者,并且运行良好。所以我猜我的数据在某处是错误的。我已经记录了state和next_state来检查NaN,但是没有发现任何内容...
如果您需要更多信息,请询问!