diff --git a/DeepCrazyhouse/src/tools/visualization/visualize_AlphaVile_large.ipynb b/DeepCrazyhouse/src/tools/visualization/visualize_AlphaVile_large.ipynb new file mode 100644 index 00000000..e479cbdf --- /dev/null +++ b/DeepCrazyhouse/src/tools/visualization/visualize_AlphaVile_large.ipynb @@ -0,0 +1,662 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualization of the current learned Model\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%reload_ext autoreload" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "\n", + "import sys\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "sys.path.insert(0,'../../../../')\n", + "from DeepCrazyhouse.src.runtime.color_logger import enable_color_logging\n", + "from DeepCrazyhouse.src.domain.util import *\n", + "from DeepCrazyhouse.src.domain.variants.input_representation import planes_to_board, board_to_planes\n", + "from DeepCrazyhouse.src.tools.visualization.plane_representation import get_plane_vis\n", + "from DeepCrazyhouse.src.domain.variants.output_representation import *\n", + "from DeepCrazyhouse.src.preprocessing.dataset_loader import load_pgn_dataset\n", + "from DeepCrazyhouse.src.training.train_cli_util import *\n", + "from DeepCrazyhouse.src.training.trainer_agent_pytorch import load_torch_state\n", + "from DeepCrazyhouse.configs.main_config import main_config\n", + "from glob import glob\n", + "import re\n", + "import logging\n", + "from matplotlib import rc\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#plt.style.use(\"seaborn-whitegrid\")\n", + "enable_color_logging()\n", + "plt.style.use(\"seaborn-white\")\n", + "#plt.style.use(\"seaborn-colorblind\")\n", + "#plt.style.use('seaborn-notebook')\n", + "plt.rcParams['legend.frameon'] = 'True'\n", + "plt.rcParams['legend.framealpha'] = 1.0\n", + "#plt.rcParams['grid.alpha'] = 0.0\n", + "export_plots = True #True\n", + "#sns.set()\n", + "#sns.set_style(\"whitegrid\")\n", + "#colors = sns.color_palette(\"colorblind\")\n", + "rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})\n", + "## for Palatino and other serif fonts use:\n", + "rc('font',**{'family':'serif','serif':['Palatino']})\n", + "rc('text', usetex=True)\n", + "#print(plt.rcParams) # to examine all values\n", + "fac = 0.7\n", + "print(plt.rcParams.get('figure.figsize'))\n", + "#plt.rcParams['figure.figsize'] = [8.0*fac, 5.5*fac]\n", + "\n", + "logging.getLogger().setLevel(logging.INFO)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def apply_def(filename):\n", + " #plt.grid(axis='x')\n", + " #plt.xlabel('Number of Training Samples processed')\n", + " if export_plots is True:\n", + " plt.savefig('./plots/update/%s.png'%filename, bbox_inches='tight') #, pad_inches = 0)\n", + " plt.savefig('./plots/update/%s.pdf'%filename, bbox_inches='tight') #, pad_inches = 0)\n", + " #matplotlib2tikz.save('./plots/update/tikz/%s.tex' % filename)\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "main_config" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# dimensions of the generated pictures for each filter.\n", + "#input_shape = (1, 34, 8, 8)\n", + "input_shape = (52, 8, 8)\n", + "layer_idx = 25\n", + "export_plots = True #False\n", + "export_tikz = False #True\n", + "latex_style = True\n", + "data_name = 'data'\n", + "normalize = True\n", + "activation = 'relu' #'leakyrelu' #'leakyrelu' # 'prelu' # \n", + "#img_idx = 10\n", + "img_idx = 42\n", + "#img_idx = 60\n", + "opts = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "if latex_style:\n", + " from matplotlib import rc\n", + " plt.rc('text', usetex=True)\n", + " plt.rc('font', family='serif')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "train_config = TrainConfig()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "train_config.tar_file" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "train_config.model_type" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model = create_pytorch_model(input_shape, train_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load model weights" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if train_config.tar_file != \"\":\n", + " print(\"load model weights\")\n", + " load_torch_state(model, torch.optim.SGD(model.parameters(), lr=train_config.max_lr), Path(train_config.tar_file),\n", + " train_config.device_id)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "model.eval()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Hook setup\n", + "activations = {}\n", + "def get_activation(name):\n", + " def hook(model, input, output):\n", + " activations[name] = output.detach()\n", + " return hook\n", + "\n", + "model.body_spatial[0].body[0].register_forward_hook(get_activation('stem_conv0'))\n", + "for i in range(len(model.res_blocks)):\n", + " try:\n", + " model.res_blocks[i].body[0].register_forward_hook(get_activation(f'res_{i}_conv0'))\n", + " except:\n", + " model.res_blocks[i].patch_embed.register_forward_hook(get_activation(f'res_{i}_patch_embed'))\n", + "\n", + "model.policy_head.body[3].register_forward_hook(get_activation('policy_conv1'))\n", + "model.value_head.body[0].register_forward_hook(get_activation('value_conv0'))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(model.res_blocks)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = chess.Board(fen=\"2r2r1k/1b5p/p2Q1q2/3p1P2/3Pp3/8/6RP/6RK w - - 0 1\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = board_to_planes(board, normalize=normalize, mode=2)\n", + "#pred = predict_single(net, x_start_pos, tc.select_policy_from_plane)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Run the model\n", + "with torch.no_grad():\n", + " output = model(torch.Tensor(np.expand_dims(x, axis=0))) #.to(ctx))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "output" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from DeepCrazyhouse.src.domain.variants.plane_policy_representation import FLAT_PLANE_IDX\n", + "from DeepCrazyhouse.src.domain.variants.output_representation import policy_to_moves, policy_to_best_move, policy_to_move" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "output[1][0].shape" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "output[1][0].softmax(dim=0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def predict_single(net, x, select_policy_from_plane=True):\n", + " \n", + " out = [None, None]\n", + "\n", + " with torch.no_grad():\n", + " pred = net(torch.Tensor(np.expand_dims(x, axis=0))) #.to(ctx))\n", + " out[0] = pred[0].to(torch.device(\"cpu\")).numpy()\n", + " out[1] = pred[1].to(torch.device(\"cpu\")).softmax(dim=1).numpy()\n", + " if select_policy_from_plane:\n", + " out[1] = out[1][:, FLAT_PLANE_IDX]\n", + " \n", + " return out" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "out = predict_single(model, x)\n", + "selected_moves, probs = policy_to_moves(board, out[1][0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "probs[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "selected_moves" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "move_probs = {}\n", + "for move, prob in zip(selected_moves, probs):\n", + " move_probs[str(move)] = prob" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "move_probs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "readable_output = {}\n", + "readable_output['value_output'] = output[0]\n", + "readable_output['policy_output'] = move_probs\n", + "readable_output['loss_draw_win_output'] = output[3].softmax(dim=1)\n", + "readable_output['plys_to_end_output'] = output[4]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Visualization function for activations\n", + "def plot_activations(layer, num_cols=4, num_activations=16):\n", + " num_kernels = layer.shape[1]\n", + " fig, axes = plt.subplots(nrows=(num_activations + num_cols - 1) // num_cols, ncols=num_cols, figsize=(12, 12))\n", + " for i, ax in enumerate(axes.flat):\n", + " if i < num_kernels:\n", + " ax.imshow(layer[0, i].cpu().numpy(), cmap='twilight')\n", + " ax.axis('off')\n", + " plt.tight_layout()\n", + " #plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_x(x, num_cols=8, num_activations=52):\n", + " num_kernels = x.shape[0]\n", + " fig, axes = plt.subplots(nrows=(num_activations + num_cols - 1) // num_cols, ncols=num_cols, figsize=(12, 12))\n", + " for i, ax in enumerate(axes.flat):\n", + " if i < num_kernels:\n", + " ax.imshow(x[i], cmap='Blues')\n", + " ax.axis('off')\n", + " plt.tight_layout()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_x(x)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Display a subset of activations\n", + "#plot_activations(activations['res_0_conv0'])#, num_cols=8, num_activations=64)\n", + "plot_activations(activations['stem_conv0'], num_cols=16, num_activations=224)\n", + "apply_def('stem_conv0')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_activations(activations['res_0_conv0'], num_cols=16, num_activations=224)\n", + "apply_def('res_0_conv0')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_activations(activations['res_1_conv0'], num_cols=16, num_activations=224)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_activations(activations['res_35_conv0'], num_cols=16, num_activations=224)\n", + "apply_def('res_36_conv0')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_activations(activations['res_36_patch_embed'], num_cols=16, num_activations=224)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_activations(activations['policy_conv1'], num_cols=8, num_activations=50)\n", + "apply_def('policy_conv1')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_activations(activations['value_conv0'], num_cols=4, num_activations=8)\n", + "apply_def('value_conv0')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sum_act = activations['policy_conv1'][0][0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(1,activations['policy_conv1'].shape[1]):\n", + " sum_act += activations['policy_conv1'][0][i]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.imshow(sum_act.cpu().numpy(), cmap='twilight')\n", + "plt.colorbar()\n", + "apply_def('sum_act_policy')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sum_act_value = activations['value_conv0'][0][0]\n", + "for i in range(1,activations['value_conv0'].shape[1]):\n", + " sum_act_value += activations['value_conv0'][0][i]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.imshow(sum_act_value.cpu().numpy(), cmap='twilight')\n", + "plt.colorbar()\n", + "apply_def('sum_act_value')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Export everything in a loop" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import pickle\n", + "df = pd.read_csv('dataset.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for idx, fen in enumerate(df['fen']):\n", + " print(idx, fen)\n", + " \n", + " board = chess.Board(fen=fen)\n", + " x = board_to_planes(board, normalize=normalize, mode=2)\n", + " \n", + " with torch.no_grad():\n", + " output = model(torch.Tensor(np.expand_dims(x, axis=0)))\n", + " \n", + " prefix = f'data/alpha_vile_large/'\n", + " #prefix = f'data/random/'\n", + "\n", + " out = predict_single(model, x)\n", + " selected_moves, probs = policy_to_moves(board, out[1][0])\n", + "\n", + " move_probs = {}\n", + " for move, prob in zip(selected_moves, probs):\n", + " move_probs[str(move)] = prob\n", + " \n", + " readable_output = {}\n", + " readable_output['value_output'] = output[0]\n", + " readable_output['policy_output'] = move_probs\n", + " readable_output['loss_draw_win_output'] = output[3].softmax(dim=1)\n", + " readable_output['plys_to_end_output'] = output[4]\n", + "\n", + " input_data = {}\n", + " input_data['x'] = x\n", + " input_data['fen'] = fen\n", + " \n", + " with open(f'{prefix}{idx}_activations.pickle', 'wb') as handle:\n", + " pickle.dump(activations, handle, protocol=pickle.HIGHEST_PROTOCOL)\n", + "\n", + " with open(f'{prefix}{idx}_output.pickle', 'wb') as handle:\n", + " pickle.dump(output, handle, protocol=pickle.HIGHEST_PROTOCOL)\n", + "\n", + " with open(f'{prefix}{idx}_readable_output.pickle', 'wb') as handle:\n", + " pickle.dump(readable_output, handle, protocol=pickle.HIGHEST_PROTOCOL)\n", + "\n", + " with open(f'{prefix}{idx}_input.pickle', 'wb') as handle:\n", + " pickle.dump(input_data, handle, protocol=pickle.HIGHEST_PROTOCOL)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}