# sklearnから
# データセットfetch_lfw_people
# 学習データと検証用データ分割用モジュール
# 標準化/正規化モジュール
from sklearn.datasets import fetch_lfw_people
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# Kerasから
# モデル作成用モジュール
from keras import models, optimizers,layers
from keras.utils import np_utils
from matplotlib import pyplot as plt
plt.tight_layout() # グラフを並べた場合にラベルが重ならないように
import numpy as np
np.set_printoptions(precision=3) # 表示桁数を少数点以下2桁にします
def _report_cfmatrix (test, testPred, names, fname=None) :
# 混同行列用ライブラリ
from sklearn.metrics import classification_report,confusion_matrix,ConfusionMatrixDisplay
from matplotlib import pyplot as plt
print('\n [classification_report]\n', classification_report(test, testPred, target_names=names))
print('\n [confusion_matrix]\n', confusion_matrix(test, testPred))
ConfusionMatrixDisplay(confusion_matrix=confusion_matrix(test, testPred), display_labels=lfw.target_names).plot(cmap='YlGn', values_format='d', xticks_rotation=90)
if( fname != None) :
plt.savefig('.\cmat_cnn.jpg')
lfw = fetch_lfw_people(data_home='./scikit_learn_data/', min_faces_per_person=100, resize=0.5)
X = lfw.data
y = lfw.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
v,h = lfw.images.shape[1:3] # 画像の垂直・水平サイズを保持する
n_train = X_train.shape[0] # 学習データ数を保持する
n_test = X_test.shape[0] # 検証データ数を保持する
print('Image Size [{0}, {1}]'.format(v,h))
print('num of train data [{0}]'.format(n_train))
print('num of test data [{0}]'.format(n_test))
sc = StandardScaler()
sc.fit(X_train)
X_train_sc = sc.transform(X_train)
X_test_sc = sc.transform(X_test)
ms = MinMaxScaler(feature_range=(0,1))
ms.fit(X_train_sc)
X_train_sc = ms.transform(X_train_sc)
X_test_sc = ms.transform(X_test_sc)
X_train_sc = X_train_sc.reshape([n_train, v, h, 1])
X_test_sc = X_test_sc.reshape([n_test, v, h, 1])
y_train_cat = np_utils.to_categorical(y_train,5)
y_test_cat = np_utils.to_categorical(y_test,5)
print(y_train_cat.shape)
print(y_train_cat)
model = models.Sequential()
# 入力: サイズがvxhで1チャンネルをもつ画像 -> (v, h, 1) のテンソル
# それぞれのlayerで3x3の畳み込み処理を適用している
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(v, h, 1)))
model.add(layers.Conv2D(32, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(5, activation='softmax'))
model.summary()
lr = 0.001
beta_1 = 0.9
beta_2 = 0.999
decay = 0.0
optimizers.Adam(lr=lr, beta_1=beta_1, beta_2=beta_2, epsilon=None, decay=decay, amsgrad=False)
model.compile(optimizer = 'Adam',
loss = 'categorical_crossentropy',
metrics = ['acc'])
n_epoc = 200
hist = model.fit(X_train_sc, y_train_cat, epochs=n_epoc, validation_data=(X_test_sc, y_test_cat), verbose=0)
y_test_pred_cls = model.predict_classes(X_test_sc)
y_test_pred_cls
y_test_pred = model.predict(X_test_sc)
y_test_pred
_report_cfmatrix (y_test, y_test_pred_cls, lfw.target_names, fname='.\cmat_cnn.jpg')
hist.history.keys() # ヒストリデータ
gr1 = plt.subplot(1, 2, 1)
gr1.plot(range(1, n_epoc+1), hist.history['acc'], label="training")
gr1.plot(range(1, n_epoc+1), hist.history['val_acc'], label="validation")
gr1.set_xlabel('Epochs')
gr1.set_ylabel('Accuracy')
gr1.legend()
gr2 = plt.subplot(1, 2, 2)
gr2.plot(range(1, n_epoc+1), hist.history['loss'], label="training")
gr2.plot(range(1, n_epoc+1), hist.history['val_loss'], label="validation")
gr2.set_xlabel('Epochs')
gr2.set_ylabel('loss')
gr2.legend()
plt.show()