前提・実現したいこと
プログラミングと機械学習の勉強をしている初心者です。
以下のサイトを参考にし、自前で集めたデータセットを3クラスに分類する問題を実装しました。
https://qiita.com/hiroeorz@github/items/ecb39ed4042ebdc0a957
ここで、ニューラルネット構築を変更したいと思い、現在のモデルからLenetのモデルに書き換えようとしたのですが、配列関連?のエラーが出てしまいました。
Lenetのモデルは以下のサイトを参考にしました。
https://10001ideas.com/2017/08/30
どのように変更すればlenetのモデルでも実装できるのか教えて頂きたいです。
発生している問題・エラーメッセージ
ValueError Traceback (most recent call last) <ipython-input-16-11d4b98360bf> in <module> 78 model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"]) 79 # 学習を実行。10%はテストに使用。 ---> 80 model.fit(image_list, Y, nb_epoch=1500, batch_size=100, validation_split=0.1) 81 82 # テスト用ディレクトリ(./data/train/)の画像でチェック。正解率を表示する。 ~\Miniconda3\envs\mykeras\lib\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs) 950 sample_weight=sample_weight, 951 class_weight=class_weight, --> 952 batch_size=batch_size) 953 # Prepare validation data. 954 do_validation = False ~\Miniconda3\envs\mykeras\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size) 749 feed_input_shapes, 750 check_batch_axis=False, # Don't enforce the batch size. --> 751 exception_prefix='input') 752 753 if y is not None: ~\Miniconda3\envs\mykeras\lib\site-packages\keras\engine\training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix) 126 ': expected ' + names[i] + ' to have ' + 127 str(len(shape)) + ' dimensions, but got array ' --> 128 'with shape ' + str(data_shape)) 129 if not check_batch_axis: 130 data_shape = data_shape[1:] ValueError: Error when checking input: expected conv2d_11_input to have 4 dimensions, but got array with shape (43, 2352)
変更前のソースコード(実装成功)
from keras.models import Sequential from keras.layers import Activation, Dense, Dropout from keras.utils.np_utils import to_categorical from keras.optimizers import Adagrad from keras.optimizers import Adam import numpy as np from PIL import Image import os # 学習用のデータを作る. image_list = [] label_list = [] # ./data/train 以下のorange,appleディレクトリ以下の画像を読み込む。 for dir in os.listdir("data/train"): if dir == ".DS_Store": continue dir1 = "data/train/" + dir label = 0 if dir == "dora": # doraはラベル0 label = 0 elif dir == "pika": # pikaはラベル1 label = 1 elif dir == "shin": # shinはラベル2 label = 2 for file in os.listdir(dir1): if file != ".DS_Store": # 配列label_listに正解ラベルを追加(どら:0 ぴか:1しん2) label_list.append(label) filepath = dir1 + "/" + file # 画像を25x25pixelに変換し、1要素が[R,G,B]3要素を含む配列の25x25の2次元配列として読み込む。 # [R,G,B]はそれぞれが0-255の配列。 image = np.array(Image.open(filepath).resize((25, 25))) image.shape print(filepath) # 配列を変換し、[[Redの配列],[Greenの配列],[Blueの配列]] のような形にする。 image = image.transpose(2, 0, 1) # さらにフラットな1次元配列に変換。最初の1/3はRed、次がGreenの、最後がBlueの要素がフラットに並ぶ。 image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0] # 出来上がった配列をimage_listに追加。 image_list.append(image / 255.) # kerasに渡すためにnumpy配列に変換。 image_list = np.array(image_list) # ラベルの配列を1と0からなるラベル配列に変更 # 0 -> [1,0], 1 -> [0,1] という感じ。 Y = to_categorical(label_list) print(Y.shape) # モデルを生成してニューラルネットを構築 model = Sequential() model.add(Dense(200, input_dim=1875)) model.add(Activation("relu")) model.add(Dropout(0.2)) model.add(Dense(200)) model.add(Activation("relu")) model.add(Dropout(0.2)) model.add(Dense(3)) model.add(Activation("softmax")) # オプティマイザにAdamを使用 opt = Adam(lr=0.001) # モデルをコンパイル model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"]) # 学習を実行。10%はテストに使用。 model.fit(image_list, Y, nb_epoch=1500, batch_size=100, validation_split=0.1) # テスト用ディレクトリ(./data/train/)の画像でチェック。正解率を表示する。 total = 0. ok_count = 0. for dir in os.listdir("data/train"): if dir == ".DS_Store": continue dir1 = "data/test/" + dir label = 0 if dir == "dora": label = 0 elif dir == "pika": label = 1 elif dir == "shin": label = 2 for file in os.listdir(dir1): if file != ".DS_Store": label_list.append(label) filepath = dir1 + "/" + file image = np.array(Image.open(filepath).resize((25, 25))) print(filepath) image = image.transpose(2, 0, 1) image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0] result = model.predict_classes(np.array([image / 255.])) print("label:", label, "result:", result[0]) total += 1. if label == result[0]: ok_count += 1. print("seikai: ", ok_count / total * 100, "%")
モデル変更を試みた後のソースコード(エラー)
from keras.models import Sequential from keras.layers import Activation, Dense, Dropout from keras.utils.np_utils import to_categorical from keras.optimizers import Adagrad from keras.optimizers import Adam import numpy as np from PIL import Image import os from keras.layers.convolutional import Conv2D, MaxPooling2D from keras.layers.core import Activation, Flatten, Dense # 学習用のデータを作る. image_list = [] label_list = [] # ./data/train 以下のorange,appleディレクトリ以下の画像を読み込む。 for dir in os.listdir("data/train"): if dir == ".DS_Store": continue dir1 = "data/train/" + dir label = 0 if dir == "dora": # doraはラベル0 label = 0 elif dir == "pika": # pikaはラベル1 label = 1 elif dir == "shin": # shinはラベル2 label = 2 for file in os.listdir(dir1): if file != ".DS_Store": # 配列label_listに正解ラベルを追加(どら:0 ぴか:1しん2) label_list.append(label) filepath = dir1 + "/" + file # 画像を28x28pixelに変換し、1要素が[R,G,B]3要素を含む配列の25x25の2次元配列として読み込む。 # [R,G,B]はそれぞれが0-255の配列。 image = np.array(Image.open(filepath).resize((28, 28))) image.shape print(filepath) # 配列を変換し、[[Redの配列],[Greenの配列],[Blueの配列]] のような形にする。 image = image.transpose(2, 0, 1) # さらにフラットな1次元配列に変換。最初の1/3はRed、次がGreenの、最後がBlueの要素がフラットに並ぶ。 image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0] # 出来上がった配列をimage_listに追加。 image_list.append(image / 255.) # kerasに渡すためにnumpy配列に変換。 image_list = np.array(image_list) # ラベルの配列を1と0からなるラベル配列に変更 # 0 -> [1,0], 1 -> [0,1] という感じ。 Y = to_categorical(label_list) print(Y.shape) # モデルを生成してニューラルネットを構築 model = Sequential() model.add(Conv2D(20, kernel_size=5, padding="same", input_shape=(1,28,28))) model.add(Activation("relu")) model.add(MaxPooling2D()) model.add(Conv2D(50, kernel_size=5, border_mode="same")) model.add(Activation("relu")) model.add(MaxPooling2D()) model.add(Flatten()) model.add(Dense(500)) model.add(Activation("relu")) model.add(Dense(3)) model.add(Activation("softmax")) # オプティマイザにAdamを使用 opt = Adam(lr=0.001) # モデルをコンパイル model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"]) # 学習を実行。10%はテストに使用。 model.fit(image_list, Y, nb_epoch=1500, batch_size=100, validation_split=0.1) # テスト用ディレクトリ(./data/train/)の画像でチェック。正解率を表示する。 total = 0. ok_count = 0. for dir in os.listdir("data/train"): if dir == ".DS_Store": continue dir1 = "data/test/" + dir label = 0 if dir == "dora": label = 0 elif dir == "pika": label = 1 elif dir == "shin": label = 2 for file in os.listdir(dir1): if file != ".DS_Store": label_list.append(label) filepath = dir1 + "/" + file image = np.array(Image.open(filepath).resize((28, 28))) print(filepath) image = image.transpose(2, 0, 1) image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0] result = model.predict_classes(np.array([image / 255.])) print("label:", label, "result:", result[0]) total += 1. if label == result[0]: ok_count += 1. print("seikai: ", ok_count / total * 100, "%")
試したこと
・モデルの書き換え
・Conv2D等のインポート
・25×25から28×28への変更(Lenetに合わせようとした)
補足情報(FW/ツールのバージョンなど)
・python3.6.6
・windows10
・jupyter
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/10/25 00:08