今回は失敗してしまったので書く必要性はないと思いますが記録として書いていこうと思います。
1 学習用のデータセットの読み込み
#2で作成したデータセットのに合わせてデータセットの読み込みを以下のコードで行います。
データセットの中身は、6クラスで1クラス250枚の画像があります。今回は訓練:テストで8:2で分割します。
import os
import cv2
import numpy as np
#train,testに指定した比率で分割する
train = 8
test = 10 - train
dir = './ds'
#クラス数の取得
num_class = len(os.listdir(dir))
print(num_class)
x_train = []
y_train = []
x_test = []
y_test = []
cnt = 0
class_label = 0
for folders in os.listdir(dir):
file_list = os.listdir(dir + '/' + folders)
for file in file_list:
img = cv2.imread(dir + '/' + folders + '/' + file)
size = (64,48)
img = cv2.resize(img,size)
if cnt < len(file_list)/10*8:
#print(dir + '/' + folders + '/' + file)
x_train.append(img)
y_train.append(class_label)
cnt = cnt + 1
else:
#print(dir + '/' + folders + '/' + file)
x_test.append(img)
y_test.append(class_label)
cnt = 0
class_label = class_label + 1
x_train = np.array(x_train)
y_train = np.array(y_train)
x_test = np.array(x_test)
y_test = np.array(y_test)
#保存は最初以降の読込以外はしなくても良い
dataset_dir = "dataset.npy"
dataset = (x_train,x_test,y_train,y_test)
np.save(dataset_dir,dataset)
x_train,x_test,y_train,y_test = np.load(dataset_dir, allow_pickle=True)
x_train = x_train.astype("float") / x_train.max()
x_test = x_test.astype("float") / x_train.max()
y_train = np_utils.to_categorical(y_train,(num_class))
y_test = np_utils.to_categorical(y_test ,(num_class))
2 モデルの構築・学習
様々なモデル構造を試して最も精度が良かった構造を載せています。
(他にもあると思いますが...)
import os
import cv2
import numpy as np
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from tensorflow import keras, config
from tensorflow.keras.layers import Dense, Flatten, Conv2D
from tensorflow.keras import Model
from keras.utils import np_utils
input_shape = (48, 64, 3)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(8,(3,3),padding='same',input_shape=input_shape,activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(2,2))
model.add(tf.keras.layers.Conv2D(16,(3,3),padding='same',input_shape=input_shape,activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(2,2))
model.add(tf.keras.layers.Conv2D(32,(3,3),padding='same',input_shape=input_shape,activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(2,2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(32, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(num_class,activation="softmax"))
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.summary()
model.fit(x_train, y_train, batch_size=1, epochs=10)
model.save('test.h5')
3 結果
評価から雲行きが怪しく...
score = model.evaluate(x_test, y_test, verbose=0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])
4 モデルの読み込み
import os
import cv2
import numpy as np
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from tensorflow import keras, config
from tensorflow.keras.layers import Dense, Flatten, Conv2D
from tensorflow.keras import Model
from keras.utils import np_utils
input_shape = (48, 64, 3)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(8,(3,3),padding='same',input_shape=input_shape,activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(2,2))
model.add(tf.keras.layers.Conv2D(16,(3,3),padding='same',input_shape=input_shape,activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(2,2))
model.add(tf.keras.layers.Conv2D(32,(3,3),padding='same',input_shape=input_shape,activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(2,2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(32, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(num_class,activation="softmax"))
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.summary()
model.load_weights('./test.h5')
評価用のデータセットの読込み
import os
import cv2
import numpy as np
#評価用のデータセットの読み込み
dir = './eva'
#クラス数の取得
num_class = len(os.listdir(dir))
print(num_class)
x_eva = []
y_eva = []
cnt = 0
class_label = 0
for folders in os.listdir(dir):
file_list = os.listdir(dir + '/' + folders)
for file in file_list:
img = cv2.imread(dir + '/' + folders + '/' + file)
size = (64,48)
img = cv2.resize(img,size)
#print(dir + '/' + folders + '/' + file)
x_eva.append(img)
y_eva.append(class_label)
class_label = class_label + 1
x_eva = np.array(x_eva)
y_eva = np.array(y_eva)
x_eva = x_eva.astype("float") / x_eva.max()
y_eva = np_utils.to_categorical(y_eva ,(num_class))
5 結果
この精度は、ちょっとね...
score = model.evaluate(x_eva, y_eva)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
6 今後の展望
今回は6クラスの分類を行いましたがクラス数を減らせば変わってくるかもしれません。
mediapipeでハンドトラッキングして座標を取得して学習させた方が精度が良いことが分かったのでデータ収集からやり直ししていこうと思います。