我最近尝试在 Golang 中实现一个基本的 Q-Learning 算法。请注意,我通常是强化学习和人工智能的新手,所以错误很可能是我的。
以下是我在 m,n,k 游戏环境中实现解决方案的方法: 在每个给定时间t
,代理持有最后一个状态动作(s, a)
及其获得的奖励;代理a'
根据 Epsilon-greedy 策略选择移动并计算奖励r
,然后继续更新Q(s, a)
for time的值t-1
func (agent *RLAgent) learn(reward float64) {
var mState = marshallState(agent.prevState, agent.id)
var oldVal = agent.values[mState]
agent.values[mState] = oldVal + (agent.LearningRate *
(agent.prevScore + (agent.DiscountFactor * reward) - oldVal))
}
笔记:
agent.prevState
在采取行动之后和环境响应之前(即在代理移动之后和其他玩家移动之前)保持先前的状态我用它来代替状态动作元组,但我不太确定是否这是正确的方法agent.prevScore
持有对先前状态动作的奖励reward
参数表示当前步骤的状态动作的奖励(Qmax
)
由于状态-动作值溢出agent.LearningRate = 0.2
,agent.DiscountFactor = 0.8
代理未能达到 100K 集。我正在使用 golang 的float64
(标准 IEEE 754-1985 双精度浮点变量),它在周围溢出±1.80×10^308
并产生±Infiniti
. 我想说的价值太大了!
以下是使用 2M 集的学习率0.02
和折扣因子训练的模型的状态(1M 游戏本身):0.08
Reinforcement learning model report
Iterations: 2000000
Learned states: 4973
Maximum value: 88781786878142287058992045692178302709335321375413536179603017129368394119653322992958428880260210391115335655910912645569618040471973513955473468092393367618971462560382976.000000
Minimum value: 0.000000
奖励函数返回:
- 代理赢取:1
- 代理丢失:-1
- 平局:0
- 游戏继续:0.5
但是你可以看到最小值为零,最大值太高了。
值得一提的是,我在 python 脚本中发现了一种更简单的学习方法,效果非常好,而且感觉实际上更智能!当我玩它时,大多数时候结果是平局(如果我玩不小心它甚至会赢),而使用标准的Q-Learning方法,我什至不能让它赢!
agent.values[mState] = oldVal + (agent.LearningRate * (reward - agent.prevScore))
有想法该怎么解决这个吗?这种状态-动作值在 Q-Learning 中正常吗?!
更新:
在阅读了巴勃罗的回答和尼克为这个问题提供的轻微但重要的编辑之后,我意识到问题是prevScore
包含上一步的 Q 值(等于oldVal
)而不是上一步的奖励(在这个例子中,- 1、0、0.5 或 1)。
更改后,代理现在表现正常,在 2M 集之后,模型的状态如下:
Reinforcement learning model report
Iterations: 2000000
Learned states: 5477
Maximum value: 1.090465
Minimum value: -0.554718
在与经纪人的 5 场比赛中,我赢了 2 场(经纪人没有认出我连续两块石头)和 3 场平局。