
14章 CNN:笑顔が終わらない!(前編)
はじめに
シリーズ「Python機械学習プログラミング」の紹介
本シリーズは書籍「Python機械学習プログラミング PyTorch & scikit-learn編」(初版第1刷)に関する記事を取り扱います。
この書籍のよいところは、Pythonのコードを動かしたり、アルゴリズムの説明を読み、ときに数式を確認して、包括的に機械学習を学ぶことができることです。
Pythonで機械学習を学びたい方におすすめです!
この記事では、この書籍のことを「テキスト」と呼びます。
記事の内容
この記事は「第14章 画像の分類-ディープ畳み込みニューラルネットワーク」の「14.4.3 CNN 笑顔分類器を訓練する」のモデルの訓練処理が長時間かかっていることを書きます。
14章のダイジェスト
14章は、CNN:畳み込みニューラルネットワークで画像を分類するタスクにチャレンジします。
PyTorchで画像データを処理する章です。
まず、特徴マップ、畳み込み層とプーリング層の計算の概念を学び、続いて、PyTorchでCNNを実装します。テーマは2つ。1つ目は手書き数字の分類タスク(おなじみのMNISTデータセット)。2つ目は写真画像から笑顔を分類するタスクです。
笑顔分類器の訓練が・・・
1. 笑顔分類器の正体
「14.4.3 CNN 笑顔分類器を訓練する」の節では、20万人以上の有名人の顔データベースである「CelebAデータセット」を使って、顔画像が笑顔かどうかを判定する分類器をディープ畳み込みニューラルネットワークで作成します。ディープラーニングっぽいタスクですね!
CelebAデータセットは「Large-scale CelebFaces Attributes (CelebA) Dataset」のWebサイトで取得可能な顔画像、および40種類の顔属性(メガネをかけているか、笑顔かなどのクラス属性)のことです。
次のリンクでCelebAデータセットのWebサイトに訪問できます。
過去の記事でも取り上げています。是非お読みになって下さい!
2. 笑顔分類器の処理の経過
まず、この図をご覧ください。

注目ポイントは、

処理開始から118分経過時点の様子です。
この処理では分類器の訓練・検証を行っています。
エポック数(訓練の回数)は30回。
そして、118分経過時点で完了した訓練は4回。
つまり、1エポックに30分程度かかっており、残り26回のエポックの見込み処理時間は12.7時間!
ディープCNNニューラルネットワークの訓練の処理に半日もかかる見込みなのです!
笑顔が終わらないのです!
GPUを搭載していないパソコンでディープラーニングの訓練を行うのは無謀なのでしょうか・・・・。
3. 笑顔分類器のモデル
①訓練データ、検証データの概要
・訓練データ:16,000個
・検証データ:1,000個
・入力画像のサイズ:3 x 64 x 64 (カラー3チャネルx縦横64ピクセル)
②モデルの概要
・二値分類タスク(笑顔=1):Sigmoid活性化関数で確率を算出
・torch.nn.Sequentialでモデルを構築
・損失関数:BCELoss
・オプティマイザ:Adam
・各層の流れ
・conv:畳み込み層4つ(32、64、128、256の特徴マップを出力)
・pool:プーリング層(最大値3つ、平均値1つ)
・dropout:ドロップアウト層2つ
modelの出力結果イメージ
Sequential(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu1): ReLU()
(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(dropout1): Dropout(p=0.5, inplace=False)
(conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu2): ReLU()
(pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(dropout2): Dropout(p=0.5, inplace=False)
(conv3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu3): ReLU()
(pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv4): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu4): ReLU()
(pool4): AvgPool2d(kernel_size=8, stride=8, padding=0)
(flatten): Flatten(start_dim=1, end_dim=-1)
(fc): Linear(in_features=256, out_features=1, bias=True)
(sigmoid): Sigmoid() )
4. そういえば・・・
この節より前のタスクでMNIST手書き数字を分類する分類器の訓練もそこそこ時間がかかりました。テキストの「14.3.3 torch.nnモジュールを使ってCNNを実装する」の節です。
このタスクは、手書き文字画像(28x28ピクセル)を訓練データ10,000個、検証データ10,000個をつかって、エポック数20回の訓練をするものです。
モデルは次のようなシーケンシャルなものです。
入力層(28x28x1)→畳み込み層1(28x28x32)→プーリング層(14x14x32)→畳み込み層2(14x14x64)→プーリング層2(7x7x64)→全結合層1(1024)→全結合層2+ソフトマックス層(10)
この分類器の訓練・検証(ディープラーニング)にかかった時間は43分。

この処理を終えた時は「少し時間がかかったな」くらいの軽い気持ちでした。
さて、どうしようかな。。。
後半に続く!
まとめ
今回は、顔画像データセットを入力して笑顔かどうかを識別する分類器を訓練するタスクでつまずきました。
さて、どうしようかな。。。
あのGPU環境を使うしかないか。。。
# 今日の一句
from google.colab import drive
drive.mount('/content/drive')
楽しくPython機械学習プログラミングを学びましょう!
おまけ数式
noteでは数式記法を利用できます。
今回はプーリング層で用いられる最大値プーリング演算の例示を紹介します。
入力行列$${\boldsymbol{X_1}}$$と$${\boldsymbol{X_2}}$$に対して$${2 \times 2}$$の最大値プーリングを行った結果が同じになっていることを例示しています。
$$
\begin{rcases}
\begin{align*}
\boldsymbol{X_1} =
\left[
\begin{matrix}
10&255&125&0&170&100\\
70&255&105&25&25&70\\
255&0&150&0&10&10\\
0&255&10&10&150&20\\
70&15&200&100&95&0\\
35&25&100&20&0&60
\end{matrix}
\right]\\
\boldsymbol{X_2} =
\left[
\begin{matrix}
100&100&100&50&100&50\\
95&255&100&125&125&170\\
80&40&10&10&125&150\\
255&30&150&20&120&125\\
73&30&150&100&70&70\\
70&30&100&200&70&95
\end{matrix}
\right]\\
\end{align*}
\end{rcases}
\xrightarrow{\mathrm{max-pooling} P_{2 \times 2}}
\left[
\begin{matrix}
255&125&170\\
255&150&150\\
70&200&95
\end{matrix}
\right]
$$
おわりに
AI・機械学習の学習でおすすめの書籍を紹介いたします。
「最短コースでわかる ディープラーニングの数学」
機械学習やディープラーニングなどの手法を理解する際に、数学的な知識があると、いっそう深い理解につながると思います。
でも、難しい数式がびっしりと並んでいる書面を想像すると、なんだかゾッとします。
そんな数式にアレルギーのある方にとって、この「ディープラーニングの数学」は優しく寄り添ってくれて、「数学的」な見方を広げてくれるのではないでしょうか。
この書籍は、機械学習/深層学習の基礎的なテーマを、Pythonのコードを動かしながら、そして数学的な見解も実感しながら、楽しく学ぶことができると思います。
機械学習/深層学習の入門者にとって、次のようなトピックの理解を深くするチャンスとなるでしょう。
損失関数とその微分
活性化関数
交差エントロピー関数
誤差逆伝播
勾配降下法(最急降下法)
ちなみに、私が初めて手にした機械学習/深層学習の書籍が、このディープラーニングと数学でした。思い出深い一冊です。
サンプルコードが動かなかった時に、著者の赤石先生とTwitterでやりとりさせていただいたことは、とても嬉しい出来事でした。
今もときどき、自分の理解を整理する際に、ページを捲ります。
最後まで読んでくださり、ありがとうございました。