アラカン"BOKU"のITな日常

文系システムエンジニアの”BOKU”が勉強したこと、経験したこと、日々思うことを書いてます。

Neural Network ConsoleのデータセットCSV&画像ファイルをkeras/tensorflowで直接読み込む。/使い方・番外編

今回は、Neural Network ConsoleのデータセットCSVを、keras/tensorflowのpythonプログラムの中で、直接読み込んで使うのを試します。

データは、画像ファイルを使う想定です。

f:id:arakan_no_boku:20181020211946j:plain 

何故、やってみようと思ったのか

 

ブラウザでディープラーニングを実行したい。

 

それを実現する方法として、Tensorflow.jsは非常に強い候補となります。

arakan-pgm-ai.hatenablog.com

Tensorflow.jsを使うメリットとして、keras/tensorflowで学習したモデル・パラメータを引き継いで利用することができるのも、非常にうれしいです。

arakan-pgm-ai.hatenablog.com

だから、最終的にはkeras/tensorflowでプログラムを書いて、学習と保存をすることになるわけですが、とっつきとしてモデルを設計・検討するのに、Neural Network Consoleのグラフィカルなインタフェースは捨てがたい。

どうせなら、Neural Network Consoleで設計検討して、それをkerasにうつして実行できればいいんですよね。

じゃあ、試してみよう・・というわけです。

当然、Neural Network Console用で用意したデータを使わないのはもったいない。

まず、keras/tensorflowで、Neural Network ConsoleのデータセットCSVから直接読み込めるようにするのが先決だ。

ということで、まず、そこだけやってみます。

 

Neural Network ConsoleのデータセットCSVおさらい

 

データセットCSVとは、以下のような内容をCSVテキストとして記述するものです。

f:id:arakan_no_boku:20181020213657j:plain

ようするに、1列目は入力であるxの画像ファイル名(CSVファイルからの相対パス)を、2列目は正解カテゴリのIndexを示すCSVテキストファイルです。

で、このCSVファイルのあるフォルダの下に、1列目のパスに一致する様に画像ファイルをコピーしておくわけですね。

なので、直接読み込む場合も、このCSVファイルを1行ずつ処理して、1列目に書いてある画像ファイルを読み込み、2列目の値を正解ラベルとして読み込む・・をすればよいだけです。

実にシンプル(笑)です。

 

データセットCSVを読み込みKerasで利用できるようにする

 

処理をする部分のソースです。

import tensorflow as tf
import numpy as np
import csv
from sklearn.model_selection import train_test_split
from keras.preprocessing.image import array_to_img, img_to_array, load_img
from keras.utils import np_utils

class NncData:

    def get_csv_list(self,fname):
        csv_file = open(fname, "r", encoding="utf8", errors="", newline="" )
        dset = csv.reader(csv_file, delimiter=",", doublequote=True, lineterminator="\r\n", quotechar='"', skipinitialspace=True)
        next(dset)
        return dset

    def load_nnc_image(self,fname,gray=True,width=28,height=28,category=10,test=0.3, seed=14365):
        x_data = []
        y_label = []
        tx = []
        ty = []
        dcsv = self.get_csv_list(fname)
        for r in dcsv:
            if(gray == True):
                temp_img = load_img(r[0], color_mode = "grayscale",target_size=(height,width))
            else:
                temp_img = load_img(r[0],target_size=(height,width))
            img_array  = img_to_array(temp_img)
            tx.append(img_array)
            ty.append(r[1])
        x_data = np.asarray(tx)
        y_label = np.asarray(ty)
        x_data = x_data.astype('float32')
        x_data = x_data / 255.0
        y_label = np_utils.to_categorical(y_label, category)
        return train_test_split(x_data, y_label, test_size=test, random_state=seed)

ポイントを補足します。

以下のステップが必要です。

  • データセットCSVファイルを読み込む、リスト化する。
  • リストのパスから画像ファイルを読んでデータ化する(1行ずつ処理)
  • リストの正解ラベルをkerasで利用できる形式に変換する(1行ずつ処理)
  • データを学習データと評価データに振り分ける

 

データセットCSVファイルを読み込む、リスト化する

この部分です。

def get_csv_list(self,fname):
    csv_file = open(fname, "r", encoding="utf8", errors="", newline="" )
    dset = csv.reader(csv_file, delimiter=",", doublequote=True,     lineterminator="\r\n", quotechar='"', skipinitialspace=True)
    next(dset)
    return dset

 pythonCSVライブラリを使って、ファイルを読み込んで、1行目のヘダー行を読み飛ばすために、「next(dset)」してから、リストを返してます。

14.1. csv — CSV ファイルの読み書き — Python 3.6.5 ドキュメント

 

リストのパスから画像ファイルを読んでデータ化する(1行ずつ処理)

 

画像ファイルの読み込みには、「keras.preprocessing.image」のメソッドを使います。

いろんなことができますが、今回は読み込んで、Arrayに変換する部分だけ使います。

これらの処理は関数化しています。

インタフェースは「 load_nnc_image(self,fname,gray=True,width=28,height=28,category=10,test=0.3, seed=14365):]となってます。

fnameはデータセットCSVのファイル名とパス。

gray=True or False は、画像がグレースケールか、カラー(RGB)かを指定。

width=28,height=28 は、画像の縦横サイズ。

category=10は、正解ラベルのカテゴリ数(MNISTだと、0-9の10だとか)

test=0.3, seed=14365 は、データをトレーニング用と画像用にどの程度の比率で振り分けるかの指定で、seedは振り分けに使う乱数の種です。

さて、それを踏まえて、該当する部分のソースです。

dcsv = self.get_csv_list(fname)
for r in dcsv:
    if(gray == True):
        temp_img = load_img(r[0], color_mode = "grayscale",target_size=(height,width))
    else:
        temp_img = load_img(r[0],target_size=(width,height))
    img_array = img_to_array(temp_img)

まず、 1行目でデータセットCSVをリストに読み込んで、for文で1行ずつ処理しているわけです。

gray==Trueかどうかで、グレイスケールで読むか、カラーで読むかを分岐していますが、基本は「keras.preprocessing.image」の「load_img」一発で読んでます。

それを「 img_to_array」でArrayに変換します。

さて、それに続くソースです。

x_data = np.asarray(tx)
x_data = x_data.astype('float32')
x_data = x_data / 255.0

numpyのarrayに変換してデータに追加して、Typeは'float32'に変換したあとで、255.0で割るのは、kerasで処理するデータの約束事みたいなもんです。

 

リストの正解ラベルをkerasで利用できる形式に変換する(1行ずつ処理)

正解ラベルは、リストの2列目の数字をそのまま使います。

0とか1とかですね。

でも、kerasの正解ラベルはone-hot表現にする必要があります。

例えば、カテゴリサイズが0から9までの10個で、正解ラベルが2なら、2にあたる部分だけが1で、他は0にする・・例えば「{0,0,1,0,0,0,0,0,0,0}」・・必要があります。

ONE-HOT表現への変換は、「keras.utils 」の「to_categorical」を使います。

それらの処理の該当する部分は以下になります。

y_label =
ty =

dcsv = self.get_csv_list(fname)
for r in dcsv:
    ty.append(r[1])
    y_label = np.asarray(ty)
    y_label = np_utils.to_categorical(y_label, category) 

 

データを学習データと評価データに振り分ける

最後に、上記で作った画像データ(x_data)と正解ラベル(y_label)を学習用と評価用に振り分けます。

これは、機械学習ライブラリ「sklearn」のメソッドを使ってます。

train_test_split関数でデータ分割 — PyQ 1.0 ドキュメント

ソースの該当部分は以下です。

return train_test_split(x_data, y_label, test_size=test, random_state=seed)

 

上記のような処理をクラス「NncData」にまとめてます。

 

最後に利用例です

 

上記の「NncData」クラスを使って、Neural Network ConsoleのデータセットCSVを読み込んで、簡単なCNNで処理する例のソースです。

import tensorflow as tf
import nncdata as nd

nnc = nd.NncData()
x_train, x_test, y_train, y_test = nnc.load_nnc_image('./mnist_test.csv',width=28,height=28)

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.Dropout(0.25))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy',
              optimizer=tf.keras.optimizers.RMSprop(),
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=10)
sc = model.evaluate(x_test, y_test)
print("acc=",sc[1])
 

データを読み込んでいる部分は以下です。

import nncdata as nd

nnc = nd.NncData()
x_train, x_test, y_train, y_test = nnc.load_nnc_image('./mnist_test.csv',width=28,height=28)

 なんかいい感じですね。

kerasはシンプルに記述できるので、わかりやすいです。

これができたら、Neural Network Consoleで設計検討したものを、kerasのモデルに置き換えて、学習させて、Tensorflow.jsでWEBアプリケーションに組み込むというのも、なんとなくいけそうな気がします。

今回はこんなところで。

ではでは。