2017年4月7日 更新

Deep learningで画像認識⑦〜Kerasで畳み込みニューラルネットワーク vol.3〜

Kerasと呼ばれるDeep Learingのライブラリを使って、白血球の顕微鏡画像を分類してみます。

34,835 view お気に入り 1
学習に用いたコード(上:learning.py)と評価に用いたコード(下:evaluation.py)を載せておきます。
from __future__ import print_function
import os
import struct
import numpy as np
from keras.models import Sequential
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.optimizers import RMSprop
from keras.utils import np_utils
from keras.callbacks import EarlyStopping, ModelCheckpoint
from sklearn.model_selection import KFold
from sklearn.model_selection import train_test_split
from keras.preprocessing.image import ImageDataGenerator

# 各種パラメータ
nb_filters1 = 32         # 畳み込みフィルタ1の数
nb_filters2 = 64         # 畳み込みフィルタ2の数
nb_conv1 = 3             # 畳み込みフィルタ1の縦横pixel数
nb_conv2 = 2             # 畳み込みフィルタ2の縦横pixel数
nb_pool = 2              # プーリングを行う範囲の縦横pixel数  
nb_classes = 3           # 分類するクラス数
nb_epoch = 50            # 最適化計算のループ回数
batch_size = 32          # 計算効率化のために分割された訓練データの1グループあたりのデータ数
img_rows, img_cols = 100, 100     # 入力画像の縦横pixel数
all_filenumber = 90      # 訓練用 & 評価用画像の数
bytesize = 3             # 画像のbyte数(24bit = 3byte)
pixelnum = img_rows*img_cols
index = 0

# 配列の確保
X_train_binary = [0 for j in range(bytesize*pixelnum*all_filenumber)]
X_train_int = [0 for j in range(bytesize*pixelnum*all_filenumber)]
y_train_int = []

# 画像&ラベルデータの読み込み
filenameX_train = "blood_total.raw"
filenameY_train = "blood_total_label.txt"

path1 = "/Users/satoshi/blood_data/"
rf1 = open(path1+filenameX_train, "rb")
rf2 = open(path1+filenameY_train, "r")

X_train_binary = rf1.read(bytesize*pixelnum*all_filenumber)

# 画像データの格納(バイナリから整数(char型)に変換して)
for i in range(bytesize*pixelnum*all_filenumber):
    X_train_int[i] = struct.unpack("B", X_train_binary[i])

# ラベルデータの格納
for item in rf2:
    y_train_int += list(item)

rf1.close()
rf2.close()

# numpy配列に格納
X_train = np.array(X_train_int)
y_train = np.array(y_train_int)

# 画像を4次元配列に
X_train = X_train.reshape(all_filenumber, 3, img_rows, img_cols)

# 画像を0.0~1.0の範囲に変換
X_train = X_train.astype("float32")
X_train /= 255

# 画像の前処理としての正規化
def normalization(X_train):
    X_train = X_train.reshape(all_filenumber, 3*img_rows*img_cols)
    
    for filenum in range(0, all_filenumber):
        X_train[filenum] -= np.mean(X_train[filenum])

    X_train = X_train.reshape(all_filenumber, 3, img_rows, img_cols)

    return X_train

normalization(X_train)

# Kflodによる交差検証
kf = KFold(n_splits=5, shuffle=True)

for train_index, eval_index in kf.split(X_train):
    X_tra, X_eval = X_train[train_index], X_train[eval_index]
    y_tra, y_eval = y_train[train_index], y_train[eval_index]

    model_weights = "/Users/satoshi/blood_data/blood_CNN_model[%d].h5" % index
    index = index+1

    # データの水増し(Data Augmentation)
    datagen = ImageDataGenerator(      
                                 rotation_range=180,
                                 horizontal_flip=True,
                                 fill_mode='nearest')

    # 水増し画像を訓練用画像の形式に合わせる
    datagen.fit(X_tra)

    # クラスラベル y (数字の0~2)を、one-hotエンコーディング型式に変換
    Y_tra = np_utils.to_categorical(y_tra, nb_classes)
    Y_eval = np_utils.to_categorical(y_eval, nb_classes)

    # CNNのモデル
    model = Sequential()
    model.add(Convolution2D(nb_filters1, nb_conv1, nb_conv1, border_mode ="same", input_shape=(3, img_rows, img_cols)))
    model.add(Activation("relu"))
    model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))

    model.add(Convolution2D(nb_filters2, nb_conv2, nb_conv2, border_mode ="same"))
    model.add(Activation("relu"))
    model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))

    model.add(Flatten())
    model.add(Dense(256))
    model.add(Activation("relu"))
    model.add(Dropout(0.5))
    model.add(Dense(nb_classes))
    model.add(Activation("softmax"))

    #モデルのコンパイル
    model.compile(loss="categorical_crossentropy", optimizer="rmsprop", metrics=["accuracy"])

    # 過学習の抑制
    early_stopping = EarlyStopping(monitor='val_loss', patience=10 , verbose=1)

    # 評価に用いるモデル重みデータの保存
    checkpointer = ModelCheckpoint(model_weights, monitor='val_loss', verbose=1, save_best_only=True)

    # リアルタイムに水増し生成されるバッチ画像に対するモデルの適用
    model.fit_generator(datagen.flow(X_tra, Y_tra, batch_size=batch_size),
                    samples_per_epoch=X_tra.shape[0],
                    nb_epoch=nb_epoch,
                    verbose=1,
                    validation_data=(X_eval, Y_eval),
                    callbacks=[early_stopping, checkpointer])

# 評価に用いるモデル構造の保存
def save_model(model):
    json_string = model.to_json()
    if not os.path.isdir("cache"):
        os.mkdir("cache")
    json_name = "architecture.json"
    open(os.path.join("cache", json_name),"w").write(json_string)

save_model(model)
learning.py
from __future__ import print_function
import os
import struct
import numpy as np
from keras.models import model_from_json

# 各種パラメータ
img_rows, img_cols = 100, 100
test_filenumber = 1
bytesize = 3
pixelnum = img_rows*img_cols

# 配列の確保
X_test_binary = [0 for j in range(bytesize*pixelnum*test_filenumber)]
X_test_int = [0 for j in range(bytesize*pixelnum*test_filenumber)]
test_pred = []

# テスト画像の読み込み
filenameX_test = "blood_01.raw"
path1 = "/Users/satoshi/blood_data/"
rf = open(path1+filenameX_test, "rb")

X_test_binary = rf.read(bytesize*pixelnum*test_filenumber)

# 画像データの格納(バイナリから整数(char型)に変換して)
for i in range(bytesize*pixelnum*test_filenumber):
    X_test_int[i] = struct.unpack("B", X_test_binary[i])

rf.close()

# numpy配列に格納
X_test  = np.array(X_test_int)

# 画像を4次元配列に
X_test = X_test.reshape(test_filenumber, 3, img_rows, img_cols)

# 画像を0.0~1.0の範囲に変換
X_test = X_test.astype("float32")
X_test /= 255

# 画像の前処理としての正規化
def normalization(X_test):
    X_test  = X_test.reshape(test_filenumber, 3*img_rows*img_cols)
    
    for filenum in range(0, test_filenumber):
        X_test[filenum] -= np.mean(X_test[filenum])

    X_test = X_test.reshape(test_filenumber, 3, img_rows, img_cols)

    return X_test

normalization(X_test)

# 保存したモデル重みデータとモデル構造の読み込み
for index in range(0,5):
    model_weights = "/Users/satoshi/blood_data/blood_CNN_model[%d].h5" % index
    json_name = "architecture.json"
    model = model_from_json(open(os.path.join("cache", json_name)).read())
    model.load_weights(model_weights)

    # 各モデルにおける推測確率の計算 
    test_pred.append(model.predict(X_test))
    test_average = np.array(test_pred[0])

# 5種類のモデルの推測確率の平均
for i in range(1,5):
    test_average += np.array(test_pred[i])

test_average /= 5
print(test_average)
evaluation.py
18 件

関連する記事 こんな記事も人気です♪

Deep learningで画像認識⑩〜Kerasで畳み込みニューラルネットワーク vol.6〜

Deep learningで画像認識⑩〜Kerasで畳み込みニューラルネットワーク vol.6〜

U-Netと呼ばれるU字型の畳み込みニューラルネットワークを用いて、MRI画像から肝臓の領域抽出を行ってみます。
木田智士 | 10,405 view
Deep learningで画像認識⑨〜Kerasで畳み込みニューラルネットワーク vol.5〜

Deep learningで画像認識⑨〜Kerasで畳み込みニューラルネットワーク vol.5〜

U-Netと呼ばれるU字型の畳み込みニューラルネットワークを用いて、MRI画像から肝臓の領域抽出を行ってみます。
木田智士 | 27,389 view
Deep learningで画像認識⑧〜Kerasで畳み込みニューラルネットワーク vol.4〜

Deep learningで画像認識⑧〜Kerasで畳み込みニューラルネットワーク vol.4〜

転移学習と呼ばれる学習済みのモデルを利用する手法を用いて白血球の顕微鏡画像を分類してみます。
木田智士 | 26,367 view
Deep learningで画像認識⑥〜Kerasで畳み込みニューラルネットワーク vol.2〜

Deep learningで画像認識⑥〜Kerasで畳み込みニューラルネットワーク vol.2〜

Kerasと呼ばれるDeep Learingのライブラリを使って、文字認識を行ってみます。
木田智士 | 11,343 view
Deep learningで画像認識⑤〜Kerasで畳み込みニューラルネットワーク vol.1〜

Deep learningで画像認識⑤〜Kerasで畳み込みニューラルネットワーク vol.1〜

Kerasと呼ばれるDeep Learingのライブラリを使って、簡単に畳み込みニューラルネットワークを実装してみます。
木田智士 | 16,466 view

この記事のキーワード

この記事のキュレーター

木田智士 木田智士