Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """Move prediction inference (CNN part) replicating Predict_Human_Move_Train.test_model. | |
| Sanity-checks the 12x8x8 encoding + class order on the start position.""" | |
| import sys | |
| import numpy as np | |
| import onnxruntime as ort | |
| import chess | |
| PIECE_ORDER = [chess.PAWN, chess.KNIGHT, chess.BISHOP, chess.ROOK, chess.QUEEN, chess.KING] | |
| SQUARE_MODELS = ["pawn", "knight", "bishop", "rook", "queen", "king"] | |
| def encode(board, row0_rank8=True): | |
| """12x8x8: channels 0-5 white P,N,B,R,Q,K; 6-11 black. (white-to-move board)""" | |
| enc = np.zeros((12, 8, 8), np.float32) | |
| for sq in chess.SQUARES: | |
| p = board.piece_at(sq) | |
| if p: | |
| c = PIECE_ORDER.index(p.piece_type) + (0 if p.color == chess.WHITE else 6) | |
| r = 7 - (sq // 8) if row0_rank8 else (sq // 8) | |
| enc[c, r, sq % 8] = 1.0 | |
| return enc[None] | |
| def softmax(x): | |
| e = np.exp(x - x.max()); return e / e.sum() | |
| def cnn_moves(board, piece_sess, square_sesss, row0_rank8=True): | |
| enc = encode(board, row0_rank8) | |
| pieces = softmax(piece_sess.run(None, {"input": enc})[0].flatten()) | |
| legal = list(board.legal_moves) | |
| move_prob = {} | |
| for i, ptype in enumerate(PIECE_ORDER): | |
| squares = softmax(square_sesss[i].run(None, {"input": enc})[0].flatten()) | |
| squares = (squares + pieces[i]) / 2 | |
| for from_sq in board.pieces(ptype, chess.WHITE): | |
| fs = chess.square_name(from_sq) | |
| for j in range(64): | |
| try: | |
| mv = chess.Move.from_uci(fs + chess.square_name(j)) | |
| if mv in legal: | |
| move_prob[mv.uci()] = squares[j] | |
| except Exception: | |
| pass | |
| return [m for m, _ in sorted(move_prob.items(), key=lambda x: x[1], reverse=True)] | |
| def main(): | |
| piece_sess = ort.InferenceSession("models_onnx/piece.int8.onnx", providers=["CPUExecutionProvider"]) | |
| square_sesss = [ort.InferenceSession(f"models_onnx/square_{s}.int8.onnx", | |
| providers=["CPUExecutionProvider"]) for s in SQUARE_MODELS] | |
| board = chess.Board() # start position (white to move) | |
| for orient in (True, False): | |
| moves = cnn_moves(board, piece_sess, square_sesss, row0_rank8=orient) | |
| print(f"row0_rank8={orient}: top CNN moves -> {moves[:8]}") | |
| if __name__ == "__main__": | |
| main() | |