質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

解決済

2回答

8388閲覧

Kerasで学習したモデルを用いて画像判定

tagaa

総合スコア13

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

0クリップ

投稿2018/09/29 07:34

編集2018/09/29 08:03

前提・実現したいこと

KerasのCNNで画像を2クラスに分類するモデルを学習し、そのモデルを用いて、新たな別画像の判定結果を出力するプログラムを作成したいです。
学習時のラベルは0と1で、2値に分類しています。
学習精度として、Test accuracyが約0.8です。
しかし、判定プログラムでの出力がどの画像に対しても[[1. 0.]]になってしまいます。
「1」と判定した画像の出力は[[0. 1.]]となるのかと考えていましたが、全ての画像で上記出力になります...

判定結果「0」と「1」を正しく出力できるよう、判定プログラムを改良していただけないでしょうか...?
よろしくお願いいたします。

学習プログラム(alexnet.py)

# coding:utf-8 import keras from keras.layers import Conv2D, MaxPooling2D, Lambda, Input, Dense, Flatten, BatchNormalization from keras.utils import np_utils from keras.models import Sequential from keras.layers.convolutional import Conv2D, MaxPooling2D from keras.layers.core import Dense, Dropout, Activation, Flatten import numpy as np from sklearn.model_selection import train_test_split from PIL import Image import glob from keras.utils import plot_model import matplotlib.pyplot as plt import tensorflow as tf folder = ["0","1"] image_size = 224 epoch_size = 10 X = [] Y = [] for index, name in enumerate(folder): dir = "./" + name files = glob.glob(dir + "/*.jpg") for i, file in enumerate(files): image = Image.open(file) image = image.convert("RGB") image = image.resize((image_size, image_size)) data = np.asarray(image) X.append(data) Y.append(index) #Xは画像データ、Yは正解ラベルのデータ X = np.array(X) Y = np.array(Y) #画像データを0から1の範囲に変換 X = X.astype('float32') X = X / 255.0 #正解ラベルの形式を変換 #つまり、ラベルを[0, 0, 0, 1]のようなベクトルにする。値はラベルの数に合わせる。 Y = np_utils.to_categorical(Y, 2) # 学習用データとテストデータに分割 #train_test_split 関数はデータをランダムに、好きの割合で分割できる関数。 #X_train(訓練データ), X_test(テストデータ), y_train(訓練ラベル), y_test(テストラベル) #test_sizeはテストデータにする割合 X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.25) model = Sequential() model.add(Conv2D(48, 11, strides=(3, 3), activation='relu', padding='same',input_shape=X_train.shape[1:])) model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2))) model.add(BatchNormalization()) model.add(Conv2D(128, 5, strides=(3, 3), activation='relu', padding='same')) model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2))) model.add(BatchNormalization()) model.add(Conv2D(192, 3, strides=(1, 1), activation='relu', padding='same')) model.add(Conv2D(192, 3, strides=(1, 1), activation='relu', padding='same')) model.add(Conv2D(128, 3, strides=(1, 1), activation='relu', padding='same')) model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2))) model.add(BatchNormalization()) model.add(Flatten()) model.add(Dense(2048, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(2048, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(2, activation='softmax')) #model.add(Activation('softmax')) model.summary(); model.compile(loss='categorical_crossentropy',optimizer='SGD',metrics=['accuracy']) history = model.fit(X_train, y_train, epochs=epoch_size, verbose=1, validation_split=0.15) #評価 & 評価結果出力 #print(model.evaluate(X_test, y_test)) score = model.evaluate(X_test, y_test, verbose=0) print('Test loss :', score[0]) print('Test accuracy :', score[1]) # モデルをプロット plot_model(model, to_file='./model3.png') #loss: 訓練データの損失値 #val_loss: テストデータの損失値 loss = history.history['loss'] val_loss = history.history['val_loss'] # lossのグラフ plt.plot(range(epoch_size), loss, marker='.', label='loss') plt.plot(range(epoch_size), val_loss, marker='.', label='val_loss') plt.legend(loc='best', fontsize=10) plt.grid() plt.xlabel('epoch') plt.ylabel('loss') plt.show() #acc: 訓練データの精度 #val_acc: テストデータの精度 acc = history.history['acc'] val_acc = history.history['val_acc'] # accuracyのグラフ plt.plot(range(epoch_size), acc, marker='.', label='acc') plt.plot(range(epoch_size), val_acc, marker='.', label='val_acc') plt.legend(loc='best', fontsize=10) plt.grid() plt.xlabel('epoch') plt.ylabel('acc') plt.show() ### save weights json_string = model.to_json() open('alexnet_model.json', 'w').write(json_string) model.save_weights('alexnet_weights.h5') _____________________________________________________________

保存済みの重みデータ

alexnet_model.json
alexnet_weights.h5

###判定プログラム(judge_alexnet.py)

from keras.models import model_from_json import numpy as np from keras.preprocessing import image model = model_from_json(open('alexnet_model.json').read()) model.load_weights('alexnet_weights.h5') #判定したい画像 filename = 'gazou.jpg' img = image.load_img(filename, target_size=(224, 224)) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) features = model.predict(x) #判定結果 print(features)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

一番確率が高いクラスがどれかという情報だけ得られればよければ、model.predict_classes() を使うと簡潔にかけます。

今回の件は validation accuracy が 0.8 なのに、実際テストデータを流すと全部 [[1. 0.]] になるということでしょうか。
記載いただいた範囲でコードに問題はなさそうなのですが、validation accuracy が 0.8 というのはどのように確認されましたか?


2個目のコードでは [0, 1] に正規化する処理が入っていないので、学習した際と同じ前処理を行うようにしてみてください。

MNIST データで 0/1 判定するサンプル

python

1import numpy as np 2from keras.datasets import mnist 3from keras.layers import Activation, BatchNormalization, Dense 4from keras.models import Sequential, model_from_json 5from keras.utils import np_utils 6from sklearn.model_selection import train_test_split 7 8(x_train, y_train), (x_test, y_test) = mnist.load_data() 9X = np.append(x_train, x_test, axis=0) 10Y = np.append(y_train, y_test) 11 12# 数字0と1のデータだけ取り出す 13indices = np.logical_or(Y == 0, Y == 1) 14X = X[indices] 15Y = Y[indices] 16print('X.shape', X.shape) # X.shape (14780, 28, 28) 17print('Y.shape', Y.shape) # Y.shape (14780,) 18 19# 前処理 20X = X.astype(np.float32) / 255 21X = X.reshape(len(X), -1) 22 23# 学習データ、テストデータに分割する。 24x_train, x_test, y_train, y_test = \ 25 train_test_split(X, Y, test_size=0.2) 26 27# one-hot 表現に変換する。 28y_train = np_utils.to_categorical(y_train, 2) 29 30# モデルを作成する。 31model = Sequential() 32model.add(Dense(10, input_dim=784)) 33model.add(BatchNormalization()) 34model.add(Activation('relu')) 35model.add(Dense(10)) 36model.add(BatchNormalization()) 37model.add(Activation('relu')) 38model.add(Dense(2)) 39model.add(BatchNormalization()) 40model.add(Activation('softmax')) 41model.compile(optimizer='adam', 42 loss='categorical_crossentropy', 43 metrics=['accuracy']) 44 45# 学習する。 46history = model.fit(x_train, y_train, epochs=10, batch_size=128, 47 validation_split=0.2, verbose=0) 48 49# モデル及び重みを保存する。 50with open('model.json', 'w') as f: 51 f.write(model.to_json()) 52model.save_weights('weights.h5') 53 54from sklearn.metrics import accuracy_score 55 56# 保存したモデル及び重みを読み込む。 57with open('model.json') as f: 58 model = model_from_json(f.read()) 59model.load_weights('weights.h5') 60 61# 推論する。 62y_pred = model.predict_classes(x_test) 63 64# 精度を表示する。 65accuracy = accuracy_score(y_pred, y_test) 66print('{:.2%}'.format(accuracy)) # 99.93%

投稿2018/09/29 07:45

編集2018/09/29 08:57
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tagaa

2018/09/29 08:09

ご回答ありがとうございます。validation accuracyは上記学習プログラム(追加しました)で表示するようにしています。 validation accuracy が 0.8 なのに、実際テストデータを流すと全部 [[1. 0.]] になるという認識で間違いありません。(判定プログラムのfilenameの部分を全てのテストデータで試しました)
tiitoi

2018/09/29 08:55

MNIST で0/1分類するタスクを学習し、一旦保存したあと、読み込んで推論するサンプルを記載しました。 1つ質問のコードを見てて気づいたのは、2個目のコードでは [0, 1] に正規化する処理が入っていないようですが、そこらへんは関係ないでしょうか?学習したときに前処理を行っていた場合は、推論時も同じことを行う必要があります。
guest

0

正規化の処理を追加したら正しい出力結果が出ました。誠にありがとうございました。

投稿2018/10/01 00:24

tagaa

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問