7.1~7.4 policy.py
In Anbetracht der Eingangsschicht gibt es 104 9x9-Phasendiagramme (Bilder) (= 104ch). Die Anzahl der Filter beträgt 194. Verwenden Sie den ersten Filter, um ein 9x9-Bild gegen ein Bild zu filtern. Tun Sie dies für 104 Kanäle und erhalten Sie 104 Bilder. Kombinieren Sie 104 Bilder zu einem Bild. Das ist 1ch. Machen Sie dasselbe mit dem zweiten Filter. Machen Sie dasselbe für den 194. Filter. Dies ergibt 194 Bilder. Das heißt, die Anzahl der Ausgangskanäle beträgt 194 Kanäle.
pointwise convolution Der Zweck besteht darin, die Anzahl der Dimensionen zu reduzieren Bild eines länglichen Filters von "1 Pixel x 1 Pixel x Anzahl der Schichten" https://www.robotech-note.com/entry/2017/12/24/191936 Eingabe: 1 Pixel für jeden Kanal von 1 bis 192, Ausgabe: 1 Pixelwert Dies wird für alle Pixel durchgeführt, um ein Einbild zu erhalten. Tun Sie dies für die Anzahl der Ausgangskanäle, indem Sie die Parameter ändern. Erhalten Sie Ausgabebilder für die Anzahl der Ausgabekanäle. Immerhin beträgt die Filtergröße der oben genannten 194 Filter nur 1x1 und ist gleich.
python-dlshogi\pydlshogi\network\policy.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from chainer import Chain
import chainer.functions as F
import chainer.links as L
from pydlshogi.common import *
ch = 192
class PolicyNetwork(Chain):
#Eingabe 104ch
#Eingang sind 104 9x9 Phasendiagramme.
#Anzahl der Filter 194.
#Für jeden Eingangskanal gefilterte 9x9-Werte werden von den Eingangskanälen addiert und als 1 Kanal ausgegeben.
#Da die Anzahl der Filter 194 beträgt, beträgt die Anzahl der Ausgangskanäle 194.
def __init__(self):
super(PolicyNetwork, self).__init__()
with self.init_scope():
self.l1 = L.Convolution2D(in_channels = 104, out_channels = ch, ksize = 3, pad = 1)
self.l2 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l3 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l4 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l5 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l6 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l7 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l8 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l9 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l10 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l11 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l12 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
self.l13 = L.Convolution2D(in_channels = ch, out_channels = MOVE_DIRECTION_LABEL_NUM,
ksize = 1, nobias = True)
#Filtergröße 1x1 (ksize)=1)Bedeutung von
#Eingabe: 1 Pixel für jeden Kanal von 1 bis 192, Ausgabe: 1 Pixelwert
#Dies wird für alle Pixel durchgeführt, um ein Einbild zu erhalten.
#Tun Sie dies für die Anzahl der Ausgangskanäle, indem Sie die Parameter ändern.
#Erhalten Sie Ausgabebilder für die Anzahl der Ausgabekanäle.
self.l13_bias = L.Bias(shape=(9*9*MOVE_DIRECTION_LABEL_NUM))
# MOVE_DIRECTION_LABEL_NUM=27. Zeigt 20 Bewegungsrichtungen und 7 Teile.
def __call__(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
h3 = F.relu(self.l3(h2))
h4 = F.relu(self.l4(h3))
h5 = F.relu(self.l5(h4))
h6 = F.relu(self.l6(h5))
h7 = F.relu(self.l7(h6))
h8 = F.relu(self.l8(h7))
h9 = F.relu(self.l9(h8))
h10 = F.relu(self.l10(h9))
h11 = F.relu(self.l11(h10))
h12 = F.relu(self.l12(h11))
h13 = self.l13(h12)
return self.l13_bias(F.reshape(h13,(-1, 9*9*MOVE_DIRECTION_LABEL_NUM)))
#Der Grund, warum die Softmax-Funktion in der Ausgabe nicht beschrieben wird, ist
#F beim Lernen.softmax_cross_Verwendung der Entropiefunktion.
#Diese Funktion berechnet gleichzeitig die Softmax-Funktion und den Kreuzentropiefehler.
common.py bb_rotate180() Argument: 81-stellige Binärzahl. (Ein Element vonpiece_bb und besetzt, dh eine Bitplatine ist enthalten) Ausgabe: Invertiert 81 Ziffern und Ausgaben.
python-dlshogi\pydlshogi\common.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import shogi
#Konstante der Bewegung
# UP=0、UP_LEFT=1、、、、UP_RIGHT_PROMOTE=Es ist definiert als 19.
#Bei Verwendung von zum Beispiel 〇〇=Wenn UP, wird der Variablen 〇〇 0 zugewiesen.
MOVE_DIRECTION = [
UP, UP_LEFT, UP_RIGHT, LEFT, RIGHT, DOWN, DOWN_LEFT, DOWN_RIGHT,
UP2_LEFT, UP2_RIGHT,
UP_PROMOTE, UP_LEFT_PROMOTE, UP_RIGHT_PROMOTE, LEFT_PROMOTE, RIGHT_PROMOTE,
DOWN_PROMOTE, DOWN_LEFT_PROMOTE, DOWN_RIGHT_PROMOTE,
UP2_LEFT_PROMOTE, UP2_RIGHT_PROMOTE
] = range(20)
#Umrechnungstabelle
# **_Die Variable PROMOTE lautet MOVE_In RICHTUNG vordefiniert.
# UP_PROMOTE=10,・ ・ ・,UP_RIGHT_PROMOTE=Es ist definiert als 19.
MOVE_DIRECTION_PROMOTED = [
UP_PROMOTE, UP_LEFT_PROMOTE, UP_RIGHT_PROMOTE, LEFT_PROMOTE, RIGHT_PROMOTE,
DOWN_PROMOTE, DOWN_LEFT_PROMOTE, DOWN_RIGHT_PROMOTE,
UP2_LEFT_PROMOTE, UP2_RIGHT_PROMOTE
]
#Anzahl der Beschriftungen, die Bewegungen darstellen
MOVE_DIRECTION_LABEL_NUM = len(MOVE_DIRECTION) + 7 #7 ist die Art des Stückes
# rotate 180degree
# shogi.I1 ist 80, ..., Shogi.A9 ist 0. Mit anderen Worten, QUADRATE_R180 = [80, 79,・ ・ ・, 1, 0]
SQUARES_R180 = [
shogi.I1, shogi.I2, shogi.I3, shogi.I4, shogi.I5, shogi.I6, shogi.I7, shogi.I8, shogi.I9,
shogi.H1, shogi.H2, shogi.H3, shogi.H4, shogi.H5, shogi.H6, shogi.H7, shogi.H8, shogi.H9,
shogi.G1, shogi.G2, shogi.G3, shogi.G4, shogi.G5, shogi.G6, shogi.G7, shogi.G8, shogi.G9,
shogi.F1, shogi.F2, shogi.F3, shogi.F4, shogi.F5, shogi.F6, shogi.F7, shogi.F8, shogi.F9,
shogi.E1, shogi.E2, shogi.E3, shogi.E4, shogi.E5, shogi.E6, shogi.E7, shogi.E8, shogi.E9,
shogi.D1, shogi.D2, shogi.D3, shogi.D4, shogi.D5, shogi.D6, shogi.D7, shogi.D8, shogi.D9,
shogi.C1, shogi.C2, shogi.C3, shogi.C4, shogi.C5, shogi.C6, shogi.C7, shogi.C8, shogi.C9,
shogi.B1, shogi.B2, shogi.B3, shogi.B4, shogi.B5, shogi.B6, shogi.B7, shogi.B8, shogi.B9,
shogi.A1, shogi.A2, shogi.A3, shogi.A4, shogi.A5, shogi.A6, shogi.A7, shogi.A8, shogi.A9,
]
def bb_rotate_180(bb):
#Es ist Stück, bb einzugeben_Ein Element von bb und ein Element von besetzt. Das heißt, eine 81-stellige Binärzahl.
bb_r180 = 0
for pos in shogi.SQUARES: #SQUARES ist Reichweite(0, 81)Das
if bb & shogi.BB_SQUARES[pos] > 0:
# BB_QUADRATE[0b000 ・ ・ ・ 0001,0b000 ・ ・ ・ 0010,0b000 ・ ・ ・ 0100,・ ・ ・,0b100 ・ ・ ・ 0000].. 81 Elemente.
# &Ist der Bitoperator AND.
bb_r180 += 1 << SQUARES_R180[pos]
# a<<b ist ein Operator, der das Bit von a um b Ziffern nach links verschiebt.
return bb_r180
features.py make_input_features() Argumente: Stück_bb, besetzt, Stücke_in_hand Ausgabe: Wo das erste Stück ist, das erste Stück, das zweite Stück, das zweite Stück [(9 × 9-Matrix), (9 × 9-Matrix), ... (18 + 4 + 4 + 4 + 4 + 2 + 2), (9 × 9-Matrix), (9x9 Matrix), ... (18 + 4 + 4 + 4 + 4 + 2 + 2)]
make_input_features_from_board() Nehmen Sie Piece_bb, Occuped, Pieces_in_hand heraus, drehen Sie sich mit Board als Argument und führen Sie make_input_features aus.
make_output_label() Argumente: move (move_from und move_to), color (first oder second) Mit color kann move_direction sowohl als erstes als auch als zweites verwendet werden.
Ausgabe: move_direction (81 Stellen) + move_to (1 Stelle) 81-jähriges Bild. move_direction ist 81-stellig, move_to ist 1-stellig. 81 Ziffern ... 27 1 Stelle ・ ・ ・ 9x9
Mit anderen Worten, move wird in einen numerischen Wert umgewandelt und ausgegeben. Der numerische Wert dieser Ausgabe ist übrigens auch der Index der Ausgabe von NN. Es wird verwendet, wenn Sie das gewünschte Element aus der Ausgabe von NN extrahieren möchten.
make_features() Nehmen Sie Stück_bb, besetzt, Stücke_in_hand mit Position als Argument heraus und führen Sie make_input_features aus.
python-dlshogi\pydlshogi\features.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
import shogi
import copy
from pydlshogi.common import *
def make_input_features(piece_bb, occupied, pieces_in_hand):
features = []
for color in shogi.COLORS:
# board pieces
for piece_type in shogi.PIECE_TYPES_WITH_NONE[1:]: #PIECE_TYPES_WITH_KEIN ist Reichweite(0, 16)Das
bb = piece_bb[piece_type] & occupied[color] #Ermitteln Sie für jedes Stück die Position des Stücks auf der Drehseite (&Ist ein Bitoperator)
feature = np.zeros(9*9)
for pos in shogi.SQUARES: #SQUARES ist Reichweite(0, 81)Das
if bb & shogi.BB_SQUARES[pos] > 0: #BB_QUADRATE[0b1, 0b10, 0b100,・ ・ ・,0b1 ・ ・ ・ 0].. 81 Elemente.
feature[pos] = 1 #Jedes Bit der Bitplatine wird in Elemente zerlegt. Zum Beispiel 1010 ...[1,0,1,0,・ ・ ・]Zerlegt in.
features.append(feature.reshape((9, 9))) #Jedes Bit der Bitplatine wird in Elemente zerlegt und als 9x9-Matrix zurückgegeben.
# pieces in hand
for piece_type in range(1, 8):
for n in range(shogi.MAX_PIECES_IN_HAND[piece_type]):
#shogi.MAX_PIECES_IN_HAND ist die Anzahl der Teile, die Sie haben. Index 1~7 sieht wahrscheinlich so aus:
#shogi.MAX_PIECES_IN_HAND[1] =18: Ayumu
#shogi.MAX_PIECES_IN_HAND[2] =4: Weihrauchauto
#shogi.MAX_PIECES_IN_HAND[3] =4: Katsura
#shogi.MAX_PIECES_IN_HAND[4] =4: Silber
#shogi.MAX_PIECES_IN_HAND[5] =4: Fr.
#shogi.MAX_PIECES_IN_HAND[6] =2: Ecke
#shogi.MAX_PIECES_IN_HAND[7] =2: Fliegendes Auto
if piece_type in pieces_in_hand[color] and n < pieces_in_hand[color][piece_type]:
feature = np.ones(9*9)
else:
feature = np.zeros(9*9)
features.append(feature.reshape((9, 9)))
return features
#Ausgabe: Wo das erste Stück ist, das erste Stück, das zweite Stück, das zweite Stück
# [(9x9 Matrix),
# (9x9 Matrix),... ist (18 + 4 + 4 + 4 + 4 + 2 + 2),
# (9x9 Matrix),
# (9x9 Matrix),... ist (18 + 4 + 4 + 4 + 4 + 2 + 2)]
def make_input_features_from_board(board): #mit Brett als Argument machen_input_Funktionen ausführen.
if board.turn == shogi.BLACK:
piece_bb = board.piece_bb
occupied = (board.occupied[shogi.BLACK], board.occupied[shogi.WHITE])
pieces_in_hand = (board.pieces_in_hand[shogi.BLACK], board.pieces_in_hand[shogi.WHITE])
else:
piece_bb = [bb_rotate_180(bb) for bb in board.piece_bb]
occupied = (bb_rotate_180(board.occupied[shogi.WHITE]), bb_rotate_180(board.occupied[shogi.BLACK]))
pieces_in_hand = (board.pieces_in_hand[shogi.WHITE], board.pieces_in_hand[shogi.BLACK])
return make_input_features(piece_bb, occupied, pieces_in_hand)
def make_output_label(move, color):
move_to = move.to_square
move_from = move.from_square
#■ Klasse verschieben
# from_Quadratvariable: Der Wert der Bewegungsquelle, wenn die Plattenoberfläche durch einen numerischen Wert von 0 bis 80 dargestellt wird.
#Der durch 9 geteilte Quotient ist die y-Koordinate und der Rest ist die x-Koordinate. Die xy-Koordinate ist 0 Ursprung.
# to_quadratische Variable: Wie oben (Ziel).
#
#x-Koordinate
# 0 1 2 3 4 5 6 7 8
#
#0 1 2 3 4 5 6 7 8 0 y Koordinaten
# 9 10 11 12 13 14 15 16 17 1
# 18 19 20 21 22 23 24 25 26 2
# 27 28 29 30 31 32 33 34 35 3
# 36 37 38 39 40 41 42 43 44 4
# 45 46 47 48 49 50 51 52 53 5
# 54 55 56 57 58 59 60 61 62 6
# 63 64 65 66 67 68 69 70 71 7
# 72 73 74 75 76 77 78 79 80 8
#Wenn weiß, drehen Sie die Platine
if color == shogi.WHITE:
move_to = SQUARES_R180[move_to]
if move_from is not None: #Wenn Sie ein Stück auf dem Brett bewegen, anstatt das Stück, das Sie haben
move_from = SQUARES_R180[move_from]
# move direction
if move_from is not None: #Wenn Sie ein Stück auf dem Brett bewegen, anstatt das Stück, das Sie haben
to_y, to_x = divmod(move_to, 9)
from_y, from_x = divmod(move_from, 9)
dir_x = to_x - from_x
dir_y = to_y - from_y
if dir_y < 0 and dir_x == 0:
move_direction = UP
elif dir_y == -2 and dir_x == -1:
move_direction = UP2_LEFT
elif dir_y == -2 and dir_x == 1:
move_direction = UP2_RIGHT
elif dir_y < 0 and dir_x < 0:
move_direction = UP_LEFT
elif dir_y < 0 and dir_x > 0:
move_direction = UP_RIGHT
elif dir_y == 0 and dir_x < 0:
move_direction = LEFT
elif dir_y == 0 and dir_x > 0:
move_direction = RIGHT
elif dir_y > 0 and dir_x == 0:
move_direction = DOWN
elif dir_y > 0 and dir_x < 0:
move_direction = DOWN_LEFT
elif dir_y > 0 and dir_x > 0:
move_direction = DOWN_RIGHT
# promote
if move.promotion:
move_direction = MOVE_DIRECTION_PROMOTED[move_direction]
else:
#Eigenes Stück
# len(MOVE_DIRECTION)Ist 20
# move.drop_piece_Ist Typ die Art von Stück, die Sie platziert haben?
# -Ist 1 die Nummer?
move_direction = len(MOVE_DIRECTION) + move.drop_piece_type - 1
move_label = 9 * 9 * move_direction + move_to
#81-jähriges Bild. Bewegung_Richtung ist 81 Stellen, bewegen_to ist eine Ziffer von 1.
#81 Ziffern ... 27
#1 Stelle ・ ・ ・ 9x9
return move_label
def make_features(position):
piece_bb, occupied, pieces_in_hand, move, win = position
features = make_input_features(piece_bb, occupied, pieces_in_hand)
return(features, move, win)
Recommended Posts