日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

自學(xué)圍棋的AlphaGo Zero,你也可以造一個( 二 )


3 super(ValueNet, self).__init__()
4 self.outplanes = outplanes
5 self.conv = nn.Conv2d(inplanes, 1, kernel_size=1)
6 self.bn = nn.BatchNorm2d(1)
7 self.fc1 = nn.Linear(outplanes - 1, 256)
8 self.fc2 = nn.Linear(256, 1)
9、10
11 def forward(self, x):
12 x = F.relu(self.bn(self.conv(x)))
13 x = x.view(-1, self.outplanes - 1)
14 x = F.relu(self.fc1(x))
15 winning = F.tanh(self.fc2(x))
16 return winning
未雨綢繆的樹
狗零 , 還有一個很重要的組成部分,就是蒙特卡洛樹搜索 (MCTS)。
它可以讓AI棋手提前找出 , 勝率最高的落子點 。
在模擬器里,模擬對方的下一手,以及再下一手,給出應(yīng)對之策,所以提前的遠(yuǎn)不止是一步 。
節(jié)點 (Node)
樹上的每一個節(jié)點,都代表一種不同的局勢,有不同的統(tǒng)計數(shù)據(jù):
每個節(jié)點被經(jīng)過的次數(shù)n,總動作值w,經(jīng)過這一點的先驗概率p , 平均動作值q (q=w/n) , 還有從別處來到這個節(jié)點走的那一步,以及從這個節(jié)點出發(fā)、所有可能的下一步 。
1class Node:
2 def __init__(self, parent=None, proba=None, move=None):
3 self.p = proba
4 self.n = 0
5 self.w = 0
6 self.q = 0
7 self.children = []
8 self.parent = parent
9 self.move = move
部署 (Rollout)
第一步是PUCT (多項式上置信樹) 算法,選擇能讓PUCT函數(shù) (下圖) 的某個變體 (Variant) 最大化,的走法 。
寫成代碼的話——
1def select(nodes, c_puct=C_PUCT):
2 " Optimized version of the selection based of the PUCT formula "
3、4 total_count = 0
5 for i in range(nodes.shape[0]):
6 total_count= nodes[i][1]
7、8 action_scores = np.zeros(nodes.shape[0])
9 for i in range(nodes.shape[0]):
10 action_scores[i] = nodes[i][0]c_puct * nodes[i][2] *
11 (np.sqrt(total_count) / (1nodes[i][1]))
12、13 equals = np.where(action_scores == np.max(action_scores))[0]
14 if equals.shape[0] > 0:
15 return np.random.choice(equals)
16 return equals[0]
結(jié)束 (Ending)
選擇在不停地進(jìn)行,直至到達(dá)一個葉節(jié)點 (Leaf Node) , 而這個節(jié)點還沒有往下生枝 。
1def is_leaf(self):
2 """ Check whether a node is a leaf or not """
3、4 return len(self.children) == 0
到了葉節(jié)點,那里的一個隨機(jī)狀態(tài)就會被評估 , 得出所有“下一步”的概率 。
所有被禁的落子點,概率會變成零,然后重新把總概率歸為1 。
然后,這個葉節(jié)點就會生出枝節(jié) (都是可以落子的位置,概率不為零的那些)。代碼如下——
1def expand(self, probas):
2 self.children = [Node(parent=self, move=idx, proba=probas[idx])
3 for idx in range(probas.shape[0]) if probas[idx] > 0]
更新一下
枝節(jié)生好之后,這個葉節(jié)點和它的媽媽們 , 身上的統(tǒng)計數(shù)據(jù)都會更新,用的是下面這兩串代碼 。
1def update(self, v):
2 """ Update the node statistics after a rollout """
3、4 self.w = self.wv
5 self.q = self.w / self.n if self.n > 0 else 0
1while current_node.parent:
2 current_node.update(v)
3 current_node = current_node.parent
選擇落子點
模擬器搭好了,每個可能的“下一步”,都有了自己的統(tǒng)計數(shù)據(jù) 。
按照這些數(shù)據(jù) , 算法會選擇其中一步,真要落子的地方 。
選擇有兩種,一就是選擇被模擬的次數(shù)最多的點 。試用于測試和實戰(zhàn) 。
另外一種,隨機(jī) (Stochastically) 選擇,把節(jié)點被經(jīng)過的次數(shù)轉(zhuǎn)換成概率分布,用的是以下代碼——
1 total = np.sum(action_scores)
2 probas = action_scores / total
3 move = np.random.choice(action_scores.shape[0], p=probas)
后者適用于訓(xùn)練,讓AlphaGo探索更多可能的選擇 。

推薦閱讀