整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

本科作业到Nature子刊:大二学生突破量子计算近20年的纠错码难题

器之心报道

作者:张倩、维度

别人家孩子的本科生涯:悉尼大学的一位本科生在大二写物理作业时「一不小心」解决了一个量子计算难题,相关论文刚刚登上了《自然 - 通讯》杂志。

一作、悉尼大学本科生 Pablo Bonilla Ataides(左);通讯作者、悉尼大学博士生 Benjamin J. Brown(右)

在量子计算领域,利用量子计算机执行大规模计算可能需要基于量子纠错码的容错架构,其中面临的挑战在于设计一种使用适度资源即可有效对抗实际噪声的实用量子纠错码。

两年前,在一次物理作业中,悉尼大学的一名大二本科生 Pablo Bonilla「一不小心」取得了该领域的重要突破。他所在的研究团队对一些常用的量子纠错码进行了简单但优雅的更改,将它们的纠错能力提升了一倍,从而缩短了实现可扩展量子计算的进程。在此之前,这种常用的纠错码已经被研究了近 20 年。

随后,他们在 arXiv 上公布了一篇名为《The XZZX surface code》的论文,详细介绍了所提出的「XZZX」计算码。

近日,这项研究又登上了《自然 - 通讯》杂志,更引起了 AWS 帕萨迪纳量子计算中心以及耶鲁大学和杜克大学量子研究项目组的注意。这些机构还打算使用他的计算码。

AWS 高级量子研究科学家 Earl Campbell 表示,「在量子计算领域取得任何真正、实际的效益之前,我们有大量的工作要做。但是,Bonilla 等人的这项研究令我惊讶,我没想到量子纠错码的微小变化会对预测性能产生这么大的影响。」AWS 量子计算中心团队还期待与 Bonilla 等人进一步合作,探索其他有前景的替代方案,进而使得新的、更强大的计算技术更加接近现实。

此外,悉尼大学理论物理学教授 Stephen Bartlett 进一步追问了该研究,「这些就是量子计算机容错的最高阈值吗?是否仍然有超越哈希的空间呢?」

量子纠错

经典计算机利用晶体管(可以理解为「开关」)运行我们的手机、笔记本等各种设备,出错的概率非常小。但是,量子计算机中的「开关」(即量子比特)对外部环境的干扰(噪声)却非常敏感。

为了让量子计算机平稳运行,研究者需要制造出大量高质量的量子比特。具体实现方法包括:改进机器,减少噪声,或利用机器的某种能力将量子比特错误抑制在某一阈值以下。

这就是量子纠错(quantum error correction)的作用所在。

量子错误的发生分为几种情况:其中一种叫做 X-error,发生在量子比特围绕自己的轴翻转的时候;还有一种叫做 Z-error,属于相位翻转错误;二者结合便产生了 Y-error。

杜克大学量子纠错专家 Kenneth Brown 介绍说,「在量子纠错中,我们通常假设 X-、Y-、Z-error 是等可能的。然而,真实的实验结果却并非如此。」

Bonilla 所做的工作就是在每一秒都重新调整纠错码的一部分。这种码被称为 surface code,可以在已经连通的量子比特的二维网络中工作。

量子棋盘

为了便于理解,我们可以把 surface code 想象成一个 国际象棋棋盘。在其最初的设计中,黑色方块用于检测 Z-error,白色方块用于检测 X-error。但是,相比之下,Z-error 要更加普遍。因此,用那么多的方块去检测不那么常见的 X-error 显得非常浪费。

Bonilla 设计的计算码打破了这种设计,将一半的量子开关进行了翻转,使每一个方块都能用于检测两种错误。这种计算码被称为「XZZX」码,显示了对 surface code 的重新设计。

XZZX surface code 示意图。

「XZZX」计算码的容错阈值。

Brown 教授表示,「XZZX 码非常了不起,因为它通过简单的局部变换就能为所有 X、Z 错误不均的情况提供最佳解决方案。」

耶鲁大学量子研究项目助理教授 Shruti Puri 表示,她的团队对在工作中使用新计算码很感兴趣。

「这种计算码的优雅让人眼前一亮。它的卓越纠错特性来自于对原码的简单修改,而后者我们已经研究了近 20 年。」Puri 说道,「这与耶鲁和其他机构正在开发的新一代量子技术极为相关。我相信,有了这套计算码,我们可以大大缩短实现可扩展量子计算的时间线。」

该研究的合著者、物理学院的 David Tuckett 博士表示,「这有点像和量子对手玩海战棋。从理论上来说,他们可以把船放在棋盘的任何地方。但在玩了数百万场后,我们已经掌握了他们的一些布局规律。」「从实验中我们知道,Z-error 要比 X-error 常见得多。根据这一特性,Pablo 重新设计了 surface code,大大提高了其抑制错误的能力。」

实用价值

该研究的合著者、悉尼大学理学院研究副院长 Stephen Bartlett 表示,「这一设计的伟大之处在于,我们可以有效地对其进行改进,以适应整个行业正在开发的 surface code」。

「对于一个长期从事 2D 芯片设计的行业来说,让新计算码在一个二维表面上工作有着非常理想的应用价值。」

文章的另一位合著者、悉尼大学纳米研究所和物理学院博士 Ben Brown 表示,「建造一台实用的量子计算机有点像莱特兄弟要造飞机,我们现在甚至还没离开过地面。」

「实验人员正在生产用来造飞机的坚固、轻便材料,而我们刚刚为机翼贡献了一个更符合空气动力学的设计,它有更大的升力。我们的设计可能会帮助大规模量子计算起飞。」

参考链接:

https://www.eurekalert.org/pub_releases/2021-04/uos-ssh041221.php

https://phys.org/news/2021-04-student-physics-homework-amazon-quantum.html

段时间发的飞机大战的游戏很多小伙伴都私聊让再做个游戏,今天小猿圈web前端讲师为大家分享的是JS五子棋的游戏,想玩的小伙伴记得自己运行一下呦。

JS五子棋游戏代码:

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>五子棋</title>

<style type="text/css">

canvas {

display: block;

margin: 50px auto;

box-shadow: -2px -2px 2px #EFEFEF, 5px 5px 5px #B9B9B9;

cursor: pointer;

}

#btn-wrap {

display: flex;

flex-direction: row;

justify-content: center;

}

#btn-wrap div {

margin: 0 10px;

}

div>span {

display: inline-block;

padding: 10px 20px;

color: #FFFFFF;

background-color: #EE82EE;

border-radius: 5px;

cursor: pointer;

}

div.unable span {

background: #D6D6D4;

color: #ADACAA;

}

#result-wrap {

text-align: center;

}

</style>

</head>

<body>

<h3 id="result-wrap">三人行慕课(www.3mooc.com)——五子棋</h3>

<canvas id="chess" width="450px" height="450px"></canvas>

<div id="btn-wrap">

<div id="restart" class="restart">

<span>重新开始</span>

</div>

<div id="goback" class="goback unable">

<span>悔棋</span>

</div>

<div id="return" class="return unable">

<span>撤销悔棋</span>

</div>

</div>

<script type="text/javascript">

var over = false;

var me = true; //我

var _nowi = 0, _nowj = 0; //记录自己下棋的坐标

var _compi = 0, _compj = 0; //记录计算机当前下棋的坐标

var _myWin = [], _compWin = []; //记录我,计算机赢的情况

var backAble = false, returnAble = false;

var resultTxt = document.getElementById("result-wrap");

var chressBord = []; //棋盘

for (var i = 0; i < 15; i++) {

chressBord[i] = [];

for (var j = 0; j < 15; j++) {

chressBord[i][j] = 0;

}

}

//赢法的统计数组

var myWin = [];

var computerWin = [];

//赢法数组

var wins = [];

for (var i = 0; i < 15; i++) {

wins[i] = [];

for (var j = 0; j < 15; j++) {

wins[i][j] = [];

}

}

var count = 0; //赢法总数

//横线赢法

for (var i = 0; i < 15; i++) {

for (var j = 0; j <11; j++) {

for (var k = 0; k < 5; k++) {

wins[i][j+k][count] = true;

}

count++;

}

}

//竖线赢法

for (var i = 0; i < 15; i++) {

for (var j = 0; j <11; j++) {

for (var k = 0; k < 5; k++) {

wins[j+k][i][count] = true;

}

count++;

}

}

//正斜线赢法

for (var i = 0; i < 11; i++) {

for (var j = 0; j <11; j++) {

for (var k = 0; k < 5; k++) {

wins[i+k][j+k][count] = true;

}

count++;

}

}

//反斜线赢法

for (var i = 0; i < 11; i++) {

for (var j = 14; j > 3; j--) {

for (var k = 0; k < 5; k++) {

wins[i+k][j-k][count] = true;

}

count++;

}

}

// debugger;

for (var i = 0; i < count; i++) {

myWin[i] = 0;

_myWin[i] = 0;

computerWin[i] = 0;

_compWin[i] = 0;

}

var chess = document.getElementById("chess");

var context = chess.getContext('2d');

context.strokeStyle = '#bfbfbf'; //边框颜色

var backbtn = document.getElementById("goback");

var returnbtn = document.getElementById("return");

window.onload = function() {

drawChessBoard(); // 画棋盘

}

document.getElementById("restart").onclick = function(){

window.location.reload();

}

// 我,下棋

chess.onclick = function(e){

if(over){

return;

}

if(!me){

return;

}

// 悔棋功能可用

backbtn.className = backbtn.className.replace(new

RegExp("(\s|^)unable(\s|$)")," ");

var x = e.offsetX;

var y = e.offsetY;

var i = Math.floor(x / 30);

var j = Math.floor(y / 30);

_nowi = i;

_nowj = j;

if(chressBord[i][j] == 0){

oneStep(i,j,me);

chressBord[i][j] = 1; //我,已占位置

for (var k = 0; k < count; k++) { // 将可能赢的情况都加1

if(wins[i][j][k]){

// debugger;

myWin[k]++;

_compWin[k] = computerWin[k];

computerWin[k] = 6; //这个位置对方不可能赢了

if(myWin[k] == 5){

// window.alert('你赢了');

resultTxt.innerHTML = '恭喜,你赢了!';

over = true;

}

}

}

if(!over){

me = !me;

computerAI();

}

}

}

// 悔棋

backbtn.onclick = function(e){

if(!backAble) { return;}

over = false;

me = true;

// resultTxt.innerHTML = 'o(╯□╰)o,悔棋中';

// 撤销悔棋功能可用

returnbtn.className = returnbtn.className.replace( new

RegExp("(\s|^)unable(\s|$)")," ");

// 我,悔

chressBord[_nowi][_nowj] = 0; //我,已占位置 还原

minusStep(_nowi, _nowj); //销毁棋子

for (var k = 0; k < count; k++) { // 将可能赢的情况都减1

if(wins[_nowi][_nowj][k]){

myWin[k]--;

computerWin[k] = _compWin[k]; //这个位置对方可能赢

}

}

// 计算机相应的悔棋

chressBord[_compi][_compj] = 0; //计算机,已占位置 还原

minusStep(_compi, _compj);//销毁棋子

for (var k = 0; k < count; k++) {// 将可能赢的情况都减1

if(wins[_compi][_compj][k]){

computerWin[k]--;

myWin[k] = _myWin[i];//这个位置对方可能赢

}

}

resultTxt.innerHTML = '--益智五子棋--';

returnAble = true;

backAble = false;

}

// 撤销悔棋

returnbtn.onclick = function(e){

if(!returnAble){ return;}

// 我,撤销悔棋

chressBord[_nowi][_nowj] = 1;//我,已占位置

oneStep(_nowi,_nowj,me);

for (var k = 0; k < count; k++) {

if(wins[_nowi][_nowj][k]){

myWin[k]++;

_compWin[k] = computerWin[k];

computerWin[k] = 6;//这个位置对方不可能赢

}

if(myWin[k] == 5){

resultTxt.innerHTML = '恭喜,你赢了!';

over = true;

}

}

// 计算机撤销相应的悔棋

chressBord[_compi][_compj] = 2;//计算机,已占位置

oneStep(_compi,_compj,false);

for (var k = 0; k < count; k++) {// 将可能赢的情况都减1

if(wins[_compi][_compj][k]){

computerWin[k]++;

_myWin[k] = myWin[k];

myWin[k] = 6;//这个位置对方不可能赢

}

if(computerWin[k] == 5){

resultTxt.innerHTML = 'o(╯□╰)o,计算机赢了,继续加油哦!';

over = true;

}

}

returnbtn.className += '' + 'unable';

returnAble = false;

backAble = true;

}

// 计算机下棋

var computerAI = function(){

var myScore = [];

var computerScore = [];

var max = 0;

var u =0, v = 0;

for (var i = 0; i < 15; i++) {

myScore[i] = [];

computerScore[i] = [];

for (var j = 0; j < 15; j++) {

myScore[i][j] = 0;

computerScore[i][j] = 0;

}

}

for (var i = 0; i < 15; i++) {

for (var j = 0; j < 15; j++) {

if(chressBord[i][j] == 0){

for (var k = 0; k < count; k++) {

if(wins[i][j][k]){

if(myWin[k] == 1){

myScore[i][j] += 200;

}else if(myWin[k] == 2){

myScore[i][j] += 400;

}

else if(myWin[k] == 3){

myScore[i][j] += 2000;

}

else if(myWin[k] == 4){

myScore[i][j] += 10000;

}

if(computerWin[k] == 1){

computerScore[i][j] += 220;

}else if(computerWin[k] == 2){

computerScore[i][j] += 420;

}

else if(computerWin[k] == 3){

computerScore[i][j] += 2100;

}

else if(computerWin[k] == 4){

computerScore[i][j] += 20000;

}

}

}

if(myScore[i][j] > max){

max = myScore[i][j];

u = i;

v = j;

}else if(myScore[i][j] == max){

if(computerScore[i][j]>computerScore[u][v]){

u = i;

v = j;

}

}

if(computerScore[i][j] > max){

max = computerScore[i][j];

u = i;

v = j;

}else if(computerScore[i][j] == max){

if(myScore[i][j]>myScore[u][v]){

u = i;

v = j;

}

}

}

}

}

_compi = u;

_compj = v;

oneStep(u,v,false);chressBord[u][v] = 2; //计算机占据位置

for (var k = 0; k < count; k++) {

if(wins[u][v][k]){

computerWin[k]++;

_myWin[k] = myWin[k];

myWin[k] = 6; //这个位置对方不可能赢了

if(computerWin[k] == 5){

resultTxt.innerHTML = 'o(╯□╰)o,计算机赢了,继续加油哦!';

over = true;

}

}

}

if(!over){

me = !me;

}

backAble = true;

returnAble = false;

var hasClass = new RegExp('unable').test('' +

returnbtn.className + '');

if(hasClass) {

returnbtn.className += '' + 'unable';

}

}

//绘画棋盘

var drawChessBoard = function(){

for (var i = 0; i < 15; i++) {

context.moveTo(15 + i * 30 , 15);

context.lineTo(15 + i * 30 , 435);

context.stroke();

context.moveTo(15 , 15 + i * 30);

context.lineTo(435 , 15 + i * 30);

context.stroke();

}

}

//画棋子

var oneStep = function(i,j,me) {

context.beginPath();

context.arc(15 +i * 30, 15 + j * 30, 13, 0, 2 * Math.PI);// 画圆

context.closePath();

//渐变

var gradient = context.createRadialGradient(15 + i * 30

+ 2, 15 + j * 30 - 2, 13, 15 + i * 30 + 2, 15 + j * 30 -

2, 0);

if(me){

gradient.addColorStop(0,'#0a0a0a');

gradient.addColorStop(1,'#636766');

}else{

gradient.addColorStop(0,'#d1d1d1');

gradient.addColorStop(1,'#f9f9f9')

}

context.fillStyle = gradient;

context.fill();

}

//销毁棋子

var minusStep = function(i,j){

//擦除该圆

context.clearRect((i) * 30, (j) * 30, 30, 30);

// 重画该圆周围的格子

context.beginPath();

context.moveTo(15+i*30, j*30);

context.lineTo(15+i*30, j*30 + 30);

context.moveTo(i*30, j*30+15);

context.lineTo((i+1)*30, j*30+15);

context.stroke();

}

</script>

</body>

</html>

以上就是JS五子棋游戏的代码,如果有什么问题可以留言给小猿圈web前端讲师,遇到的问题可以直接私聊或者提问,看到会尽快帮大家解决的。

要: 相信很多朋友都会玩国际象棋,那么有尝试过构建一个国际象棋引擎吗,一起来玩玩看吧!


来源:Pexels


我不擅长国际象棋。

我父亲在我年幼的时候教过我,但我猜他是那些一直让他们的孩子获胜的爸爸之一。为了弥补世界上最受欢迎的游戏之一的技能的缺乏,我做了任何数据科学爱好者会做的事情:建立一个人工智能来击败我无法击败的人。遗憾的是,它不如AlphaZero(甚至普通玩家)好。但我想看看国际象棋引擎在没有强化学习的情况下如何做,以及学习如何将深度学习模型部署到网络上。

比赛在这里!

获取数据

FICS拥有一个包含3亿场比赛,个人走法,结果以及所涉玩家评级的数据库。我下载了所有在2012年的比赛,其中至少有一名玩家超过2000 ELO。这总计约97000场比赛,有730万个走子。胜利分配是:43000次白方胜利,40000次黑方胜利和14000次平局。

极小极大算法

了解如何做一个深度学习象棋AI,我必须首先了解传统象棋AI程序。来自于极小极大算法。Minimax是“最小化最大损失”的缩写,是博弈论中决定零和博弈应如何进行的概念。

Minimax通常用于两个玩家,其中一个玩家是最大化者,另一个玩家是最小化者。机器人或使用此算法获胜的人假设他们是最大化者,而对手是最小化者。该算法还要求有一个棋盘评估函数,来衡量谁赢谁输。该数字介于-∞和∞之间。最大化者希望最大化此值,而最小化者希望最小化此值。这意味着当你,最大化者,有两个走法可以选择的时候,你将选择一个给你更高评估的那个,而最小化者将做相反的选择。这个游戏假设两个玩家都发挥最佳状态并且没有人犯任何错误。


来源:GlobalSoftwareSupport


以上面的GIF为例。你,最大化者(圆圈)有三个你可以选择的走法(从顶部开始)。你直接选择的走法取决于你的对手(方块)在走子后将选择的走法。但是你的对手直接选择的走法取决于你走子后选择的走法,依此类推,直到游戏结束。玩到游戏结束会占用大量的计算资源和时间,所以在上面的例子中,选择一个深度,2。如果最小化者(最左边的方块)选择左移,你有1和-1可供选择。你选择1,因为它会给你最高分。如果最小化者选择正确的走法,则选择0,因为它更高。现在是最小化者的回合,他们选择0因为这更低。这个游戏继续进行,一直进行到所有的走子都完成或你的思维时间耗尽。对于我的国际象棋引擎来说,假设白方是最大化者,而黑方是最小化者。如果引擎是白方,则算法决定哪个分支将给出最高的最低分数,假设人们在每次走子时选择最低分数,反之亦然。为了获得更好的性能,该算法还可以与另一种算法结合使用:alpha-beta剪枝。 Alpha-beta剪枝截止系统适用于决定是否应该搜索下一个分支。

深度学习架构

我的研究始于Erik Bernhardsson关于国际象棋深度学习的优秀文章。他讲述了他如何采用传统方法制作AI下棋并将其转换为使用神经网络作为引擎。

第一步是将棋盘转换为输入层的数字形式。我借用了Erik Bernhardsson的编码策略,其中棋盘是一个热编码,每一个方块中都有一个棋子。这总计为768个元素数组(8 x 8 x 12,因为有12种棋子)。



Bernhardsson选择将输出图层设为1表示白方胜利,-1表示黑方胜利,0表示平局。他认为游戏中的每个板位置都与结果有关。如果黑方赢了,每个棋的位置都被训练成“支持黑方”,如果白方赢了,则“支持白方棋”。这允许网络返回介于-1和1之间的值,这将告诉你该位置是否更有可能导致白赢或黑赢。

我想用稍微不同的评估函数来解决这个问题。网络是否能够看到不是白方还是黑方获胜,而是能够看到哪个走子将导致胜利?首先,我尝试将768元素的棋盘表示放入输出,其中一个位置是输入,下一个位置是输出。当然,这没有用,因为这把它变成了一个多分类问题。这导致引擎适当地选择合法走子时出现太多的错误,因为输出层中的所有768个元素可以是1或0。因此,我查阅了Barak Oshri和Nishith Khandwala的斯坦福大学论文《利用卷积神经网络预测国际象棋中的运动》,了解他们如何解决这个问题。他们训练了7个神经网络,其中1个网络是棋子选择器网络。这个网络决定哪一个方格最有可能被移动。其他六个网络专门针对每一个棋子类型,并决定将一个特定的棋子移动到哪里。如果棋子选择器选择了一个带有兵的方格,那么只有棋子神经网络会响应最有可能移动到的方格。

我从他们的想法中借鉴了两个卷积神经网络。第一个,从网络移动,将被训练成采用768元素数组表示并输出专业棋手移动的方格(在方块0和方块63之间)。 第二个网络:移动到网络,将做同样的事情,除了输出层将是专业棋手移动到的地方。我没有考虑谁赢了,因为我认为训练数据中的所有移动都是相对最优的,无论最终结果如何。

我选择的架构是两个128卷积层,带有2x2滤波器,后面是两个1024神经元完全连接层。我没有应用任何池,因为池提供位置不变性。图片左上角的猫就像图片右下角的猫一样。然而,对于国际象棋,,棋子国王的值是完全不同于车兵。隐藏图层的激活功能是RELU,而我将softmax应用到最后一层,因此我基本上得到一个概率分布,其中所有方格的概率总和加起来达到100%。



我的训练数据是训练集的600万个位置,其余130万个位置用于验证集。在训练结束时,我从网络上获得了34.8%的验证准确率,并且在转移到网络时获得了27.7%的验证准确率。这并不意味着70%的时间它没有学习合法的走子,这只意味着AI没有像验证数据中的专业玩家那样做出相同的举动。相比之下,Oshri和Khandwala的网络平均验证准确率为37%。

将深度学习与Minimax结合起来

因为现在这是一个分类问题,其中输出可以是64个类之一,这就留下了很大的错误空间。关于训练数据(来自高级别玩家的比赛)的一个警告是,优秀的棋手很少会玩到“将军”。他们知道什么时候输了,通常没有必要跟进整场比赛。这种缺乏平衡的数据使得网络在最终游戏结束时非常混乱。它会选择车来移动,并试图沿对角线移动。如果失败,网络甚至会试图指挥对手的棋子(厚颜无耻!)。

为了解决这个问题,我命令输出的概率。然后,我使用python-chess库获取给定位置的所有合法走子的列表,并选择具有最高结果概率的合法走子。最后,我应用了一个带有惩罚的预测分数方程式,用于选择较不可能的走子:400(选择的走子指数之和)。名单上的合法走子越远,其预测得分就越低。例如,如果从网络移动的第一个索引(索引0)与移动到网络的第一个索引相结合是合法的,那么预测分数是400(0 + 0),这是最高可能分数:400。



在与材料分数结合使用数字后,我选择了400作为最大预测分数。材料分数是一个数字,可以判断所做的走子是否会捕获一个棋子。根据捕获的棋子,走子的整体得分将得到提升。我选择的材料价值如下:

兵:10,马:500,象:500,车:900,后:5000,王:50000。

这特别有助于残局。在将杀走子将是第二个最可能的合法行动且预测得分较低的情况下,国王的物质价值将超过它。兵的分数如此之低,因为网络在早期比赛中考虑得足够充分,所以如果它是战略举措,它将会采用兵。

然后我将这些分数结合起来,以返回给定任何潜在走子的棋盘的评估。我通过深度为3的minimax算法(使用alpha-beta修剪)提供了这个,并得到了一个可以将杀的可运行国际象棋引擎!

使用Flask和Heroku进行部署

我在Youtube上使用了Bluefever Software的指南,展示了如何通过向flask服务器发出AJAX请求来制作javascript国际象棋UI并通过它来路由我的引擎。 我使用Heroku将python脚本部署到Web并将其连接到我的自定义域:Sayonb.com。

结论

虽然引擎的性能没有我希望的那么好,但是我学到了很多关于AI的基础知识,将机器学习模型部署到web上,以及为什么AlphaZero不使用卷积神经网络来玩游戏!

可以通过以下方式进行改进:

1.通过使用bigram模型LSTM将从网络移动和移动到网络中的时间序列组合在一起。 这可能有助于将移出和移动到决策中,因为每个目前都是独立接近的。

2.通过添加夺取的棋子的位置来改进棋子的赋值(夺取棋盘中心的兵比它在边缘时夺取更有利)。

3.在使用神经网络预测分数和子力分值之间切换,而不是在每个节点使用两者。这可以允许更高的极小极大算法搜索深度。

4.考虑边缘情况,例如:减少孤立自己的兵的可能性,增加马靠近棋盘中心的可能性。

查看代码,或者在GitHub repo用自己的训练数据自己训练一个新网络!

阿里云云栖社区组织翻译。

文章原标题《Predicting Professional Players’ Chess Moves with Deep Learning》

作者:Sayon Bhattacharjee

译者:Viola,审校:。