こんにちは､ このチュートリアルにようこそ｡
さて､ これまでのチュートリアルで､ a3cの脳を作りましたが､ この脳をトレーニングする必要があります｡
しかし､ このような頭脳を鍛えるためには､ オプティマイザーが必要なのです｡
この2つは確率的勾配降下法で､ 予測値と目標値の誤差にどれだけ寄与したかに応じて重みを更新していくわけですが､
これまで第1モジュールと第2モジュールでは､ 学習時にtorchによる原子最適化器を使いました｡
しかし､ 先ほどお話したように､ 私たちはブレイクアウトという非常に難しい問題を扱っており､ a3cアルゴリズム単体ではこの問題を解決することはできないのです｡
この問題を解決するためには､ カスタマイズされたオプティマイザーや様々なトリックが必要で､ 何時間も待たされることはありません｡
そのため､ アトム・オプティマイザをベースにしたカスタム・オプティマイザを別途用意し､
この共有アトム・クラスの中に入れているわけです｡
そして､ なぜシェアードアトムなのか？
実はアトムオプティマイザだからなのですが､ これだと共有状態でも動いてしまいます｡
そこで､ このチュートリアルでは､ その仕組みについて説明します｡
次の実装のためにエネルギーを残しておきたいので､ ここではコーディングせずにさまざまな機能を見ていきます｡
それが電車で､ 100行以上のコードがかかるあのPIファイルです｡
だから､ そのための準備をする｡
そこで､ このチュートリアルでは､ 1つのチュートリアルで何が起こっているのかを説明しようと思います｡
そして､ 今すぐにでも始めましょう｡
わかりました｡
このクラスは､ init関数､ 共有メモリ関数､ ステップ関数という3つの関数を含んでいます｡
まず最初にすることは､ atomを継承することです｡ atomはもちろんatomオプティマイザで､ torchライブラリのOptimモジュールから取得します｡
そこで､ ここでは､ アトム・オプティマイザに関連するすべてのツールを取得するために､ 継承を適用しています｡
そして､ init機能からスタートします｡
では､ ここで何が起こるのか？
まず､ スーパー関数を使って､ すべてのツールとすべての基本パラメータをatomクラスから継承しました｡
そして､ これらの基本パラメータは､ ここでは､ params､ 学習率､ ベータ､ イプシロン､ ウェイト減衰である｡
そして､ この最初のforループをselfのgroupのために開始します｡
Paramsのグループ｡
ではまず､ paramsグループとは何でしょうか？
paramsグループにはオプティマイザのすべての属性が含まれていることを自己紹介｡
そして､ その属性の中に､ 最適化しなければならないパラメータがあるのです｡
この最適化したいパラメータは､ self dot params groups paramsに含まれるネットワークの重みである｡
そうそう､ そうなんです｡
groups を指定した self に属するグループ｡
そして､ 2つ目のforループで､ self dot parameter groups paramsに含まれる､
最適化したいパラメータを取得します｡
つまり､ 基本的にはすべてのパラメータを含むself that params groupsを通り､ self dot
parameter groupsの各パラメータ群について､ 最適化したいパラメータを調べていくことになる｡
したがって､ ここでいうgroup paramsのpは､ 最適化したい重みの各センサーを意味する｡
そこで､ 最適化したい重みのテンソルごとに
そして､ この4行のコードで構成されるループの中では何が起こっているのでしょうか？
基本的には､ Atom Optimizerが行う更新は､ 勾配の指数移動平均に基づいて行われます｡
それが､ こちらのコードラインです｡
それは､ モーメントの勾配の指数移動平均で､ 1次である｡
しかし､ Atomが行う更新はそれだけでなく､ グラデーションの平方根の指数移動平均に基づいている｡
それは､ 移動2の勾配を指数関数的に移動平均したものである｡
そこで､ ここに1次の指数移動平均と､ 2次の指数移動平均をそれぞれ､
勾配のEMAを示します｡
指数移動平均がどのように機能するのか､ もっと深く知りたい方は､
この研究論文､ Adam a method for stochastic
optimizationをぜひご覧ください｡
ですから､ もしあなたが､ このアルゴリズムがどのように機能するのか､ もっと詳しく知りたいのであれば､ まあ､ この論文は間違いなく役に立つことでしょう｡
そして､ アトムズアップデートルールによるアルゴリズムのさらなる解説がありますね｡
それでね､ その後に作る大きな電車の機能を攻める前に､ これを攻めたい場合だけなんです｡
さて､ それではPythonに戻り､ 2つ目の関数､ share memoryに移りましょう｡
それでは､ 一言ずつ｡
このシェアメモリー機能というのは､ Cuda､ つまりCUDAがGPUをベースにしたアクセラレータであることを示すテンソルのようなものです｡
基本的にここで起こるのは､ メモリを共有する状態のセンサーがこことこことここにあり､ TensorやCudaのように少し振る舞うということです｡
つまり､ 計算を高速化するんです｡
しかし､ 違いは､ ここでテンソルは､ メモリを共有し､ GPUまたはすべての麻痺スレッドにアクセス可能なCPUの一部に計算を送信することです｡
ここでは基本的にそうなっているわけです｡
これはTensor Cudaと少し似ていますが､ 並列ラインのスレッドがアクセスできるGPUまたはCPUの一部にのみ送信されます｡
わかりました｡
そして､ 最後のファンクションステップです｡
つまり､ この関数､ この講座ですでに使ったアトムオプティマイザーのステップメソッドみたいなものですね｡
そして､ これもまた､ 以前見た同じ論文のアルゴリズムに基づいています｡
だから､ このアルゴリズム｡
ですから､ 次のコードの行を詳しく理解したい場合は､ もう一度､ この論文によるこのアルゴリズム1を見てもらうことをお勧めします｡
しかも､ ここで行われているのは､ 実は最適化されたアトムクラスのステップメソッドのコピーペーストなので､
全く強制されることはないのです｡
では､ 基本的にここでは何が行われているのでしょうか｡
ここでは最適化されたアトムから継承しているため､ 継承を利用することで実現できたのです｡
そして､ 相続財産をうまく使うために､ こんなことをする代わりに何ができるかというと､ ここにコメントとして書くだけです｡
共有に適用するスーパーファンクションを使うだけなんです｡
Atom クラスの後､ 私たちのオブジェクト self.
そして､ ここでは括弧でステップを追加しているだけです｡
Stepは最適化されたアイテムクラスのメソッドで､ これは全く同じです｡
だから､ ここはOptim atomクラスのstepメソッドをコピペしただけの話なんです｡
だから､ これを全部､ 共有原子に適用したこのスーパー関数とステップ法に置き換えれば､ まあ､ まったく同じものができるかもしれないと思うんです｡
わかりました｡
だから､ ざっと見た感じでは面白かったですね｡
基本的にはアトムオプティマイザーと捉えていただければと思います｡
より深い見方ができたという感じです｡
しかし､ もしあなたがこのことについてもっと詳しく知りたい､ 舞台裏で何が起こっているのかを理解したいと思うのであれば､
私はこの研究論文を見ることをお勧めします｡
こちらのコメントにリンクを貼っておきますね｡
覚えておいてください､ すべてのコードが詳細にコメントされているはずです｡
だから､ 見てもらえるとすごくいいんです｡
このファイルには巨大な列車関数が含まれていて､ 基本的に脳をトレーニングすることになります｡
では､ 今はゆっくり休んでください､ おやすみなさい｡
そして､ 調子がいいと感じるたびに､ 次のステップに進みましょう｡
それまではお楽しみに｡
I.