mmclassification の基本的な導入についてはここでは詳しく説明しませんが、初期の段階では、画像の機能を実現する必要があることと、mmlab 関連のライブラリを使用してきたため、mmcls を選択しました。実際、他の mmlab の利用プロセスと似ており、基本的にはデータセットの構造が固まった後に実行できる可能性があります。
1.カスタムデータセット
ImageNet のデータ形式を使用していますが、登録機構のないものは元のコードを基に直接修正されるので便利ですが、一方で、その後のコンフィグにも image1k を使用するため、直面する問題は少なくなるかもしれません。
1. mmclsにおけるimagenetのデータ形式
全体的なツリー構造は次のとおりです。
—data
|----meta
|——|—train.txt
|——|—val.txt
|——|—test.txt
|——train
|——|—class1
|————|—01.jpg
|————|—02.jpg
|————|—…
|——|—クラス 2
|————|—01.jpg
|————| — 02.jpg
|————|—…
|——テスト
|——|—クラス1
|————|—01.jpg
|————|—02.jpg
|————| —…
| —|—class2
|————|—01.jpg
|————|—02.jpg
|————|—…
|——val
|——|—class1
|—— ———| —01.jpg
|————|—02.jpg
|———|—…
|——|—クラス2
|————|—01.jpg
|———|—02 .jpg
|—— —|—…
図に示すように:
このうち、metaに格納されている3つは、イメージタグを含むアドレスディレクトリです:
パス+スペース+タグインデックス
train、val、testはすべてイメージ形式のファイルに格納されており、対応するtrain.txtなどのファイルを既にお持ちの場合は、つまり、ラベル アドレスがすでにわかっている場合は、すべての画像をまとめることはできますが、そうでない場合は、カテゴリごとにフォルダーを作成し、対応するラベルを生成します。カスタム データセットを使用しているため、次のように 2 番目の方法を使用します。
can と cant train、val、test の合計 2 つのラベルがあり、データは 7:2:1 に従って分割されています。
具体的には、まず一般的なフォルダーを設定し、そのフォルダーの下にラベルカテゴリに応じたフォルダーを作成し、
対応する画像部門のコードを格納するコードも添付します。
import os, random, shutil
##############################################################
## 分割数据集,首先将所有数据放在同一个文件夹下###################
def moveFile(fileDir, val_ratio, test_ration2):
pathDir1 = os.listdir(fileDir) # 取图片的原始路径
filenumber = len(pathDir1)
val_number = int(filenumber * val_ratio) # 抽取验证集的数量
test_number = int(filenumber * test_ratio) # 抽取测试集的数量
val_sample = random.sample(pathDir1, val_number) # 随机选取val图片
# 先抽取验证集图片
for name1 in val_sample:
shutil.move(os.path.join(fileDir, name1), os.path.join(valDir, name1))
# 从剩余的图片中抽取测试集
pathDir2 = os.listdir(fileDir) # 取图片的原始路径
test_sample = random.sample(pathDir2, test_number) # 随机选取val图片
for name2 in test_sample:
shutil.move(os.path.join(fileDir, name2), os.path.join(testDir, name2))
return
if __name__ == '__main__':
ori_path = './data/space_all/train' # 最开始train的文件夹路径
test_Dir = './data/space_all/test' # 移动到新的文件夹路径
val_Dir = './data/space_all/val' # 移动到新的文件夹路径
val_ratio, test_ratio = 0.1, 0.2 # 抽取比例 ******自己改*******
for firstPath in os.listdir(ori_path):
fileDir = os.path.join(ori_path, firstPath) # 原图片文件夹路径
valDir = os.path.join(val_Dir, firstPath) # val下子文件夹名字
testDir = os.path.join(test_Dir, firstPath) # test下子文件夹名字
if not os.path.exists(valDir): # 如果val下没有子文件夹,就创建
os.makedirs(valDir)
if not os.path.exists(testDir): # 如果test下没有子文件夹,就创建
os.makedirs(testDir)
moveFile(fileDir, val_ratio, test_ratio) # 从每个子类别开始逐个划分
print("Successfully splited!")
次のステップでは、対応する txt ファイルを生成します。
## 制作标签,在此之前需要用上半部分代码划分好数据集
path='./data/space_all/train'
data_path = pathlib.Path(path)
all_images_path = list(data_path.glob('*/*'))
all_images_path = [str(path) for path in all_images_path] # 所有图片路径名存入列表
random.shuffle(all_images_path) # 打散
print(len(all_images_path))
# print(all_images_path) # 打印前五个
# 开始制作标签
label_names = sorted(item.name for item in data_path.glob('*/') if item.is_dir())
print(label_names) # 打印类别名 注:下一步是制作与类别名对应的标签
label_to_index = dict((name, index) for index, name in enumerate(label_names))
all_image_labels = [label_to_index[pathlib.Path(path).parent.name] for path in all_images_path]
for image, label in zip(all_images_path[:5], all_image_labels[:5]):
print(image, '-----', label)
filename='./data/space_all/train.txt' # ***这里也要记得改***
print(image + " " + str(label) + "\n")
with open(filename,'w') as f:
for image,label in zip(all_images_path,all_image_labels):
f.write(image+" "+str(label)+"\n")
print("\nAll images and labels have been written in .txt!\n")
完了するとデータの準備は完了です。
2、トレーニング
mmcls を使用するプロセスも比較的単純で、他の mmlab コード ベースを使用するプロセスと同じであり、config 内の対応するファイルを変更します。ここでは resnet18_8xb32_in1k.py を使用しています。この名前の意味は、resnet18、8 枚のカード、batchsize32 を使用し、データ セットは imagenet1k を使用することです。このファイルを最初に開いても構いません。configs/resnet/resnet18_8xb32_in1k.py には
非常に多くのものがあり、実際、ファイルのこの部分を表示するには /base/datasets/imagenet_bs32.py の部分を変更するだけで済みます。
データに対応するパス以外の微調整を行わない場合は、何も変更する必要はありません。
次に、独自のデータ ラベルを ImageNet データセット ラベルに追加する必要があります。もちろん、ここで新しいラベルを作成することもできます。私は怠け者なので、それをしませんでした。
具体的な操作は次のとおりです。
mmcls/imagenet.py で、独自のラベルを CLASS に追加します。
他のラベルは変更しないでください。
それからトレーニングすることができます。方法は 2 つあり、1 つは直接実行しますが、必ず実行コンフィギュレーションを変更すること、もう 1 つはターミナルにコマンドを入力することです。私は怠け者なので、毎回それほど多くのコマンドを入力する必要がないように最初のものを選択します。
最初の部分では構成ファイルを指定し、2 番目の部分では作業アーカイブ フォルダーを指定します。その後、実行できます。指定したフォルダーにログ ファイル、チェックポイント ファイル、構成ファイルが生成され、この構成ファイルでモデルのトレーニング プロセスを微調整できます。
特定のパラメーターについては他の記事で紹介しているので、ここでは詳しく説明しません。
実はこのファイルは、以前の設定の下にある 4 つのファイルを自動的に統合するシステムであり、次回実行するときに、他のトレーニング設定に影響を与えることなく、ここで直接変更することができ、より合理的になります。パスやその他の基本設定が含まれます。次に、実行コンフィギュレーションを設定するときに、これを構成として使用します。
3. 検証
トレーニング指標は主に acc-top1 と acc-top5 で、top-1 は最良の分類を持つもので、top-5 は最初の 5 つのドローの最良の分類です (当然であるはずです)。トレーニング結果は log.json ファイルに保存されます。最後に生成されたチェックポイント ファイルlatest.pthを使用して、テスト セットを検証できます。主な用途はtrainと同じtools/test.pyで動作モードが2つありますが、ここでは命令を直接使用しています。
python tools/test.py work_dir/resnet18_8xb32_in1k.py work_dir/latest.pth --metrics accuracy --metric-option topk=1
ここでの最初の部分は構成ファイルのアドレス、2 番目の部分は使用されるチェックポイントのアドレス、メトリクスは設定された評価基準、精度が選択され、topk=1 は acc-top1 の値です。
結果を json ファイルに出力することもできます。コードは次のとおりです。
python tools/test.py work_dir/resnet18_8xb32_in1k.py work_dir/latest.pth --out result.json --out-items all
出力時に選択できるキーワードは同じで、全て出力します
4. 視覚化
内蔵の分析ツールを直接使用するだけで、トレーニング ログを視覚化できます。たとえば、ログ内の上位 1 の変更を視覚化するコードは次のとおりです。
python tools/analysis_tools/analyze_logs.py plot_curve work_dir/20230214_153510.log.json --keys accuracy_top-1 --legend accuracy --out result.jpg
このうち、plot_curve は曲線を描くためのもの、keys は曲線を描くために選択したキー (複数可)、legend は凡例、out は保存したファイルの名前です。
5. 予報
トレーニング済みのモデルを使用して新しい画像を予測したい場合は、API を直接呼び出すことができます。コードは比較的単純です。jupyter lab で直接書きました。写真を載せますので、ご自身でソースコードをクリックしてください
要約する
実際、これらはドキュメント文書に非常に明確に書かれていますが、多くの人は読むのが面倒かもしれません。私も同じですが、インターネット上にある多くのチュートリアルは不完全であることがわかったので、ゆっくり読むことしかできません、不完全なところもあるかもしれませんが、みんなで交流し、一緒に学んでいくことができると言えます。mmlabの全体的な感想としては、始めてみると本当に便利で使いやすいので、ぜひ試してみてください。