RL: self-play PPO trening siete
BridzikNet (trup + guess/play/value hlavy s maskovanim), self-play generator so zdielanou sietou na 4 sedadlach a opponent mixingom (random/heuristicke sedadla pre robustnost), vlastny clipped-PPO so skalovanim odmien a lr/entropy annealom. Torch je len trenovacia zavislost na hoste (requirements-rl.txt); checkpointy a logy su gitignorovane. Spustenie: py -m rl.train. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
"""Natrenovana siet ako hrac so standardnym rozhranim guess/play.
|
||||
|
||||
Rovnake rozhranie ako rl/players.py, takze funguje v rl/evaluate.py aj ako
|
||||
boti "mozog" v api/bots.py. Hrac vidi len observaciu + masku z rl/encoding.py
|
||||
-- z principu nemoze podvadzat (do cudzich ruk sa nedostane).
|
||||
"""
|
||||
|
||||
import torch
|
||||
|
||||
from rl.encoding import encode_observation, guess_mask, play_mask
|
||||
from rl.model import BridzikNet, mask_tensor, masked_categorical, obs_tensor
|
||||
|
||||
|
||||
class NeuralPlayer:
|
||||
def __init__(self, net: BridzikNet, greedy: bool = True):
|
||||
self.net = net
|
||||
self.greedy = greedy # argmax pri evaluacii; sampling pre pestrost
|
||||
|
||||
def _act(self, rnd, seat: int, use_play_head: bool) -> int:
|
||||
obs = obs_tensor(encode_observation(rnd, seat)).unsqueeze(0)
|
||||
mask = mask_tensor(
|
||||
play_mask(rnd, seat) if use_play_head else guess_mask(rnd)
|
||||
).unsqueeze(0)
|
||||
self.net.eval()
|
||||
with torch.no_grad():
|
||||
guess_logits, play_logits, _ = self.net(obs)
|
||||
logits = play_logits if use_play_head else guess_logits
|
||||
logits = logits.masked_fill(~mask, float('-inf'))
|
||||
if self.greedy:
|
||||
return int(logits.argmax(dim=-1).item())
|
||||
return int(masked_categorical(logits, mask).sample().item())
|
||||
|
||||
def guess(self, rnd, seat: int) -> int:
|
||||
return self._act(rnd, seat, use_play_head=False)
|
||||
|
||||
def play(self, rnd, seat: int) -> int:
|
||||
return self._act(rnd, seat, use_play_head=True)
|
||||
|
||||
|
||||
def load_player(checkpoint_path: str, greedy: bool = True) -> NeuralPlayer:
|
||||
from rl.train import load_checkpoint
|
||||
return NeuralPlayer(load_checkpoint(checkpoint_path), greedy=greedy)
|
||||
Reference in New Issue
Block a user