設置環境Gym は、強化学習アルゴリズムの開発と比較のためのツールキットです。gym ライブラリとそのサブシーンを Python にインストールするのは簡単です。 ジムをインストール: pip インストール ジム
自動運転モジュールをインストールします。ここでは、Edouard Leurent が github で公開した highway-env パッケージを使用します。 pip インストール
6つのシーンが含まれています: - 高速道路 - 「highway-v0」
- インポート - 「merge-v0」
- ラウンドアバウト - 「roundabout-v0」
- 駐車場 - 「parking-v0」
- 交差点 - 「交差点-v0」
- レーストラック - 「racetrack-v0」
詳細なドキュメントはここにあります: https://highway-env.readthedocs.io/en/latest/ 環境を構成するインストール後、コード内で実験を行うことができます (高速道路のシナリオを例に挙げます)。 ジムをインポート highway_env をインポートする % matplotlib インライン env = gym.make ( 'highway-v0' ) です。 env.reset ( )は、 _が範囲( 3 ) 内にある場合: アクション= env.action_type.actions_indexes [ "IDLE " ] obs 、 reward 、 done 、 info = env.step ( アクション) env.render ( )は、
実行すると、シミュレーターに次のシーンが生成されます。 env クラスには設定可能なパラメータが多数あります。詳細については元のドキュメントを参照してください。 モデルのトレーニング1. データ処理(1)状態 highway-env パッケージにはセンサーが定義されておらず、すべての車両の状態 (観測値) は基礎となるコードから読み取られるため、初期作業が大幅に節約されます。ドキュメントによると、状態 (ovservations) には、Kinematics、Grayscale Image、Occupancy grid の 3 つの出力モードがあります。 運動学 V*F 行列を出力します。V は観測対象の車両の数 (自車両自体を含む) を表し、F はカウントする特徴の数を表します。例: データが生成されると、デフォルトで正規化され、値の範囲は [100, 100, 20, 20] になります。また、自車両以外の車両属性をマップの絶対座標または自車両に対する相対座標に設定することもできます。 環境を定義するときは、機能のパラメータを設定する必要があります。 設定= \ { "観察" : { 「タイプ」 : 「運動学」 、 「車両数」 : 5 , 「特徴」 : [ 「存在」 、 「x」 、 「y」 、 「vx」 、 「vy」 、 「cos_h」 、 「sin_h」 ]、 「機能範囲」 : { "x" : [ - 100 , 100 ], "y" : [ - 100 , 100 ], "vx" : [ - 20 , 20 ], "ヴィ" : [ - 20 , 20 ] }, 「絶対」 : False 、 「順序」 : 「ソート済み」 }, "シミュレーション周波数" : 8 、 "ポリシー周波数" : 2 、 }
グレースケール画像 W*Hグレースケール画像を生成します。Wは画像の幅、Hは画像の高さを表します。 占有グリッド WHF の 3 次元マトリックスを生成し、W*H テーブルを使用して自車両の周囲の車両状況を表します。各グリッドには F 機能が含まれます。 (2)行動 highway-env パッケージ内のアクションは、連続と離散の 2 つのタイプに分けられます。連続アクションは、スロットルとステアリング角度の値を直接定義できます。離散アクションには 5 つのメタアクションが含まれます。 アクション_ALL = { 0 : 'LANE_LEFT' 、 1 : 「アイドル」 、 2 : '右車線' 、 3 : 「より速く」 、 4 : 「もっとゆっくり」 }
(3)報酬 highway-env パッケージは、駐車シナリオを除いて同じ報酬関数を使用します。 この関数はソースコード内でのみ変更可能であり、外側のレイヤーでは重みのみを調整できます。 (駐車シーンの報酬関数は原文にあります) 2. モデルを構築するDQN ネットワークの場合、デモンストレーションには最初の状態表現方法である運動学を使用します。状態データの量が少ない(5台の車* 7つの特徴)ため、CNNの使用を無視して、2次元データのサイズ[5,7]を[1,35]に直接変換できます。モデルの入力は35で、出力は離散アクションの数で、合計5です。 輸入トーチ torch.nnをnn としてインポートします torch.autograd から変数をインポートします torch.nn.function をF としてインポートする torch.optimをoptim としてインポートします torchvision をインポートします。 torch からFloatTensor 、 LongTensor 、 ByteTensor をインポートします コレクションからnamedtuple をインポートする ランダムにインポート テンソル= FloatTensor EPSILON = 0 ガンマ= 0.9 TARGET_NETWORK_REPLACE_FREQ = 40 メモリ容量= 100 バッチサイズ= 80 LR = 0.01 クラスDQNNet ( nn . モジュール): def __init__ ( 自己): super ( DQNNet 、 self )。__ init__ () 自己. 線形1 = nn . 線形( 35 , 35 ) 自己. 線形2 = nn . 線形( 35 , 5 ) def forward ( self 、 s ): s = torch.FloatTensor (s )です。 s = s . view ( s . size ( 0 ), 1 , 35 ) s = 自己. linear1 ( s ) s = 自己. linear2 ( s ) 返品 クラスDQN ( オブジェクト): def __init__ ( 自己): self.net 、 self.target_net = DQNNet ( )、DQNNet ( ) 自己.learn_step_counter = 0 自己. メモリ= [] 自分. 位置= 0 自己. 容量= MEMORY_CAPACITY self.optimizer = torch.optim.Adam ( self.net.parameters ( ) , lr = LR ) self.loss_func = nn.MSELoss ( ) def choose_action ( self 、 s 、 e ) : アクションを選択します。 x = np . expand_dims ( s 、 軸= 0 ) np.random.uniform ( ) < 1 - e の場合: アクション値= self.net.forward ( x ) アクション= torch.max ( actions_value , - 1 )[ 1 ] .data.numpy ( ) アクション= action.max ( ) それ以外: アクション= np . ランダム.randint ( 0,5 ) リターンアクション def push_memory ( self 、 s 、 a 、 r 、 s_ ) : 定義: len ( self.memory ) < self.capacity の場合: 自己. メモリ. 追加( なし) self.memory [self.position ] = Transition ( torch.unsqueeze(torch.FloatTensor ( s ) , 0 ) , torch.unsqueeze (torch.FloatTensor ( s_ ), 0 ),\ torch.from_numpy ( np.array ([ a ]) ) 、 torch.from_numpy (np.array ( [ r ], dtype = 'float32' ))) 自己. 位置= ( 自己. 位置+ 1 ) % 自己. 容量 get_sample を定義します( self 、 batch_size ): サンプル= ランダム. サンプル( 自己. メモリ, バッチサイズ) 返品サンプル def learn ( 自己): self.learn_step_counter % TARGET_NETWORK_REPLACE_FREQ == 0 の場合: self.target_net.load_state_dict ( self.net.state_dict () ) は、 自己.learn_step_counter += 1 遷移= self.get_sample (BATCH_SIZE ) バッチ= 遷移( * zip ( * 遷移)) b_s = 変数( torch.cat ( batch.state ) ) b_s_ = 変数( torch.cat ( batch.next_state ) ) b_a = 変数( torch.cat ( batch.action )) b_r = 変数( torch.cat ( batch.reward )) q_eval = self.net.forward ( b_s ) .squeeze ( 1 ) .gather ( 1 , b_a.unsqueeze ( 1 ) .to (torch.int64 ) ) q_next = self.target_net.forward ( b_s _ ) . detach () q_target = b_r + GAMMA * q_next . squeeze ( 1 ). max ( 1 )[ 0 ]. view ( BATCH_SIZE , 1 ). t () 損失= self.loss_func ( q_eval , q_target.t ( )) self.optimizer.zero_grad () リセットする 損失。 後方() self.optimizer.step () # する リターンロス 遷移= namedtuple ( '遷移' ,( '状態' , '次の状態' , 'アクション' , '報酬' ))
3. 運用結果すべてのパーツが完成したら、それらを組み合わせてモデルをトレーニングします。プロセスは CARLA を使用する場合と似ているため、詳細は説明しません。 環境を初期化します (DQN クラスを追加するだけです): ジムをインポート highway_env をインポートする matplotlib からpyplotをplt としてインポートします numpyをnp としてインポートする インポート時間 設定= \ { "観察" : { 「タイプ」 : 「運動学」 、 「車両数」 : 5 , 「特徴」 : [ 「存在」 、 「x」 、 「y」 、 「vx」 、 「vy」 、 「cos_h」 、 「sin_h」 ]、 「機能範囲」 : { "x" : [ - 100 , 100 ], "y" : [ - 100 , 100 ], "vx" : [ - 20 , 20 ], "ヴィ" : [ - 20 , 20 ] }, 「絶対」 : False 、 「順序」 : 「ソート済み」 }, "シミュレーション周波数" : 8 、 "ポリシー周波数" : 2 、 } env = gym.make ( "highway-v0" ) です。 env.configure ( config ) で設定します。
モデルをトレーニングします。 dqn = DQN () カウント= 0 報酬= [] 平均報酬= 0 すべての報酬= [] 時間_ = [] オールタイム= [] 衝突_his = [] すべての衝突= [] 真の場合: 完了= False start_time = 時間. 時間() s = env.reset ( )で初期化します。 完了していない間: e = np . exp ( - count / 300 ) a = dqn . choose_action ( s , e ) s_ 、 r 、 完了、 情報= env . ステップ( a ) env.render ( )は、 dqn . push_memory ( s 、 a 、 r 、 s_ ) は、 if (( dqn . position != 0 ) & ( dqn . position % 99 == 0 )): 損失_ = dqn.learn ( ) カウント+= 1 print ( 'トレーニング回数:' , count ) ( カウント% 40 == 0 ) の場合: avg_reward = np . 平均( 報酬) 平均時間= np . 平均( 時間_ ) 衝突率= np . 平均( 衝突時間) all_reward . append ( avg_reward ) all_time . append ( avg_time ) all_collision . append ( 衝突率) plt . plot ( all_reward ) plt . 表示() plt . plot ( all_time ) plt . 表示() plt . plot ( all_collision ) plt . 表示() 報酬= [] 時間_ = [] 衝突_his = [] s = s_ 報酬。 追加( r ) end_time = 時間. 時間() エピソード時間= 終了時間- 開始時間 time_ . append ( エピソード時間) is_collision = 1 if info [ 'crashed' ] == True else 0 collision_his . append ( is_collision ) 衝突の有無
実行プロセス中にいくつかの重要な指標を取得し、40 回のトレーニングごとに平均値を計算できるように、コードにいくつかの描画関数を追加しました。 平均衝突率: 平均エポック期間(秒): 平均報酬: トレーニング回数が増えるにつれて平均衝突率が徐々に減少し、各エポックの継続時間が徐々に増加することがわかります(衝突が発生すると、エポックはすぐに終了します)。 要約するシミュレータ CARLA と比較すると、highway-env 環境パッケージは明らかにより抽象的です。ゲームのような表現方法を使用しており、データ取得方法、センサーの精度、計算時間などの実用的な問題を考慮せずに、理想的な仮想環境でアルゴリズムをトレーニングできます。エンドツーエンドのアルゴリズム設計とテストには非常に便利ですが、自動制御の観点から見ると、開始する側面が少なく、研究の柔軟性があまりありません。 |