今回は、Neural Network ConsoleのデータセットCSVを、keras/tensorflowのpythonプログラムの中で、直接読み込んで使うのを試します。
データは、画像ファイルを使う想定です。
なんで、こんな事を考えたか
ブラウザでディープラーニングを実行できるTensorflow.jsがあります。
Tensorflow.jsは、keras/tensorflowで学習したモデル・パラメータを利用できます。
だから。
最終的にはkeras/tensorflowでプログラムを書いて、学習と保存をするわけだけど、Neural Network Consoleで設計検討して、それをkerasにうつして実行できれれば、結構いいかもしれないなと思ったわけです。
そのときに、Neural Network Console用で用意したデータを使わないのはもったいないので、直接読み込める方法を整理しておこう・・とまあ、そういうわけです。
Neural Network ConsoleのデータセットCSV
まず、keras/tensorflowで、Neural Network ConsoleのデータセットCSVから直接読み込めるようにするのが先決だ。
ということで、まず、そこだけやってみます。
データセットCSVとは、以下のような内容をCSVテキストとして記述するものです。
ようするに、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を読み込みKerasで利用するポイント
以下のステップが必要です。
- データセット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
pythonのCSVライブラリを使って、ファイルを読み込んで、1行目のヘダー行を読み飛ばすために、「next(dset)」してから、リストを返してます。
14.1. csv — CSV ファイルの読み書き — Python 3.6.5 ドキュメント
リストのパスから画像ファイルを読んでデータ化する(1行ずつ処理)
画像ファイルの読み込みには、「keras.preprocessing.image」のメソッドを使います。
いろんなことができますが、今回は読み込んで、Arrayに変換する部分だけ使います。
これらの処理は関数化しています。
load_nnc_image関数
「 load_nnc_image(self,fname,gray=True,width=28,height=28,category=10,test=0.3, seed=14365):]となってます。
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アプリケーションに組み込むというのも、なんとなくいけそうな気がします。
今回はこんなところで。
ではでは。