\documentclass{article}

\input{../common-preamble}
\input{../bmstu-preamble}
\input{../fancy-listings-preamble}

\begin{document}
\pagestyle{empty}
\makeBMSTUHeader

\makeReportTitle{лабораторной}{1}{Разработка программы «Глубокое Q-обучение игрового агента Atari»}{Мультиагентные интеллектуальные системы}{}{Большаков В.Э.}
\newpage
\tableofcontents
\newpage
\section{Цель работы}

\section{Задание}

\section{Работа и результат}

\section{Выводы}

\newpage
\appendix
\setcounter{secnumdepth}{3}
\section*{Приложения}
\addcontentsline{toc}{section}{Приложения}
\renewcommand{\thesubsection}{\Asbuk{subsection}}

\subsection{Перевод оригинальной статьи Model dynamics}
Чтобы сделать Ваше ожидание не таким скучным, наш код сохраняет лучшие веса модели. В файле \code{/03_dqn_play.py} у нас есть программа, которая может загрузить этот файл модели и сыграть один эпизод, отображая динамику модели. Код очень простой, но наблюдение за тем, как несколько матриц с миллионом параметров играет в пинг-понг с нечеловеческой точностью, глядя только на пиксели, может показаться магией.

\begin{lstlisting}[language=Python,style=PyCodeStyle]
import gym
import time
import argparse
import numpy as np
import torch
from lib import wrappers
from lib import dqn_model

DEFAULT_ENV_NAME = 'PongNoFrameskip-v4'
FPS = 25
\end{lstlisting}

В самом начале мы импортируем уже знакомые PyTorch и Gym модули. Параметр FPS устанавливает примерную скорость демонстрируемых фреймов.

\begin{lstlisting}[language=C,style=CCodeStyle]
if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument('-m', '--model', required=True, help='Model file to load')
  parser.add_argument(
      '-e', '--env', default=DEFAULT_ENV_NAME,
      help=f'Environment name to use, default={DEFAULT_ENV_NAME}')
  parser.add_argument(
      '-r', '--record', help='Directory to store video recording')
  parser.add_argument(
      '--no-visualize', default=True, action='store_false', dest='visualize',
      help='Disable visualization of the game play')
  args = parser.parse_args()
\end{lstlisting}

Скрипт принимает имя файла сохранённой модели и позволяет уточнить Gym-окружение (конечно, модель и окружение, должны соответствовать). В дополнение, возможно передать ключ \code{-r} с именем несуществующей директории, которая будет использована для сохранения видео Вашей игры (используя обёртку монитора). По умолчанию, скрипт просто показывает кадры, но если, например, нужно загрузить видео игры на YouTube, ключ \code{-r} может оказаться полезен.

\begin{lstlisting}[language=Python,style=PyCodeStyle]
env = wrappers.make_env(args.env)
if args.record:
  env = gym.wrappers.Monitor(env, args.record)
net = dqn_model.DQN(env.observation_space.shape, env.action_space.n)
net.load_state_dict(
  torch.load(args.model, map_location=lambda storage, loc: storage))
\end{lstlisting}

Код выше должен быть понятен без комментариев: мы создаём окружение и модель, затем загружаем веса из файла, путь до которого передан в аргументах.

\begin{lstlisting}[language=C,style=CCodeStyle]
state = env.reset()
total_reward = 0.0
  
while True:
  start_ts = time.time()
  if args.visualize:
    env.render()
  state_v = torch.tensor(np.array([state], copy=False))
  q_vals = net(state_v).data.numpy()[0]
  action = np.argmax(q_vals)
\end{lstlisting}

Это почти точная копия метода \code{play_step()} класса \code{Agent} из тренировочного кода без выбора эпсилон-жадной стратегии. Мы просто передаём наши наблюдения агенту и выбираем действие с максимальной наградой. Единственное, что здесь есть нового, это метод \code{render()} в окружении, который является стандартным способом в \code{Gym}, чтобы показать текущие наблюдения (для этого понадобится GUI).

\begin{lstlisting}[language=C,style=CCodeStyle]
  state, reward, done, _ = env.step(action)
  total_reward += reward
  if done:
    break
  if args.visualize:
    delta = 1/FPS - (time.time() - start_ts)
    if delta > 0:
      time.sleep(delta)
print(f'Total reward: {total_reward:.2f}')
\end{lstlisting}

Остальной код также примитивен, мы передаём действие окружению, считаем конечную награду и останавливаем цикл, когда заканчивается эпизод.

\subsection{Перевод оригинальной статьи Deep Q-Learning Agent}
Исследователи обнаружили много советов и приемов для того, чтобы сделать DQN обучение более стабильным и эффективным. Однако основа, позволяющая \code{DeepMind} успешно обучить DQN на наборе из 49 игр Atari и продемонстрировать эффективность этот подход применялся к сложным средам. Оригинальная бумага (без мишени
сети) был опубликован в конце 2013 года (Игра в Atari с Deep Reinforcement
Изучаем 1312.5602v1, Mnih и др.), а для тестирования использовали семь игр. Потом,
в начале 2015 года была опубликована исправленная версия статьи с 49 различными играми.
опубликовано в Nature (Контроль на уровне человека с помощью глубокого обучения с подкреплением
doi:10.1038/nature14236, Mnih и др.) Алгоритм для DQN из предыдущего
бумаги имеет следующие этапы:

\end{document}