前書き#
前回のブログでは、提供された VGG ネットワークを使用して完全なプロセスを実行しましたが、すぐに MobileNet を使用してトレーニングを試みます。
解決すべき問題が 2 つあります:
-
平均値の問題。【2017.11.20 この問題を解決】
-
MobileNet の提供する caffemodel を finetune できない。【2017.11.3 この問題を解決】
【2017.11.03 更新】ncnn 形式に正常に変換されました。
一、データセットの収集と整理#
参考: 【SSD】用 caffe-ssd フレームワークで独自のデータセットをトレーニングする
使用するものは次のとおりです:
二、MobileNet 関連ファイルのダウンロード#
Github Repo not found
The embedded github repo could not be found…
パスは自分で調整してください。
三、train.prototxt、test.prototxt、deploy.prototxt の生成#
ここで、少し前に言及する必要があります。
-
デフォルトで MobileNet_deploy.prototxt には batch_norm 層がありません。公式の caffemodel と一緒に使用できます。
-
テンプレートには 4 つのファイルがあります。2 つの deploy、1 つの train、1 つの test。
検証によると、train と test は自分で生成するネットワーク構造と一致します。
ただし、template ディレクトリのものは使用しないでください。後の num_output のいくつかのレイヤーを手動で変更する必要があります。手間です!
著者は prototxt ファイルを生成するための 2 つのツールを提供しています。1 つは gen.py で、もう 1 つは gen_model.sh です。
私は後者を使用することを好みます。操作が簡単です。
次のコマンドを実行します:
sh gen_model.sh 7
後ろに続く数字はクラス数 + 1 です。
生成されたファイルは example ディレクトリにあります。
ここで注意が必要です。データセットに完全に RGB の 3 チャンネルが含まれていない場合。
その場合、train.prototxt と test.prototxt ファイルを変更する必要があります:
transform_param {
scale: 0.007843
force_color: true ###追加
mean_value: 127.5
mean_value: 127.5
mean_value: 127.5
具体的なエラーメッセージは、前のブログ 【SSD】用 caffe-ssd フレームワークで独自のデータセットをトレーニングする
を参照してください。
次に、ファイル内の source と label_map_file のパスをそれぞれ変更し、できるだけ絶対パスを使用してください。
四、solver.prototxt ファイルの変更#
私は solver_train.prototxt を直接使用しましたが、パスを修正し、できるだけ絶対パスを使用して他のパラメータを変更してください。
ここで、半日間詰まった問題について説明します。
最初に、デバッグのために test_initialization を true に設定する習慣があります。
その後、常に「Couldn't find any detections」というエラーメッセージが表示されます。
しかし、トレーニングフェーズには問題ありません。
後で問題の原因がわかりました。finetune を行っていないため、最初の val フェーズでは何も検出できません。
test_initialization を false に設定した後、一定時間トレーニングしてから val を実行すると、もう何も見つからないというエラーメッセージは表示されません。
五、トレーニングスクリプト#
#!/bin/sh
/home/hans/caffe-ssd/build/tools/caffe train \
--solver="/home/hans/data/ImageNet/Detection/cup/MobileNet-SSD/doc/solver_train.prototxt \
-gpu 6 2>&1 | tee /home/hans/data/ImageNet/Detection/cup/MobileNet-SSD/MobileNet-SSD.log
以下の 2017.11.03 の更新内容からわかるように、トレーニングが終了したら、著者が提供するツールを使用して bn 層と conv 層のパラメータをマージして計算速度を向上させる必要があります。
merge_bn.py のパスとファイル名を変更してください。
新しい生成されたモデルは、元のモデルよりもわずかに小さくなるはずです。
六、トレーニング出力の可視化(2017.11.02)#
参考: 【SSD】用 caffe-ssd フレームワークで独自のデータセットをトレーニングする
七、モデルの効果をテストする(2017.11.03)#
参考: 【SSD】用 caffe-ssd フレームワークで独自のデータセットをトレーニングする
後書き#
なぜ pre_trained モデルを finetune しようとするとエラーが発生するのですか!!!!!conv0 の入力数が間違っています(1 vs. 2)と言われます。1 であるべきですが、2 つ渡されましたか???train.prototxt と test.prototxt ファイルをさまざまな方法で比較しましたが、何も変わりませんでした!!
-------【2017.11.3 解決できない finetune の問題】-------
ついに原因がわかりました!
finetune できるモデルと deploy ファイルを公開します。
https://pan.baidu.com/s/16dw-dJ779By9AWdiSOxSuQ
著者は 2 つの caffemodel を GitHub に公開しています。1 つはトレーニング時のもので、このモデルには bn 層と cnov 層のパラメータが分かれています。もう 1 つは deploy 用で、このモデルは bn 層と conv 層のパラメータをマージしています。
著者の言葉では、マージ後のモデルの速度が少し速くなるはずです。
-------【2017.11.3 ncnn 形式に正常に変換】---------
https://github.com/arlose/ncnn-mobilenet-ssd
.param ファイルは上記の作者が提供しているものを使用することをお勧めします。自分でトレーニングしたデータの場合、クラス数を変更するだけで十分です。8 か所変更する必要があります。
自分で変換した場合、2 つの問題があります。
1 つは、ヘッダーの 2 つのレイヤー Input と Split が欠落しています。この問題を解決するには、deploy.prototxt ファイルの先頭を次のように変更します:
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: 1 dim: 3 dim: 300 dim: 300 } }
}
2 つ目は、後のレイヤーの処理ピクセルが 600*600 に変わっていることです。
.bin ファイルは、merge.py で処理された caffemodel を使用して変換する必要があります!
-------【2017.11.16 更新】---------
私は以前から 6 月にリリースされた ncnn を使用していましたが、
これらの日々の移植作業を私に任せてくれたので、公式の ncnn はすでに ssd のサポートを追加しています。
さらに、モデルの圧縮も追加されました。計算ビット数の観点からの圧縮ですが、効果には割引がありますが、非常に便利です。
-------【2017.11.20 更新】---------
付属の make_mean.sh では平均値を求めることができませんでしたが、2 つの lmdb 変換ツールがあることがわかりました。1 つはアノテーション付きで、もう 1 つはアノテーションなしです。
ssd は、アノテーションツールを使用して変換された detection メソッドを使用しています。
私は従来の方法で平均値を求め、build/tools/convert_imageset と build/tools/compute_iamge_mean を使用しました。
シェルスクリプトのコード:
まず、画像を通常の lmdb 形式に変換します。
#!/bin/sh
set -e
size=300
TOOLS=/home/hans/caffe/build/tools
cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
DATA_ROOT="${cur_dir}/data/"
FILE_PATH="${cur_dir}/doc"
echo "Creating train lmdb..."
GLOG_logtostderr=1 $TOOLS/convert_imageset \
--resize_height=$size \
--resize_width=$size \
--shuffle=false \
$DATA_ROOT \
$FILE_PATH/train.txt \
$FILE_PATH/train_lmdb_mean
平均値を計算し、出力を mean.txt に保存します。
#!/bin/sh
TOOLS=/home/hans/caffe/build/tools
$TOOLS/compute_image_mean doc/train_lmdb_mean doc/mean.binaryproto 2>&1 | tee doc/mean.txt
echo "Done."