この記事はデータオーグメンテーション(Data Augmentation)から派生した内容となっているため、未読の場合は一読することをおすすめします。
データオーグメンテーション(Data Augmentation)では、データオーグメンテーションの目的やいくつかの代表的な手法を紹介しました。そこで、本記事では実際にデータオーグメンテーションがどのように用いられているかをYOLOv5を例に解説したいと思います。
YOLOv5は物体検出タスクを得意とするライブラリで、GitHub上で公開されています。You Only Look Once と呼ばれる物体検出アルゴリズムの略であるYOLOのバージョン5としてUltralyticsがリリースしました。高速処理が特徴で、画像や動画内の複数の物体をリアルタイムに検出することが可能です。
また、YOLOv5はPyTorchを使用して実装されているため、まずPyTorchについて理解を深めましょう。
※Ultralyticsは、より高性能なYOLOv8をリリースしていますが、様々なタスクやモードが統合されたライブラリです。そのため、この記事ではDatasets&DataLoadersモジュールの解説において、YOLOv5を例に取り上げることで理解しやすくしています。
PyTorchは、主にpythonで使われる機械学習のためのライブラリです。このライブラリでは、テンソルと呼ばれる数値データの多次元配列を操作するための様々な機能を提供し、ニューラルネットワークのトレーニングを支援します。簡潔で直感的な構文を持っているため、初心者にも取り組みやすく、柔軟性が高いため様々な機械学習タスクに応用できます。
ミニバッチ学習
ミニバッチ学習はDatasets & DataLoadersを理解する上で重要なためこちらも理解を深めましょう。
ミニバッチ学習は、データセットを効率的に処理するための手法です。通常、全てのトレーニングデータを一度にモデルに与えるのではなく、データを小さなバッチに分割してモデルに供給します。これにより、メモリの効率的な利用や計算の並列化が可能となります。YOLOv5でもミニバッチ学習が使用されています。
例えば、手書き数字の画像データセット(MNIST)をバッチサイズ10でミニバッチに分割する場合、以下のようになります。
バッチサイズは元画像サイズやメモリに依存して指定することができ、あまり大きすぎる値を設定しない方が精度が良くなる傾向にあります。ただし、バッチサイズが小さいと学習にかかる時間が増えてしまうため、調整する必要があります。
ここからはいよいよ本題のDatasets & DataLoadersに触れていきます。
Datasets
Datasetsモジュールは、ミニバッチ学習で紹介したようなバッチへの分割を定義する際に用いられます。
PyTorch公式ドキュメントを見ると以下のようにDatasetクラスを継承しカスタマイズしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# https://pytorch.org/tutorials/beginner/basics/data_tutorial.html#creating-a-custom-dataset-for-your-files import os import torch from torch.utils.data import Dataset import pandas as pd from torchvision.io import read_image class CustomImageDataset(Dataset): def __init__(self, annotations_file, img_dir, transform=None, target_transform=None): self.img_labels = pd.read_csv(annotations_file) self.img_dir = img_dir self.transform = transform self.target_transform = target_transform def __len__(self): return len(self.img_labels) def __getitem__(self, idx): img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0]) image = read_image(img_path) label = self.img_labels.iloc[idx, 1] if self.transform: image = self.transform(image) if self.target_transform: label = self.target_transform(label) return image, label |
YOLOv5ではこのように定義されています:
https://github.com/ultralytics/yolov5/blob/master/utils/dataloaders.py#L532
注意点として、Datasetsを定義した段階では実際にバッチへ分割されているわけではありません。Datasetsは「バッチを作成する際に何をするか」の手順書のような役割で、後に紹介するDataloadersで呼び出されるときに初めて実行されます。
そしてデータオーグメンテーションもDatasetを継承したクラスの中で定義されます。
以下はYOLOv5で定義されてるデータオーグメンテーションです:
https://github.com/ultralytics/yolov5/blob/master/utils/dataloaders.py#L872
https://github.com/ultralytics/yolov5/blob/master/utils/dataloaders.py#L916
https://github.com/ultralytics/yolov5/blob/master/utils/dataloaders.py#L775
https://github.com/ultralytics/yolov5/blob/master/utils/dataloaders.py#L807
Albumentationsを用いたものやカスタムで定義されたものなど、様々なデータオーグメンテーションが定義されていることがわかります。
DataLoaders
DataLoaderはDatasetで定義されたバッチを実際に生成する処理を制御します。例えば、バッチサイズやシャッフルオプションを設定することができます。シャッフルオプションが適用されているとき、データセットからランダムにバッチサイズの数だけ選択された画像で構成されたバッチを生成することができます。
こうすることによって過学習を抑制し、より汎用的なモデルを構築することができるようになります。
YOLOv5ではこのように定義されています:
https://github.com/ultralytics/yolov5/blob/master/utils/dataloaders.py#L201-L214
まとめ
本記事では、YOLOv5を通じて、PyTorchにおけるDatasets & DataLoadersの重要性と役割について解説しました。
ミニバッチ学習は、データを小さなバッチに分割して学習する手法であり、メモリの効率的な利用や計算の並列化を実現します。
Datasetsモジュールは、データセットをバッチに変換する手順を定義し、データオーグメンテーションもこの中で定義されます。
DataLoadersモジュールは、Datasetで定義されたバッチを実際に生成するための制御をします。
これらのモジュールを正しく活用することで、効率的なデータ処理と高性能な物体検出モデルの構築が実現できます。
Avintonでは、ITエンジニアリングトレーニングとチームメンバーの継続的な教育に特に重点を置いています。この分野でのスキルの活用、最先端のテクノロジーへの取り組み、国際的なクライアントへのソリューション提供に興味がある場合は、採用情報のページをご覧ください。ご連絡をお待ちしております!