hans

hans

【Tensorflow】【Python】自分のデータセットをトレーニングする——データの読み込み、処理、トレーニング、テスト、可視化、デバッグ(単機単カード、単機多カード、多機多カード)


Github コードアドレス: https://github.com/HansRen1024/Tensorflow-preprocessing-training-testing

** すべてのコードは Github から取得してください、ファイル名を対応させてください。 **

** TF バージョンは少なくとも 1.4.0 です。 **

**MonitoredTrainingSession に関する情報は非常に少なく、公式 API とソースコードを長い間研究しました。 **

** 2018.04.13 更新 SSD 単機トレーニング + テストコード: https://github.com/HansRen1024/Tensorflow-SSD
**

2018.03.16 更新 可視化コードを追加

2018.03.19 更新 デバッグコードを追加

2018.03.20 更新 平均値を除去し、正規化コードを追加

2018.03.21 更新 mobilenet と mobilenet v2 ネットワークモデルを追加

2018.03.22 更新 resnet-50, **resnet-101, **resnet-152, resnet-200 **
** ネットワークモデル

実行時に GPU メモリが満杯になる問題を解決しました(単機ではうまくいきますが、分散環境ではうまくいきません)

2018.03.23 更新 GPU を選択

** 2018.03.26 更新 検証段階を追加し、tensorboard で train と val 段階の loss を同時に監視できるようにしました
**

** ** 2018.03.29 更新 finetune 機能を追加しました


** ** 2018.04.02 更新 可視化効果を最適化し、計算ステップの方法を再設定しました。


** ** 2018.04.09 更新 分散環境下で同期・非同期トレーニングスイッチを追加し、MonitoredTrainingSession を再実装しました


** ** 2018.04.10 更新 カスタムの i または step を global step に置き換え、ログ出力の不一致問題を解決しました


2018.04.11 更新 非同期トレーニングで最後のイベント記録が失敗する問題を解決しました

前書き#

新しいビジネスで分散クラスターを構築する必要があり、以前は caffe を使用していましたが、今は Tensorflow を使用する必要があります。

ネット上には公式デモをそのままコピーしたものがほとんどで、データの読み込み処理からトレーニング、テストまでの詳細な説明がある記事はありません。私が書きます。

一、データセットの準備#

以前は caffe を使用しており、データセットは異なるディレクトリに分類されていました。ここで 2 つのスクリプトを公開します、それぞれの機能は説明を見てください。

スクリプト 1(img2bin.py)はこの使用をお勧めしません、後続の更新がありません:

classes は images ディレクトリ内の各データセットのディレクトリ名です。

img=img.resize ((227,227)) ネットワーク構造に応じて resize サイズを選択する必要があります。

このスクリプトは images ディレクトリと同じ階層にあり、images ディレクトリ内には「0」、「1」、「2」という 3 つのディレクトリがあり、それぞれ 3 つのカテゴリのすべての画像データセットが格納されています。最後に「train.tfrecords」という名前のバイナリファイルが生成されます。

スクリプト 2(list2bin.py):

最後に一組の bgr 三チャネル平均を印刷し、トレーニングセットの平均を記録し、arg_parsing.py に配置して平均除去操作に使用します。

必ず RGB 三チャネルに変換してください、さもないと後のデータ読み込みで問題が発生します。

以前 caffe を使用していたとき、最初に txt 文書を生成する習慣があり(形式は以下の通り)、その後文書に基づいて lmdb データセットを生成しました。

スクリプト 2 はこの txt 文書に基づいて tfrecords バイナリデータセットを生成します。

txt 文書を生成するスクリプトのブログアドレス(Github のimg2list.sh):
【Caffe】自分のデータをトレーニングするための迅速なスタート《Caffe について真剣に話す》

コードはデータセットの準備の中で train.txt と val.txt を生成する.sh スクリプトです。

2 番目のスクリプトを書くのは、トレーニング段階で val の出力を基にトレーニングプロセスが正しいかどうかを判断するための習慣です。 しかし後にいくつかの理由で、トレーニング段階で val を行うことができませんでした。さらに研究が必要です - 0-。

二、構成準備段階#

上記で生成した.tfrecords バイナリデータセットを取得したら、環境を整えてトレーニングを開始できます。

コードが多いため、説明はコード内に記載しますので、見やすくなります。正直、多くの tf の API も理解できていませんが、今はただ動かすことができました。今後も多くの時間をかけて学習研究する必要があります。

文書 1(arg_parsing.py):

この文書は主に実行入力パラメータを設定するためのもので、理解しやすいです。コード内で大文字の文字の後ろのデフォルトパラメータを変更することも、コマンドラインでパラメータを指定することもできます。

文書 2(dataset.py):

データを読み込み、平均を除去し、正規化し、ネットワークに入力するために一つのバッチに統合します。

文書 3(main.py):

コマンドラインで実行する文書で、内容は非常にシンプルです。

if tf.gfile.Exists(FLAGS.model_dir):
#コメントの 3 行は models ディレクトリを空にし、このディレクトリがない場合は作成します。誤操作を防ぐために、私はこの 3 行をコメントアウトしました。

文書 4(net/squeezenet.py):

ネットワーク構造文書で、別に書き出しておくと、将来的にネットワーク構造を変更するのが便利です。

私のは squeezenet ネットワークで、公式デモでは 3232 データセットしか処理できませんが、私は変更しました。今このネットワークは正常に 227227 を処理できます。

network.py は見るだけで、後に私が捨てて更新を停止しました。

文書 5(test.py):

テスト用の文書です。

文書 6(train.py)

トレーニング文書で、3 つのトレーニング方法があります。最も疲れた文書です、面倒です~~~。

train ():# 単機単カード + 単機多カード共通トレーニング方法。
train_dis_():# 使用可能な分散多機多カード。

train.py についてはもう少し言いたいことがあります。

1. セッションについて、一般的には tf.Session () を使用します。ここでは tf.train.MonitoredTrainingSession () を使用しています。これは公式 API の推奨と cifar-10 デモでの使用を見たからです。このインターフェースのhook部分は非常に便利で、いくつかの機能を柔軟に定義して使用できます。公式 API 文書では、ほとんどすべての hook がここで使用できます。例えばデバッグ、サマリーなど、研究する価値があります。(
2018.03.23
この MTS マネージャーを通じて検証段階を追加するのは非常に難しいです。共有パラメータを使用して検証する場合、問題は主に global_step の競合です。ローカル ckpt を読み込む場合、ckpt を保存する頻度と検証の頻度をバランスさせるのが難しいです。

  1. なぜトレーニングを開始するとすべての GPU のメモリがすぐに占有されるのか理解できません。batch_size を 1 に設定しても 32 でも 64 でも結果は同じです。したがって、val を実行すると GPU メモリ不足のエラーが発生し、しばらくするとマシンがフリーズします - 0-。この問題は後でゆっくり解決しましょう~

3.3 番目の train_dis () メソッドは同期または非同期を制御できますが、少し問題があります。急いでプロセスを通過させるために気にしませんでした。後で時間があれば見ます。

4.2 番目の train_dis_() は使用可能な分散多機多カード方法で、私はそれが非同期であると判断しています。

5.CUDA_VISIBLE_DEVICES=0,1 という文を使用して特定の GPU を制御できます。または main.py に以下の文を追加して設定できます。

三、トレーニング段階の配置#

第一の状況(単機単カード、単機多カード):

main.py で呼び出す train の方法とパスを設定し、直接実行します:

python main.py

デフォルトではトレーニングモードです

第二の状況(多機多カード):

コマンドラインで --job_name を指定するだけで、自動的に分散トレーニングが実行されます。

すべての文書とデータセットをそれぞれのサーバーに分配する必要があります。

例えば、私には現在 2 台のサーバー 10.100.1.151 と 10.100.1.120 があります。

私は 151 サーバーを同時に ps と worker として使用し、

120 サーバーを worker として使用します。

まず arg_parsing.py で ps_hosts と worker_hosts を設定し、カンマで区切り、スペースを入れないでください。

次に 151 サーバーで実行します:

CUDA_VISIBLE_DEVICES='' python src/main.py --job_name=ps --task_index=0

ここで CUDA_VISIBLE_DEVICES='' は GPU を使用しないことを示します。パラメータサーバーとして CPU で処理できます。

次に、151 サーバーで続けて実行します:

CUDA_VISIBLE_DEVICES=0 python src/main.py --job_name=worker --task_index=0

最後に 120 サーバーで実行します:

CUDA_VISIBLE_DEVICES=0 python src/main.py --job_name=worker --task_index=1

CUDA_VISIBLE_DEVICES を使用して有効にする GPU を設定できます。シーケンスはカンマで区切ります。

四、テスト#

特に多機多カードでは、index が 0 のホストでのみ ckpt が保存されることを特に指摘します。

テストセットの.tfrecords を準備し、パスを設定し、コマンドラインで実行します:

python main.py --mode=testing

テストモードを指定する必要があります。

後記#

コマンドラインパラメータを研究してみてください。多くありますが、すべて非常にシンプルです。

今後も継続的に更新していきます。。。

1. 同期・非同期(2018.04.09 完了)

2. 平均除去、正規化(2018.03.20 完了)

3. 可視化(2018.03.16 完了)

4. デバッグ(2018.03.19 完了)

5. 検証(2018.03.26 完了)

  1. GPU メモリが常に占有される問題について(2018.03.22 完了)

  2. さらに多くのネットワークモデル文書の準備(2018.03.19 mobilenet、2018.03.22 resnet)

  3. GPU の選択(2018.03.19 完了)

  4. 可視化のネットワーク構造図の最適化(2018.04.02 完了)

10.Finetune(2018.03.29 完了)

11. 新しい問題、ネット上で解決策が見つかりませんでした。非同期分散トレーニングが完了した後、最後のイベント記録が失敗します。これは、index=0 のホストが run_context.request_stop () を実行する際に、他のマシンが検証段階にいる可能性があるためです。(2018.04.11 完了)

1668714987733.jpg

12. 新しい問題、分散同期トレーニング環境下で、検証段階を経た後、global step と i が一致しない問題。具体的には画像を参照してください。

index=0 のマシン:

1668714995590.jpg

index=1 のマシン(990step で停止し、0 マシンの検証が終了するのを待っています。):

1668715002213.jpg

私が考えた解決策は、log と検証を hook として MonitoredTrainingSession に追加することですが、試した後、問題は解決しませんでした。(2018.04.10 解決)

これも以下の問題に関連しています:

検証のこのステップに到達すると、性能の異なるマシンが検証を同期して行わないことになります。

順序は:検証ステップに到達すると、性能の良いマシンが先に検証を行い、終わった後、性能の悪いマシンが検証を行います。

これにより、全体のトレーニング時間が増加します。具体的な理由は、検証ステップを 1000 に設定した場合、sess run が 1001 ステップに達すると、1000 ステップのパラメータが ps マシンに渡され、更新されてから worker マシンに戻され、続けて 1001 ステップのトレーニングが行われるからです。(あなたが理解できるかどうかわかりませんが - 0-、MonitoredTrainingSession のこのセッションは毎回実行されるときに実際には 3 つのステップに分かれています。begin、before run、after run。パラメータは ps マシンに渡され、worker マシンに戻されるのは before のステップで行われるはずです。) (2018.04.02 MonitoredTrainingSession を再実装した後、index=0 のマシンでのみ検証を行うようにしました)

同期モードのトレーニングが完了するたびに、index 0 のマシンがしばらく停止し、その後エラーが発生します:

1668715013234.jpg

Google で検索しましたが、解決策は見つかりませんでした。しかし、全体のトレーニングには影響しないので、無視します!

  1. 一つの疑問があります。tensorboard で観察すると、val_loss は 100 ステップごとに記録されます。しかし実際には 1000 ステップごとに検証を行っています。少し混乱しています。

  2. 同期トレーニング中、性能の良いマシンが先にトレーニングを開始します。もしホストが先にトレーニングを開始しなければ、tensorboard の初期ステップは 1 から始まらないことになります。

---------2018.03.16 更新 ----- 可視化 -------

ネットワーク構造文書(squeezenet.py)を再実装し、パラメータ計算プロセスを最適化し、サマリーコードを追加しました。これにより、tensorboard で多くの内容を確認できるようになりました。

他の文書も相応に更新しました。

古いネットワーク構造文書(network.py)を使用したい場合は、train.py 文書内の inference の行を変更すれば大丈夫です。

index=0 のサーバー上の models ディレクトリを自分のホストに戻し、コマンドラインで実行します:

tensorboard --logdir=models/

ブラウザのアドレスバーに入力します:

localhost:6006

これで可視化内容を確認できます。また、サーバー上で tensorboard コマンドを実行し、自分のホストのブラウザのアドレスバーに IP:ポート番号を入力することで、可視化内容を確認することもできます。

---------2018.03.19 更新 -----DEBUG-------

train コードにデバッグコードを追加しました、たった一行です。tf.train.MonitoredTrainingSession の hook リストに、arg_parsing.py でデバッグモードを有効にするかどうかを設定します。

API の中で tensorboard でデバッグするためのインターフェース tfdbg.TensorBoardDebugHook () も見つけましたが、私のホストの tensorflow バージョン 1.2 にはこのインターフェースがまだないので、テストは行っていません。個人の好みによりますが、コマンドラインでデバッグするのが好きか、tensorboard でデバッグするのが好きかです。

同時にパラメータコードを修正し、毎回実行する際にはトレーニングモードを指定する必要があります。

---------2018.03.20 更新 ----- 平均除去、正規化 -------

  1. img2bin_list.py を修正し、最後に bgr 三チャネルの平均を計算して印刷します。

  2. arg_parsing.py を修正し、平均パラメータを追加しました。

  3. dataset.py を修正し、データ読み込み時に平均除去と正規化操作を追加しました。

---------2018.03.21 更新 ----- ネットワークモデルの追加 -------

  1. arg_parsing.py、test.py、train.py を修正しました。

  2. mobilenet と mobilenet v2 ネットワークモデルを追加しました。

** --------- 2018.03.22 更新 ----- ネットワークモデルの追加、GPU メモリ問題の解決 ------- **

  1. arg_parsing.py、test.py、train.py を修正しました。

  2. resnet-50、resnet-101、resnet-152、resnet-200 ネットワークモデルを追加しました。

  3. 実行時に GPU メモリが満杯になる問題を解決しましたが、単機でしかうまくいかず、分散環境ではうまくいきません。

---------2018.03.26 更新 ----- トレーニング段階で検証段階を追加 ------- ****

train.py の変更が比較的大きく、すべてのネットワーク構造.py にも変更があり、tensorflow バージョンは少なくとも 1.4.0 が必要です。

理由は tf.variable_scope () 内に reuse=tf.AUTO_REUSE がないためです。

もちろん、もしあなたが自分で一つ一つ reuse を設定できるなら、理論的には低バージョンの tensorflow でも使用可能です。

少し面倒ですが、train か val かを判断し、それぞれ reuse を False または True に設定する必要があります。

---------2018.03.29 更新 -----Finetune------- ****

finetune が可能になりました。

私は以前にトレーニングしたモデルを基に finetune しています、

まだオープンソースのトレーニング済みモデルを探していません。 ( 2018.04.02 Github で適切な事前トレーニングモデルが見つからず、たとえ見つかってもいくつかの問題に直面する可能性があります。)

コマンドラインでモデル保存パスを指定するだけで自動的に finetune できます。

--finetune=path/

---------2018.04.02 更新 ----- 可視化効果を最適化 ------- ****

  1. トレーニング段階と検証段階のサマリーをそれぞれ異なる namespace に配置し、ネットワーク構造図も最適化しました。

---------2018.04.09 更新 ----- 同期・非同期トレーニング ------- ****

  1. 分散環境で、パラメータの同期または非同期更新を制御するためのブールスイッチ(--issync)を追加しました。

  2. worker サーバーは必ず index が 0 から始まるマシンを一つずつ実行する必要があります。順番にプログラムを実行しないと、各サーバーのステップに大きな差が生じます。

  3. MonitoredTrainingSession を再実装し、log と検証をそれぞれ 2 つの hook に書き込み、同期モードでは index=0 の worker マシンのみが検証を行います。

---------2018.04.10 更新 ----- ログ出力ステップ不一致問題の解決 -------

  1. 分散、同期トレーニング環境下で、hook 内で run_context.session.run (global_step) を使用してグローバルステップを読み取り、ログと検証を制御し、異なるマシン間のステップ不一致問題を解決しました。

---------2018.04.11 更新 ----- 非同期トレーニングで最後のイベント記録失敗問題の解決 -------

  1. 非同期トレーニングも global_step を読み取ることで制御し、ExitHook 内で強制的に index=0 のホストが最後の段階で一度検証を行い、他のマシンが先に run_context.request_stop () を実行することを保証しました。こうすることで、最後のイベント記録失敗問題を解決しました。私が理想とする解決方法は、index=0 のホストが現在の global step がトレーニング終了回数に達したことを発見したとき、他のマシンがすべて request stop を実行した後に自分が request stop を実行することです。

---------2018.04.13 更新 -----SSD コードを追加 -------

  1. 具体的なモデル保存パスとデータパスを設定する必要があります。

  2. データパス内の画像と xml ファイルはそれぞれ 2 つのディレクトリに保存する必要があります。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。