畳み込みニューラルネットワーク(CNN)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】畳み込みニューラルネットワーク(CNN)の実装方法を初心者にも分かりやすく解説。Pythonコード付きで、画像認識の仕組みを実践的に学べます。AI、ディープラーニング、画像分類に興味がある方必見です。
はじめに
前回までの入門編、活用例編では、畳み込みニューラルネットワーク(CNN)がどのような仕組みで、どのような場面で活躍するのかを解説しました。今回はその最終章「実践編」として、実際にプログラムコードを書きながら、CNNを構築し、画像認識を体験してみましょう。
「プログラミングは難しそう…」と感じる方もご安心ください。この記事では、一つ一つの手順を丁寧に追いながら、なぜその処理が必要なのかをかみ砕いて解説します。専門的な知識がなくても、コードの意味を理解し、AIが画像を認識する仕組みを実感できるよう構成しました。
この記事を最後まで読み進めれば、あなたもCNNを自らの手で動かし、その強力な能力の一端に触れることができるでしょう。
記事の最後に、環境構築なしでスマホからでも即実行可能なGoogle Colabノートブックをご用意しています。 まずは全体を読み進めていただき、最後にぜひご自身の手でコードを動かしてみてください。
CNN実装の全体像
私たちがこれから作るのは、「手書きされた数字の画像」を見て、それが「0」から「9」のどの数字なのかを当てるAIモデルです。このプロセスは、大きく分けて以下のステップで進めていきます。
- データの準備: AIの「教科書」となる、たくさんの手書き数字画像を用意します。
- モデルの構築: CNNの「脳」にあたる部分を設計します。画像を分析するための層を順番に積み重ねていきます。
- モデルの学習: 用意したデータを使って、AIに画像のパターンを学ばせます。「これは7の画像」「これは2の画像」といった具合に覚えさせていきます。
- モデルの評価: 学習が終わったAIが、初めて見る画像に対しても正しく数字を当てられるか、実力をテストします。
この一連の流れを、Pythonというプログラミング言語と、AI開発でよく使われる「TensorFlow」という道具(ライブラリ)を使って実現していきます。
1. データの準備
何事も、まずは材料がなければ始まりません。CNNにおける材料は「データ」です。今回は、AIの学習用として非常に有名な「MNIST(エムニスト)」というデータセットを使用します。
MNISTには、あらかじめ用意された手書き数字の画像が70,000枚(学習用60,000枚、テスト用10,000枚)と、それぞれの画像がどの数字であるかを示す「正解ラベル」が含まれています。
必要な道具(ライブラリ)を読み込む
まず、プログラミングを始めるにあたり、便利な道具箱(ライブラリ)をいくつか読み込みます。
# AIモデル構築のための道具箱「TensorFlow」をインポート
import tensorflow as tf
# TensorFlowの中から、特にモデル構築に便利な「Keras」をインポート
from tensorflow import keras
# データセットや層の部品をインポート
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
MNISTデータを読み込む
次に、先ほど紹介したMNISTデータセットをプログラムに読み込みます。これは数行のコードで完了します。
# MNISTデータセットを読み込む
# (train_images, train_labels)が学習用の画像と正解ラベル
# (test_images, test_labels)がテスト用の画像と正解ラベル
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
これで、私たちの手元に学習用とテスト用の画像データ、そしてそれぞれの正解ラベルが用意できました。
データをAIが扱いやすい形に整える(前処理)
人間が画像を見るときはそのまま見ることができますが、AI(コンピュータ)は画像を数値の集まりとして扱います。そのため、AIが学習しやすいように、データを少しだけ加工してあげる必要があります。この工程を「前処理」と呼びます。
今回は、以下の2つの処理を行います。
-
画像の色の濃淡を調整する(正規化): 現在、画像の各点(ピクセル)の色は0(黒)から255(白)までの256段階で表現されています。このままだと数値が大きすぎるため、AIの計算が不安定になることがあります。そこで、すべての数値を255で割り、0から1の範囲に収まるように調整します。これは、計算を効率的かつ正確に進めるための下準備です。
-
画像の形を整える: CNNは、画像に「チャンネル」という概念を加えて扱います。カラー画像なら赤・緑・青の3チャンネルですが、今回は白黒画像なので1チャンネルです。「縦28ピクセル × 横28ピクセル × 1チャンネル」という形にデータを整えてあげます。
# 学習用画像の前処理
# チャンネルの次元を追加し、255.0で割って0-1の範囲に正規化
train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype('float32') / 255
# テスト用画像の前処理
# 同様にチャンネルの次元を追加し、正規化
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255
これでデータの準備は完了です。いよいよCNNモデルの設計に入ります。
2. モデルの構築
ここがCNNの心臓部です。入門編で解説した「畳み込み層」や「プーリング層」といった部品を、プラモデルのように順番に組み立てて、画像から特徴を見つけ出し、最終的に数字を判断するAIの構造(モデル)を作っていきます。
今回は、部品をまっすぐ一列に並べる「Sequential」というシンプルな方法でモデルを構築します。
# モデルの器を準備
model = Sequential()
# ---- ここから層を積み重ねていく ----
# 第1層:畳み込み層 (Conv2D)
# 32種類のフィルターで画像の特徴を抽出する
# フィルターのサイズは3x3
# 活性化関数としてReLUを使用
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
# 第2層:プーリング層 (MaxPooling2D)
# 2x2の範囲で最も重要な情報だけを取り出し、画像を圧縮する
model.add(MaxPooling2D((2, 2)))
# 第3層:畳み込み層 (Conv2D)
# さらに細かな特徴を捉えるため、64種類のフィルターで再度畳み込み
model.add(Conv2D(64, (3, 3), activation='relu'))
# 第4層:プーリング層 (MaxPooling2D)
# 再度、情報を圧縮
model.add(MaxPooling2D((2, 2)))
# 第5層:畳み込み層 (Conv2D)
# 最後の仕上げとして、もう一度畳み込み
model.add(Conv2D(64, (3, 3), activation='relu'))
# ---- 特徴抽出はここまで ----
# 第6層:平坦化層 (Flatten)
# これまで抽出した2次元の特徴マップを、1列のデータに変換する
# この後の判断部分(全結合層)にデータを渡すための準備
model.add(Flatten())
# 第7層:全結合層 (Dense)
# 抽出された特徴を元に、総合的な判断を行う部分
# 64個のニューロンで情報を整理する
model.add(Dense(64, activation='relu'))
# 第8層:出力層 (Dense)
# 最終的な答えを出力する層
# 0から9までの10クラスに分類するため、10個の出力を用意
# softmax関数で、各数字である確率を出力する
model.add(Dense(10, activation='softmax'))
各層の役割をもう一度おさらい
Conv2D
(畳み込み層): 画像の上を小さな「フィルター(虫眼鏡)」が移動しながら、エッジや曲線といった画像の特徴を探します。最初の層では大まかな特徴を、後の層ではより複雑な特徴を捉えます。MaxPooling2D
(プーリング層): 畳み込み層が見つけた特徴マップの中から、特に重要な部分だけを抜き出して画像のサイズを小さくします。これにより、多少の位置のズレに強くなり、計算も効率化されます。Flatten
(平坦化層): これまでの層で抽出された特徴は、まだ二次元の「地図」のような形をしています。これを、次の判断プロセスに進めるために、一列の長いデータに引き伸ばします。Dense
(全結合層): 平坦化されたデータを受け取り、すべての特徴を総合的に考慮して、画像がどの数字に近いかを判断する準備をします。- 出力層 (
Dense
withsoftmax
): 最終的に「この画像は『7』である確率が98%、『1』である確率が1%…」というように、0から9までの各数字である確率を出力します。この中で最も確率の高いものが、AIの出した答えとなります。
構築したモデルの全体像を確認してみましょう。
# モデルの構造を表示
model.summary()
このコマンドを実行すると、各層がどのように繋がっているか、また計算されるパラメータ(AIが学習で調整する数値)の数が表示されます。
3. モデルの学習
モデルの設計図が完成したので、次はこのモデルに「学習」をさせて賢くしていきます。学習とは、モデルが正しく予測できるように、内部の膨大な数のパラメータを少しずつ調整していく作業です。
学習方針を決める(コンパイル)
学習を始める前に、「どのような方針で学習を進めるか」をモデルに教えてあげる必要があります。これを「コンパイル」と呼びます。
具体的には、以下の3つを決めます。
- オプティマイザ (optimizer): 学習の進め方です。予測の「間違い」を、どのようにパラメータの調整に反映させるかを決めます。今回は「Adam」という、効率的で性能が良いと評判のものを採用します。
- 損失関数 (loss function): モデルの予測が、正解ラベルとどれくらい「間違っているか」を計算するための物差しです。この間違い(損失)が小さくなるように学習を進めます。今回は、複数の選択肢から一つを選ぶ分類問題でよく使われる「
sparse_categorical_crossentropy
」を選びます。 - 評価指標 (metrics): 学習の途中で、モデルの性能を客観的に測るための指標です。今回は「
accuracy
(正解率)」を設定し、学習がうまく進んでいるかを確認します。
# モデルの学習方針を設定(コンパイル)
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
学習を実行する
いよいよ、準備した学習用データ (train_images
, train_labels
) を使って、モデルの学習を開始します。
# モデルの学習を実行
# 学習用データを与え、5回繰り返して学習させる (epochs=5)
# 一度に128枚の画像を処理する (batch_size=128)
model.fit(train_images, train_labels, epochs=5, batch_size=128)
epochs=5
とは、学習用の全データ(60,000枚)を5周繰り返し学習させる、という意味です。学習が進むにつれて、loss
(間違いの度合い)が減り、accuracy
(正解率)が上がっていくのが確認できるはずです。最初は50%程度だった正解率が、最終的には98%や99%といった非常に高い数値に到達することでしょう。
4. モデルの評価
学習が完了したモデルは、学習に使った画像については非常に高い正解率を出すはずです。しかし、本当に重要なのは、今まで一度も見たことのない新しいデータに対しても、正しく答えを出せるかです。これを「汎化性能」と呼びます。
そこで、学習には使っていない「テスト用」のデータ (test_images
, test_labels
) を使って、モデルの真の実力を評価します。
# テストデータを使ってモデルの最終的な性能を評価
test_loss, test_acc = model.evaluate(test_images, test_labels)
# 結果を表示
print(f'テストデータでの正解率: {test_acc:.4f}')
この結果、学習時と近い高い正解率(例えば98%以上)が出ていれば、このモデルは未知のデータにも対応できる、優れた汎化性能を持つと言えます。
まとめ
今回は、畳み込みニューラルネットワーク(CNN)をPythonで実装する一連の流れを体験しました。
- データを準備し、AIが扱いやすい形に整え、
- 畳み込み層やプーリング層を積み重ねてモデルを構築し、
- そのモデルにデータを学習させ、
- 未知のデータで評価する。
この基本的な流れは、手書き数字認識だけでなく、より複雑な犬や猫の画像の分類、医療画像の解析、自動運転など、様々な画像認識タスクに応用されています。
一見複雑に見えるコードも、一つ一つの部品の役割を理解すれば、全体として何をしているのかが見えてきたのではないでしょうか。AIやディープラーニングは、決して魔法ではなく、このような論理的なステップの積み重ねで成り立っています。
この記事が、あなたがAIの世界へさらに一歩踏み出すきっかけとなれば幸いです。
図解即戦力 機械学習&ディープラーニングのしくみと技術がこれ1冊でしっかりわかる教科書
エンジニア1年生、機械学習関連企業への就職・転職を考えている人が、機械学習・ディープラーニングの基本と関連する技術、しくみ、開発の基礎知識などを一通り学ぶことのできる、最初の1冊目にふさわしい入門書を目指します。
▶ Amazonで見る環境構築なしで
実行できるファイルはこちら!
このボタンからGoogle Colabを開き、すぐにコードをお試しいただけます。
お仕事のご依頼・ご相談はこちら
フロントエンドからバックエンドまで、アプリケーション開発のご相談を承っております。
まずはお気軽にご連絡ください。
関連する記事
主成分分析(PCA)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】主成分分析(PCA)のPythonによる実装方法を、初心者向けにコード付きで丁寧に解説します。scikit-learnライブラリを使い、データの要約から可視化までをステップバイステップで学べます。機械学習やデータ分析の第一歩に最適です。
KAN (Kolmogorov-Arnold Networks)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】AIの新しい波、KAN(Kolmogorov-Arnold Networks)の実装方法を、具体的なPythonコード付きで一から丁寧に解説。本記事では、KANの理論的な背景から、実際の回帰問題への適用、モデルの解釈、そしてチューニングまでを網羅。機械学習の新しいアーキテクチャを実践的に学びたい方に最適です。
ガウス過程回帰を実装してみよう!わかりやすく解説
【スマホからでも実行可能】Pythonでガウス過程回帰を実装する方法を初心者向けにわかりやすく解説します。機械学習のモデル構築や不確実性の可視化に興味がある方必見です。
ベイズ最適化を実装してみよう!わかりやすく解説
【スマホからでも実行可能】ベイズ最適化の実装方法をPythonコード付きで徹底解説。機械学習のハイパーパラメータチューニングを効率化したい方必見。サンプルコードを動かしながら、実践的に学べます。
エクストラツリー(ExtraTrees)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】この記事では、機械学習のアルゴリズムであるエクストラツリー(ExtraTrees)について、その仕組みからPythonによる実装方法までを丁寧に解説します。ランダムフォレストとの違いも理解しながら、実践的なスキルを身につけましょう。