プログラミング備忘録

初級プログラマ。python、DL勉強中

VGG16の実装(作業中)

VGG16

from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout, Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPool2D
from keras.utils.np_utils import to_categorical
from keras.optimizers import Adagrad
from keras.optimizers import Adam
from keras.utils import plot_model
import numpy as np
from PIL import Image
import json
import os

# ユーザ設定
xsize=128
ysize=128
classnum=15
train_path="../../data/football/train"
test_path="../../data/football/test"

# クラス分類表読み込み
jsondata=open("./class.json","r")
classdict=json.load(jsondata)

def VGG16_keras(X,Y):
    #ハイパーパラメーター
    dout=0.2
    lr=0.001
    batch_size=100
    nb_epoch=1000
    validation_split=0.1

    model = Sequential()

    model.add(Conv2D(64,3, input_shape=(xsize,ysize,3)))
    model.add(Activation("relu"))
    model.add(Conv2D(64,3))
    model.add(Activation("relu"))
    model.add(MaxPool2D(pool_size=(2,2)))

    model.add(Conv2D(128,3))
    model.add(Activation("relu"))
    model.add(Conv2D(128,3))
    model.add(Activation("relu"))
    model.add(MaxPool2D(pool_size=(2,2)))

    model.add(Conv2D(256,3))
    model.add(Activation("relu"))
    model.add(Conv2D(256,3))
    model.add(Activation("relu"))
    model.add(Conv2D(256,3))
    model.add(Activation("relu"))
    model.add(MaxPool2D(pool_size=(2,2)))

    model.add(Conv2D(512,3))
    model.add(Activation("relu"))
    model.add(Conv2D(512,3))
    model.add(Activation("relu"))
    model.add(Conv2D(512,3))
    model.add(Activation("relu"))
    model.add(MaxPool2D(pool_size=(2,2)))


    """
    model.add(Conv2D(512,3))
    model.add(Activation("relu"))
    model.add(Conv2D(512,3))
    model.add(Activation("relu"))
    model.add(Conv2D(512,3))
    model.add(Activation("relu"))
    model.add(MaxPool2D(pool_size=(2,2)))
    """

    model.add(Flatten())
    model.add(Dense(512))
    model.add(Activation("relu"))
    model.add(Dropout(0.5))

    model.add(Dense(128))
    model.add(Activation("relu"))
    model.add(Dropout(0.5))

    model.add(Dense(64))
    model.add(Activation("relu"))
    model.add(Dropout(0.5))

    model.add(Dense(classnum))
    model.add(Activation("softmax"))
    model.compile(loss="categorical_crossentropy", optimizer=Adam(lr=lr), metrics=["accuracy"])
    plot_model(model, to_file='footballl_cnn.png',show_shapes=True)
    model.summary()
    model.fit(X, Y, nb_epoch=nb_epoch, batch_size=batch_size, validation_split=validation_split)

    return model

#PILを使用して、画像を数値に変換
def imgconverter_PIL(target_path):
    image_list = []
    label_list = []

    #1クラスづつにディレクトリを選択
    for class_name in os.listdir(target_path):
        #ラベルの読み込み
        try:
            label = classdict[class_name]
        except:
            print("class is not defined in class.json")
            exit()

        #各クラスの画像データを処理しリストに詰める
        dataset_path = target_path + "/" + class_name
        for file_name in sorted(os.listdir(dataset_path)):
            file_path = dataset_path + "/" + file_name
            image = np.array(Image.open(file_path).resize((xsize, ysize)))

            # RGBの順に変換、[[Redの配列],[Greenの配列],[Blueの配列]]
            #image = image.transpose(2, 0, 1)
            # 1次元配列に変換(25*25*3) Red,Green,Blueの要素が順番に並ぶ。
            #image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0]
            # 0〜1の範囲に変換してリスト化
            image_list.append(image / 255.)
            label_list.append(label)
    return image_list,label_list

#メイン処理
def traintest():

    #教師データ準備
    train_image_list,train_label_list=imgconverter_PIL(train_path)

    # 入力:numpy変換する
    X = np.array(train_image_list)
    print(X.shape)
    # 出力:label=0 -> [1,0], label=1 -> [0,1] に変換
    Y = to_categorical(train_label_list)
    print(Y.shape)

    # 学習
    model=VGG16_keras(X,Y)

    #テストデータ準備
    test_image_list,test_label_list=imgconverter_PIL(test_path)

    #推論
    total=0
    ok_count=0
    for img,lbl in zip(test_image_list,test_label_list):
        result = model.predict_classes(np.array([img]))
        print("Collet label:", lbl, " | ","predict:", result[0])

        #正解率計算
        total += 1.
        if lbl == result:
            ok_count += 1.

    print("accuracy: ", ok_count / total * 100, "%")


if __name__=="__main__":
    traintest()