1
1

Tensorflowで犬と猫の画像判定をする

Last updated at Posted at 2024-07-17

目次

  1. はじめに
  2. 本記事の概要
  3. 作成したプログラム
    1. Googleドライブから画像を読み込めるようにする
    2. モジュールのインポート
    3. ハイパーパラメータの設定
    4. 乱数を固定する
    5. 画像を読み込む
    6. 画像を加工する
    7. 正解ラベルを付与する
    8. データを結合しランダムに並び替える
    9. データをTensorflowの学習に適した形に変更する
    10. モデルの学習をし、エポックごとの予測精度を取得します
    11. 予測精度をグラフで可視化する
  4. おわりに
  5. 参考にしたサイト

1,はじめに
※このブログはAidemy Premiumのカリキュラムの一環で、受講修了条件を満たすために公開しています。
Aidemyの「データ分析講座」で学習した成果を、本ブログに投稿させていただきます。


2,本記事の概要

本記事では、データセットに kaggle の「Cat and Dog」、モデルとして Tensorflowを使用して、犬と猫の画像判定をするモデルを作成します。

使用するデータセット「Cat and Dog」には、犬と猫の画像が大量に格納されていますが、今回は訓練データから1000枚ずつ、テストデータから100枚ずつの計2200枚をランダムに選択して使用します。

また、使用する画像は 100x100 の大きさに統一し、グレースケールを施します。

Tensorflowのバージョンは「2.15.0」を使用しています。
※以下を実行して確認できます。

import tensorflow as tf
print(tf.__version__)

3,作成したプログラム
3-1,Googleドライブから画像を読み込めるようにする
まずはGoogleドライブから画像を読み込めるようにします。
以下のURLから、Cat and Dog のテストデータと訓練データをダウンロードします。
https://www.kaggle.com/datasets/tongpython/cat-and-dog

ダウンロードしたzipファイルを展開します。
私の場合は、マイドライブに「/Aidemy/dataset/」フォルダを作成し、その下に展開しました。

以上が終わればコーディングに移ります。

以下を実行して、Googleドライブのデータにアクセス出来るようにします。

from google.colab import drive
drive.mount('/content/drive')

3-2,モジュールのインポート
必要なモジュールをインポートします。

# ファイルを扱うためのモジュール
import os

# 画像を加工するためのモジュール
import cv2

# 配列を扱うためのモジュール
import numpy as np

# グラフや画像を描画するためのモジュール
import matplotlib.pyplot as plt

# 配列をランダムに並び替えるためのモジュール
import random

# Tensorflowのモデル
import tensorflow as tf

# ラベルをOne-hot表現にするための関数
from tensorflow.keras.utils import to_categorical

# Tensorflowにレイヤーを追加するためのモジュール
from tensorflow.keras.layers import Dense, Activation, Dropout

3-3,ハイパーパラメータの設定
以降で使用するパラメータを設定します。

# 乱数のシード値
random_seed = 0

# 訓練データの数(犬猫それぞれ1000枚)
train_dataset_num = 1000

# テストデータの数(犬猫それぞれ100枚)
test_dataset_num = 100

# 画像データのサイズ(画像データの縦幅・横幅は同じにします)
img_size = 100

# Tensorflow の1エポックで使用する画像データの数
batch_size = 64

# Tensorflow の学習回数
epochs = 5

3-4,乱数を固定する
再現性を担保するために乱数を固定します。

# Python固有の乱数シードの固定
random.seed(random_seed)

# Numpyの乱数シードの固定
np.random.seed(random_seed)

# Tensorflowの乱数シードの固定
tf.random.set_seed(random_seed)

3-5,画像を読み込む
Gドライブにダウンロードしたデータを読み込みます。
また、読み込んだデータから使用するデータをランダムに取得します。

# 画像が格納されているパスを作成します
# 画像の格納場所に合わせて変更してください
train_dog_folder_path = "/content/drive/MyDrive/Aidemy/dataset/training_set/dogs/"
train_cat_folder_path = "/content/drive/MyDrive/Aidemy/dataset/training_set/cats/"
test_dog_folder_path = "/content/drive/MyDrive/Aidemy/dataset/test_set/dogs/"
test_cat_folder_path = "/content/drive/MyDrive/Aidemy/dataset/test_set/cats/"

# folder_path に格納されているファイル名一覧を取得します
train_dog_datalist = os.listdir(train_dog_folder_path)
train_cat_datalist = os.listdir(train_cat_folder_path)
test_dog_datalist = os.listdir(test_dog_folder_path)
test_cat_datalist = os.listdir(test_cat_folder_path)

# ファイル名からランダムにデータを選択します
train_dog_image_filename = random.sample(train_dog_datalist, train_dataset_num)
train_cat_image_filename = random.sample(train_cat_datalist, train_dataset_num)
test_dog_image_filename = random.sample(test_dog_datalist, test_dataset_num)
test_cat_image_filename = random.sample(test_cat_datalist, test_dataset_num)

3-6,画像を加工する
取得したデータに対して、
・リサイズ
・グレースケール
を施します

※このコードの完了には時間がかかります。

# 加工後のデータを格納するための変数を定義します
train_dog_imgset = []
train_cat_imgset = []
test_dog_imgset = []
test_cat_imgset = []

# データを加工するための関数
def get_proccesing_imgset_from_filename_list(folder_path, filename_list):
  result_array = []
  for filename in filename_list:
    img = cv2.imread(folder_path + filename)
    img = cv2.resize(img, (img_size, img_size))
    img = cv2.cvtColor(src=img, code=cv2.COLOR_BGR2GRAY)
    result_array.append(img)

  return result_array

# 加工したデータを変数に格納します
train_dog_imgset = get_proccesing_imgset_from_filename_list(train_dog_folder_path, train_dog_image_filename)
train_cat_imgset = get_proccesing_imgset_from_filename_list(train_cat_folder_path, train_cat_image_filename)
test_dog_imgset = get_proccesing_imgset_from_filename_list(test_dog_folder_path, test_dog_image_filename)
test_cat_imgset = get_proccesing_imgset_from_filename_list(test_cat_folder_path, test_cat_image_filename)

3-7,正解ラベルを付与する
今回は犬のラベルを0、猫のラベルを1として付与します。

train_dog_label = [0]*len(train_dog_imgset)
train_cat_label = [1]*len(train_cat_imgset)
test_dog_label = [0]*len(test_dog_imgset)
test_cat_label = [1]*len(test_cat_imgset)

3-8,データを結合しランダムに並び替える
学習の偏りが生じないようにするため、データをランダムに並び替えます。
また、データとそれに対応するラベルを同様に並び替える必要があります。
そのため、zip関数でデータとラベルを対応付けたのち並び替えを行います。

# データとラベルを結合します
train_imgset = train_dog_imgset + train_cat_imgset
train_label = train_dog_label + train_cat_label
test_imgset = test_dog_imgset + test_cat_imgset
test_label = test_dog_label + test_cat_label

# データとラベルを同様に並び替えるための関数
def get_similarly_shuffled_list(list1, list2):
  temp_list = list(zip(list1, list2))
  random.shuffle(temp_list)
  list1, list2 = zip(*temp_list)
  return list1, list2

# データとラベルを対応付けて並び替えます
train_imgset, train_label = get_similarly_shuffled_list(train_imgset, train_label)
test_imgset, test_label = get_similarly_shuffled_list(test_imgset, test_label)

3-9,データをTensorflowの学習に適した形へ変形する
現在のままでは、Tensorflowでは学習できないため、データとラベルを学習に適した形へ変形します。

# データとラベルをNumpy配列に変形します
train_imgset = np.array(train_imgset)
train_label = np.array(train_label)
test_imgset = np.array(test_imgset)
test_label = np.array(test_label)

# データの形を変形します (2000,50,50)→(2000,2500)
train_imgset = train_imgset.reshape(train_imgset.shape[0], train_imgset.shape[1] * train_imgset.shape[2])
test_imgset = test_imgset.reshape(test_imgset.shape[0], test_imgset.shape[1] * test_imgset.shape[2])

# ラベルをOne-hot表現に変形する
train_label = to_categorical(train_label)
test_label = to_categorical(test_label)

3-10,モデルの学習をし、エポックごとの予測精度を取得します
モデルの設定をした後、学習を行いエポックごとの予測精度を取得します。

# 最初のレイヤーで入力する要素のサイズを取得しておきます
input_dim = train_imgset.shape[1]

# モデルを定義します
model = tf.keras.Sequential()

# ニューラルネットワークを構築します
model.add(Dense(256, input_dim=input_dim))
model.add(Activation("sigmoid"))
model.add(Dropout(rate=0.2))
model.add(Dense(128))
model.add(Activation("sigmoid"))
model.add(Dropout(rate=0.2))
model.add(Dense(2))
model.add(Activation("softmax"))

# モデルを確定します
model.compile(optimizer="sgd", loss="categorical_crossentropy", metrics=['accuracy'])

# モデルの学習を実行し、エポックごとの予測精度を取得する
history = model.fit(train_imgset, train_label, batch_size=batch_size, epochs=epochs, verbose=0, validation_data=(test_imgset, test_label))

3-11,予測精度をグラフで可視化する
取得した予測精度をグラフで可視化します。

# 取得した予測精度「acc」と「val_acc」をグラフで可視化します
plt.plot(history.history['accuracy'], label="acc", ls="-", marker="o")
plt.plot(history.history["val_accuracy"], label="val_acc", ls="-", marker="x")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(loc="best")
plt.show()

グラフで可視化した結果は以下のようになります。

image.png

ハイパーパラメータの設定に問題があったのか、あまり良い精度は得られませんでした


4,おわりに

今回はTensorflowを用いて犬と猫の画像の予測精度を調べました。
また、ハイパーパラメータを変更して何回か試してみましたが、予測精度はあまり改善されませんでした。

モデルに対して最適なパラメータを探すには、グリッドサーチ・ランダムサーチ・ベイズ最適化などがありますので、そちらを試すのが良いと思われます。

これからもデータ分析やAIについての学習をすすめつつ、より最適なモデルの構築を目指していきたいと思います。

5,参考にしたサイト

【Python初心者が犬・猫の画像認識をやってみる】
https://qiita.com/AnnoJou/items/86ba0f91b8c2cc747573

【[TensorFlow 2.x (tf.keras)] 乱数シードを固定して再現性を向上】
https://qiita.com/bee2/items/08eab7a899c9ff56eb35

【[TensorFlow]インストールされているTensorFlowのバージョンを調べる】
https://www.curict.com/item/6c/6c3a76c.html

【【Python】 二つのリストの対応関係を保ったままシャッフルする】
https://ni4muraano.hatenablog.com/entry/2017/01/30/182447

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1