Aleatoriedad en el juego del motor

11

Si consigo que dos motores jueguen uno contra el otro con los mismos colores, ¿el mismo juego resultará siempre? Si no, ¿de dónde viene la aleatoriedad en el juego del motor? (Descuidando el libro de apertura, donde si no me equivoco, el libro puede decirle al motor que elija entre dos movimientos al azar, ya que son igualmente buenos).

Supongo que hay aleatoriedad porque en el partido Alphazero vs. Stockfish, no tuvimos el mismo juego muchas veces seguidas. Sin embargo, no entiendo por qué. Presumiblemente, la única forma de hacer esto es hacer que el motor juegue un movimiento inferior en algunas ocasiones, que suena como seppuku.

Seducir
fuente
AlphaZero aprende jugando, así que después de cada juego se actualiza su modelo.
ferit
Agregar un valor aleatorio pequeño a la evaluación es una de las formas posibles. Creo que stockfish está haciendo eso.
hoacin

Respuestas:

8

En cuanto al partido AlphaZero vs Stockfish, esta pregunta ya ha sido cubierta aquí por SmallChess .

Dejando a un lado AlphaZero (que emplea una rutina especializada Monte Carlo 1 en su exploración de las líneas de juego), que se hace que no sea determinista por construcción, para los motores de ajedrez basados ​​en heurística habituales, como Stockfish y otros (aunque hay otros motores que tienen rutinas basadas en MC, AFAIK Rybka solía tener esa característica), la fuente de aleatoriedad generalmente es solo una consecuencia de aspectos técnicos en la implementación, en lugar de la aleatoriedad intencional introducida algorítmicamente en la toma de decisiones del motor. Hablando de manera abstracta, una de las razones es el hecho de que los motores no están funcionando de manera puramente secuencial (ejecutando una tarea tras otra). En cambio, para hacer que los motores sean más eficientes, realizan búsquedas paralelas en varias ramas del árbol de posibles movimientos. Lo hacen a través de lo que se llama subprocesamiento múltiple (o procesamiento, pero eso es un poco diferente). Por lo tanto, múltiples hilos de las CPU son concurrentesejecutar operaciones para buscar en el árbol (y almacenar en caché las evaluaciones de las posiciones visitadas), así que imagine que a cada hilo se le asigna un subárbol. El problema con este tipo de implementación es que la ejecución general de los subprocesos se vuelve altamente dependiente de todo tipo de condiciones (tiempos de espera, intercambios de RAM, ...), por lo que al final se puede elegir una variación principal sin haber permitido todos los demás hilos para terminar su búsqueda.

De hecho, esto sucede a menudo porque el motor está configurado para tomar una decisión en un período de tiempo determinado, por lo que la gestión del tiempo altera el comportamiento. También puede revertir esta declaración diciendo: conocer el algoritmo e implementar rutinas de subprocesos deterministas no son suficientes para predecir de manera confiable el estado del programa después de cualquier tiempo t. Por supuesto, si uno siempre permite que todos los hilos terminen su búsqueda, y no ha habido problemas de concurrencia durante esa ejecución (por ejemplo, un hilo que intenta acceder a un cierto caché que no es accesible), entonces el comportamiento será completamente reproducible dado que todo lo demás es igual 2 .


1 : Junto con el hecho de que a través del entrenamiento adicional (por ejemplo, el auto-juego) su red neuronal sigue evolucionando (parámetros reajustados), o si lo desea, su función de evaluación no tiene una definición constante y fija (a diferencia de los motores basados ​​en heurística )

2 : Incluso entonces, como dijiste, en el nivel inicial, con un libro inicial, a veces el motor toma decisiones aleatorias intencionales sobre qué variación elegir. Del mismo modo, fuera de la fase de apertura, puede haber momentos en los que múltiples variaciones tienen evaluaciones casi iguales (dentro de la resolución elegida para el Eval), luego, según el diseño, puede terminar eligiendo uno al azar. Finalmente, a nivel de la configuración del motor, también debe tener cuidado, por ejemplo, la profundidad de búsqueda y los tiempos de reflexión elegidos para cada motor (y si pueden calcular aún más durante los tiempos de reflexión del otro).

Ellie
fuente
6

Gracias a @Phonon que cubre mis respuestas anteriores en detalles. Me gustaría agregar un punto más: control de tiempo .

El único control de tiempo determinista es por número de nodos , pero esto es poco común. El control de tiempo mucho más común: el número fijo de segundos o el tiempo de juego generalmente no son deterministas.

Probemos un ejemplo. Ejecute stockfish en su terminal. Tipo:

go movetime 20000

Este comando le indica al motor que haga un movimiento después de 20 segundos. Mis resultados:

info depth 23 seldepth 32 multipv 1 score cp 6 upperbound nodes 24325860 nps 1216171 hashfull 999 tbhits 0 time 20002 pv g1f3 d7d5
bestmove g1f3 ponder d7d5

El movimiento fue 1.Cf3. Luego, maté a mi Stockfish, comencé uno nuevo. De nuevo, 20 segundos. Tengo:

info depth 23 seldepth 32 multipv 1 score cp 20 nodes 26185280 nps 1309067 hashfull 999 tbhits 0 time 20003 pv d2d4
bestmove d2d4 ponder g8f6

¡Es 1.d4! Misma posición, ¡ambos 20 segundos de búsqueda!

¿Lo ves? Ambos 20 segundos para el movimiento, pero debido a la fluctuación en el sistema operativo Linux, mi segunda ejecución tuvo una búsqueda más profunda (26185280> 24325860).

Tenga en cuenta que este pequeño experimento ni siquiera fue multiproceso (número de subprocesos = 1). Multithreading haría las cosas aún más no deterministas.

Stockfish recibió un minuto por jugada en el partido Google AlphaZero. El número de hilos era 64. Las decisiones de Stockfish en el partido no podrían ser deterministas.

SmallChess
fuente
De hecho, ejemplo y comentario muy instructivo.
user929304
¡bonito! idea genial para mostrar incluso la caja de 1 hilo.
Ellie
Gracias por la respuesta. Estúpida pregunta de seguimiento: ¿qué es un nodo (en el contexto de los motores de juego de ajedrez)?
Allure
@ user3727079 Los nodos son los vértices (posiciones únicas) en el árbol del juego . Por ejemplo, si el nodo raíz es la posición inicial, entonces tiene 20 nodos secundarios, que son las 20 posiciones legales únicas que están a una capa de la raíz.
Ellie