PythonMania

普段はロボットとAIを組み合わせて色々作ってます。Python関係以外も色々投稿していくと思います。

【Python】画像認識 - kerasでResNet50をfine-tuningしてみる 【DeepLearning】

f:id:mizuhiki0111:20190430180019p:plain

#必要なライブラリの読み込み
from sklearn.model_selection import train_test_split
import numpy as np
from PIL import Image
import os
from glob import glob
from sklearn.preprocessing import LabelEncoder
import cv2
from keras.utils import np_utils
from matplotlib import pyplot as plt
import pandas as pd



#画像のサイズ指定
ScaleTo = 70
seed = 7
n_categories = 12

#トレーニングデータの読み込み
data_dir ="../input/train"
path = "../input/train/*/*.png"
files = glob(path)

trainImg = []
trainLabel = []
j = 1
num = len(files)

#画像データをリストに格納
for img in files:
    print(str(j) + "/" + str(num) , end="\r")
    trainImg.append(cv2.resize(cv2.imread(img) ,(ScaleTo,ScaleTo)))
    #trainLabel.append(img.split("/")[-2])
    j += 1


#ラベルをリストに格納
for dir in os.listdir(data_dir):
    if dir == ".DS_Store":
        continue
    dir1 = data_dir + "/" + dir
    label = dir

    for file in os.listdir(dir1):
        if file != "Thumbs.db":

            trainLabel.append(label)


# kerasに渡すためにnumpy配列に変換。
image_list = np.asarray(trainImg)
label_list = pd.DataFrame(trainLabel)


clearTrainImg = []
examples = [];getEx = True

for img in image_list:
    #ぼかしを入れてノイズを除去
    blurImg = cv2.GaussianBlur(img ,(5,5),0)
    #RGBからHSVに変換
    hsvImg = cv2.cvtColor(blurImg , cv2.COLOR_BGR2HSV)
    #マスクを作成
    lower_green = (25,40,50)
    upper_green = (75,255,255)
    mask = cv2.inRange(hsvImg , lower_green ,upper_green)
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))
    mask = cv2.morphologyEx(mask , cv2.MORPH_CLOSE,kernel)

    #ブールマスクの作成
    bMask = mask > 0

    #マスクの適用
    #空のイメージの作成
    clear = np.zeros_like(img , np.uint8)
    #オリジナル画像にブールマスクを適用
    clear[bMask] = img[bMask]

    clearTrainImg.append(clear)


for i in range(8):
    plt.subplot(2, 4, i + 1)
    plt.imshow(clearTrainImg[i])


clearTrainImg = np.asarray(clearTrainImg)
clearTrainImg.shape
# クラスの形式を変換
le = LabelEncoder()
le = le.fit(label_list)
label_list = le.transform(label_list)
label_list
label_list = np_utils.to_categorical(label_list)
label_list

X_train, X_test, y_train, y_test = train_test_split(clearTrainImg, label_list, test_size=0.33, random_state=0)



from keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
        rotation_range=180,  # randomly rotate images in the range
        zoom_range = 0.1, # Randomly zoom image
        width_shift_range=0.1,  # randomly shift images horizontally
        height_shift_range=0.1,  # randomly shift images vertically
        horizontal_flip=True,  # randomly flip images horizontally
        vertical_flip=True  # randomly flip images vertically
    )
datagen.fit(X_train)











#モデル作成・学習
from keras.applications.resnet50 import ResNet50
from keras.models import Model
import tensorflow as tf
import keras
from tensorflow import keras
from keras.layers import Conv2D, MaxPooling2D,Input
from keras.layers import Dense, Dropout, Flatten, Activation,GlobalAveragePooling2D,Input
from keras.models import Sequential
from keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
from keras.optimizers import Adam
from keras import optimizers


# ResNet50のロード。FC層は不要なので include_top=False
input_tensor = Input(shape=(ScaleTo, ScaleTo, 3))
resnet50 = ResNet50(include_top=False, weights='imagenet', input_tensor=input_tensor)

# FC層の作成
top_model = Sequential()
top_model.add(Flatten(input_shape=resnet50.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(nb_classes, activation='softmax'))

# ResNet50とFC層を結合してモデルを作成
resnet50_model = Model(input=resnet50.input, output=top_model(resnet50.output))

#ResNet50の一部の重みを固定
for layer in resnet50_model.layers[:100]:
    layer.trainable = False

# 多クラス分類を指定
resnet50_model.compile(loss='categorical_crossentropy',
          optimizer=optimizers.SGD(lr=1e-3, momentum=0.9),
          metrics=['accuracy'])
resnet50_model.summary()


#学習の実行
hist = resnet50_model.fit_generator(datagen.flow(X_train, y_train, batch_size=75),
                        epochs=35, validation_data=(X_test, y_test),
                        steps_per_epoch=X_train.shape[0])


                        steps_per_epoch=X_train.shape[0])


#モデルの評価
print(resnet50_model.evaluate(X_train, y_train)) #トレーニングの精度
print(resnet50_model.evaluate(X_test, y_test))  #テスト精度


#パラメータの保存
model.save_weights('../content/weights.h5')