スライドショー

【深層学習入門】ディープラーニングで画像認識!CNNで簡単入門!

近年、注目を浴びているディープラーニング画像認識。

テレビやネットなどでも、大きく取り扱われています。

しかし、

「CNNってなに?」
「画像認識をやりたいけどどうすればいいのか分からない」

と、分からないことだらけですよね。

ということでこの記事では、CNN(Convolutional Neural Network、畳込みニューラルネットワーク)を使って画像認識(画像分類)のハンズオンをします。

CNNは畳み込み層とプーリング層という、いうなれば画像処理に特化したレイヤーを持っています。

CNNの画像処理における優位性は未だに並び立つものがなく、CNNベースの様々なアルゴリズムが発表されています。

まずはCNNの基礎的な実装を覚えて、ディープラーニングに入門しましょう!

この記事の内容

  • CNNとは?
  • CNNのTensorflow/Keras実装
  • CNNを使った画像分類問題に挑戦

※この記事のコードは、Ubuntu 18.04、Python 3.6.7、TensorFlow 1.12.0で動作を確かめました。

CNNとは

CNNとは、畳み込み層とプーリング層という二つの特殊なレイヤーを持ったニューラルネットワークです。

CNNのイメージ図:http://nkdkccmbr.hateblo.jp/entry/2016/10/06/222245より

CNNの具体的な解説については、他の記事で紹介したいと思っています。

CNNの解説については、以下のスライドがおすすめです。

また、CNNのより実用的な知識が書かれているスライドとしては以下の記事がおすすめです。

そして最後に、最新の研究動向がまとめられたスライドです。

Tensorflow/KerasによるTensorflowの実装

ライブラリのimport

まずはライブラリをimportしましょう。

import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt

importしたライブラリは以下の通りです。

  • tensorflow (version 1.12.0)
  • 深層学習でGPUを簡単に使うことができる行列計算ライブラリ

 

  • tensorflow.keras
  • tensorflowの上位ラッパー
  • よりニューラルネットワークの実装の際に便利な機能がまとめられたライブラリ

 

  • numpy
  • CPUでの行列計算ライブラリ
  • Pythonで科学計算を行うならほぼ必ず必要になる

 

  • matplotlib
  • Pythonのデファクトスタンダードな可視化ライブラリ

データの読み込み

kerasのdatasetsモジュールを使って深層学習で使うデータセットをダウンロードします。

(train_images, train_labels), (test_images, test_labels) \
= keras.datasets.fashion_mnist.load_data()

使い方はsklearnと同様なので簡単ですね。

この関数で読み込めるものは以下の4つです。

  • 教師データ
  • 教師ラベル
  • テストデータ
  • テストラベル

また、クラスの名前は以下のリストをみてください。

ラベルはone hot表現にしたいので、kerasのto_categorical関数を使いましょう。

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
train_labels_onehot = keras.utils.to_categorical(train_labels, 10)
test_labels_onehot = keras.utils.to_categorical(test_labels, 10)

ちなみに……

one hot表現とは、

「あるデータのクラスが1でクラスが全部で5個ある場合、[0,1,0,0,0]」
「あるデータのクラスが3でクラスが全部で5個ある場合、[0,0,0,1,0]」

のように表現する方法です。

次に、データのスケールを0~1の範囲に直すために、255で割ります。

(8bitカラーなら2**8で256階調なので、0スタートで255までのため)

train_images = train_images.astype("float32") / 255.0

test_images = test_images.astype("float32") / 255.0

データの可視化

ここまででデータの準備ができたので、実際に分類する画像を表示してみてみましょう。

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])

教師データとそれに対応するラベルを25個表示してみました。

似たような画像ファイルがテストデータにも入っているので、画像ファイルからラベルを予測していきます。

CNNのモデル構築

画像分類を行うCNNを実装します。

model = keras.Sequential([
    keras.layers.Conv2D(filters=64, kernel_size=2, padding="same", activation="relu", input_shape=(28,28,1)),
    keras.layers.MaxPooling2D(pool_size=(2,2)),
    keras.layers.Dropout(0.3),

    keras.layers.Conv2D(filters=32, kernel_size=2, padding="same", activation="relu"),
    keras.layers.MaxPooling2D(pool_size=(2,2)),
    keras.layers.Dropout(0.3),

    keras.layers.Flatten(),
    keras.layers.Dense(256, activation="relu"),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(10,  activation="softmax")
])

kerasのニューラルネットワークは、keras.Sequentialにリスト形式でレイヤーを追加していくことで実装ができます。

kerasのレイヤを構成するクラスはすべてlayersの下にあるので、そこから選んで使いましょう。

  • Conv2D
  • 畳込み層
  • 特徴量の畳み込みを行う

 

  • MaxPooling2D
  • マックスプーリング
  • レイヤーを縮小して使いやすくする

 

  • Dropout
  • ドロップアウト
  • ネットワークの結合を削って過学習を防ぐ

 

  • Flatten
  • 8x8の二次元配列を64要素の一次元配列に直す
  • (あんまりニューラルネット関係なし)

 

  • Dense
  • 全結合層
  • t層目のすべてのニューロンがt+1層目のすべてのニューロンに繋がっているレイヤ

フィルタサイズ、カーネルサイズ、paddingの設定などがCNNで大切になる部分です。

これらについては最初に貼ったスライドなどでCNNの仕組みを覚えてから設定してください。

わからなければこの値のままで。

model.compile(optimizer=tf.train.AdamOptimizer(),
              loss='categorical_crossentropy',
              metrics=["accuracy"])

kerasで作ったモデル(素のtesnorflowで作ったモデルも)はコンパイルという作業が必要になります。

この際に、以下のような設定をします。

  • オプティマイザ(optimizer)
  • ニューラルネットの学習を効率的に行ってくれるものです

 

  • SGD
  • Adam
  • 他にもたくさん

 

  • 損失関数(loss)
  • ニューラルネットの学習の際に、この関数の値を小さくするようにパラメータを調整します
  • タスクによって損失関数は変わります
  • categorical_crossentropy
  • binary_crossentropy
  • 他にもたくさん

 

  • メトリクス(metrix)
  • 学習の監視に使う関数です。
  • あくまでも監視なので、この関数が学習には影響しません。

CNNの学習学習

学習はfitメソッドを使って行います(sklearnっぽいですね)。

教師データ、教師ラベル、epoch数、batch_sizeなどの基本的な設定をして関数を実行してください。

モニタリング用のログが表示されながら学習の様子が表示され始めます。

model.fit(
    train_images[:,:,:,None],
    train_labels_onehot,
    epochs=20,
    batch_size=64,
)
[学習中のログ]
Epoch 1/20
60000/60000 [==============================] - 6s 102us/step - loss: 0.5929 - acc: 0.7817
Epoch 2/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.4117 - acc: 0.8512
Epoch 3/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.3738 - acc: 0.8640
Epoch 4/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.3410 - acc: 0.8751
Epoch 5/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.3228 - acc: 0.8818
Epoch 6/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.3085 - acc: 0.8863
Epoch 7/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2965 - acc: 0.8900
Epoch 8/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2847 - acc: 0.8951
Epoch 9/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2778 - acc: 0.8985
Epoch 10/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2674 - acc: 0.9015
Epoch 11/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2603 - acc: 0.9039
Epoch 12/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2563 - acc: 0.9045
Epoch 13/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2471 - acc: 0.9092
Epoch 14/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2441 - acc: 0.9086
Epoch 15/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2402 - acc: 0.9117
Epoch 16/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2337 - acc: 0.9113
Epoch 17/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2287 - acc: 0.9139
Epoch 18/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2286 - acc: 0.9150
Epoch 19/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2244 - acc: 0.9161
Epoch 20/20
60000/60000 [==============================] - 4s 74us/step - loss: 0.2202 - acc: 0.9180
<tensorflow.python.keras.callbacks.History at 0x7f4a2ffd9278>

教師データの正答率は91パーセプトロンくらいまで上がっていますね。

結果の確認

以上で学習は終わりましたが、実際にクラス分類を行ったのでその精度を見てみましょう。

テストデータに対して予測ラベルを出すには、predictメソッドを使います。

labels = model.predict(test_images[:,:,:,None])

また、評価にはevaluateメソッドを使います。

score = model.evaluate(test_images[:,:,:,None], test_labels_onehot)

# scoreの値は [3.6148554523468017, 0.7712]でした。

scoreはリストになっていて、ここでは1つ目がloss、2つ目がaccでした。

そして最後にテストデータと予測ラベルを表示してみましょう。

正解を緑色に、不正解を赤色にします。

figure = plt.figure(figsize=(20, 8))
for i, index in enumerate(np.random.choice(test_images.shape[0], size=15, replace=False)):
    ax = figure.add_subplot(3, 5, i + 1, xticks=[], yticks=[])

    ax.imshow(np.squeeze(test_images[index]))
    predict_index = np.argmax(labels[index])
    true_index = np.argmax(test_labels_onehot[index])

    ax.set_title("{} ({})".format(class_names[predict_index],
                                  class_names[true_index]),
                                  color=("green" if predict_index == true_index else "red"))

最後に

この記事ではCNNを使った画像認識として画像分類タスクを解いてみました

CNNはDeep Learningの中でもホットなアルゴリズムです。

是非覚えてDeep Learningの最新動向を追いかけましょう!

LINEで送る
Pocket

無料でSEからWebエンジニアへ転職しませんか?



侍エンジニア塾では、完全未経験の方から現在SEだけどプログラミングはやっていないという経験者まで、幅広い方々の人生を好転させるプログラミング指導を行ってきました。SEの方とお話していくなかで、

  • システムエンジニアという職業だけどコードが書けない
  • 事務作業が多くスキルがないため将来が不安
  • スクールに通うと完全未経験者と同じスタートになるからレベルが合わない
という、すでに知識があるSEならではのお悩みがあることに気づきました。そんな方におすすめなのが、弊社の「転職コース 」です。

弊社では、マンツーマンでレッスンを行いますので、現在お持ちの知識レベルからカリキュラムを作成いたします。さらにこちらの転職コースは無料で受講を始められて転職成功でそのまま卒業できるというとてもお得なコースとなっています。

既に知識のあるSEといっても転職は年齢が若いほど受かりやすいため、まずは無料体験レッスンで今の現状や理想の働き方について一緒に考えていきましょう。

まずは無料体験レッスンを予約する

書いた人

フクロウ

フクロウ

第一言語はPythonです。
皆さんRustやりましょう。

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説