Created
March 12, 2017 11:15
-
-
Save pilipolio/27dc3e6b0d2e2f6dd9ca44887662a6db to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"import numpy as np\n", | |
"import gym\n", | |
"import ppaquette_gym_doom\n", | |
"from ppaquette_gym_doom.wrappers import SetResolution, ToDiscrete\n", | |
"from gym.wrappers import SkipWrapper\n", | |
"from gym import wrappers\n", | |
"\n", | |
"from skimage.transform import resize\n", | |
"from skimage.color import rgb2gray\n", | |
"import types \n", | |
"\n", | |
" \n", | |
"def resize_observation_patch(env, size):\n", | |
" \"\"\" Because unfortunately SetResolution also impacts the recorded videos...\n", | |
" \"\"\"\n", | |
" def resized_obs(obs):\n", | |
" return resize(rgb2gray(obs), size).reshape(size + (-1,))\n", | |
" \n", | |
" original_reset = env.reset\n", | |
" def reset_with_resized_obs(self):\n", | |
" observation = original_reset()\n", | |
" return resized_obs(observation)\n", | |
"\n", | |
" original_step = env.step\n", | |
" def step_with_resized_obs(self, action):\n", | |
" observation, reward, done, end = original_step(action)\n", | |
" return resized_obs(observation), reward, done, end\n", | |
"\n", | |
" env.step = types.MethodType(step_with_resized_obs, env)\n", | |
" env.reset = types.MethodType(reset_with_resized_obs, env)\n", | |
" return env\n", | |
"\n", | |
"WIDTH, HEIGHT, CHANNELS = 200, 150, 3\n", | |
"\n", | |
"# (see https://github.com/ppaquette/gym-doom/blob/master/ppaquette_gym_doom/doom_basic.py)\n", | |
"def create_env(seed=None, monitor_directory=None, size=(WIDTH, HEIGHT)):\n", | |
" env_spec = gym.spec('ppaquette/DoomBasic-v0')\n", | |
" env_spec.id = 'DoomBasic-v0'\n", | |
" env = env_spec.make()\n", | |
"\n", | |
" if seed is not None:\n", | |
" env.seed(seed)\n", | |
"\n", | |
" if monitor_directory is not None:\n", | |
" env = wrappers.Monitor(env, monitor_directory, force=True, mode='training', \n", | |
" video_callable=lambda episode_id: episode_id % 100 == 0)\n", | |
"\n", | |
" return SetResolution('200x150')(\n", | |
" SkipWrapper(repeat_count=4)(\n", | |
" ToDiscrete('minimal')(env)))\n", | |
" #return resize_observation_patch(size=size,\n", | |
" # env=SkipWrapper(repeat_count=4)(ToDiscrete('minimal')(env)))\n", | |
"\n", | |
"env = create_env()\n", | |
"\n", | |
"\n", | |
"NOOP, SHOOT, RIGHT, LEFT = 0, 1, 2, 3" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"(150, 200, 3)\n" | |
] | |
}, | |
{ | |
"data": { | |
"image/png": "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\nrkJggg==\n", | |
"text/plain": [ | |
"<matplotlib.figure.Figure at 0x1393550f0>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"from matplotlib import pyplot as plt\n", | |
"%matplotlib inline\n", | |
"\n", | |
"obs = env.reset()\n", | |
"obs, _, _, _ = env.step(action=1)\n", | |
"\n", | |
"plt.figure(figsize=[6, 6])\n", | |
"\n", | |
"print(obs.shape)\n", | |
"def show(observation):\n", | |
" plt.imshow(observation, interpolation=None)\n", | |
" #plt.imshow(observation.reshape((HEIGHT, WIDTH)), interpolation=None, cmap='gray')\n", | |
" plt.xticks([]); plt.yticks([]);\n", | |
" \n", | |
"show(obs)\n", | |
"env.close()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Deep Q-learning\n", | |
"\n", | |
" * https://github.com/coreylynch/async-rl/blob/master/model.py and https://github.com/tflearn/tflearn/blob/master/examples/reinforcement_learning/atari_1step_qlearning.py with 84 x 84 images\n", | |
"\n", | |
"```\n", | |
" net = tflearn.conv_2d(net, 32, 8, strides=4, activation='relu')\n", | |
" net = tflearn.conv_2d(net, 64, 4, strides=2, activation='relu')\n", | |
" net = tflearn.fully_connected(net, 256, activation='relu')\n", | |
"```\n", | |
"\n", | |
" * https://github.com/ebonyclock/deep_rl_vizdoom/blob/master/networks/common.py#L20 with 80 x 60 images\n", | |
" \n", | |
"```\n", | |
" conv1 = layers.conv2d(img_input, num_outputs=8, kernel_size=[6, 6], stride=3, padding=\"VALID\", ...)\n", | |
" conv2 = layers.conv2d(conv1, num_outputs=8, kernel_size=[3, 3], stride=2, padding=\"VALID\", ...)\n", | |
"\n", | |
"```\n", | |
" * From http://vizdoom.cs.put.edu.pl/tutorial#learning with images (30, 45)!\n", | |
"```\n", | |
"dqn = Conv2DLayer(dqn, num_filters=8, filter_size=[6, 6], nonlinearity=rectify, W=HeUniform(\"relu\"),b=Constant(.1), stride=3)\n", | |
"dqn = Conv2DLayer(dqn, num_filters=8, filter_size=[3, 3],nonlinearity=rectify, W=HeUniform(\"relu\"),b=Constant(.1), stride=2)\n", | |
"dqn = DenseLayer(dqn, num_units=128, nonlinearity=rectify, W=HeUniform(\"relu\"), b=Constant(.1))\n", | |
"```\n", | |
" " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"____________________________________________________________________________________________________\n", | |
"Layer (type) Output Shape Param # Connected to \n", | |
"====================================================================================================\n", | |
"convolution2d_345 (Convolution2D (None, 50, 67, 8) 872 convolution2d_input_173[0][0] \n", | |
"____________________________________________________________________________________________________\n", | |
"activation_517 (Activation) (None, 50, 67, 8) 0 convolution2d_345[0][0] \n", | |
"____________________________________________________________________________________________________\n", | |
"convolution2d_346 (Convolution2D (None, 25, 34, 8) 584 activation_517[0][0] \n", | |
"____________________________________________________________________________________________________\n", | |
"activation_518 (Activation) (None, 25, 34, 8) 0 convolution2d_346[0][0] \n", | |
"____________________________________________________________________________________________________\n", | |
"flatten_173 (Flatten) (None, 6800) 0 activation_518[0][0] \n", | |
"____________________________________________________________________________________________________\n", | |
"dense_345 (Dense) (None, 128) 870528 flatten_173[0][0] \n", | |
"____________________________________________________________________________________________________\n", | |
"activation_519 (Activation) (None, 128) 0 dense_345[0][0] \n", | |
"____________________________________________________________________________________________________\n", | |
"dense_346 (Dense) (None, 4) 516 activation_519[0][0] \n", | |
"====================================================================================================\n", | |
"Total params: 872,500\n", | |
"Trainable params: 872,500\n", | |
"Non-trainable params: 0\n", | |
"____________________________________________________________________________________________________\n" | |
] | |
} | |
], | |
"source": [ | |
"import tensorflow as tf\n", | |
"from keras import backend as K\n", | |
"\n", | |
"from keras.layers import Dense, Convolution2D, Flatten, Activation\n", | |
"from keras.models import Sequential\n", | |
"from keras.optimizers import Adam\n", | |
"\n", | |
"sess = tf.InteractiveSession()\n", | |
"K.set_session(sess)\n", | |
"\n", | |
"def create_q_model(conv1_weights=None, conv2_weights=None, dense1_weights=None, dense2_weights=None):\n", | |
" model = Sequential()\n", | |
"\n", | |
" #model.add(Input(shape=(agent_history_length, resized_width, resized_height,)))\n", | |
" model.add(\n", | |
" Convolution2D(nb_filter=8, nb_row=6, nb_col=6, subsample=(3, 3), border_mode='same', weights=conv1_weights,\n", | |
" input_shape=[HEIGHT, WIDTH, CHANNELS], dim_ordering='tf'))\n", | |
" model.add(Activation('relu'))\n", | |
" model.add(\n", | |
" Convolution2D(nb_filter=8, nb_row=3, nb_col=3, subsample=(2, 2), border_mode='same', weights=conv2_weights, dim_ordering='tf'))\n", | |
" model.add(Activation('relu'))\n", | |
" model.add(Flatten())\n", | |
" model.add(Dense(128, init='normal', weights=dense1_weights))\n", | |
" model.add(Activation('relu'))\n", | |
" model.add(Dense(4, init='normal', weights=dense2_weights))\n", | |
" model.compile(loss='mse', optimizer=Adam())\n", | |
" \n", | |
" return model\n", | |
"\n", | |
"acting_model = create_q_model()\n", | |
"target_model = create_q_model()\n", | |
"\n", | |
"def copy_model(model):\n", | |
" conv1_weights = [w.eval() for w in model.layers[0].weights]\n", | |
" conv2_weights = [w.eval() for w in model.layers[2].weights]\n", | |
" dense1_weights = [w.eval() for w in model.layers[5].weights]\n", | |
" dense2_weights = [w.eval() for w in model.layers[7].weights]\n", | |
" return create_q_model(conv1_weights, conv2_weights, dense1_weights, dense2_weights)\n", | |
"\n", | |
"acting_model.summary()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Collecting and preparing experiences for learning" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# from https://docs.python.org/3/library/itertools.html#recipes\n", | |
"from itertools import tee, zip_longest\n", | |
"\n", | |
"def pairwise(iterable):\n", | |
" \"s -> (s0,s1), (s1,s2), (s2, s3), ...\"\n", | |
" a, b = tee(iterable)\n", | |
" next(b, None)\n", | |
" return zip(a, b)\n", | |
"\n", | |
"def grouper(iterable, n, fillvalue=None):\n", | |
" \"Collect data into fixed-length chunks or blocks\"\n", | |
" # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx\n", | |
" args = [iter(iterable)] * n\n", | |
" return zip_longest(fillvalue=fillvalue, *args)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 0\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"Exception ignored in: <bound method Env.__del__ of <SkipWrapper<ToDiscreteWrapper<_Monitor<TimeLimit<DoomBasicEnv instance>>>>>>\n", | |
"Traceback (most recent call last):\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 252, in __del__\n", | |
" self.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 190, in close\n", | |
" self._close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 346, in _close\n", | |
" return self.env.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 190, in close\n", | |
" self._close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 346, in _close\n", | |
" return self.env.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 190, in close\n", | |
" self._close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/wrappers/monitoring.py\", line 38, in _close\n", | |
" self._monitor.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 193, in close\n", | |
" self._flush(force=True)\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 183, in _flush\n", | |
" 'env_info': self._env_info(),\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 300, in _env_info\n", | |
" if self.env.spec:\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 98, in env\n", | |
" raise error.Error(\"env has been garbage collected. To keep using a monitor, you must keep around a reference to the env object. (HINT: try assigning the env to a variable in your code.)\")\n", | |
"gym.error.Error: env has been garbage collected. To keep using a monitor, you must keep around a reference to the env object. (HINT: try assigning the env to a variable in your code.)\n", | |
"Exception ignored in: <bound method Env.__del__ of <ToDiscreteWrapper<_Monitor<TimeLimit<DoomBasicEnv instance>>>>>\n", | |
"Traceback (most recent call last):\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 252, in __del__\n", | |
" self.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 190, in close\n", | |
" self._close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 346, in _close\n", | |
" return self.env.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 190, in close\n", | |
" self._close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/wrappers/monitoring.py\", line 38, in _close\n", | |
" self._monitor.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 193, in close\n", | |
" self._flush(force=True)\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 183, in _flush\n", | |
" 'env_info': self._env_info(),\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 300, in _env_info\n", | |
" if self.env.spec:\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 98, in env\n", | |
" raise error.Error(\"env has been garbage collected. To keep using a monitor, you must keep around a reference to the env object. (HINT: try assigning the env to a variable in your code.)\")\n", | |
"gym.error.Error: env has been garbage collected. To keep using a monitor, you must keep around a reference to the env object. (HINT: try assigning the env to a variable in your code.)\n", | |
"Exception ignored in: <bound method Env.__del__ of <_Monitor<TimeLimit<DoomBasicEnv instance>>>>\n", | |
"Traceback (most recent call last):\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 252, in __del__\n", | |
" self.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/core.py\", line 190, in close\n", | |
" self._close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/wrappers/monitoring.py\", line 38, in _close\n", | |
" self._monitor.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 193, in close\n", | |
" self._flush(force=True)\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 183, in _flush\n", | |
" 'env_info': self._env_info(),\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 300, in _env_info\n", | |
" if self.env.spec:\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 98, in env\n", | |
" raise error.Error(\"env has been garbage collected. To keep using a monitor, you must keep around a reference to the env object. (HINT: try assigning the env to a variable in your code.)\")\n", | |
"gym.error.Error: env has been garbage collected. To keep using a monitor, you must keep around a reference to the env object. (HINT: try assigning the env to a variable in your code.)\n", | |
"Exception ignored in: <bound method MonitorManager.__del__ of <gym.monitoring.monitor_manager.MonitorManager object at 0x10d9efb00>>\n", | |
"Traceback (most recent call last):\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 306, in __del__\n", | |
" self.close()\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 193, in close\n", | |
" self._flush(force=True)\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 183, in _flush\n", | |
" 'env_info': self._env_info(),\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 300, in _env_info\n", | |
" if self.env.spec:\n", | |
" File \"/Users/gui/.virtualenvs/gui3/lib/python3.6/site-packages/gym/monitoring/monitor_manager.py\", line 98, in env\n", | |
" raise error.Error(\"env has been garbage collected. To keep using a monitor, you must keep around a reference to the env object. (HINT: try assigning the env to a variable in your code.)\")\n", | |
"gym.error.Error: env has been garbage collected. To keep using a monitor, you must keep around a reference to the env object. (HINT: try assigning the env to a variable in your code.)\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"200\n" | |
] | |
} | |
], | |
"source": [ | |
"from collections import namedtuple, deque\n", | |
"from itertools import islice \n", | |
"import operator\n", | |
"import functools\n", | |
"import random\n", | |
"\n", | |
"\n", | |
"SARE = namedtuple('SAR', ['state', 'action', 'reward', 'end'])\n", | |
"Experience = namedtuple('Experience', ['previous_state', 'action', 'reward', 'next_state', 'end'])\n", | |
"\n", | |
"\n", | |
"class EpsilonGreedyQAgent(object):\n", | |
" def __init__(self, model, epsilon=.1):\n", | |
" self.model = model\n", | |
" self.epsilon = epsilon\n", | |
"\n", | |
" def act(self, observation, reward, done):\n", | |
" if random.uniform(0, 1) <= self.epsilon:\n", | |
" return random.choice([NOOP, SHOOT, LEFT, RIGHT])\n", | |
" else:\n", | |
" return self.model.predict(observation[np.newaxis])[0].argmax()\n", | |
"\n", | |
"\n", | |
"def generate_sares(env, agent, episode_count=2000):\n", | |
" reward = 0\n", | |
" done = False\n", | |
"\n", | |
" for i in range(episode_count):\n", | |
" if (i % 10) == 0:\n", | |
" print('episode {i}'.format(i=i))\n", | |
" observation = env.reset()\n", | |
" while True:\n", | |
" action = agent.act(observation, reward, done)\n", | |
" new_observation, reward, done, _ = env.step(action)\n", | |
" yield SARE(observation, action, reward, done)\n", | |
" \n", | |
" if done:\n", | |
" break\n", | |
" else:\n", | |
" observation = new_observation\n", | |
"\n", | |
"\n", | |
"env = create_env()\n", | |
"sares = generate_sares(env, EpsilonGreedyQAgent(acting_model), episode_count=1000)\n", | |
"\n", | |
"experiences = (\n", | |
" Experience(previous_s, a, r, next_s, end) \n", | |
" for (previous_s, a, r, end), (next_s, _, _, _) \n", | |
" in pairwise(sares))\n", | |
"\n", | |
"\n", | |
"experience_batches = grouper(experiences, n=200)\n", | |
"\n", | |
"print(len(list(next(experience_batches))))\n", | |
"env.close()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 0\n", | |
"32 32\n", | |
"32 50\n" | |
] | |
} | |
], | |
"source": [ | |
"from itertools import islice\n", | |
"\n", | |
"class ExperiencesReplay:\n", | |
" def __init__(self, experiences_iterable, memory_size=50, batch_size=32):\n", | |
" self.experiences_iterable = experiences_iterable\n", | |
" self.batch_size = batch_size\n", | |
" self.memory = deque(maxlen=memory_size)\n", | |
"\n", | |
" def __iter__(self):\n", | |
" return self\n", | |
"\n", | |
" def __next__(self):\n", | |
" for exp in islice(self.experiences_iterable, self.batch_size):\n", | |
" self.memory.appendleft(exp)\n", | |
" sampled_experiences = random.choices(self.memory, k=self.batch_size)\n", | |
" return sampled_experiences\n", | |
" \n", | |
"env = create_env()\n", | |
"\n", | |
"experiences = (\n", | |
" Experience(previous_s, a, r, next_s, end) \n", | |
" for (previous_s, a, r, end), (next_s, _, _, _) \n", | |
" in pairwise(generate_sares(env, EpsilonGreedyQAgent(acting_model))))\n", | |
"\n", | |
"replay = ExperiencesReplay(experiences)\n", | |
"\n", | |
"print(len(next(replay)), len(replay.memory))\n", | |
"print(len(next(replay)), len(replay.memory))\n", | |
"\n", | |
"env.close()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Training" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:42:55,986] DEPRECATION WARNING: env.spec.timestep_limit has been deprecated. Replace your call to `env.spec.timestep_limit` with `env.spec.tags.get('wrapper_config.TimeLimit.max_episode_steps')`. This change was made 12/28/2016 and is included in version 0.7.0\n", | |
"[2017-03-12 08:42:55,988] Clearing 42 monitor files from previous run (because force=True was provided)\n", | |
"[2017-03-12 08:42:56,320] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000000.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 0\n", | |
"Batch of 128 exps with avg reward -3.7265625 and dist. [125, 0, 3] and actions distribution [48, 40, 22, 18]\n", | |
"Batch of 128 exps with avg reward -5.3125 and dist. [8, 0, 120] and actions distribution [117, 8, 1, 2]\n", | |
"Batch of 128 exps with avg reward -5.078125 and dist. [2, 0, 126] and actions distribution [117, 2, 6, 3]\n", | |
"Batch of 128 exps with avg reward -5.15625 and dist. [4, 0, 124] and actions distribution [116, 4, 6, 2]\n", | |
"episode 10\n", | |
"Batch of 128 exps with avg reward -5.078125 and dist. [2, 0, 126] and actions distribution [121, 2, 1, 4]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.25 and dist. [127, 0, 1] and actions distribution [119, 2, 2, 5]\n", | |
"Batch of 128 exps with avg reward -5.078125 and dist. [2, 0, 126] and actions distribution [124, 2, 2]\n", | |
"Batch of 128 exps with avg reward -5.0390625 and dist. [1, 0, 127] and actions distribution [121, 1, 2, 4]\n", | |
"Batch of 128 exps with avg reward -5.0 and dist. [0, 128, 0] and actions distribution [124, 0, 0, 4]\n", | |
"episode 20\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [116, 3, 4, 5]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [121, 3, 1, 3]\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [114, 3, 6, 5]\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [116, 3, 6, 3]\n", | |
"Batch of 128 exps with avg reward -5.078125 and dist. [2, 0, 126] and actions distribution [114, 2, 5, 7]\n", | |
"Batch of 128 exps with avg reward -5.15625 and dist. [4, 0, 124] and actions distribution [111, 4, 9, 4]\n", | |
"target_model <- acting_model\n", | |
"episode 30\n", | |
"Batch of 128 exps with avg reward -5.0 and dist. [0, 128, 0] and actions distribution [121, 0, 4, 3]\n", | |
"Batch of 128 exps with avg reward -4.3671875 and dist. [127, 0, 1] and actions distribution [113, 5, 7, 3]\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [90, 3, 20, 15]\n", | |
"Batch of 128 exps with avg reward -4.40625 and dist. [127, 0, 1] and actions distribution [84, 6, 24, 14]\n", | |
"episode 40\n", | |
"Batch of 128 exps with avg reward -5.15625 and dist. [4, 0, 124] and actions distribution [77, 4, 42, 5]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.328125 and dist. [127, 0, 1] and actions distribution [100, 4, 20, 4]\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [75, 3, 38, 12]\n", | |
"Batch of 128 exps with avg reward -5.0390625 and dist. [1, 0, 127] and actions distribution [26, 1, 87, 14]\n", | |
"Batch of 128 exps with avg reward -5.3125 and dist. [8, 0, 120] and actions distribution [28, 8, 66, 26]\n", | |
"episode 50\n", | |
"Batch of 128 exps with avg reward -5.234375 and dist. [6, 0, 122] and actions distribution [38, 6, 51, 33]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.078125 and dist. [2, 0, 126] and actions distribution [38, 2, 46, 42]\n", | |
"Batch of 128 exps with avg reward -4.2890625 and dist. [127, 0, 1] and actions distribution [54, 3, 41, 30]\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [57, 3, 25, 43]\n", | |
"Batch of 128 exps with avg reward -5.1953125 and dist. [5, 0, 123] and actions distribution [34, 6, 54, 34]\n", | |
"episode 60\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [46, 3, 43, 36]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.0 and dist. [0, 128, 0] and actions distribution [28, 0, 51, 49]\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [42, 3, 48, 35]\n", | |
"Batch of 128 exps with avg reward -5.0 and dist. [0, 128, 0] and actions distribution [45, 0, 36, 47]\n", | |
"Batch of 128 exps with avg reward -5.0390625 and dist. [1, 0, 127] and actions distribution [50, 1, 45, 32]\n", | |
"Batch of 128 exps with avg reward -5.234375 and dist. [6, 0, 122] and actions distribution [33, 6, 44, 45]\n", | |
"target_model <- acting_model\n", | |
"episode 70\n", | |
"Batch of 128 exps with avg reward -5.0390625 and dist. [1, 0, 127] and actions distribution [43, 1, 41, 43]\n", | |
"Batch of 128 exps with avg reward -5.1171875 and dist. [3, 0, 125] and actions distribution [30, 4, 44, 50]\n", | |
"Batch of 128 exps with avg reward -5.3125 and dist. [8, 0, 120] and actions distribution [41, 8, 42, 37]\n", | |
"Batch of 128 exps with avg reward -5.3515625 and dist. [9, 0, 119] and actions distribution [25, 9, 45, 49]\n", | |
"Batch of 128 exps with avg reward -4.484375 and dist. [127, 0, 1] and actions distribution [42, 8, 35, 43]\n", | |
"target_model <- acting_model\n", | |
"episode 80\n", | |
"Batch of 128 exps with avg reward -5.15625 and dist. [4, 0, 124] and actions distribution [62, 4, 33, 29]\n", | |
"Batch of 128 exps with avg reward -4.4453125 and dist. [127, 0, 1] and actions distribution [44, 7, 39, 38]\n", | |
"Batch of 128 exps with avg reward -4.5625 and dist. [127, 0, 1] and actions distribution [33, 10, 46, 39]\n", | |
"Batch of 128 exps with avg reward -5.703125 and dist. [18, 0, 110] and actions distribution [37, 29, 33, 29]\n", | |
"episode 90\n", | |
"Batch of 128 exps with avg reward -4.5234375 and dist. [127, 0, 1] and actions distribution [46, 10, 36, 36]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.3125 and dist. [8, 0, 120] and actions distribution [40, 8, 35, 45]\n", | |
"Batch of 128 exps with avg reward -5.5078125 and dist. [13, 0, 115] and actions distribution [44, 16, 35, 33]\n", | |
"Batch of 128 exps with avg reward -5.390625 and dist. [10, 0, 118] and actions distribution [37, 10, 47, 34]\n", | |
"Batch of 128 exps with avg reward -3.9296875 and dist. [126, 0, 2] and actions distribution [25, 15, 43, 45]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:44:59,577] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000100.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 100\n", | |
"Batch of 128 exps with avg reward -4.1171875 and dist. [126, 0, 2] and actions distribution [36, 21, 29, 42]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.71875 and dist. [127, 0, 1] and actions distribution [42, 15, 28, 43]\n", | |
"Batch of 128 exps with avg reward -5.390625 and dist. [10, 0, 118] and actions distribution [34, 11, 30, 53]\n", | |
"episode 110\n", | |
"Batch of 128 exps with avg reward -4.046875 and dist. [126, 0, 2] and actions distribution [33, 21, 29, 45]\n", | |
"Batch of 128 exps with avg reward -4.7578125 and dist. [127, 0, 1] and actions distribution [42, 20, 40, 26]\n", | |
"Batch of 128 exps with avg reward -3.171875 and dist. [125, 0, 3] and actions distribution [33, 19, 44, 32]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.03125 and dist. [127, 0, 1] and actions distribution [37, 23, 32, 36]\n", | |
"episode 120\n", | |
"Batch of 128 exps with avg reward -4.46875 and dist. [126, 0, 2] and actions distribution [23, 36, 29, 40]\n", | |
"Batch of 128 exps with avg reward -4.28125 and dist. [126, 0, 2] and actions distribution [27, 28, 35, 38]\n", | |
"Batch of 128 exps with avg reward -5.78125 and dist. [20, 0, 108] and actions distribution [36, 23, 30, 39]\n", | |
"episode 130\n", | |
"Batch of 128 exps with avg reward -5.03125 and dist. [127, 0, 1] and actions distribution [31, 25, 36, 36]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.15625 and dist. [126, 0, 2] and actions distribution [49, 22, 23, 34]\n", | |
"Batch of 128 exps with avg reward -4.875 and dist. [127, 0, 1] and actions distribution [25, 20, 37, 46]\n", | |
"Batch of 128 exps with avg reward -3.5234375 and dist. [125, 0, 3] and actions distribution [15, 29, 43, 41]\n", | |
"episode 140\n", | |
"Batch of 128 exps with avg reward -5.1484375 and dist. [127, 0, 1] and actions distribution [22, 33, 37, 36]\n", | |
"Batch of 128 exps with avg reward -3.4375 and dist. [125, 0, 3] and actions distribution [26, 27, 40, 35]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.8359375 and dist. [127, 0, 1] and actions distribution [39, 19, 35, 35]\n", | |
"episode 150\n", | |
"Batch of 128 exps with avg reward -5.78125 and dist. [20, 0, 108] and actions distribution [49, 20, 29, 30]\n", | |
"Batch of 128 exps with avg reward -4.046875 and dist. [126, 0, 2] and actions distribution [46, 21, 33, 28]\n", | |
"Batch of 128 exps with avg reward -4.125 and dist. [126, 0, 2] and actions distribution [42, 24, 32, 30]\n", | |
"episode 160\n", | |
"Batch of 128 exps with avg reward -0.9609375 and dist. [122, 0, 6] and actions distribution [26, 29, 36, 37]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.4140625 and dist. [125, 0, 3] and actions distribution [30, 30, 30, 38]\n", | |
"episode 170\n", | |
"Batch of 128 exps with avg reward -3.5625 and dist. [125, 0, 3] and actions distribution [32, 34, 30, 32]\n", | |
"Batch of 128 exps with avg reward -3.859375 and dist. [125, 0, 3] and actions distribution [25, 60, 25, 18]\n", | |
"Batch of 128 exps with avg reward -5.34375 and dist. [127, 0, 1] and actions distribution [29, 37, 35, 27]\n", | |
"episode 180\n", | |
"Batch of 128 exps with avg reward -1.875 and dist. [123, 0, 5] and actions distribution [35, 30, 36, 27]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.390625 and dist. [126, 0, 2] and actions distribution [23, 30, 36, 39]\n", | |
"episode 190\n", | |
"Batch of 128 exps with avg reward -4.875 and dist. [127, 0, 1] and actions distribution [27, 18, 35, 48]\n", | |
"Batch of 128 exps with avg reward -4.9140625 and dist. [127, 0, 1] and actions distribution [40, 23, 27, 38]\n", | |
"Batch of 128 exps with avg reward -5.7421875 and dist. [19, 0, 109] and actions distribution [35, 21, 32, 40]\n", | |
"Batch of 128 exps with avg reward -3.4140625 and dist. [125, 0, 3] and actions distribution [24, 26, 33, 45]\n", | |
"target_model <- acting_model\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:46:34,827] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000200.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 200\n", | |
"Batch of 128 exps with avg reward -5.3046875 and dist. [127, 0, 1] and actions distribution [19, 32, 32, 45]\n", | |
"Batch of 128 exps with avg reward -5.15625 and dist. [127, 0, 1] and actions distribution [27, 32, 33, 36]\n", | |
"Batch of 128 exps with avg reward -5.0703125 and dist. [127, 0, 1] and actions distribution [36, 32, 36, 24]\n", | |
"episode 210\n", | |
"Batch of 128 exps with avg reward -2.546875 and dist. [124, 0, 4] and actions distribution [41, 26, 38, 23]\n", | |
"Batch of 128 exps with avg reward -5.1875 and dist. [127, 0, 1] and actions distribution [33, 36, 27, 32]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.46875 and dist. [126, 0, 2] and actions distribution [30, 39, 25, 34]\n", | |
"Batch of 128 exps with avg reward -5.0546875 and dist. [127, 0, 1] and actions distribution [29, 28, 25, 46]\n", | |
"episode 220\n", | |
"Batch of 128 exps with avg reward -4.15625 and dist. [126, 0, 2] and actions distribution [26, 23, 37, 42]\n", | |
"Batch of 128 exps with avg reward -3.3359375 and dist. [125, 0, 3] and actions distribution [25, 24, 28, 51]\n", | |
"Batch of 128 exps with avg reward -5.03125 and dist. [127, 0, 1] and actions distribution [14, 32, 35, 47]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.8203125 and dist. [21, 0, 107] and actions distribution [21, 26, 35, 46]\n", | |
"episode 230\n", | |
"Batch of 128 exps with avg reward -6.1328125 and dist. [29, 0, 99] and actions distribution [33, 41, 25, 29]\n", | |
"Batch of 128 exps with avg reward -6.171875 and dist. [30, 0, 98] and actions distribution [28, 46, 25, 29]\n", | |
"Batch of 128 exps with avg reward -4.359375 and dist. [126, 0, 2] and actions distribution [39, 33, 33, 23]\n", | |
"Batch of 128 exps with avg reward -5.703125 and dist. [18, 0, 110] and actions distribution [35, 23, 30, 40]\n", | |
"target_model <- acting_model\n", | |
"episode 240\n", | |
"Batch of 128 exps with avg reward -4.8359375 and dist. [127, 0, 1] and actions distribution [49, 20, 27, 32]\n", | |
"Batch of 128 exps with avg reward -4.9140625 and dist. [127, 0, 1] and actions distribution [35, 21, 27, 45]\n", | |
"Batch of 128 exps with avg reward -2.5390625 and dist. [124, 0, 4] and actions distribution [26, 29, 35, 38]\n", | |
"episode 250\n", | |
"Batch of 128 exps with avg reward -5.265625 and dist. [127, 0, 1] and actions distribution [31, 32, 28, 37]\n", | |
"Batch of 128 exps with avg reward -4.3203125 and dist. [126, 0, 2] and actions distribution [23, 33, 32, 40]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.9375 and dist. [127, 0, 1] and actions distribution [41, 23, 30, 34]\n", | |
"episode 260\n", | |
"Batch of 128 exps with avg reward -1.484375 and dist. [123, 0, 5] and actions distribution [36, 20, 31, 41]\n", | |
"Batch of 128 exps with avg reward -5.8203125 and dist. [21, 0, 107] and actions distribution [27, 26, 38, 37]\n", | |
"Batch of 128 exps with avg reward -3.53125 and dist. [125, 0, 3] and actions distribution [37, 40, 18, 33]\n", | |
"Batch of 128 exps with avg reward -5.9765625 and dist. [25, 0, 103] and actions distribution [24, 35, 27, 42]\n", | |
"target_model <- acting_model\n", | |
"episode 270\n", | |
"Batch of 128 exps with avg reward -5.03125 and dist. [127, 0, 1] and actions distribution [29, 30, 32, 37]\n", | |
"Batch of 128 exps with avg reward -4.1640625 and dist. [126, 0, 2] and actions distribution [30, 35, 29, 34]\n", | |
"Batch of 128 exps with avg reward -3.4453125 and dist. [125, 0, 3] and actions distribution [24, 27, 46, 31]\n", | |
"episode 280\n", | |
"Batch of 128 exps with avg reward -3.515625 and dist. [125, 0, 3] and actions distribution [25, 32, 37, 34]\n", | |
"Batch of 128 exps with avg reward -4.1640625 and dist. [126, 0, 2] and actions distribution [57, 34, 23, 14]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.9765625 and dist. [25, 0, 103] and actions distribution [19, 41, 8, 60]\n", | |
"Batch of 128 exps with avg reward -5.03125 and dist. [127, 0, 1] and actions distribution [25, 31, 38, 34]\n", | |
"episode 290\n", | |
"Batch of 128 exps with avg reward -2.546875 and dist. [124, 0, 4] and actions distribution [31, 32, 40, 25]\n", | |
"Batch of 128 exps with avg reward -4.125 and dist. [126, 0, 2] and actions distribution [26, 22, 31, 49]\n", | |
"Batch of 128 exps with avg reward -5.2578125 and dist. [127, 0, 1] and actions distribution [24, 43, 24, 37]\n", | |
"target_model <- acting_model\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:48:22,095] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000300.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 300\n", | |
"Batch of 128 exps with avg reward -5.2265625 and dist. [127, 0, 1] and actions distribution [34, 38, 22, 34]\n", | |
"Batch of 128 exps with avg reward -5.0234375 and dist. [127, 0, 1] and actions distribution [26, 29, 29, 44]\n", | |
"Batch of 128 exps with avg reward -2.6484375 and dist. [124, 0, 4] and actions distribution [37, 33, 23, 35]\n", | |
"episode 310\n", | |
"Batch of 128 exps with avg reward -3.5703125 and dist. [125, 0, 3] and actions distribution [35, 35, 32, 26]\n", | |
"Batch of 128 exps with avg reward -5.703125 and dist. [18, 0, 110] and actions distribution [65, 22, 15, 26]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.6171875 and dist. [125, 0, 3] and actions distribution [38, 38, 23, 29]\n", | |
"episode 320\n", | |
"Batch of 128 exps with avg reward -5.3828125 and dist. [127, 0, 1] and actions distribution [24, 47, 26, 31]\n", | |
"Batch of 128 exps with avg reward -6.0546875 and dist. [27, 0, 101] and actions distribution [15, 43, 34, 36]\n", | |
"Batch of 128 exps with avg reward -5.09375 and dist. [127, 0, 1] and actions distribution [30, 31, 31, 36]\n", | |
"Batch of 128 exps with avg reward -4.875 and dist. [127, 0, 1] and actions distribution [22, 22, 38, 46]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.546875 and dist. [14, 0, 114] and actions distribution [24, 16, 38, 50]\n", | |
"episode 330\n", | |
"Batch of 128 exps with avg reward -5.6640625 and dist. [17, 0, 111] and actions distribution [32, 20, 33, 43]\n", | |
"Batch of 128 exps with avg reward -2.71875 and dist. [124, 0, 4] and actions distribution [28, 32, 31, 37]\n", | |
"Batch of 128 exps with avg reward -3.9609375 and dist. [126, 0, 2] and actions distribution [45, 19, 29, 35]\n", | |
"episode 340\n", | |
"Batch of 128 exps with avg reward -4.0390625 and dist. [126, 0, 2] and actions distribution [21, 21, 21, 65]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.9140625 and dist. [127, 0, 1] and actions distribution [30, 28, 39, 31]\n", | |
"episode 350\n", | |
"Batch of 128 exps with avg reward -3.3671875 and dist. [125, 0, 3] and actions distribution [23, 30, 42, 33]\n", | |
"Batch of 128 exps with avg reward -2.3046875 and dist. [124, 0, 4] and actions distribution [29, 19, 46, 34]\n", | |
"Batch of 128 exps with avg reward -5.390625 and dist. [127, 0, 1] and actions distribution [29, 49, 22, 28]\n", | |
"episode 360\n", | |
"Batch of 128 exps with avg reward -4.2734375 and dist. [126, 0, 2] and actions distribution [35, 30, 22, 41]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -2.421875 and dist. [124, 0, 4] and actions distribution [36, 23, 36, 33]\n", | |
"Batch of 128 exps with avg reward -4.8359375 and dist. [127, 0, 1] and actions distribution [32, 21, 41, 34]\n", | |
"episode 370\n", | |
"Batch of 128 exps with avg reward -5.5859375 and dist. [15, 0, 113] and actions distribution [37, 21, 34, 36]\n", | |
"Batch of 128 exps with avg reward -4.34375 and dist. [126, 0, 2] and actions distribution [22, 36, 38, 32]\n", | |
"Batch of 128 exps with avg reward -4.8359375 and dist. [127, 0, 1] and actions distribution [35, 21, 31, 41]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.5234375 and dist. [125, 0, 3] and actions distribution [25, 26, 34, 43]\n", | |
"episode 380\n", | |
"Batch of 128 exps with avg reward -1.0078125 and dist. [122, 0, 6] and actions distribution [22, 27, 29, 50]\n", | |
"episode 390\n", | |
"Batch of 128 exps with avg reward -1.953125 and dist. [123, 0, 5] and actions distribution [32, 38, 32, 26]\n", | |
"Batch of 128 exps with avg reward -4.6953125 and dist. [126, 0, 2] and actions distribution [39, 63, 13, 13]\n", | |
"Batch of 128 exps with avg reward -3.46875 and dist. [125, 0, 3] and actions distribution [24, 38, 42, 24]\n", | |
"target_model <- acting_model\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:49:55,603] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000400.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 400\n", | |
"Batch of 128 exps with avg reward -1.0703125 and dist. [122, 0, 6] and actions distribution [26, 30, 35, 37]\n", | |
"episode 410\n", | |
"Batch of 128 exps with avg reward -1.484375 and dist. [123, 0, 5] and actions distribution [40, 17, 34, 37]\n", | |
"Batch of 128 exps with avg reward -3.5234375 and dist. [125, 0, 3] and actions distribution [21, 34, 32, 41]\n", | |
"Batch of 128 exps with avg reward -6.2109375 and dist. [31, 0, 97] and actions distribution [18, 40, 31, 39]\n", | |
"Batch of 128 exps with avg reward -5.9765625 and dist. [25, 0, 103] and actions distribution [21, 31, 37, 39]\n", | |
"target_model <- acting_model\n", | |
"episode 420\n", | |
"Batch of 128 exps with avg reward -3.9296875 and dist. [126, 0, 2] and actions distribution [27, 19, 37, 45]\n", | |
"Batch of 128 exps with avg reward -3.8515625 and dist. [126, 0, 2] and actions distribution [43, 13, 45, 27]\n", | |
"Batch of 128 exps with avg reward -4.71875 and dist. [127, 0, 1] and actions distribution [44, 16, 42, 26]\n", | |
"episode 430\n", | |
"Batch of 128 exps with avg reward -5.9375 and dist. [24, 0, 104] and actions distribution [36, 27, 32, 33]\n", | |
"Batch of 128 exps with avg reward -2.6953125 and dist. [124, 0, 4] and actions distribution [20, 31, 37, 40]\n", | |
"target_model <- acting_model\n", | |
"episode 440\n", | |
"Batch of 128 exps with avg reward -2.6171875 and dist. [124, 0, 4] and actions distribution [21, 29, 34, 44]\n", | |
"Batch of 128 exps with avg reward -2.046875 and dist. [123, 0, 5] and actions distribution [27, 42, 28, 31]\n", | |
"Batch of 128 exps with avg reward -6.1328125 and dist. [29, 0, 99] and actions distribution [23, 52, 35, 18]\n", | |
"Batch of 128 exps with avg reward -5.9375 and dist. [24, 0, 104] and actions distribution [29, 30, 42, 27]\n", | |
"episode 450\n", | |
"Batch of 128 exps with avg reward -2.625 and dist. [124, 0, 4] and actions distribution [29, 31, 34, 34]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -2.1953125 and dist. [124, 0, 4] and actions distribution [43, 14, 29, 42]\n", | |
"episode 460\n", | |
"Batch of 128 exps with avg reward -4.3046875 and dist. [126, 0, 2] and actions distribution [35, 34, 28, 31]\n", | |
"Batch of 128 exps with avg reward -5.2578125 and dist. [127, 0, 1] and actions distribution [25, 42, 21, 40]\n", | |
"Batch of 128 exps with avg reward -5.78125 and dist. [20, 0, 108] and actions distribution [29, 26, 42, 31]\n", | |
"episode 470\n", | |
"Batch of 128 exps with avg reward -2.65625 and dist. [124, 0, 4] and actions distribution [27, 28, 41, 32]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.7109375 and dist. [127, 0, 1] and actions distribution [32, 15, 38, 43]\n", | |
"Batch of 128 exps with avg reward -4.6015625 and dist. [127, 0, 1] and actions distribution [68, 13, 13, 34]\n", | |
"episode 480\n", | |
"Batch of 128 exps with avg reward -2.453125 and dist. [124, 0, 4] and actions distribution [22, 20, 35, 51]\n", | |
"Batch of 128 exps with avg reward -1.8671875 and dist. [123, 0, 5] and actions distribution [21, 28, 35, 44]\n", | |
"Batch of 128 exps with avg reward -5.9765625 and dist. [25, 0, 103] and actions distribution [26, 36, 36, 30]\n", | |
"target_model <- acting_model\n", | |
"episode 490\n", | |
"Batch of 128 exps with avg reward -2.65625 and dist. [124, 0, 4] and actions distribution [38, 30, 32, 28]\n", | |
"Batch of 128 exps with avg reward -5.2265625 and dist. [127, 0, 1] and actions distribution [31, 40, 36, 21]\n", | |
"Batch of 128 exps with avg reward -5.2265625 and dist. [127, 0, 1] and actions distribution [29, 38, 29, 32]\n", | |
"Batch of 128 exps with avg reward -4.8984375 and dist. [127, 0, 1] and actions distribution [43, 29, 33, 23]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:51:21,209] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000500.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 500\n", | |
"Batch of 128 exps with avg reward -4.8359375 and dist. [127, 0, 1] and actions distribution [31, 19, 35, 43]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.1640625 and dist. [126, 0, 2] and actions distribution [38, 25, 31, 34]\n", | |
"Batch of 128 exps with avg reward -3.515625 and dist. [125, 0, 3] and actions distribution [31, 35, 29, 33]\n", | |
"episode 510\n", | |
"Batch of 128 exps with avg reward -0.34375 and dist. [121, 0, 7] and actions distribution [22, 36, 44, 26]\n", | |
"Batch of 128 exps with avg reward -5.1484375 and dist. [127, 0, 1] and actions distribution [24, 42, 49, 13]\n", | |
"episode 520\n", | |
"Batch of 128 exps with avg reward -5.1484375 and dist. [127, 0, 1] and actions distribution [26, 39, 34, 29]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.78125 and dist. [20, 0, 108] and actions distribution [31, 30, 30, 37]\n", | |
"Batch of 128 exps with avg reward -3.0625 and dist. [125, 0, 3] and actions distribution [39, 17, 32, 40]\n", | |
"episode 530\n", | |
"Batch of 128 exps with avg reward -3.09375 and dist. [125, 0, 3] and actions distribution [20, 18, 45, 45]\n", | |
"Batch of 128 exps with avg reward -4.984375 and dist. [127, 0, 1] and actions distribution [30, 28, 27, 43]\n", | |
"Batch of 128 exps with avg reward -4.3046875 and dist. [126, 0, 2] and actions distribution [18, 34, 31, 45]\n", | |
"target_model <- acting_model\n", | |
"episode 540\n", | |
"Batch of 128 exps with avg reward -5.3046875 and dist. [127, 0, 1] and actions distribution [40, 44, 21, 23]\n", | |
"Batch of 128 exps with avg reward -3.6875 and dist. [125, 0, 3] and actions distribution [40, 42, 31, 15]\n", | |
"Batch of 128 exps with avg reward -4.234375 and dist. [126, 0, 2] and actions distribution [44, 38, 28, 18]\n", | |
"episode 550\n", | |
"Batch of 128 exps with avg reward -2.6640625 and dist. [124, 0, 4] and actions distribution [32, 33, 32, 31]\n", | |
"episode 560\n", | |
"Batch of 128 exps with avg reward 0.2265625 and dist. [120, 0, 8] and actions distribution [14, 56, 19, 39]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.578125 and dist. [126, 0, 2] and actions distribution [19, 54, 18, 37]\n", | |
"Batch of 128 exps with avg reward -5.296875 and dist. [127, 0, 1] and actions distribution [23, 45, 25, 35]\n", | |
"episode 570\n", | |
"Batch of 128 exps with avg reward -5.0703125 and dist. [127, 0, 1] and actions distribution [24, 28, 34, 42]\n", | |
"Batch of 128 exps with avg reward -4.2109375 and dist. [126, 0, 2] and actions distribution [27, 29, 37, 35]\n", | |
"Batch of 128 exps with avg reward -4.953125 and dist. [127, 0, 1] and actions distribution [33, 24, 31, 40]\n", | |
"target_model <- acting_model\n", | |
"episode 580\n", | |
"Batch of 128 exps with avg reward 1.9921875 and dist. [118, 0, 10] and actions distribution [21, 51, 15, 41]\n", | |
"episode 590\n", | |
"Batch of 128 exps with avg reward -2.984375 and dist. [124, 0, 4] and actions distribution [24, 56, 17, 31]\n", | |
"Batch of 128 exps with avg reward -5.0234375 and dist. [127, 0, 1] and actions distribution [79, 34, 10, 5]\n", | |
"Batch of 128 exps with avg reward -4.5625 and dist. [126, 0, 2] and actions distribution [20, 54, 29, 25]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:52:41,626] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000600.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 600\n", | |
"Batch of 128 exps with avg reward -1.9453125 and dist. [123, 0, 5] and actions distribution [18, 34, 35, 41]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.796875 and dist. [127, 0, 1] and actions distribution [24, 22, 38, 44]\n", | |
"Batch of 128 exps with avg reward -4.71875 and dist. [127, 0, 1] and actions distribution [23, 14, 37, 54]\n", | |
"episode 610\n", | |
"Batch of 128 exps with avg reward -4.03125 and dist. [126, 0, 2] and actions distribution [28, 23, 32, 45]\n", | |
"Batch of 128 exps with avg reward -5.5078125 and dist. [13, 0, 115] and actions distribution [26, 15, 40, 47]\n", | |
"Batch of 128 exps with avg reward -4.0234375 and dist. [126, 0, 2] and actions distribution [24, 24, 43, 37]\n", | |
"target_model <- acting_model\n", | |
"episode 620\n", | |
"Batch of 128 exps with avg reward -2.578125 and dist. [124, 0, 4] and actions distribution [48, 25, 32, 23]\n", | |
"Batch of 128 exps with avg reward -5.8984375 and dist. [23, 0, 105] and actions distribution [28, 32, 34, 34]\n", | |
"episode 630\n", | |
"Batch of 128 exps with avg reward -1.3828125 and dist. [122, 0, 6] and actions distribution [31, 57, 26, 14]\n", | |
"Batch of 128 exps with avg reward -3.625 and dist. [125, 0, 3] and actions distribution [23, 45, 35, 25]\n", | |
"Batch of 128 exps with avg reward -5.2265625 and dist. [127, 0, 1] and actions distribution [40, 36, 28, 24]\n", | |
"target_model <- acting_model\n", | |
"episode 640\n", | |
"Batch of 128 exps with avg reward -4.15625 and dist. [126, 0, 2] and actions distribution [26, 27, 37, 38]\n", | |
"Batch of 128 exps with avg reward -4.5546875 and dist. [127, 0, 1] and actions distribution [37, 11, 38, 42]\n", | |
"Batch of 128 exps with avg reward -4.5234375 and dist. [127, 0, 1] and actions distribution [20, 11, 44, 53]\n", | |
"episode 650\n", | |
"Batch of 128 exps with avg reward -3.296875 and dist. [125, 0, 3] and actions distribution [34, 21, 25, 48]\n", | |
"Batch of 128 exps with avg reward -5.1484375 and dist. [127, 0, 1] and actions distribution [42, 30, 26, 30]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.7421875 and dist. [19, 0, 109] and actions distribution [33, 22, 36, 37]\n", | |
"Batch of 128 exps with avg reward -3.796875 and dist. [125, 0, 3] and actions distribution [18, 63, 22, 25]\n", | |
"episode 660\n", | |
"Batch of 128 exps with avg reward -6.09375 and dist. [28, 0, 100] and actions distribution [27, 40, 31, 30]\n", | |
"Batch of 128 exps with avg reward -4.1640625 and dist. [126, 0, 2] and actions distribution [37, 25, 33, 33]\n", | |
"Batch of 128 exps with avg reward -2.6171875 and dist. [124, 0, 4] and actions distribution [25, 38, 30, 35]\n", | |
"target_model <- acting_model\n", | |
"episode 670\n", | |
"Batch of 128 exps with avg reward -3.4765625 and dist. [125, 0, 3] and actions distribution [29, 32, 28, 39]\n", | |
"Batch of 128 exps with avg reward -2.609375 and dist. [124, 0, 4] and actions distribution [25, 28, 36, 39]\n", | |
"Batch of 128 exps with avg reward -6.09375 and dist. [28, 0, 100] and actions distribution [27, 40, 25, 36]\n", | |
"Batch of 128 exps with avg reward -4.2734375 and dist. [126, 0, 2] and actions distribution [18, 37, 35, 38]\n", | |
"episode 680\n", | |
"Batch of 128 exps with avg reward -3.2578125 and dist. [125, 0, 3] and actions distribution [38, 27, 32, 31]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.234375 and dist. [125, 0, 3] and actions distribution [32, 22, 45, 29]\n", | |
"episode 690\n", | |
"Batch of 128 exps with avg reward -0.765625 and dist. [122, 0, 6] and actions distribution [42, 25, 31, 30]\n", | |
"Batch of 128 exps with avg reward -2.9375 and dist. [124, 0, 4] and actions distribution [26, 54, 30, 18]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:54:17,831] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000700.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 700\n", | |
"Batch of 128 exps with avg reward -4.4296875 and dist. [126, 0, 2] and actions distribution [26, 44, 34, 24]\n", | |
"episode 710\n", | |
"Batch of 128 exps with avg reward 0.453125 and dist. [120, 0, 8] and actions distribution [16, 46, 39, 27]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.8984375 and dist. [23, 0, 105] and actions distribution [30, 26, 38, 34]\n", | |
"Batch of 128 exps with avg reward -4.421875 and dist. [126, 0, 2] and actions distribution [20, 38, 40, 30]\n", | |
"Batch of 128 exps with avg reward -3.1328125 and dist. [125, 0, 3] and actions distribution [47, 17, 38, 26]\n", | |
"episode 720\n", | |
"Batch of 128 exps with avg reward -2.6328125 and dist. [124, 0, 4] and actions distribution [31, 34, 31, 32]\n", | |
"Batch of 128 exps with avg reward -5.9765625 and dist. [25, 0, 103] and actions distribution [34, 28, 20, 46]\n", | |
"target_model <- acting_model\n", | |
"episode 730\n", | |
"Batch of 128 exps with avg reward -3.609375 and dist. [125, 0, 3] and actions distribution [13, 38, 21, 56]\n", | |
"Batch of 128 exps with avg reward -3.515625 and dist. [125, 0, 3] and actions distribution [30, 35, 38, 25]\n", | |
"Batch of 128 exps with avg reward -2.8671875 and dist. [124, 0, 4] and actions distribution [15, 58, 32, 23]\n", | |
"episode 740\n", | |
"Batch of 128 exps with avg reward -1.3203125 and dist. [122, 0, 6] and actions distribution [14, 50, 40, 24]\n", | |
"Batch of 128 exps with avg reward -3.4765625 and dist. [125, 0, 3] and actions distribution [18, 36, 36, 38]\n", | |
"target_model <- acting_model\n", | |
"episode 750\n", | |
"Batch of 128 exps with avg reward -5.625 and dist. [16, 0, 112] and actions distribution [44, 19, 27, 38]\n", | |
"Batch of 128 exps with avg reward -4.2265625 and dist. [126, 0, 2] and actions distribution [45, 32, 20, 31]\n", | |
"Batch of 128 exps with avg reward -4.9375 and dist. [127, 0, 1] and actions distribution [55, 29, 18, 26]\n", | |
"episode 760\n", | |
"Batch of 128 exps with avg reward -3.453125 and dist. [125, 0, 3] and actions distribution [42, 41, 23, 22]\n", | |
"Batch of 128 exps with avg reward -4.9453125 and dist. [127, 0, 1] and actions distribution [28, 29, 38, 33]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.125 and dist. [125, 0, 3] and actions distribution [32, 24, 39, 33]\n", | |
"episode 770\n", | |
"Batch of 128 exps with avg reward -3.484375 and dist. [125, 0, 3] and actions distribution [18, 36, 43, 31]\n", | |
"Batch of 128 exps with avg reward -1.890625 and dist. [123, 0, 5] and actions distribution [30, 42, 31, 25]\n", | |
"Batch of 128 exps with avg reward -5.3203125 and dist. [127, 0, 1] and actions distribution [25, 49, 30, 24]\n", | |
"episode 780\n", | |
"Batch of 128 exps with avg reward -3.2890625 and dist. [125, 0, 3] and actions distribution [52, 29, 27, 20]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.1875 and dist. [126, 0, 2] and actions distribution [31, 30, 39, 28]\n", | |
"Batch of 128 exps with avg reward -5.546875 and dist. [14, 0, 114] and actions distribution [34, 17, 34, 43]\n", | |
"Batch of 128 exps with avg reward -5.46875 and dist. [12, 0, 116] and actions distribution [30, 15, 43, 40]\n", | |
"episode 790\n", | |
"Batch of 128 exps with avg reward -3.2890625 and dist. [125, 0, 3] and actions distribution [29, 28, 40, 31]\n", | |
"Batch of 128 exps with avg reward -3.4921875 and dist. [125, 0, 3] and actions distribution [27, 34, 31, 36]\n", | |
"target_model <- acting_model\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:55:52,776] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000800.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 800\n", | |
"Batch of 128 exps with avg reward -1.84375 and dist. [123, 0, 5] and actions distribution [27, 33, 28, 40]\n", | |
"Batch of 128 exps with avg reward -2.84375 and dist. [124, 0, 4] and actions distribution [25, 45, 27, 31]\n", | |
"episode 810\n", | |
"Batch of 128 exps with avg reward -2.1484375 and dist. [123, 0, 5] and actions distribution [27, 59, 24, 18]\n", | |
"Batch of 128 exps with avg reward -2.6953125 and dist. [124, 0, 4] and actions distribution [42, 35, 31, 20]\n", | |
"episode 820\n", | |
"Batch of 128 exps with avg reward -2.5625 and dist. [124, 0, 4] and actions distribution [39, 30, 37, 22]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.875 and dist. [127, 0, 1] and actions distribution [32, 21, 35, 40]\n", | |
"Batch of 128 exps with avg reward -3.3671875 and dist. [125, 0, 3] and actions distribution [24, 27, 36, 41]\n", | |
"episode 830\n", | |
"Batch of 128 exps with avg reward -2.7265625 and dist. [124, 0, 4] and actions distribution [18, 42, 34, 34]\n", | |
"Batch of 128 exps with avg reward -0.9921875 and dist. [122, 0, 6] and actions distribution [21, 38, 31, 38]\n", | |
"episode 840\n", | |
"Batch of 128 exps with avg reward -2.7734375 and dist. [124, 0, 4] and actions distribution [27, 44, 29, 28]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.140625 and dist. [127, 0, 1] and actions distribution [47, 29, 32, 20]\n", | |
"Batch of 128 exps with avg reward -5.0625 and dist. [127, 0, 1] and actions distribution [43, 30, 31, 24]\n", | |
"episode 850\n", | |
"Batch of 128 exps with avg reward -3.90625 and dist. [126, 0, 2] and actions distribution [47, 21, 42, 18]\n", | |
"Batch of 128 exps with avg reward -4.140625 and dist. [126, 0, 2] and actions distribution [34, 29, 36, 29]\n", | |
"Batch of 128 exps with avg reward -3.4453125 and dist. [125, 0, 3] and actions distribution [26, 41, 20, 41]\n", | |
"target_model <- acting_model\n", | |
"episode 860\n", | |
"Batch of 128 exps with avg reward -3.6875 and dist. [125, 0, 3] and actions distribution [13, 46, 29, 40]\n", | |
"Batch of 128 exps with avg reward -5.0703125 and dist. [127, 0, 1] and actions distribution [27, 31, 33, 37]\n", | |
"Batch of 128 exps with avg reward -5.8984375 and dist. [23, 0, 105] and actions distribution [32, 36, 31, 29]\n", | |
"episode 870\n", | |
"Batch of 128 exps with avg reward -4.03125 and dist. [126, 0, 2] and actions distribution [49, 25, 31, 23]\n", | |
"Batch of 128 exps with avg reward -2.7890625 and dist. [124, 0, 4] and actions distribution [22, 44, 31, 31]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.546875 and dist. [126, 0, 2] and actions distribution [10, 51, 29, 38]\n", | |
"episode 880\n", | |
"Batch of 128 exps with avg reward -2.7109375 and dist. [124, 0, 4] and actions distribution [18, 47, 18, 45]\n", | |
"Batch of 128 exps with avg reward -3.65625 and dist. [125, 0, 3] and actions distribution [13, 53, 21, 41]\n", | |
"episode 890\n", | |
"Batch of 128 exps with avg reward -4.8359375 and dist. [127, 0, 1] and actions distribution [23, 20, 32, 53]\n", | |
"Batch of 128 exps with avg reward -3.28125 and dist. [125, 0, 3] and actions distribution [26, 27, 30, 45]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.6640625 and dist. [125, 0, 3] and actions distribution [18, 44, 25, 41]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:57:18,827] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video000900.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 900\n", | |
"Batch of 128 exps with avg reward -0.515625 and dist. [121, 0, 7] and actions distribution [43, 55, 13, 17]\n", | |
"Batch of 128 exps with avg reward -6.3671875 and dist. [35, 0, 93] and actions distribution [27, 83, 11, 7]\n", | |
"episode 910\n", | |
"Batch of 128 exps with avg reward -0.4765625 and dist. [121, 0, 7] and actions distribution [26, 63, 29, 10]\n", | |
"episode 920\n", | |
"Batch of 128 exps with avg reward -2.359375 and dist. [124, 0, 4] and actions distribution [35, 26, 36, 31]\n", | |
"target_model <- acting_model\n", | |
"episode 930\n", | |
"Batch of 128 exps with avg reward 2.15625 and dist. [118, 0, 10] and actions distribution [24, 46, 21, 37]\n", | |
"Batch of 128 exps with avg reward -2.1875 and dist. [123, 0, 5] and actions distribution [14, 62, 16, 36]\n", | |
"episode 940\n", | |
"Batch of 128 exps with avg reward -4.5390625 and dist. [126, 0, 2] and actions distribution [16, 45, 25, 42]\n", | |
"Batch of 128 exps with avg reward -3.359375 and dist. [125, 0, 3] and actions distribution [21, 27, 38, 42]\n", | |
"episode 950\n", | |
"Batch of 128 exps with avg reward -3.3671875 and dist. [125, 0, 3] and actions distribution [19, 39, 38, 32]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -2.859375 and dist. [125, 0, 3] and actions distribution [60, 11, 28, 29]\n", | |
"Batch of 128 exps with avg reward -5.546875 and dist. [14, 0, 114] and actions distribution [58, 15, 33, 22]\n", | |
"Batch of 128 exps with avg reward -4.4453125 and dist. [127, 0, 1] and actions distribution [61, 8, 38, 21]\n", | |
"episode 960\n", | |
"Batch of 128 exps with avg reward -1.65625 and dist. [123, 0, 5] and actions distribution [33, 26, 40, 29]\n", | |
"Batch of 128 exps with avg reward -5.6640625 and dist. [17, 0, 111] and actions distribution [25, 24, 41, 38]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.5859375 and dist. [15, 0, 113] and actions distribution [34, 18, 40, 36]\n", | |
"episode 970\n", | |
"Batch of 128 exps with avg reward -3.2421875 and dist. [125, 0, 3] and actions distribution [26, 26, 35, 41]\n", | |
"Batch of 128 exps with avg reward -3.734375 and dist. [126, 0, 2] and actions distribution [27, 13, 44, 44]\n", | |
"Batch of 128 exps with avg reward -3.8671875 and dist. [126, 0, 2] and actions distribution [27, 18, 44, 39]\n", | |
"episode 980\n", | |
"Batch of 128 exps with avg reward -4.0703125 and dist. [126, 0, 2] and actions distribution [24, 22, 36, 46]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.2890625 and dist. [125, 0, 3] and actions distribution [35, 24, 34, 35]\n", | |
"episode 990\n", | |
"Batch of 128 exps with avg reward -1.765625 and dist. [123, 0, 5] and actions distribution [28, 35, 36, 29]\n", | |
"Batch of 128 exps with avg reward -5.9765625 and dist. [25, 0, 103] and actions distribution [14, 39, 44, 31]\n", | |
"Batch of 128 exps with avg reward -3.5390625 and dist. [125, 0, 3] and actions distribution [23, 35, 49, 21]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:58:32,712] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001000.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1000\n", | |
"Batch of 128 exps with avg reward -4.171875 and dist. [126, 0, 2] and actions distribution [33, 32, 34, 29]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.9453125 and dist. [126, 0, 2] and actions distribution [49, 23, 25, 31]\n", | |
"Batch of 128 exps with avg reward -3.2265625 and dist. [125, 0, 3] and actions distribution [43, 27, 25, 33]\n", | |
"episode 1010\n", | |
"Batch of 128 exps with avg reward -4.0 and dist. [126, 0, 2] and actions distribution [44, 22, 28, 34]\n", | |
"episode 1020\n", | |
"Batch of 128 exps with avg reward 0.4921875 and dist. [120, 0, 8] and actions distribution [15, 51, 36, 26]\n", | |
"Batch of 128 exps with avg reward -4.3984375 and dist. [126, 0, 2] and actions distribution [16, 42, 31, 39]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.0546875 and dist. [125, 0, 3] and actions distribution [28, 17, 49, 34]\n", | |
"episode 1030\n", | |
"Batch of 128 exps with avg reward -1.6875 and dist. [123, 0, 5] and actions distribution [37, 29, 39, 23]\n", | |
"Batch of 128 exps with avg reward -2.6171875 and dist. [124, 0, 4] and actions distribution [43, 36, 28, 21]\n", | |
"episode 1040\n", | |
"Batch of 128 exps with avg reward -3.453125 and dist. [125, 0, 3] and actions distribution [26, 45, 33, 24]\n", | |
"Batch of 128 exps with avg reward -3.9609375 and dist. [126, 0, 2] and actions distribution [40, 18, 40, 30]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.5859375 and dist. [15, 0, 113] and actions distribution [29, 20, 44, 35]\n", | |
"episode 1050\n", | |
"Batch of 128 exps with avg reward -4.5234375 and dist. [127, 0, 1] and actions distribution [25, 11, 49, 43]\n", | |
"Batch of 128 exps with avg reward -0.0625 and dist. [121, 0, 7] and actions distribution [25, 35, 39, 29]\n", | |
"episode 1060\n", | |
"Batch of 128 exps with avg reward -3.3046875 and dist. [125, 0, 3] and actions distribution [36, 34, 31, 27]\n", | |
"Batch of 128 exps with avg reward -2.7578125 and dist. [124, 0, 4] and actions distribution [25, 43, 27, 33]\n", | |
"target_model <- acting_model\n", | |
"episode 1070\n", | |
"Batch of 128 exps with avg reward -3.6640625 and dist. [125, 0, 3] and actions distribution [15, 46, 37, 30]\n", | |
"Batch of 128 exps with avg reward -5.8203125 and dist. [21, 0, 107] and actions distribution [21, 31, 46, 30]\n", | |
"Batch of 128 exps with avg reward -4.3515625 and dist. [126, 0, 2] and actions distribution [26, 36, 38, 28]\n", | |
"episode 1080\n", | |
"Batch of 128 exps with avg reward -3.96875 and dist. [126, 0, 2] and actions distribution [36, 22, 38, 32]\n", | |
"Batch of 128 exps with avg reward -4.4453125 and dist. [126, 0, 2] and actions distribution [33, 48, 23, 24]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -1.9921875 and dist. [123, 0, 5] and actions distribution [29, 56, 16, 27]\n", | |
"episode 1090\n", | |
"Batch of 128 exps with avg reward -0.9609375 and dist. [122, 0, 6] and actions distribution [39, 43, 24, 22]\n", | |
"Batch of 128 exps with avg reward -3.6796875 and dist. [125, 0, 3] and actions distribution [12, 46, 34, 36]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 08:59:57,712] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001100.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1100\n", | |
"Batch of 128 exps with avg reward -1.0859375 and dist. [122, 0, 6] and actions distribution [30, 52, 23, 23]\n", | |
"Batch of 128 exps with avg reward -4.7890625 and dist. [127, 0, 1] and actions distribution [51, 22, 25, 30]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.390625 and dist. [10, 0, 118] and actions distribution [68, 12, 22, 26]\n", | |
"episode 1110\n", | |
"Batch of 128 exps with avg reward -4.03125 and dist. [126, 0, 2] and actions distribution [41, 25, 35, 27]\n", | |
"Batch of 128 exps with avg reward 0.0234375 and dist. [121, 0, 7] and actions distribution [25, 37, 26, 40]\n", | |
"episode 1120\n", | |
"Batch of 128 exps with avg reward -1.046875 and dist. [122, 0, 6] and actions distribution [19, 37, 25, 47]\n", | |
"Batch of 128 exps with avg reward -4.0859375 and dist. [126, 0, 2] and actions distribution [23, 25, 40, 40]\n", | |
"target_model <- acting_model\n", | |
"episode 1130\n", | |
"Batch of 128 exps with avg reward -1.6328125 and dist. [123, 0, 5] and actions distribution [27, 32, 34, 35]\n", | |
"Batch of 128 exps with avg reward -2.65625 and dist. [124, 0, 4] and actions distribution [29, 41, 33, 25]\n", | |
"episode 1140\n", | |
"Batch of 128 exps with avg reward -6.0546875 and dist. [27, 0, 101] and actions distribution [41, 44, 25, 18]\n", | |
"Batch of 128 exps with avg reward -0.421875 and dist. [121, 0, 7] and actions distribution [33, 45, 32, 18]\n", | |
"episode 1150\n", | |
"Batch of 128 exps with avg reward -0.4921875 and dist. [121, 0, 7] and actions distribution [27, 51, 27, 23]\n", | |
"target_model <- acting_model\n", | |
"episode 1160\n", | |
"Batch of 128 exps with avg reward 0.6796875 and dist. [120, 0, 8] and actions distribution [17, 38, 32, 41]\n", | |
"Batch of 128 exps with avg reward -4.890625 and dist. [127, 0, 1] and actions distribution [31, 31, 36, 30]\n", | |
"episode 1170\n", | |
"Batch of 128 exps with avg reward -3.8359375 and dist. [126, 0, 2] and actions distribution [25, 22, 38, 43]\n", | |
"Batch of 128 exps with avg reward -3.234375 and dist. [125, 0, 3] and actions distribution [30, 25, 37, 36]\n", | |
"episode 1180\n", | |
"Batch of 128 exps with avg reward 2.0546875 and dist. [118, 0, 10] and actions distribution [13, 50, 40, 25]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.265625 and dist. [127, 0, 1] and actions distribution [14, 41, 43, 30]\n", | |
"Batch of 128 exps with avg reward -5.421875 and dist. [127, 0, 1] and actions distribution [19, 72, 25, 12]\n", | |
"episode 1190\n", | |
"Batch of 128 exps with avg reward -2.53125 and dist. [124, 0, 4] and actions distribution [64, 28, 29, 7]\n", | |
"Batch of 128 exps with avg reward -4.109375 and dist. [126, 0, 2] and actions distribution [30, 33, 40, 25]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:01:10,479] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001200.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1200\n", | |
"Batch of 128 exps with avg reward -2.71875 and dist. [124, 0, 4] and actions distribution [27, 37, 36, 28]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -2.25 and dist. [123, 0, 5] and actions distribution [4, 76, 27, 21]\n", | |
"episode 1210\n", | |
"Batch of 128 exps with avg reward -4.4140625 and dist. [126, 0, 2] and actions distribution [5, 51, 37, 35]\n", | |
"Batch of 128 exps with avg reward -4.2734375 and dist. [126, 0, 2] and actions distribution [17, 34, 32, 45]\n", | |
"episode 1220\n", | |
"Batch of 128 exps with avg reward -3.0859375 and dist. [125, 0, 3] and actions distribution [35, 23, 28, 42]\n", | |
"Batch of 128 exps with avg reward -4.65625 and dist. [127, 0, 1] and actions distribution [41, 20, 26, 41]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.6484375 and dist. [126, 0, 2] and actions distribution [11, 67, 26, 24]\n", | |
"episode 1230\n", | |
"Batch of 128 exps with avg reward -2.0859375 and dist. [123, 0, 5] and actions distribution [14, 72, 30, 12]\n", | |
"Batch of 128 exps with avg reward -1.140625 and dist. [122, 0, 6] and actions distribution [20, 50, 33, 25]\n", | |
"episode 1240\n", | |
"Batch of 128 exps with avg reward -4.5 and dist. [126, 0, 2] and actions distribution [11, 53, 32, 32]\n", | |
"Batch of 128 exps with avg reward -0.9765625 and dist. [122, 0, 6] and actions distribution [19, 50, 34, 25]\n", | |
"target_model <- acting_model\n", | |
"episode 1250\n", | |
"Batch of 128 exps with avg reward -3.4296875 and dist. [125, 0, 3] and actions distribution [15, 33, 44, 36]\n", | |
"Batch of 128 exps with avg reward -2.4765625 and dist. [124, 0, 4] and actions distribution [15, 35, 42, 36]\n", | |
"episode 1260\n", | |
"Batch of 128 exps with avg reward -1.640625 and dist. [123, 0, 5] and actions distribution [23, 37, 45, 23]\n", | |
"Batch of 128 exps with avg reward -3.5390625 and dist. [125, 0, 3] and actions distribution [29, 49, 30, 20]\n", | |
"episode 1270\n", | |
"Batch of 128 exps with avg reward -4.1484375 and dist. [126, 0, 2] and actions distribution [47, 24, 31, 26]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.3046875 and dist. [126, 0, 2] and actions distribution [30, 43, 33, 22]\n", | |
"episode 1280\n", | |
"Batch of 128 exps with avg reward -3.6484375 and dist. [126, 0, 2] and actions distribution [32, 11, 68, 17]\n", | |
"Batch of 128 exps with avg reward -4.671875 and dist. [127, 0, 1] and actions distribution [22, 18, 55, 33]\n", | |
"Batch of 128 exps with avg reward -2.0234375 and dist. [123, 0, 5] and actions distribution [19, 49, 24, 36]\n", | |
"episode 1290\n", | |
"Batch of 128 exps with avg reward -3.4453125 and dist. [125, 0, 3] and actions distribution [19, 48, 30, 31]\n", | |
"target_model <- acting_model\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:02:34,129] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001300.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1300\n", | |
"Batch of 128 exps with avg reward 2.984375 and dist. [117, 0, 11] and actions distribution [29, 48, 33, 18]\n", | |
"Batch of 128 exps with avg reward -4.234375 and dist. [126, 0, 2] and actions distribution [22, 39, 47, 20]\n", | |
"episode 1310\n", | |
"Batch of 128 exps with avg reward -3.3984375 and dist. [125, 0, 3] and actions distribution [24, 47, 44, 13]\n", | |
"Batch of 128 exps with avg reward -5.234375 and dist. [6, 0, 122] and actions distribution [26, 7, 87, 8]\n", | |
"episode 1320\n", | |
"Batch of 128 exps with avg reward -0.328125 and dist. [121, 0, 7] and actions distribution [32, 52, 25, 19]\n", | |
"target_model <- acting_model\n", | |
"episode 1330\n", | |
"Batch of 128 exps with avg reward 3.7734375 and dist. [116, 0, 12] and actions distribution [34, 51, 12, 31]\n", | |
"Batch of 128 exps with avg reward -5.4453125 and dist. [127, 0, 1] and actions distribution [8, 63, 26, 31]\n", | |
"episode 1340\n", | |
"Batch of 128 exps with avg reward -1.7890625 and dist. [123, 0, 5] and actions distribution [26, 37, 32, 33]\n", | |
"Batch of 128 exps with avg reward -1.5234375 and dist. [123, 0, 5] and actions distribution [27, 25, 37, 39]\n", | |
"episode 1350\n", | |
"Batch of 128 exps with avg reward -1.6953125 and dist. [123, 0, 5] and actions distribution [26, 30, 37, 35]\n", | |
"target_model <- acting_model\n", | |
"episode 1360\n", | |
"Batch of 128 exps with avg reward 0.3984375 and dist. [120, 0, 8] and actions distribution [16, 65, 29, 18]\n", | |
"Batch of 128 exps with avg reward -2.265625 and dist. [123, 0, 5] and actions distribution [7, 79, 29, 13]\n", | |
"episode 1370\n", | |
"Batch of 128 exps with avg reward -4.3671875 and dist. [126, 0, 2] and actions distribution [29, 58, 22, 19]\n", | |
"Batch of 128 exps with avg reward -5.0078125 and dist. [127, 0, 1] and actions distribution [44, 32, 32, 20]\n", | |
"Batch of 128 exps with avg reward -4.859375 and dist. [127, 0, 1] and actions distribution [30, 29, 37, 32]\n", | |
"target_model <- acting_model\n", | |
"episode 1380\n", | |
"Batch of 128 exps with avg reward -4.109375 and dist. [126, 0, 2] and actions distribution [27, 30, 39, 32]\n", | |
"Batch of 128 exps with avg reward -5.109375 and dist. [127, 0, 1] and actions distribution [11, 31, 46, 40]\n", | |
"Batch of 128 exps with avg reward -3.328125 and dist. [125, 0, 3] and actions distribution [19, 35, 41, 33]\n", | |
"episode 1390\n", | |
"Batch of 128 exps with avg reward -0.6796875 and dist. [122, 0, 6] and actions distribution [15, 21, 51, 41]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:03:33,681] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001400.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1400\n", | |
"Batch of 128 exps with avg reward -0.4140625 and dist. [121, 0, 7] and actions distribution [13, 55, 33, 27]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -4.015625 and dist. [126, 0, 2] and actions distribution [33, 27, 40, 28]\n", | |
"Batch of 128 exps with avg reward -5.140625 and dist. [127, 0, 1] and actions distribution [23, 42, 41, 22]\n", | |
"episode 1410\n", | |
"Batch of 128 exps with avg reward -5.7421875 and dist. [19, 0, 109] and actions distribution [36, 24, 44, 24]\n", | |
"Batch of 128 exps with avg reward -5.703125 and dist. [18, 0, 110] and actions distribution [48, 23, 33, 24]\n", | |
"Batch of 128 exps with avg reward -5.171875 and dist. [127, 0, 1] and actions distribution [37, 31, 34, 26]\n", | |
"target_model <- acting_model\n", | |
"episode 1420\n", | |
"Batch of 128 exps with avg reward 1.6328125 and dist. [119, 0, 9] and actions distribution [30, 31, 38, 29]\n", | |
"Batch of 128 exps with avg reward -4.2421875 and dist. [126, 0, 2] and actions distribution [14, 49, 34, 31]\n", | |
"episode 1430\n", | |
"Batch of 128 exps with avg reward 1.4453125 and dist. [119, 0, 9] and actions distribution [17, 41, 33, 37]\n", | |
"episode 1440\n", | |
"episode 1450\n", | |
"Batch of 128 exps with avg reward 5.3359375 and dist. [114, 0, 14] and actions distribution [10, 62, 41, 15]\n", | |
"Batch of 128 exps with avg reward -1.0859375 and dist. [122, 0, 6] and actions distribution [23, 50, 32, 23]\n", | |
"target_model <- acting_model\n", | |
"episode 1460\n", | |
"Batch of 128 exps with avg reward -1.1953125 and dist. [123, 0, 5] and actions distribution [40, 11, 38, 39]\n", | |
"Batch of 128 exps with avg reward -3.2734375 and dist. [125, 0, 3] and actions distribution [43, 33, 29, 23]\n", | |
"episode 1470\n", | |
"Batch of 128 exps with avg reward -3.2734375 and dist. [125, 0, 3] and actions distribution [60, 32, 23, 13]\n", | |
"Batch of 128 exps with avg reward -4.046875 and dist. [126, 0, 2] and actions distribution [45, 30, 32, 21]\n", | |
"Batch of 128 exps with avg reward -5.625 and dist. [16, 0, 112] and actions distribution [51, 16, 35, 26]\n", | |
"target_model <- acting_model\n", | |
"episode 1480\n", | |
"Batch of 128 exps with avg reward -3.3125 and dist. [125, 0, 3] and actions distribution [14, 27, 48, 39]\n", | |
"Batch of 128 exps with avg reward -3.1171875 and dist. [125, 0, 3] and actions distribution [15, 23, 57, 33]\n", | |
"episode 1490\n", | |
"Batch of 128 exps with avg reward -4.9140625 and dist. [127, 0, 1] and actions distribution [8, 23, 52, 45]\n", | |
"Batch of 128 exps with avg reward -0.2421875 and dist. [121, 0, 7] and actions distribution [10, 49, 39, 30]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:04:45,336] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001500.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1500\n", | |
"Batch of 128 exps with avg reward -0.828125 and dist. [122, 0, 6] and actions distribution [35, 28, 38, 27]\n", | |
"target_model <- acting_model\n", | |
"episode 1510\n", | |
"Batch of 128 exps with avg reward -0.890625 and dist. [122, 0, 6] and actions distribution [19, 32, 40, 37]\n", | |
"Batch of 128 exps with avg reward -3.9453125 and dist. [126, 0, 2] and actions distribution [51, 23, 32, 22]\n", | |
"Batch of 128 exps with avg reward -3.984375 and dist. [126, 0, 2] and actions distribution [68, 24, 27, 9]\n", | |
"episode 1520\n", | |
"Batch of 128 exps with avg reward -3.40625 and dist. [125, 0, 3] and actions distribution [48, 44, 26, 10]\n", | |
"Batch of 128 exps with avg reward -4.234375 and dist. [126, 0, 2] and actions distribution [19, 32, 48, 29]\n", | |
"target_model <- acting_model\n", | |
"episode 1530\n", | |
"Batch of 128 exps with avg reward -3.7109375 and dist. [126, 0, 2] and actions distribution [15, 14, 61, 38]\n", | |
"Batch of 128 exps with avg reward -4.7578125 and dist. [127, 0, 1] and actions distribution [22, 17, 49, 40]\n", | |
"episode 1540\n", | |
"Batch of 128 exps with avg reward 1.59375 and dist. [119, 0, 9] and actions distribution [23, 42, 47, 16]\n", | |
"episode 1550\n", | |
"Batch of 128 exps with avg reward 1.9921875 and dist. [118, 0, 10] and actions distribution [14, 77, 18, 19]\n", | |
"episode 1560\n", | |
"Batch of 128 exps with avg reward -1.0234375 and dist. [122, 0, 6] and actions distribution [29, 42, 25, 32]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.5078125 and dist. [13, 0, 115] and actions distribution [24, 17, 50, 37]\n", | |
"Batch of 128 exps with avg reward -4.4765625 and dist. [127, 0, 1] and actions distribution [31, 14, 58, 25]\n", | |
"Batch of 128 exps with avg reward -4.7109375 and dist. [127, 0, 1] and actions distribution [39, 21, 48, 20]\n", | |
"Batch of 128 exps with avg reward -5.8203125 and dist. [21, 0, 107] and actions distribution [22, 41, 43, 22]\n", | |
"episode 1570\n", | |
"episode 1580\n", | |
"Batch of 128 exps with avg reward 2.4140625 and dist. [118, 0, 10] and actions distribution [34, 32, 46, 16]\n", | |
"target_model <- acting_model\n", | |
"episode 1590\n", | |
"Batch of 128 exps with avg reward 1.609375 and dist. [119, 0, 9] and actions distribution [26, 33, 44, 25]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:05:54,318] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001600.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1600\n", | |
"Batch of 128 exps with avg reward 5.4296875 and dist. [114, 0, 14] and actions distribution [18, 57, 36, 17]\n", | |
"episode 1610\n", | |
"Batch of 128 exps with avg reward 1.375 and dist. [119, 0, 9] and actions distribution [16, 54, 24, 34]\n", | |
"episode 1620\n", | |
"Batch of 128 exps with avg reward 0.5625 and dist. [120, 0, 8] and actions distribution [8, 46, 48, 26]\n", | |
"Batch of 128 exps with avg reward -2.5625 and dist. [124, 0, 4] and actions distribution [25, 33, 42, 28]\n", | |
"target_model <- acting_model\n", | |
"episode 1630\n", | |
"Batch of 128 exps with avg reward -4.1171875 and dist. [126, 0, 2] and actions distribution [45, 28, 35, 20]\n", | |
"Batch of 128 exps with avg reward -5.234375 and dist. [6, 0, 122] and actions distribution [53, 6, 64, 5]\n", | |
"Batch of 128 exps with avg reward -1.453125 and dist. [123, 0, 5] and actions distribution [51, 31, 36, 10]\n", | |
"episode 1640\n", | |
"Batch of 128 exps with avg reward 0.3359375 and dist. [120, 0, 8] and actions distribution [16, 66, 27, 19]\n", | |
"episode 1650\n", | |
"Batch of 128 exps with avg reward 1.328125 and dist. [119, 0, 9] and actions distribution [20, 44, 42, 22]\n", | |
"target_model <- acting_model\n", | |
"episode 1660\n", | |
"Batch of 128 exps with avg reward 3.65625 and dist. [116, 0, 12] and actions distribution [15, 55, 29, 29]\n", | |
"episode 1670\n", | |
"Batch of 128 exps with avg reward -2.15625 and dist. [123, 0, 5] and actions distribution [8, 56, 30, 34]\n", | |
"episode 1680\n", | |
"Batch of 128 exps with avg reward 3.15625 and dist. [117, 0, 11] and actions distribution [9, 41, 41, 37]\n", | |
"episode 1690\n", | |
"Batch of 128 exps with avg reward 3.8359375 and dist. [116, 0, 12] and actions distribution [9, 46, 40, 33]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:06:35,826] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001700.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1700\n", | |
"episode 1710\n", | |
"Batch of 128 exps with avg reward 6.125 and dist. [113, 0, 15] and actions distribution [10, 53, 33, 32]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -2.109375 and dist. [123, 0, 5] and actions distribution [12, 57, 33, 26]\n", | |
"episode 1720\n", | |
"Batch of 128 exps with avg reward -2.9453125 and dist. [124, 0, 4] and actions distribution [13, 54, 33, 28]\n", | |
"Batch of 128 exps with avg reward -2.6640625 and dist. [124, 0, 4] and actions distribution [32, 39, 39, 18]\n", | |
"episode 1730\n", | |
"Batch of 128 exps with avg reward -1.9609375 and dist. [123, 0, 5] and actions distribution [22, 58, 33, 15]\n", | |
"Batch of 128 exps with avg reward -2.6015625 and dist. [124, 0, 4] and actions distribution [41, 43, 35, 9]\n", | |
"target_model <- acting_model\n", | |
"episode 1740\n", | |
"Batch of 128 exps with avg reward -4.890625 and dist. [126, 0, 2] and actions distribution [4, 100, 20, 4]\n", | |
"Batch of 128 exps with avg reward -6.015625 and dist. [26, 0, 102] and actions distribution [7, 45, 57, 19]\n", | |
"Batch of 128 exps with avg reward -4.96875 and dist. [127, 0, 1] and actions distribution [14, 35, 57, 22]\n", | |
"episode 1750\n", | |
"Batch of 128 exps with avg reward -4.421875 and dist. [126, 0, 2] and actions distribution [8, 41, 47, 32]\n", | |
"Batch of 128 exps with avg reward -1.140625 and dist. [122, 0, 6] and actions distribution [10, 46, 52, 20]\n", | |
"target_model <- acting_model\n", | |
"episode 1760\n", | |
"Batch of 128 exps with avg reward -5.34375 and dist. [127, 0, 1] and actions distribution [9, 43, 46, 30]\n", | |
"Batch of 128 exps with avg reward -3.515625 and dist. [125, 0, 3] and actions distribution [18, 32, 55, 23]\n", | |
"episode 1770\n", | |
"Batch of 128 exps with avg reward 0.0078125 and dist. [121, 0, 7] and actions distribution [21, 30, 52, 25]\n", | |
"Batch of 128 exps with avg reward -2.9375 and dist. [124, 0, 4] and actions distribution [13, 53, 41, 21]\n", | |
"episode 1780\n", | |
"Batch of 128 exps with avg reward -3.5234375 and dist. [125, 0, 3] and actions distribution [14, 49, 47, 18]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -5.7421875 and dist. [19, 0, 109] and actions distribution [20, 25, 47, 36]\n", | |
"episode 1790\n", | |
"Batch of 128 exps with avg reward -0.8828125 and dist. [122, 0, 6] and actions distribution [24, 28, 49, 27]\n", | |
"Batch of 128 exps with avg reward -4.8203125 and dist. [127, 0, 1] and actions distribution [30, 24, 45, 29]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:07:49,943] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001800.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1800\n", | |
"Batch of 128 exps with avg reward -1.015625 and dist. [122, 0, 6] and actions distribution [16, 33, 47, 32]\n", | |
"episode 1810\n", | |
"Batch of 128 exps with avg reward -0.3046875 and dist. [121, 0, 7] and actions distribution [16, 41, 42, 29]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -3.578125 and dist. [125, 0, 3] and actions distribution [11, 44, 46, 27]\n", | |
"episode 1820\n", | |
"Batch of 128 exps with avg reward -1.1171875 and dist. [122, 0, 6] and actions distribution [9, 47, 49, 23]\n", | |
"episode 1830\n", | |
"Batch of 128 exps with avg reward -0.625 and dist. [122, 0, 6] and actions distribution [14, 23, 73, 18]\n", | |
"Batch of 128 exps with avg reward -1.671875 and dist. [123, 0, 5] and actions distribution [16, 33, 59, 20]\n", | |
"episode 1840\n", | |
"Batch of 128 exps with avg reward -2.0 and dist. [123, 0, 5] and actions distribution [15, 56, 38, 19]\n", | |
"target_model <- acting_model\n", | |
"Batch of 128 exps with avg reward -2.8046875 and dist. [124, 0, 4] and actions distribution [38, 58, 24, 8]\n", | |
"episode 1850\n", | |
"Batch of 128 exps with avg reward -3.6171875 and dist. [125, 0, 3] and actions distribution [18, 45, 35, 30]\n", | |
"episode 1860\n", | |
"Batch of 128 exps with avg reward 5.3515625 and dist. [114, 0, 14] and actions distribution [9, 59, 37, 23]\n", | |
"episode 1870\n", | |
"Batch of 128 exps with avg reward 4.6171875 and dist. [115, 0, 13] and actions distribution [7, 49, 46, 26]\n", | |
"episode 1880\n", | |
"Batch of 128 exps with avg reward 0.40625 and dist. [120, 0, 8] and actions distribution [6, 49, 45, 28]\n", | |
"target_model <- acting_model\n", | |
"episode 1890\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:08:40,579] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video001900.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 1900\n", | |
"Batch of 128 exps with avg reward 3.7734375 and dist. [116, 0, 12] and actions distribution [4, 54, 43, 27]\n", | |
"Batch of 128 exps with avg reward -4.3203125 and dist. [126, 0, 2] and actions distribution [4, 39, 48, 37]\n", | |
"episode 1910\n", | |
"Batch of 128 exps with avg reward -0.765625 and dist. [122, 0, 6] and actions distribution [14, 29, 56, 29]\n", | |
"Batch of 128 exps with avg reward -2.15625 and dist. [124, 0, 4] and actions distribution [13, 13, 65, 37]\n", | |
"episode 1920\n", | |
"Batch of 128 exps with avg reward 2.296875 and dist. [118, 0, 10] and actions distribution [7, 35, 42, 44]\n", | |
"target_model <- acting_model\n", | |
"episode 1930\n", | |
"Batch of 128 exps with avg reward -3.6015625 and dist. [125, 0, 3] and actions distribution [19, 44, 33, 32]\n", | |
"episode 1940\n", | |
"Batch of 128 exps with avg reward 1.796875 and dist. [118, 0, 10] and actions distribution [9, 71, 21, 27]\n", | |
"episode 1950\n", | |
"Batch of 128 exps with avg reward 2.078125 and dist. [118, 0, 10] and actions distribution [14, 46, 33, 35]\n", | |
"episode 1960\n", | |
"Batch of 128 exps with avg reward 2.09375 and dist. [118, 0, 10] and actions distribution [15, 48, 28, 37]\n", | |
"episode 1970\n", | |
"Batch of 128 exps with avg reward 6.7578125 and dist. [112, 0, 16] and actions distribution [7, 54, 35, 32]\n", | |
"target_model <- acting_model\n", | |
"episode 1980\n", | |
"Batch of 128 exps with avg reward 0.578125 and dist. [120, 0, 8] and actions distribution [4, 44, 36, 44]\n", | |
"episode 1990\n", | |
"Batch of 128 exps with avg reward 2.2578125 and dist. [118, 0, 10] and actions distribution [5, 44, 32, 47]\n", | |
"Batch of 60 exps with avg reward 0.9166666666666666 and dist. [56, 0, 4] and actions distribution [4, 27, 16, 13]\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:09:21,687] Starting new video recorder writing to /Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay/openaigym.video.1.23179.video002000.mp4\n" | |
] | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"episode 0\n", | |
"episode 10\n", | |
"episode 20\n", | |
"episode 30\n", | |
"episode 40\n", | |
"episode 50\n", | |
"episode 60\n", | |
"episode 70\n", | |
"episode 80\n", | |
"episode 90\n" | |
] | |
}, | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2017-03-12 09:09:33,865] Finished writing results. You can upload them to the scoreboard via gym.upload('/Users/gui/Dev/rl-study/tmp/DoomBasic_dqn_replay')\n", | |
"[2017-03-12 09:09:33,873] [DoomBasic-v0] Uploading 2100 episodes of training data\n", | |
"[2017-03-12 09:09:39,734] [DoomBasic-v0] Uploading videos of 21 training episodes (2652401 bytes)\n", | |
"[2017-03-12 09:10:08,711] [DoomBasic-v0] Creating evaluation object from tmp/DoomBasic_dqn_replay with learning curve and training video\n", | |
"[2017-03-12 09:10:09,155] \n", | |
"****************************************************\n", | |
"You successfully uploaded your evaluation on DoomBasic-v0 to\n", | |
"OpenAI Gym! You can find it at:\n", | |
"\n", | |
" https://gym.openai.com/evaluations/eval_kOeHaJ2CQxaaQc2nOOLRA\n", | |
"\n", | |
"****************************************************\n" | |
] | |
} | |
], | |
"source": [ | |
"N_BATCHES = 200\n", | |
"\n", | |
"\n", | |
"class DeepQNetworkTrainer:\n", | |
" \n", | |
" MINI_BATCH_SIZE = 128\n", | |
" UPDATE_TARGET_EVERY_N_BACTHES = 5\n", | |
" \n", | |
" def __init__(self, acting_model, target_model, double_q=False, gamma=.99, reward_clip=5):\n", | |
" self.acting_model = acting_model\n", | |
" self.target_model = target_model\n", | |
" self.double_q = double_q\n", | |
" \n", | |
" self.gamma = gamma\n", | |
" self.reward_clip = reward_clip\n", | |
"\n", | |
" # counter to periodically set target_model <- acting_model\n", | |
" self.trained_epochs = 0\n", | |
" \n", | |
" def fit_episodes(self, experiences_batch):\n", | |
" prev_frames, target_action_rewards = self._batch_to_input_targets(experiences_batch, double_q=self.double_q)\n", | |
" self.acting_model.fit(x=prev_frames, y=target_action_rewards, batch_size=self.MINI_BATCH_SIZE, nb_epoch=1, verbose=0)\n", | |
" self.trained_epochs += 1\n", | |
"\n", | |
" if (self.trained_epochs % self.UPDATE_TARGET_EVERY_N_BACTHES) == 0:\n", | |
" print('target_model <- acting_model')\n", | |
" self.target_model = copy_model(self.acting_model)\n", | |
"\n", | |
" def _batch_to_input_targets(self, experiences_batch, double_q=False):\n", | |
" \n", | |
" experiences = list(filter(None, experiences_batch))\n", | |
" random.shuffle(experiences)\n", | |
" n_samples = len(experiences)\n", | |
"\n", | |
" prev_frames, actions, rewards, next_frames, is_ends = zip(*experiences)\n", | |
" prev_frames = np.asarray(prev_frames)\n", | |
" next_frames = np.asarray(next_frames)\n", | |
" actions = np.asarray(actions)\n", | |
" rewards = np.asarray(rewards)\n", | |
" is_ends = np.asarray(is_ends)\n", | |
"\n", | |
" print('Batch of {} exps with avg reward {} and dist. {} and actions distribution {}'.format(\n", | |
" n_samples,\n", | |
" np.mean(rewards),\n", | |
" np.histogram(rewards, bins=3)[0].tolist(),\n", | |
" np.bincount(actions).tolist()))\n", | |
"\n", | |
" clipped_rewards = np.clip(rewards, -np.inf, self.reward_clip)\n", | |
"\n", | |
" if double_q:\n", | |
" greedy_actions = self.acting_model.predict(next_frames).argmax(axis=1)\n", | |
" actions_target_values = self.target_model.predict(next_frames)[np.arange(n_samples), greedy_actions] \n", | |
" targets = clipped_rewards + self.gamma * (1 - is_ends) * actions_target_values\n", | |
" else:\n", | |
" # Transcription of the Q-learning target formula\n", | |
" targets = clipped_rewards + self.gamma * (1 - is_ends) * self.target_model.predict(next_frames).max(axis=1)\n", | |
"\n", | |
" target_action_rewards = self.target_model.predict(prev_frames)\n", | |
" target_action_rewards[np.arange(n_samples), actions] = targets\n", | |
"\n", | |
" return prev_frames, target_action_rewards\n", | |
"\n", | |
"directory = 'tmp/DoomBasic_dqn_replay'\n", | |
"env = create_env(monitor_directory=directory)\n", | |
"\n", | |
"trainer = DeepQNetworkTrainer(acting_model, target_model)\n", | |
"\n", | |
"experiences = (\n", | |
" Experience(previous_s, a, r, next_s, end) \n", | |
" for (previous_s, a, r, end), (next_s, _, _, _) \n", | |
" in pairwise(generate_sares(env, EpsilonGreedyQAgent(acting_model))))\n", | |
"\n", | |
"#experience_batches = ExperiencesReplay(experiences, memory_size=1000, batch_size=128)\n", | |
"experience_batches = grouper(experiences, n=128)\n", | |
"\n", | |
"for experience_batch in experience_batches:\n", | |
" trainer.fit_episodes(experience_batch)\n", | |
" \n", | |
"# final greedy episodes\n", | |
"sares = list(generate_sares(env, EpsilonGreedyQAgent(acting_model, epsilon=0), episode_count=100))\n", | |
"\n", | |
"env.close()\n", | |
"gym.upload(directory, api_key='sk_bNZUvCfkTfabQCoKoKbjFA')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"collapsed": true | |
}, | |
"source": [ | |
"## Embedding viz\n", | |
"\n", | |
"See http://projector.tensorflow.org/?config=https://raw.githubusercontent.com/pilipolio/rl-study/master/projectors/doom_v1_projector_config.json" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"import pandas as pd\n", | |
"\n", | |
"prev_frames, target_action_rewards = sares_to_input_targets(target_model, sares, n_misses=None)\n", | |
"\n", | |
"n_frames = 1000\n", | |
"frames = prev_frames[:n_frames, :, :, :]\n", | |
"thumbnails = frames[:, :, 25:-25, :]\n", | |
"frame_embeddings = Sequential(acting_model.layers[:-1]).predict(frames)\n", | |
"\n", | |
"\n", | |
"frame_action_rewards = acting_model.predict(frames)\n", | |
"frame_metadata = pd.DataFrame.from_dict({\n", | |
" 'best_action': np.array(['NOOP', 'SHOOT', 'LEFT', 'RIGHT'])[frame_action_rewards.argmax(1)], \n", | |
" 'value': frame_action_rewards.max(1)})\\\n", | |
" .assign(value_quantile=lambda df: np.digitize(df.value, bins=np.percentile(df.value, q=[25, 50, 75])))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"import os\n", | |
"import scipy.misc\n", | |
"\n", | |
"def images_to_sprite(data):\n", | |
" \"\"\"Creates the sprite image along with any necessary padding\n", | |
" From https://github.com/tensorflow/tensorflow/issues/6322\n", | |
" Args:\n", | |
" data: NxHxW[x3] tensor containing the images.\n", | |
"\n", | |
" Returns:\n", | |
" data: Properly shaped HxWx3 image with any necessary padding.\n", | |
" \"\"\"\n", | |
" if len(data.shape) == 3:\n", | |
" data = np.tile(data[...,np.newaxis], (1,1,1,3))\n", | |
" data = data.astype(np.float32)\n", | |
" min = np.min(data.reshape((data.shape[0], -1)), axis=1)\n", | |
" data = (data.transpose(1,2,3,0) - min).transpose(3,0,1,2)\n", | |
" max = np.max(data.reshape((data.shape[0], -1)), axis=1)\n", | |
" data = (data.transpose(1,2,3,0) / max).transpose(3,0,1,2)\n", | |
" # Inverting the colors seems to look better for MNIST\n", | |
" #data = 1 - data\n", | |
"\n", | |
" n = int(np.ceil(np.sqrt(data.shape[0])))\n", | |
" padding = ((0, n ** 2 - data.shape[0]), (0, 0),\n", | |
" (0, 0)) + ((0, 0),) * (data.ndim - 3)\n", | |
" data = np.pad(data, padding, mode='constant',\n", | |
" constant_values=0)\n", | |
" # Tile the individual thumbnails into an image.\n", | |
" data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3)\n", | |
" + tuple(range(4, data.ndim + 1)))\n", | |
" data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])\n", | |
" data = (data * 255).astype(np.uint8)\n", | |
" return data\n", | |
"\n", | |
"def save_projector_config(frame_embeddings, frame_metadata, thumbnails=None):\n", | |
" gh_root = 'https://raw.githubusercontent.com/pilipolio/rl-study/master'\n", | |
" projector_dir = 'projectors'\n", | |
" embedding_name = 'doom_v1'\n", | |
" \n", | |
" projector_config = {\n", | |
" 'embeddings': [\n", | |
" {\n", | |
" 'metadataPath': os.path.join(gh_root, projector_dir, embedding_name + '_metadata.tsv'),\n", | |
" 'tensorName': 'Frames',\n", | |
" 'tensorShape': frame_embeddings.shape,\n", | |
" 'tensorPath': os.path.join(gh_root, projector_dir, embedding_name + '.tsv')\n", | |
" }\n", | |
" ]\n", | |
" }\n", | |
" \n", | |
" if thumbnails is not None:\n", | |
" projector_config['embeddings'][0]['sprite'] = {\n", | |
" 'imagePath': os.path.join(gh_root, projector_dir, embedding_name + '_sprite.png'),\n", | |
" 'singleImageDim': thumbnails.shape}\n", | |
" sprite = images_to_sprite(thumbnails)\n", | |
" scipy.misc.imsave(os.path.join(projector_dir, embedding_name + '_sprite.png'), sprite)\n", | |
" \n", | |
" pd.DataFrame(frame_embeddings).to_csv(os.path.join(projector_dir, embedding_name + '.tsv'),\n", | |
" sep='\\t', index=None, header=None)\n", | |
" frame_metadata.to_csv(os.path.join(projector_dir, embedding_name + '_metadata.tsv'), sep='\\t', index=None)\n", | |
"\n", | |
" with open(os.path.join(projector_dir, embedding_name + ('_with_sprite' if thumbnails is not None else '') + '_projector_config.json'), 'w+') as f:\n", | |
" json.dump(projector_config, f)\n", | |
"\n", | |
"save_projector_config(frame_embeddings, frame_metadata)\n", | |
"\n", | |
"save_projector_config(frame_embeddings, frame_metadata, thumbnails)" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"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.6.0" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment