機械学習のブーム到来によって、今までに様々なフレームワークが開発されてきました。有名なのは Google が開発している Tensorflow と Facebook が開発している PyTorch ですね。さらにこれらのフレームワークを手軽に試せるようなフレームワークも次々と登場してきました。Tensorflow ですと Keras が Tensorflow をバックエンドに使うようできます。PyTorch をバックエンドに使うフレームワークとして有名なのが fast.ai です。fast.ai は下のようなスローガンを掲げており、なるべく多くの人に深層学習に触れられる機会を与えることを目指していて、実際非常に使いやすいフレームワークです。
Being cool is about being exclusive, and that’s the opposite of what we want. We want to make deep learning as accessible as possible
この記事では、fast.ai の基本的な使い方について紹介したいと思います。
この記事で扱うこと
- 動物の画像分類
- ハイパーパラメータの調整
- モデルの fine tune
データの準備
import fastai2.vision.all as fastai path = fastai.untar_data(fastai.URLs.PETS) pets = fastai.DataBlock( blocks = (fastai.ImageBlock, fastai.CategoryBlock), get_items = fastai.get_image_files, splitter = fastai.RandomSplitter(seed=42), get_y = fastai.using_attr(fastai.RegexLabeller(r"(.+)_\d+.jpg"), "name"), item_tfms = fastai.Resize(460), batch_tfms = fastai.aug_transforms(size=224, min_scale=0.75), ) dls = pets.dataloaders(path/"images")
fast.ai に最初から用意されているペット画像を使って画像分類を試して見ます。fast.ai ではインポートにワイルドカード(*
) を使うことが多いようですが、ここではわかりやすさのために fastai.vision.all
を fastai
という名前でインポートします。
読み込むデータは、入力値が画像データ(ImageBlock
) で 出力値がカテゴリ(CategoryBlock
) です。カテゴリ名はファイル名から正規表現を使って抽出します(RegexLabeller(r"(.+)_\d+.jpg"), "name")
)。さらに、画像の前処理としてサイズを揃え(Resize(460)
)、augmentation をします(aug_transforms(size=224, min_scale=0.75)
)。
きちんとデータが読み込まれたか確認してみます。
dls.show_batch(rows=2, cols=3)
うまく行っていれば下のように動物の写真が6枚表示されます。
また、DataBlock
でどレくらいの画像が読み込まれ、どのような処理がなされたかは summary()
メソッドを使って確認することができます。今、path
には動物画像のデータセットを指定していますが、実際の画像はサブディレクトリ images
に入っているので summary()
メソッドの引数には path/"images"
で指定します。
pets.summary(path/"images")
出力が長いので一部を載せると下のような感じになります。
Setting-up type transforms pipelines Collecting items from ~/.fastai/data/oxford-iiit-pet/images Found 7390 items 2 datasets of sizes 5912,1478 Setting up Pipeline: PILBase.create Setting up Pipeline: partial -> Categorize Building one sample Pipeline: PILBase.create starting from ~/.fastai/data/oxford-iiit-pet/images/american_bulldog_30.jpg applying PILBase.create gives PILImage mode=RGB size=334x500 Pipeline: partial -> Categorize starting from ~/.fastai/data/oxford-iiit-pet/images/american_bulldog_30.jpg applying partial gives american_bulldog applying Categorize gives TensorCategory(12) Final sample: (PILImage mode=RGB size=334x500, TensorCategory(12)) Setting up after_item: Pipeline: Resize -> ToTensor Setting up before_batch: Pipeline: Setting up after_batch: Pipeline: IntToFloatTensor -> AffineCoordTfm -> RandomResizedCropGPU -> LightingTfm Building one batch Applying item_tfms to the first sample: Pipeline: Resize -> ToTensor starting from (PILImage mode=RGB size=334x500, TensorCategory(12)) applying Resize gives ...
訓練してみる
データは読み込めたので、訓練をしてみます。まずは試しに ResNet34 の学習済みモデルをfine tuneしてみます。
learn = fastai.cnn_learner(dls, fastai.resnet34, metrics=fastai.error_rate)
learn.fine_tune(2)
pandas の DataFrame を表示するときのようなデザインで各エポックの訓練状況が表示されます。さて訓練結果はどうなっているでしょうか?混同行列を見てみます。
interp = fastai.ClassificationInterpretation.from_learner(learn) interp.plot_confusion_matrix(figsize=(12, 12), dpi=60)
2行のコードで seaborn を使ったときのようなきれいなグラフが表示されます。
ハイパーパラメータの調整
ハイパーパラメータの調整も、fast.ai ではそれを支援する機能があります。
lr_min, lr_steep = learn.lr_find()
この一つのコマンドで、学習率を変化させたときの loss の変化を調べることができます。loss が最も急激に減少する学習率と、最も小さくなる学習率が lr_steep, lr_min
に入ります。これと同時に、loss の学習率依存性のグラフが表示されます。
モデルの細かい調整
モデルによっては、学習率を層によって変化させたいこともあります。fast.ai ではこのようなことも簡単にできます。
learn.fit_one_cycle(12, lr_max=slice(1e-6, 1e-4))
lr_max
にスライスを指定することによって学習率を 1e-6 から 1e-4 まで変化させていくことが可能です。
また、モデルの学習を高速化させ、メモリ消費を抑える手法として混合精度の訓練があります。これも簡単に実現できます。
learn = fastai.cnn_learner(dls, fastai.resnet50, metrics=fastai.error_rate).to_fp16()
最後に、この混合精度モデルで、最初の3エポックは fine tune して、その後に全てのパラメータをフリーにして訓練してみます。
learn.fine_tune(6, freeze_epochs=3) learn.recorder.plot_loss()
まとめ
この記事では、fast.ai の初歩的な使い方をザッと見てきました。データセットの準備や訓練が簡単にできることはもちろん、モデルの調整や訓練結果の確認のためのツールも非常に豊富にもっていることがわかると思います。私もまだ触り始めたばかりですがこれからどんどん使っていきたいと思います。