コンピューター ビジョン、機械学習、その他の分野における DRL の応用Atari ゲーム向けの深層強化学習

著者: 禅とコンピュータープログラミングの芸術

1 はじめに

強化学習 (RL) は、機械学習の分野で革命的で人気のある方向性です。近年、研究者たちはこの分野で大きな進歩を遂げ、驚くべき成果を達成し、多くの学習者やエンジニアにインスピレーション、インスピレーション、モチベーションを与えてきました。ただし、強化学習の複雑さと膨大なアルゴリズム空間のため、誰もがその動作メカニズム、原理、機能、および起こり得る問題を十分に理解できるわけではありません。したがって、深層強化学習 (DRL) の知識をどのように広め、活用するかが注目に値するトピックです。
この記事では、2013 年のジョージ ワシントン大学 Atari ゲーム コンソール プロジェクトを例として、Atari ゲームにおける DRL の適用について説明し、さまざまな段階での DRL 研究の進捗状況とその適用可能なシナリオについて説明し、次の分野での DRL の適用について検討します。コンピュータービジョン、機械学習などの幅広い見通しを示し、具体的な計画や提案をいくつか示します。詳細、分析、実践を通じて、読者に貴重な参考資料を提供できれば幸いです。

2. 基本的な概念と用語の説明

2.1 概念の説明

強化学習 (RL) は、意思決定の問題を解決するために使用される機械学習手法の一種です。これはエージェントと環境の間の相互作用に依存しており、エージェントは特定の戦略で環境を継続的に探索し、報酬 (つまり、期待収益) を獲得し、それによって戦略のパフォーマンスに応じて戦略を更新し、戦略をより良くしていきます。基本的な考え方は、限られた時間内でタスクを完了できるように、自己学習を行うエージェント システムを構築することです。強化学習の主な特徴は、エージェントが環境に関する完全な情報を事前に知る必要がなく、エージェントが環境内で認識できる情報と、アクションを実行することによる報酬を観察するだけでよいことです。他の機械学習アルゴリズムと比較すると、強化学習は、エージェントが環境に適応して最適なアクションを選択できるという点で独特です。したがって、強化学習は新しいタイプの最適化アルゴリズムとみなされます。
強化学習プロセスでは、エージェントと環境の間の関係は、状態、アクション、報酬という 3 つの主要な側面に分割できます。状態は、エージェントの現在の環境状態を表します。アクションは、環境の変化に影響を与えるためにエージェントが使用する動作であり、与えられる外部入力です。報酬は、エージェントがアクションを実行したときに得られる報酬です。RL では、反復ごとに、エージェントはアクションを実行して環境に報酬をフィードバックし、フィードバックに基づいてアクション戦略を更新し、最終的に最適な解決策に到達します。
RL の中心的な問題は、累積報酬を最大化する方法を学ぶことです。各反復で、エージェントは最大の報酬を得るためにさまざまなアクション戦略を試みます。効率を向上させるために、エージェントは一定のトレーニング期間内でランダムな戦略 (探索) を試行錯誤し、徐々に最適な戦略 (搾取) に転換します。トレーニング中、エージェントは継続的に探索すると同時に、既知の条件下でより良いパフォーマンスを確保する必要があり、この 2 つは相互に補完し合います。

2.2 用語の説明

2.2.1 DQN

DQN (ディープ Q ネットワーク) は、2013 年に DeepMind チームによって行われた研究です。その中心的なアイデアは、ニューラル ネットワークを使用して状態伝達関数を自動的に学習し、ニューラル ネットワークを Q 関数として使用してエンドツーエンドの強化を実現することです。学習過程。関数近似手法を使わずに、完全な状態で目的の出力(アクション)を直接予測するのが特徴です。さらに、DQN はネットワーク構造を再利用することでパラメータの数を減らし、コンピューティング リソースの消費を効果的に削減します。現在、DQN は Atari ゲームの主流モデルとなり、2 回連続のメジャー バージョン (バージョン 7 とバージョン 9) で目覚ましい成果を上げています。

2.2.2 DPG

DPG (Deterministic Policy Gradient) は、DeepMind チームによる 2016 年の研究です。その中心的なアイデアは、強化学習手法を使用して、高速応答と安定性の両方を考慮できるエージェントをトレーニングすることです。DPG のアルゴリズム フローは DQN のアルゴリズム フローと似ていますが、エージェントが特定のアクションのみを選択できるようにポリシー パラメーターが制約されています。その主な目的は、DQN のコールド スタート問題を克服することです。現在、DPG はロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。

2.2.3 DDPG

DDPG (Deep Deterministic Policy Gradient) は、DeepMind チームによる 2016 年の研究です。その特徴は、DQN と DPG の利点を組み合わせ、以前の浅いネットワークに代わる深い決定論的なポリシー ネットワークを提案していることです。その主な目的は、DQN または DPG が遭遇するローカル ミニマムの問題を克服し、安定性を向上させ、収束を加速することです。現在、DDPG は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。

2.2.4 A2C

A2C (Asynchronous Advantage Actor Critic、非同期アドバンテージ アクタークリティック) は、2016 年の DeepMind チームによる研​​究です。その中心的なアイデアは、非同期 SGD アルゴリズムを提案し、A3C (Asynchronous Methods for Deep Reinforcement Learning、非同期深層強化学習) を組み合わせるというものです。 DQNには非同期方式)の考え方が導入されています。A2C のアルゴリズム プロセスには、データの収集、ポリシー ネットワークの更新、ポリシー ネットワークの評価、パラメーターの更新、モデルの保存が含まれており、基本的に DQN と同じです。その主な目的は、DQN の単一ステップのサンプル更新方法によって引き起こされる局所的な変動の問題を克服し、パフォーマンスを向上させ、収束を加速することでもあります。現在、A2C は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。

2.2.5 PPO

PPO (Proximal Policy Optimization、近接ポリシー最適化) は、2017 年に OpenAI チームによって行われた研究研究です。その中心的なアイデアは、探索と活用のバランスを達成するために、損失関数に KL 発散制限を設定することでポリシー検索範囲を制御することです。バランス。基本的な処理は従来モデルとほぼ同じですが、戦略の多様性を制御するエントロピーペナルティ項を追加し、学習効率を向上させています。PPO は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。

2.2.6 TRPO

TRPO (Trust Regional Policy Optimization) は、2015 年にスタンフォード大学のチームによって実施された研究です。その中心的な考え方は、ポリシーの検索範囲内に制限を追加することで、局所的な最適解に陥ることを回避することです。TRPO は、強化学習で KL 発散を利用して、さまざまなアクション間の接続を表現し、パラメーター空間のサイズを制御することで探索効率を向上させます。基本的なプロセスは前のモデルとほぼ同じですが、モデルの過学習を防ぐ戦略の多様性を制御するためにペナルティ項が追加されています。TRPO は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。

2.2.7 エイサー

ACER (Actor-Critic with Experience Replay) は、2016 年にスタンフォード大学チームによって行われた研究研究であり、その中心的なアイデアは、時間差に基づいて Q 学習方法を改良し、トレーニング サンプルを強化するためのエクスペリエンス リプレイ方法を提案することです。ACER のアルゴリズム フローは基本的に DQN と同じですが、メモリ上の情報を最大限に活用し、サンプル効率の低下を軽減するためにエクスペリエンス再生手法が導入されています。現在、ACER は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。

3. コアアルゴリズム原理、具体的な操作手順、数式の説明

このセクションでは、DQN、DPG、DDPG、A2C、PPO、TRPO、ACER の基本原理、特性、設計思想を詳細に紹介し、読者がその動作メカニズムをよりよく理解できるように、具体的な操作手順や数式と組み合わせて紹介します。

3.1 DQN

DQN (ディープ Q ネットワーク) は、2013 年に DeepMind チームによって行われた研究です。その中心的なアイデアは、ニューラル ネットワークを使用して状態伝達関数を自動的に学習し、ニューラル ネットワークを Q 関数として使用してエンドツーエンドの強化を実現することです。学習過程。関数近似手法を使わずに、完全な状態で目的の出力(アクション)を直接予測するのが特徴です。さらに、DQN はネットワーク構造を再利用することでパラメータの数を減らし、コンピューティング リソースの消費を効果的に削減します。現在、DQN は Atari ゲームの主流モデルとなり、2 回連続のメジャー バージョン (バージョン 7 とバージョン 9) で目覚ましい成果を上げています。
Atari ゲームでは、各ゲームは RGB ピクセルの集合を表す複数の画面で構成されており、ゲーム画面全体はこのような画面を複​​数重ね合わせることで得られます。特定のエージェントが受け取る唯一の情報は、現在の画面の画像情報と、エージェントが実行できるアクションのリストです。DQN の目標は、この情報を使用してマッピングを学習し、各画面上のピクセルを対応するアクションに変換して、エージェントがゲーム内で適切なアクションを実行できるようにすることです。
まず、DQN はエクスペリエンス プール (再生メモリ) とニューラル ネットワークの 2 つのコンポーネントで構成されます。このうちエクスペリエンスプールは、トレーニングデータ、ゲームのステータス(画面)、リワード(報酬)、終了したかどうか(完了)などを含むゲームデータを保存するために使用されます。ニューラル ネットワークは Q ネットワークであり、フィーチャー ネットワークとアクション ネットワークの 2 つの部分で構成されます。フィーチャー ネットワークは、現在の画面イメージを入力として受け取り、有用なフィーチャーを抽出して、処理のためにアクション ネットワークに送信します。アクション ネットワークはフィーチャ ネットワークの出力を受け取り、各アクションに対応する Q 値を生成し、Q 値に基づいて最適なアクションを選択します。
第二に、DQN が採用するアルゴリズム フレームワークは完全に Q ラーニングに基づいています。Q ラーニングは、問題をマルコフ決定プロセス (MDP) として表す値反復アルゴリズムです。このアルゴリズムでは、エージェントと環境の間の相互作用が状態アクション空間の MDP として定義され、目標は、状態アクション 値関数 (状態アクション値関数、Q 関数) を使用すると、エージェントは後続の状態で最適なアクションを選択できます。DQN は、Q 学習の数学的原理を利用して、状態遷移確率を値ネットワークとしてモデル化し、アクション選択確率をポリシー ネットワークとしてモデル化します。Q 学習でベルマン方程式を最小化することで、DQN は経験プールに基づいて最適な戦略を自動的に学習できます。
最後に、DQN はニューラル ネットワークの自動学習機能を使用して学習効率を向上させます。たとえば、再利用されたネットワーク構造を使用してパラメータの数を削減し、ターゲット ネットワークを固定して学習リスクを軽減し、ターゲット ネットワークの目標を使用して更新頻度を削減します。等 これらの手法により、DQN は 2 つの連続したメジャー バージョン (バージョン 7 とバージョン 9) で顕著な結果を示しました。

3.2 DPG

DPG (Deterministic Policy Gradient) は、DeepMind チームによる 2016 年の研究です。その中心的なアイデアは、強化学習手法を使用して、高速応答と安定性の両方を考慮できるエージェントをトレーニングすることです。DPG のアルゴリズム フローは DQN のアルゴリズム フローと似ていますが、エージェントが特定のアクションのみを選択できるようにポリシー パラメーターが制約されています。その主な目的は、DQN のコールド スタート問題を克服することです。現在、DPG はロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。
まず、DPG と DQN の主な違いは、DPG のポリシー ネットワークはアクションの選択に Q 値を使用できず、決定論的なアクション分布を直接出力することです。次に、DPG は戦略の逸脱を制限するために正則化項も追加します。最後に、DPG はポリシー ネットワークの勾配上昇ステップ サイズを敵対的トレーニングの勾配上昇ステップ サイズに置き換えます。これにより、収束の困難がある程度軽減されます。

3.3 DDPG

DDPG (Deep Deterministic Policy Gradient) は、DeepMind チームによる 2016 年の研究です。DQN と DPG の利点を組み合わせ、以前の浅いネットワークに代わる深い決定論的ポリシー ネットワークを提案することを特徴としています。その主な目的は、DQN または DPG が遭遇するローカル ミニマムの問題を克服し、安定性を向上させ、収束を加速することです。現在、DDPG は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。
DPG と同様に、DDPG のポリシー ネットワークは Q 値を使用してアクションを選択することはできませんが、決定論的なアクション分布を直接出力します。主な違いは、DDPG がターゲット ネットワークに基づいて目的関数を構築し、DQN のエクスペリエンス再生メソッドを組み合わせてトレーニング サンプルを強化することです。最後に、DDPG の更新ステップ サイズは、敵対的トレーニングに基づいて固定ステップ サイズに設定されます。つまり、ネットワークは常に収束できます。

3.4 A2C

A2C (Asynchronous Advantage Actor Critic、非同期アドバンテージ アクタークリティック) は、2016 年の DeepMind チームによる研​​究です。その中心的なアイデアは、非同期 SGD アルゴリズムを提案し、A3C (Asynchronous Methods for Deep Reinforcement Learning、非同期深層強化学習) を組み合わせるというものです。 DQNには非同期方式)の考え方が導入されています。A2C のアルゴリズム プロセスには、データの収集、ポリシー ネットワークの更新、ポリシー ネットワークの評価、パラメーターの更新、モデルの保存が含まれており、基本的に DQN と同じです。その主な目的は、DQN の単一ステップのサンプル更新方法によって引き起こされる局所的な変動の問題を克服し、パフォーマンスを向上させ、収束を加速することでもあります。現在、A2C は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。
DQN と同様に、A2C はエクスペリエンス プール (リプレイ メモリ) とニューラル ネットワークの 2 つのコンポーネントで構成されます。エクスペリエンスプールは、トレーニングデータ、ゲームステータス(画面)、報酬(報酬)、終了したかどうか(完了)などを含むゲームデータを保存するために使用されます。ニューラル ネットワークは、フィーチャー ネットワークとアクション ネットワークの 2 つの部分で構成されます。フィーチャー ネットワークは、現在の画面イメージを入力として受け取り、有用なフィーチャーを抽出して、処理のためにアクション ネットワークに送信します。アクション ネットワークはフィーチャ ネットワークの出力を受け取り、各アクションに対応する Q 値を生成し、Q 値に基づいて最適なアクションを選択します。
ただし、A2C と DQN の違いは、A2C では効率を向上させるためにアルゴリズム プロセスに並列処理用の複数のスレッドを導入していることです。具体的には、A2C がデータを収集する際、複数の軌跡からデータを並行して収集し、統合された方法でエクスペリエンス プールに保存できます。ニューラル ネットワークを更新する場合、A2C は非同期 SGD アルゴリズムを使用します。これにより、複数のエージェントを並行してトレーニングできるようになり、アルゴリズムの同時実行機能が向上します。さらに、A2C では、ポリシー ネットワークを更新するときに、モデルがより適切なアクション値関数を学習できるようにするために、アドバンテージ アクター クリティカル法も導入され、それによってパフォーマンスが向上しました。最後に、A2C は、モデルの予測に完全に基づいたり、履歴データに完全に依存したりすることのない貪欲なポリシーを使用して意思決定を行うため、探索係数を最大化し、モデルの堅牢性を向上させます。

3.5 PPO

PPO (Proximal Policy Optimization、近接ポリシー最適化) は、2017 年に OpenAI チームによって行われた研究研究です。その中心的なアイデアは、探索と活用のバランスを達成するために、損失関数に KL 発散制限を設定することでポリシー検索範囲を制御することです。バランス。基本的な処理は従来モデルとほぼ同じですが、戦略の多様性を制御するエントロピーペナルティ項を追加し、学習効率を向上させています。PPO は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。
DQN、A2C、DDPG とは異なり、PPO には明確な目的関数がありませんが、動的な KL 制約を使用してポリシー ネットワークのパラメーターを調整します。具体的なアプローチは、PPO が kl 発散を使用して 2 つの戦略の類似性を測定し、スーパー パラメーター λ を設定して kl 発散のサイズを制御することです。λ が大きすぎる場合、kl 発散限界が広すぎるため、ポリシー ネットワークの収束が遅くなります。λ が小さすぎる場合、kl 発散限界が小さすぎるため、モデルを新しい環境に一般化できなくなります。したがって、PPO は λ の値を動的に調整することで適切なバランス ポイントを見つけます。
さらに、PPO ではサンプル効率の低下を軽減するために、一次ダイナミクス損失も導入されます。

3.6 TRPO

TRPO (Trust Regional Policy Optimization) は、2015 年にスタンフォード大学のチームによって実施された研究です。その中心的な考え方は、ポリシーの検索範囲内に制限を追加することで、局所的な最適解に陥ることを回避することです。TRPO は、強化学習で KL 発散を利用して、さまざまなアクション間の接続を表現し、パラメーター空間のサイズを制御することで探索効率を向上させます。基本的なプロセスは前のモデルとほぼ同じですが、モデルの過学習を防ぐ戦略の多様性を制御するためにペナルティ項が追加されています。TRPO は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。
DQN、A2C、DDPG、PPO とは異なり、TRPO には明確な目的関数がありませんが、制御制約を使用してポリシー ネットワークのパラメーターを調整します。具体的な方法は、TRPO が各反復でまず現在のポリシーの kl 発散を計算し、kl 発散の大きさに応じてハイパーパラメーター δ を設定して、ポリシー ネットワークのパラメーターの更新振幅を制御します。δ が大きすぎる場合、制約が小さすぎるため、モデルが保守的になりすぎます。δ が小さすぎる場合、制約が広すぎるため、モデルは大域的な最適解を探索できなくなります。したがって、TRPO は δ の値を動的に調整することで適切なバランス ポイントを見つけます。

3.7 エイサー

ACER (Actor-Critic with Experience Replay) は、2016 年にスタンフォード大学チームによって行われた研究研究であり、その中心的なアイデアは、時間差に基づいて Q 学習方法を改良し、トレーニング サンプルを強化するためのエクスペリエンス リプレイ方法を提案することです。ACER のアルゴリズム フローは基本的に DQN と同じですが、メモリ上の情報を最大限に活用し、サンプル効率の低下を軽減するためにエクスペリエンス再生手法が導入されています。現在、ACER は、ロボットの動作計画など、いくつかの複雑な制御問題に役立つことが証明されています。
DQN、A2C、DDPG、PPO、TRPO とは異なり、ACER には明確な目的関数はなく、DQN の利点を組み合わせて、Advantage Actor-Critic (A2C) ソリューションを提案します。ACER の有利なアクター-クリティカル アーキテクチャは、アクター ネットワークとクリティカル ネットワークという 2 つの部分で構成されます。アクターネットワークは、現在の画面イメージを入力として受け取り、各アクションに対応する確率分布を生成し、確率分布に基づいて最適なアクションを選択します。クリティカル ネットワークは現在の画面イメージを入力として受け取り、アクター ネットワークとともに各アクションの Q 値を計算し、Q 値を最適化します。ACER は、トレーニング サンプルを強化するためにエクスペリエンス リプレイも使用します。

4. 具体的なコード例と説明

上記で紹介したアルゴリズム モデルは概要を示しているだけで、実際の操作では、アルゴリズムのハイパーパラメーターの選択、データセットの準備、モデル パラメーターの読み込み、サンプル データの記録、結果の可視化、トレーニング中のサンプリングなど、多くの詳細が必要になります。パターン、推論実装など 参考までに、具体的なコード例をいくつか示します。

4.1 DQN

以下は、PyTorch を使用して記述された DQN の具体的なコード例です。

import torch
import torch.nn as nn
import gym
from collections import deque
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
class DQN(nn.Module):
def __init__(self, num_inputs, num_outputs):
  super(DQN, self).__init__()
   self.fc = nn.Sequential(
      nn.Linear(num_inputs, 128),
      nn.ReLU(),
      nn.Linear(128, 128),
      nn.ReLU(),
      nn.Linear(128, num_outputs)
  )
def forward(self, x):
  return self.fc(x)
env = gym.make('CartPole-v0')
# set up the model
model = DQN(env.observation_space.shape[0], env.action_space.n)
optimizer = torch.optim.Adam(model.parameters())
loss_fn = nn.MSELoss()
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print("Using device:", device)
model = model.to(device)
def train(model, optimizer, loss_fn, experience):
state, action, next_state, reward, done = experience
state = torch.FloatTensor(np.float32(state)).unsqueeze(0).to(device)
next_state = torch.FloatTensor(np.float32(next_state)).unsqueeze(0).to(device)
action = torch.LongTensor(action).unsqueeze(0).to(device)
reward = torch.FloatTensor([reward]).unsqueeze(0).to(device)
done = torch.FloatTensor([done]).unsqueeze(0).to(device)
# get Q(s',a) and best action a' using target net
q_values_next = model(next_state)
_, actions_next = q_values_next.max(dim=1)
q_values_next_target = target_net(next_state)
q_value_next_target = q_values_next_target.gather(1, actions_next.unsqueeze(1)).squeeze(-1)
# compute target value y
target = (q_value_next * GAMMA) + (reward + (GAMMA ** N_STEP) * q_value_next_target * (not done))
# predict current Q values
q_values = model(state)
q_value = q_values.gather(1, action.unsqueeze(1)).squeeze(-1)
# calculate loss between predicted Q value and actual label
loss = loss_fn(q_value, target)
# optimize the model
optimizer.zero_grad()
loss.backward()
optimizer.step()
def run_episode():
episode_rewards = []
state = env.reset()
while True:
  # select an action based on epsilon greedy strategy
  eps_threshold = EPS_END + (EPS_START - EPS_END) * \
      math.exp(-1. * steps_done / EPS_DECAY)
  if random.random() < eps_threshold:
      action = env.action_space.sample()
  else:
      state = torch.FloatTensor(np.float32(state)).unsqueeze(0).to(device)
      q_values = model(state)
      _, action = q_values.max(1)
      action = int(action.item())
      
  # perform the selected action in the environment
  next_state, reward, done, _ = env.step(action)
  
  # store the transition in the replay buffer
  exp = (state, action, next_state, reward, done)
  replay_buffer.append(exp)
          
  # update the state and step count
  state = next_state
  steps_done += 1
  
  # train the model after every C steps
  if len(replay_buffer) > BATCH_SIZE and steps_done % C == 0:
      for i in range(TRAIN_FREQ):
          batch = random.sample(replay_buffer, BATCH_SIZE)
          train(model, optimizer, loss_fn, batch)
          
              
  episode_rewards.append(reward)
  if done or steps_done >= MAX_STEPS:
      break
      
return sum(episode_rewards)
  
      
if __name__ == '__main__':
NUM_EPISODES = 200
REWARDS = []
# initialize target network to same parameters as online network
target_net = DQN(env.observation_space.shape[0], env.action_space.n)
target_net.load_state_dict(model.state_dict())
  
for ep in range(NUM_EPISODES):
  rewards = run_episode()
  REWARDS.append(rewards)
  
  print('[Episode {}/{}] Reward {}'.format(ep+1, NUM_EPISODES, rewards))
  
  if ep % TARGET_UPDATE == 0:
      target_net.load_state_dict(model.state_dict())
          
# plot the total reward per episode
plt.plot(REWARDS)
plt.xlabel('Episode')
plt.ylabel('Total Reward')
plt.show()

4.2 A2C

以下は、PyTorch を使用して記述された A2C の具体的なコード例です。

import os
import time
import torch
import torch.nn as nn
import gym
from tensorboardX import SummaryWriter
import numpy as np
import math
class ActorCritic(nn.Module):
"""
This class implements the ACTOR CRITIC NETWORK used by the A2C algorithm. It takes as input 
the size of the observations space and outputs two vectors of length n_actions representing
the probability distribution over possible actions and the expected value of each action respectively.
"""
def __init__(self, observation_size, hidden_size, n_actions):
  super().__init__()
  self.hidden_size = hidden_size
  self.actor = nn.Sequential(
              nn.Linear(observation_size, hidden_size),
              nn.Tanh(),
              nn.Linear(hidden_size, hidden_size),
              nn.Tanh(),
              nn.Linear(hidden_size, n_actions)
          )
  self.critic = nn.Sequential(
              nn.Linear(observation_size, hidden_size),
              nn.Tanh(),
              nn.Linear(hidden_size, hidden_size),
              nn.Tanh(),
              nn.Linear(hidden_size, 1)
          )
  
def forward(self, x):
  """
  Forward pass through both actor and critic networks. Returns tuple consisting of 
  the actor output (action probabilities) and the critic output (expected value of each action).
  """
  probs = F.softmax(self.actor(x), dim=-1)
  value = self.critic(x)
  return probs, value
class A2CAgent:
"""This is a single agent that interacts with the environment."""
def __init__(self, name, obs_size, act_size, gamma, lr, entropy_coef, max_steps, log_interval, seed):
  self.name = name
  self.obs_size = obs_size
  self.act_size = act_size
  self.gamma = gamma
  self.lr = lr
  self.entropy_coef = entropy_coef
  self.max_steps = max_steps
  self.log_interval = log_interval
  self.seed = seed
  self.training_mode = False
def choose_action(self, obs, training=True):
  """Choose an action given an observation"""
  self.training_mode = training
  self.model.train(training)
  with torch.no_grad():
      obs = torch.tensor(obs, dtype=torch.float32).unsqueeze(0).to(self.device)
      prob = self.model.actor(obs)[0].detach().cpu().numpy()
      dist = Categorical(prob)
      action = dist.sample().item()
  return action
def learn(self, rollout):
  """Update policy using the given rollout"""
  obs_batch, acts_batch, rews_batch, vals_batch, dones_batch = map(
      lambda x: torch.cat(x, dim=0).to(self.device),
      zip(*rollout)
  )
  advantages = rews_batch - vals_batch[:-1]
  
  probs, vals = self.model(obs_batch)
  m_probs, m_vals = self.model(obs_batch[-1])
  last_val = m_vals.view(-1).item()
  discounted_rews = utils.discount_rewards(rews_batch + [last_val], self.gamma)[:-1]
  
  val_loss = ((discounted_rews - vals)**2).mean()
  entropy_loss = (-(m_probs*torch.log(probs))).sum()
  pol_loss = -(advantages.detach() * torch.log(probs)).mean()
  
  loss = pol_loss + val_loss + (self.entropy_coef * entropy_loss)
  loss.backward()
  nn.utils.clip_grad_norm_(self.model.parameters(), max_norm=0.5)
  self.optimizer.step()
  
  return {
    
    'pol_loss': pol_loss.item(), 
          'val_loss': val_loss.item(), 
          'entropy_loss': entropy_loss.item()}
def init_model(self, env, device='cpu'):
  """Initialize actor-critic neural networks"""
  self.device = device
  self.model = ActorCritic(self.obs_size, HIDDEN_SIZE, self.act_size).to(self.device)
  self.optimizer = optim.Adam(self.model.parameters(), lr=self.lr)
  
  
class RolloutStorage:
"""Stores rollouts data until they can be used to update a model"""
def __init__(self, num_steps, num_processes, obs_size, act_size):
  self.observations = torch.zeros(num_steps+1, num_processes, obs_size)
  self.actions = torch.zeros(num_steps, num_processes, 1).long()
  self.rewards = torch.zeros(num_steps, num_processes, 1)
  self.returns = torch.zeros(num_steps+1, num_processes, 1)
  self.masks = torch.ones(num_steps+1, num_processes, 1)
  self.index = 0
  self.num_steps = num_steps
  self.num_processes = num_processes
  self.obs_size = obs_size
  self.act_size = act_size
  
def insert(self, current_obs, action, reward, mask):
  """Insert new observation into the storage buffer"""
  self.observations[self.index+1].copy_(current_obs)
  self.actions[self.index].copy_(action)
  self.rewards[self.index].copy_(reward)
  self.masks[self.index+1].copy_(mask)
  self.index = (self.index + 1) % self.num_steps
  
def after_update(self):
  """Compute returns and clear out the buffers"""
  self._compute_returns()
  self.observations.zero_()
  self.actions.zero_()
  self.rewards.zero_()
  self.masks.fill_(1)
  self.index = 0
  
def compute_advantages(self, last_val=0.0):
  """Computes advantage estimates based on the current returns"""
  advs = self.returns[:-1] - self.values + last_val
  advs = (advs - advs.mean())/(advs.std()+1e-8)
  return advs
def feed_forward_generator(self, advantages, mini_batch_size):
  """Generates batches of data from stored rollout"""
  batch_size = self.num_processes * self.num_steps
  assert batch_size >= mini_batch_size, "Batch size should be greater than or equal to sample size"
  indices = torch.randperm(batch_size).tolist()
  for start_idx in range(0, batch_size, mini_batch_size):
      end_idx = start_idx + mini_batch_size
      sampled_indices = indices[start_idx:end_idx]
      yield self._get_samples(sampled_indices, advantages)
      
      
def _get_samples(self, indices, advantages):
  """Retrieves samples according to the specified indices"""
  obs_batch = self.observations[:-1].view(-1, *self.obs_size)[indices]
  act_batch = self.actions.view(-1, 1)[indices]
  ret_batch = self.returns[:-1].view(-1, 1)[indices]
  adv_batch = advantages.view(-1, 1)[indices]
  old_v_batch = self.values.view(-1, 1)[indices]
  old_p_batch = self.old_log_probs.view(-1, 1)[indices]
  return obs_batch, act_batch, ret_batch, adv_batch, old_v_batch, old_p_batch
def _compute_returns(self):
  """Computes returns recursively from the rewards"""
  R = 0
  self.returns[-1] = self.rewards
  for t in reversed(range(self.rewards.size(0))):
      R = self.gamma * R + self.rewards[t]
      self.returns[t] = R

おすすめ

転載: blog.csdn.net/universsky2015/article/details/132158109