Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

方策ラベル(MoveLabel / CompactMoveLabel)

ディープラーニング将棋エンジン(AlphaZero 型や dlshogi 型)では、ニューラルネットワークの Policy Head(方策出力層)が「現在の局面における各指し手の選択確率(ロジット)」を固定長ベクトルとして出力する。 rsshogi は policy-labels Cargo feature が有効なとき、任意の合法手を固定次元インデックスへ O(1) で双方向マッピングする MoveLabel(u16)(2187 次元)と CompactMoveLabel(u16)(1496 次元)を提供する。


手番の正規化(先手視点への統一)

ニューラルネットワークの入力特徴量と出力ラベルは、常に「手番側から見た相対座標(先手視点)」で統一される。 そのため、MoveLabel::from_move(mv, color) では、後手番(Color::WHITE)のときに移動元マス from と移動先マス to の双方に対して 180 度回転 Square::flip()(80 - sq)を適用してからラベルを計算する。

この正規化により、先手の「▲7六歩」と後手の「△3四歩」は、手番側から見てまったく同じ幾何学的移動として同一のラベル ID にマッピングされる。


2187 ラベル表現(MoveLabel)

dlshogi 等で標準的に用いられる 2187 次元表現は、「移動先マス(81 通り)× 移動クラス(27 通り)= 2187 通り」の直積空間として定義される。

#![allow(unused)]
fn main() {
let label_id: u16 = class.raw() as u16 * 81 + to_sq.raw() as u16;
}

27 種類の移動クラス(MoveLabelClass)

盤上の任意のマスへ到達し得る動きは、8 方向の直線および斜め移動(1〜8 マス移動を同一方向として集約)と桂馬の 2 方向跳躍を合わせた 10 方向 に分類できる。 これに「成と不成」の区別(10 × 2 = 20 通り)と、持ち駒 7 種の「駒打ち」(7 通り)を加えた計 27 クラス(0..=26)が MoveLabelClass である。

クラス ID(0..=26)カテゴリMoveLabelClass 定数幾何学的意味(先手視点)
0..=7盤上移動(不成)UP, UP_LEFT, UP_RIGHT, LEFT, RIGHT, DOWN, DOWN_LEFT, DOWN_RIGHT8 方向への移動(1 マス移動と飛び駒の長距離移動を統合)。
8..=9盤上移動(不成)KNIGHT_LEFT, KNIGHT_RIGHT桂馬の左跳躍と右跳躍(不成)。
10..=17盤上移動(成)UP_PROMOTE 〜 DOWN_RIGHT_PROMOTE8 方向への移動 + 成り(クラス 0..=7 に +10)。
18..=19盤上移動(成)KNIGHT_LEFT_PROMOTE, KNIGHT_RIGHT_PROMOTE桂馬の左跳躍と右跳躍 + 成り(クラス 8..=9 に +10)。
20..=26駒打ちDROP_PAWN, DROP_LANCE, DROP_KNIGHT, DROP_SILVER, DROP_BISHOP, DROP_ROOK, DROP_GOLD持ち駒 7 種(歩、香、桂、銀、角、飛、金)の駒打ち。

盤上移動における方向クラス(0..=9)は、正規化後の移動元 from_sq と移動先 to_sq の筋差分 df = to_file - from_file と段差分 dr = to_rank - from_rank の符号および比率から一意に決定される。 成フラグ mv.is_promote() が真であれば方向クラスに +10 を加算し、駒打ちであれば 20 + HandPiece::from_piece_type(pt).raw() をクラス ID とする。


1496 圧縮ラベル表現(CompactMoveLabel)

2187 次元の直積空間には、将棋の盤面幾何学およびルール上、いかなる合法局面からも絶対に生成され得ない「構造的な死にラベル(Dead Labels)」が 691 個 含まれている。 代表的な死にラベルの内訳は以下の通りである。

  • 盤外からの移動:たとえば一段目のマスに対して「下から上へ移動して到達する(DOWN)」ことは盤外からの移動を意味するため存在しない。同様に 1 筋への左からの移動や、一段目および二段目への桂馬の跳躍着地も構造的に不可能である。
  • 行き所のない駒打ち:一段目への歩打ち(DROP_PAWN)や香打ち(DROP_LANCE)、一段目および二段目への桂打ち(DROP_KNIGHT)はルール上常に非合法である。
  • 強制成りの違反:一段目への桂馬跳躍で不成(KNIGHT_LEFT / KNIGHT_RIGHT)を選択する手は存在しない。

コンパイル時テーブルによる O(1) 全単射変換

rsshogi は build.rs において全 2187 ラベルの幾何学的およびルール上の到達可能性を網羅検査し、有効な 1496 個 のラベルのみを詰めた定数変換表を $OUT_DIR/policy_label_tables.rs に生成する。

#![allow(unused)]
fn main() {
// 2187 次元 -> 1496 次元への圧縮テーブル(無効ラベルは None)
pub const MOVE_LABEL_TO_COMPACT: [Option<u16>; 2187] = [ ... ];

// 1496 次元 -> 2187 次元への復元テーブル
pub const COMPACT_TO_MOVE_LABEL: [u16; 1496] = [ ... ];
}

CompactMoveLabel::from_label(label) と CompactMoveLabel::to_label(self) は、この 2 つの固定配列を 1 回引くだけで相互変換を行う。 ニューラルネットワークの出力層を 2187 次元から 1496 次元へ縮小することで、最終全結合層のパラメータ数と Softmax / Cross-Entropy 計算量を約 31.6% 削減 しつつ、実行時のラベル変換オーバーヘッドをゼロに抑えている。