【iOS11】Python3.6+Keras+TesnorFlowでiOS用の独自画像認識モデルの作成をしてみた

2020年8月26日

今回、iOSのCoreMLを使用した独自の画像認識機能の作成をしてみたので、PythonのKerasを使用した独自の学習モデルの作成。mlmodelへの変換。独自画像認識のテスト。までをまとめました。

もくじ

  1. Python3.6のインストール
  2. TesnorFlow+Kerasのインストール
  3. Python+Kerasによる独自の学習モデルの作成
  4. 画像認識のテスト実行

1. Python3.6のインストール

Pythonの公式ホームページのダウンロードページより任意のpythonのバージョンを選択してmac用のインストーラーをダウンロードし、pythonのインストールをします。

今回、私はpython6.6のページへ行き、「macOS 64-bit installer」というmac用のインストールパッケージをダウンロードしました。

ダウンロードが完了したらパッケージよりPythonをインストールしてください。
Pythonのインストールと同時にPython用のモジュールを簡単にインストールするためのpip3というのも同時にインストールされます。

パッケージによるPythonのインストールが完了したら動作確認のためPythonのバージョン、pip3の使用確認をしましょう。

Ptythonのバージョン確認

$ python3 --version
Python 3.6.6

pip3の使用確認

$ pip3 list
Package    Version
---------- -------
pip        10.0.1 
setuptools 39.0.1

注意!Python3.7だとTensorFlowが動かない

python3.7だとTensorFlowがうまく利用できない以下のようなエラーになります。
python3.6をインストールするようにしてください。

Traceback (most recent call last):
File "cnn.py", line 3, in <module>
import keras
File "/usr/local/lib/python3.7/site-packages/keras/__init__.py", line 3, in <module>
from . import utils
File "/usr/local/lib/python3.7/site-packages/keras/utils/__init__.py", line 6, in <module>
from . import conv_utils
File "/usr/local/lib/python3.7/site-packages/keras/utils/conv_utils.py", line 9, in <module>
from .. import backend as K
File "/usr/local/lib/python3.7/site-packages/keras/backend/__init__.py", line 89, in <module>
from .tensorflow_backend import *
File "/usr/local/lib/python3.7/site-packages/keras/backend/tensorflow_backend.py", line 5, in <module>
import tensorflow as tf
File "/usr/local/lib/python3.7/site-packages/tensorflow/__init__.py", line 24, in <module>
from tensorflow.python import pywrap_tensorflow # pylint: disable=unused-import
File "/usr/local/lib/python3.7/site-packages/tensorflow/python/__init__.py", line 49, in <module>
from tensorflow.python import pywrap_tensorflow
File "/usr/local/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
from tensorflow.python.pywrap_tensorflow_internal import *
File "/usr/local/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 114
def TFE_ContextOptionsSetAsync(arg1, async):
^

2. 機械学習作成ライブラリ「Keras」のインストール

Kerasを使用します。
インストール手順である、KerasのバックエンドのTensorFlowからインストールしてきます。

TensorFlowのインストール

$ pip3 install --upgrade --ignore-installed https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.8.0-py3-none-any.whl

※URLはPythonのバージョンにより異なる場合があります。

実行したものの、以下のようなエラーが出た時は--userオプションをつけてください。

Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted

$ pip3 install --upgrade --ignore-installed https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.8.0-py3-none-any.whl --user

完了した場合、ちゃんとインストールされているか確認します。

$ pip3 list
Package             Version  
------------------- ---------
absl-py             0.5.0    
astor               0.7.1    
bleach              1.5.0    
cycler              0.10.0   
gast                0.2.0    
grpcio              1.15.0   
h5py                2.8.0    
html5lib            0.9999999
Keras               2.2.2    
Keras-Applications  1.0.4    
Keras-Preprocessing 1.0.2    
kiwisolver          1.0.1    
Markdown            3.0      
matplotlib          3.0.0    
numpy               1.15.2   
pandas              0.23.4   
Pillow              5.2.0    
pip                 18.0     
protobuf            3.6.1    
pyparsing           2.2.1    
python-dateutil     2.7.3    
pytz                2018.5   
PyYAML              3.13     
scikit-learn        0.19.2   
scipy               1.1.0    
setuptools          40.4.3   
six                 1.11.0   
tensorboard         1.8.0    
tensorflow          1.8.0    
termcolor           1.1.0    
Werkzeug            0.14.1   
wheel               0.31.1   

tensorflow1.8.0があることが確認できます。
これでTensorFlowのインストールは完了です。

Kerasのインストール

$ pip3 install keras

完了した場合、再度インストールされているか確認します。

$ pip3 list
Package             Version  
------------------- ---------
absl-py             0.5.0    
astor               0.7.1    
bleach              1.5.0    
cycler              0.10.0   
gast                0.2.0    
grpcio              1.15.0   
h5py                2.8.0    
html5lib            0.9999999
Keras               2.2.2    
Keras-Applications  1.0.4    
Keras-Preprocessing 1.0.2    
kiwisolver          1.0.1    
Markdown            3.0      
matplotlib          3.0.0    
numpy               1.15.2   
pandas              0.23.4   
Pillow              5.2.0    
pip                 18.0     
protobuf            3.6.1    
pyparsing           2.2.1    
python-dateutil     2.7.3    
pytz                2018.5   
PyYAML              3.13     
scikit-learn        0.19.2   
scipy               1.1.0    
setuptools          40.4.3   
six                 1.11.0   
tensorboard         1.8.0    
tensorflow          1.8.0    
termcolor           1.1.0    
Werkzeug            0.14.1   
wheel               0.31.1   

Keras2.2.2があるのが確認できますね。
これでKerasのインストールは完了です。

3. Python+Kerasによる独自の学習モデルの作成

独自の学習モデルを作成するために、まず学習用のトレーニングデータを生成します。
次にトレーニングデータを使用し、独自の学習モデルを生成します。

機械学習用のトレーニングデータ作成のプログラム

# coding: UTF-8

from PIL import Image
import sys
from sklearn import cross_validation
import os, glob
import numpy as np
import random, math

#
# トレーニングデータを生成
#
class DataCreate : 
  def __init__(self, script_name):
    Image.LOAD_TRUNCATED_IMAGES = True

  def create(self) :
    input_dir = "images"
    categorys = []

    dir_list = os.listdir(input_dir)
    for index, dir_name in enumerate(dir_list):
      if dir_name == '.DS_Store' :
        continue
      categorys.append(dir_name)
    image_size = 50
    train_data = [] # 画像データ, ラベルデータ
    for idx, category in enumerate(categorys): 
      try :
        print("---", category)
        image_dir = input_dir + "/" + category
        files = glob.glob(image_dir + "/*.jpg")
        for i, f in enumerate(files):
          img = Image.open(f)
          img = img.convert("RGB")
          img = img.resize((image_size, image_size))
          data = np.asarray(img)
          train_data.append([data, idx])

      except:
        print("SKIP : " + category)

    # データをshuffle
    random.shuffle(train_data)
    X, Y = [],[]
    for data in train_data: 
      X.append(data[0])
      Y.append(data[1])

    test_idx = math.floor(len(X) * 0.8)
    xy = (np.array(X[0:test_idx]), np.array(X[test_idx:]), 
          np.array(Y[0:test_idx]), np.array(Y[test_idx:]))
    np.save("./npy/fruits", xy)


if __name__ == "__main__":
  args = sys.argv
  datacreate = DataCreate(args[0])
  datacreate.create()

プログラムを実行します。

エラーがでるのでpip3でインストールして行きましょう。

Traceback (most recent call last):
File "data_create.py", line 3, in <module>
from PIL import Image
ModuleNotFoundError: No module named 'PIL'

$ pip3 install pillow

Traceback (most recent call last):
File "data_create.py", line 5, in <module>
from sklearn import cross_validation
ModuleNotFoundError: No module named 'sklearn'

$ pip3 install sklearn

再度、プログラムを実行します。

$ python3 data_create.py

次はこのようなエラーがでます。

FileNotFoundError: [Errno 2] No such file or directory: './npy/fruits.npy'

生成したトレーニングデータ(fruits.npy)を保存しようと思ったけどディレクトリが見つからなかったよーということなので、npy」という名前でフォルダを作成してください。

再度、プログラムを実行します。

$ python3 data_create.py

おそらくエラーがなくなり、fruits.npyが作成できていると思います。

モデルの生成プログラム

# coding: UTF-8

import sys
import os
import numpy as np
import pandas as pd
import gc
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.utils import np_utils

#
# モデルを生成
#
class TrainModel : 
  def __init__(self):
    input_dir = 'images'
    self.nb_classes = len([name for name in os.listdir(input_dir) if name != ".DS_Store"])
    x_train, x_test, y_train, y_test = np.load("./npy/fruits.npy")
    # データを正規化する
    self.x_train = x_train.astype("float") / 256
    self.x_test = x_test.astype("float") / 256
    self.y_train = np_utils.to_categorical(y_train, self.nb_classes)
    self.y_test = np_utils.to_categorical(y_test, self.nb_classes)
    print(np.load("./npy/fruits.npy"))


  def train(self, input=None) :
    model = Sequential()
    # K=32, M=3, H=3
    if input == None :
      model.add(Conv2D(32, (3, 3), padding='same', input_shape=self.x_train.shape[1:]))
    else :
      model.add(Conv2D(32, (3, 3), padding='same', input_shape=input))

    # K=64, M=3, H=3(調整)
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Conv2D(64, (3, 3), padding='same'))
    model.add(Activation('relu'))
    # K=64, M=3, H=3(調整)
    model.add(Conv2D(64, (3, 3)))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten()) 
    model.add(Dense(512))
    # biases  nb_classes
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    model.add(Dense(self.nb_classes))
    model.add(Activation('softmax'))

    model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
    if input == None :
      # 学習してモデルを保存
      model.fit(self.x_train, self.y_train, batch_size=32, epochs=10)
      hdf5_file = "./model/fruits-model.hdf5"
      model.save_weights(hdf5_file)

      # modelのテスト
      score = model.evaluate(self.x_test, self.y_test)
      print('loss=', score[0])
      print('accuracy=', score[1])
    return model

if __name__ == "__main__":
  args = sys.argv
  train = TrainModel()
  train.train()
  gc.collect()

次にモデル生成のプログラムを実行します。

$ python3 train.py

またエラーがでるのでpip3でインストールして行きましょう。

Traceback (most recent call last):
File "train.py", line 6, in <module>
import pandas as pd
ModuleNotFoundError: No module named 'pandas'

$ pip3 install pandas

再度、プログラムを実行します。

$ python3 train.py

今度は、モデルを保存するためのディレクトリが見つからないと言われるので、先ほど同様にmodel」という名前でフォルダを作成します。

FileNotFoundError: [Errno 2] No such file or directory: './model/fruits-model.hdf5

再度、プログラムを実行します。

$ python3 train.py

おそらくエラーがなくなり、fruits-model.hdf5が作成できていると思います。

4. 画像認識のテスト実行

import train as train
import sys, os
from PIL import Image
import numpy as np
import pandas as pd

if len(sys.argv) <= 1:
  quit()

image_size = 50
input_dir = 'images'
categories = [name for name in os.listdir(input_dir) if name != ".DS_Store"]

X = []
for file_name in sys.argv[1:]:
  img = Image.open(file_name)
  img = img.convert("RGB")
  img = img.resize((image_size, image_size))
  in_data = np.asarray(img)
  X.append(in_data)

X = np.array(X)

model = train.TrainModel().train(X.shape[1:])
model.load_weights("./model/fruits-model.hdf5")

predict = model.predict(X)

for pre in predict:
  y = pre.argmax()
  print("名前 : ", categories[y])

作成したモデルを使用して、指定した画像に描かれているものを認識させるテストプログラムを実行します。

$ python3 check.py test/1.jpg

と実行すると

~~~ 略 ~~~
        [[250, 250, 250],
         [250, 250, 250],
         [250, 250, 250],
         ...,
         [250, 250, 250],
         [250, 250, 250],
         [250, 250, 250]]]], dtype=uint8)
 array([1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1])
 array([0, 1, 0, 0, 1, 1])]
2019-07-19 12:39:37.461736: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
名前:  リンゴ

と画像に描かれているものを識別してくれます。