- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
作为大学作业,我们的任务是创建一个简单的 AI,它可以使用带 alpha-beta 修剪的极小极大算法来玩选秀游戏。我们使用的其他技术由我们决定。
在我们的团队中,我们决定使用人工神经网络作为评估函数(主要是为了好玩),这样,随着时间的推移,它会学会识别对 AI 有利或不利的棋盘状态。这确实意味着我们在 AI 方面是菜鸟。
这是一个相当简单的前馈神经网络,有 50 个输入神经元(对应于 50 个方格的棋盘)、单层中的 25 个隐藏神经元和 1 个输出神经元。
输出在 -1 和 1 之间变化,较高的值表示对玩家有利的状态,较低的值表示不好。它使用 tanh
作为激活函数。
我们使用反向传播算法让它学习。
反复向它提供一组输入和期望的输出,它实际上很好地学习了这些模式!
我们首先对其进行一些初始训练,生成随机棋盘状态,并将目标值设置为“你的”棋子与“对手”的棋子之比,始终限制为 [-1,1]。 ANN 似乎也很好地掌握了这种模式。
但是,我们也希望它从经验中学习,我们可以让它玩几百场游戏,并从中学习。所以,首先,我们对其进行“初始训练”,然后,在每场比赛之后,我们用伪代码这样做:
learnRate = 0.05;
if ( the game was won ) {
desireability_adjust = 0.1f;
} else {
desireability_adjust = -0.1f;
}
foreach boardState in (board states recorded during play in reverse order) {
currentOutput = neuralnet.evaluate(boardState)
targetOutput = currentOutput + desireability_adjust * (1 - abs(currentOutput))
neuralnet.learn(boardState, targetOuput, learnRate)
// Decrease the desireability_adjust for every step
desireability_adjust *= 0.9;
}
这给出了非常复杂的结果。 “有经验”的玩家经常输给刚完成初始训练的玩家,而简单地计算棋子的经典 minimax 玩家只会屠杀 NN 驱动的玩家。
您建议对这种方法进行哪些更改,让 NN 学习游戏?让网络更大或更深会有什么用吗?赛后学习算法有什么明显不好的地方吗?
编辑:
我把赛后算法改成这样,而不是上面提出的“调整”方法:
learnRate = 0.1f;
if (win) {
resultValue = 0.95 // Not 1 because tanh cannot reach 1 or -1
} else {
resultValue = -0.95
}
// 0-based index is assumed
recordedstates = (list of states recorded during the game, in order)
for (index from recordedstates.length - 1 to 0) { {
t = (index / recordedstates.length - 1);
targetOutput = t * resultValue;
nn.learn(recordedstates[index], targetOutput, learnRate)
}
直觉上目标值表示“结果的进展”,其中接近 0 的值表示游戏接近初始状态,-0.95 和 0.95 表示接近输或赢,分别。
不管怎样,作业主要是关于带有 alpha-beta 的 minimax,我们将举行一场比赛,看看谁创造了最好的 AI。我们可能会输得很惨,但它可能会产生大量非常强大的对手球员来训练。神经网络让我着迷,所以我可能会继续研究它。
我还注意到,一些失败的网络经常变得“沮丧”,他们会报告几乎任何状态都是消极的。希望上面的新学习方法会减少很多。
EDIT:2 我还添加了一些单元测试用例。最值得注意的是这个:
int[] hitPositionNearWin = {0,
EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, BLACKPIECE, EMPTY, EMPTY,
EMPTY, EMPTY, WHITEPIECE, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
};
我期望的是神经网络从黑色和白色玩家的角度返回 1,因为棋盘总是从即将走棋的玩家的角度进行评估,而无论谁走棋这里赢了。
此时,神经网络给出:
3 层网络(1 个隐藏、1 个输入、1 个输出)应该能够识别这种情况是否正确? (无论它出现在棋盘上的什么位置。)
只剩下一个棋子会使分数更接近极端,因为这是一个获胜的位置,这是正确的。
最佳答案
这对我来说听起来像是一项强化学习技术的任务。看一下时间差异学习。查看 Tesauro 撰写的 TD-gammon 文章。请注意,您在训练时可能需要探索节点。 (西洋双陆棋不需要探索,因为它会从掷骰子中获得变化。)
要获得强化学习的最佳介绍,您应该阅读 Sutton and Barto .
编辑:我认为您可以通过向前训练(而不是您建议的向后过程)来学习。让我详细说明一些(受 C 启发的)伪代码:
/* First initialize your neural net with random weights */
for( int i = 0; i < N_TRAINING_GAMES; i++ ){
board b = board_of_initial_state;
do {
movelist ml = find_all_legal_moves( b );
/* evaluate and score each move in the list of legal moves */
for(each move m in ml){
board b_tmp = do_move( b, m );
if (b_tmp == won_game_state)
m.score = +1.0;
else if (b_tmp == lost_game_state)
m.score = -1.0;
else
m.score = neuralnet_forward_calculate( b_tmp );
}
move m = pick_a_move_for_movelist( ml ); /* do not be greedy all time. Maybe use softmax. See Sutton & Barto Ch. 2 */
neuralnet_backpropagation( b, m.score );
b = do_move( b, m ); /* Update the board state */
} while( game_is_not_over( b ) );
}
我没有在草图上测试过这段代码,但我猜它会在几千场比赛后收敛。请告诉我您的进展情况,因为这对我来说真的很有趣。
另一个编辑:我在代码中指定了一些细节。希望它是清楚的。所以在每次训练比赛中:
以上代码是我认为的 TD(0) 算法。 (如果某些强化学习大师不同意我的观点,请告诉我。)这是您在 Sutton & Barto Ch.6 中找到的算法的游戏特定实现。 .然而,书中的行话有点笼统。书中的状态通常是游戏中的棋盘位置。书中的 Action 通常是在游戏板上移动。
上面的代码仍然是伪代码,还有很多东西是缺失的。你当然应该有一种方法来衡量你的代理人的实力,这样你就知道什么时候它不再改进了。完成 TD 训练后,您的静态神经网络评估器函数可用于极小极大搜索。
关于neural-network - 让 ANN 学习识别跳棋游戏中的优势状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35711485/
我正在关注 melon js tutorial .这是在我的 HUD.js 文件的顶部。 game.HUD = game.HUD || {} 我以前在其他例子中见过这个。 namespace.some
我刚刚制作了这个小游戏,用户可以点击。他可以看到他的点击,就像“cookieclicker”一样。 一切正常,除了一件事。 我尝试通过创建一个代码行变量来缩短我的代码,我重复了很多次。 documen
在此视频中:http://www.youtube.com/watch?v=BES9EKK4Aw4 Notch(我的世界的创造者)正在做他称之为“实时调试”的事情。他实际上是一边修改代码一边玩游戏,而不
两年前,我使用C#基于MonoGame编写了一款《俄罗斯方块》游戏,相关介绍可以参考【这篇文章】。最近,使用业余时间将之前的基于MonoGame的游戏开发框架重构了一下,于是,也就趁此机会将之前的《俄
1.题目 你和你的朋友,两个人一起玩 Nim 游戏: 桌子上有一堆石头。 你们轮流进行自己的回合, 你作为先手 。 每一回合,轮到的人拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。 假设
我正在创建平台游戏,有红色方 block (他们应该杀了我)和白色方 block (平台) 当我死时,我应该在当前级别的开始处复活。 我做了碰撞检测,但它只有在我移动时才有效(当我跳到红色方 bloc
因此,我正在处理(编程语言)中创建游戏突破,但无法弄清楚检查与 bat 碰撞的功能。 到目前为止,我写的关于与球棒碰撞的部分只是将球与底座碰撞并以相反的方向返回。目前,游戏是一种永无止境的现象,球只是
我试图让我的敌人射击我的玩家,但由于某种原因,子弹没有显示,也没有向玩家射击我什至不知道为什么,我什至在我的 window 上画了子弹 VIDEO bulls = [] runninggame = T
我正在尝试添加一个乒乓游戏框架。我希望每次球与 Racket 接触时球的大小都会增加。 这是我的尝试。第一 block 代码是我认为问题所在的地方。第二 block 是全类。 public class
我想知道 3D 游戏引擎编程通常需要什么样的数学?任何特定的数学(如向量几何)或计算算法(如快速傅立叶变换),或者这一切都被 DirectX/OpenGL 抽象掉了,所以不再需要高度复杂的数学? 最佳
我正在为自己的类(class)做一个霸气游戏,我一直在尝试通过添加许多void函数来做一些新的事情,但由于某种奇怪的原因,我的开发板无法正常工作,因为它说标识符“board”未定义,但是我有到目前为止
我在使用 mousePressed 和 mouseDragged 事件时遇到了一些问题。我正在尝试创建一款太空射击游戏,我希望玩家能够通过按下并移动鼠标来射击。我认为最大的问题是 mouseDragg
你好,我正在尝试基于概率实现战斗和准确性。这是我的代码,但效果不太好。 public String setAttackedPartOfBodyPercent(String probability) {
所以我必须实现纸牌游戏 war 。我一切都很顺利,除了当循环达到其中一张牌(数组列表)的大小时停止之外。我想要它做的是循环,直到其中一张牌是空的。并指导我如何做到这一点?我知道我的代码可以缩短,但我现
我正在做一个正交平铺 map Java 游戏,当我的船移动到 x 和 y 边界时,按方向键,它会停止移动(按预期),但如果我继续按该键,我的角色就会离开屏幕. 这是我正在使用的代码: @O
这里是 Ship、Asteroids、BaseShapeClass 类的完整代码。 Ship Class 的形状继承自 BaseShapeClass。 Asteroid类是主要的源代码,它声明了Gra
我正在开发这个随机数猜测游戏。在游戏结束时,我希望用户可以选择再次玩(或让其他人玩)。我发现了几个类似的线程和问题,但没有一个能够帮助我解决这个小问题。我很确定我可以以某种方式使用我的 while 循
我认为作为一个挑战,我应该编写一个基于 javascript 的游戏。我想要声音、图像和输入。模拟屏幕的背景(例如 640x480,其中包含我的所有图像)对于将页面的其余部分与“游戏”分开非常有用。我
我正在制作一个游戏,我将图标放在网格的节点中,并且我正在使用这个结构: typedef struct node{ int x,y; //coordinates for graphics.h
我正在研究我的游戏技能(主要是阵列)来生成敌人,现在子弹来击倒他们。我能够在测试时设置项目符号,但只有当我按下一个键(比方说空格键)并且中间没有间隔时才可见,所以浏览器无法一次接受那么多。 有没有什么
我是一名优秀的程序员,十分优秀!