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

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

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

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

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

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

685閲覧

Tensorflow, kerasで作成したCNNモデルの使い方

iarik

総合スコア101

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

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

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/06/08 06:35

編集2018/06/08 06:37

やりたいこと

APIで画像分析を今までやってきましたが、もっと深い画像分析をやりたいと思いtensorflowとkerasを使って勉強をはじめました。まずは、イメージを掴むためkerasでMNIST用のCNNモデルを作成し、作成したモデルに対して自分で用意した画像を当てたときにどういった結果が得られるかやってみようとしたところです。

動作環境

Mac
Python 3.6.5
tensorflow 1.8.0
keras 2.2.0
jupyternotebook 1.0.0

わからないこと

Qiitaの記事を読みつつ、jupyter notebook上でkerasで配布されているサンプルコードをmnist_cnn.pyを実行してみました。サンプルコード自体はうまく作成できましたがmodel.predictでエラーが出て進みません。

やったこと

  • mnist_cnn.pyの実行

mnist_cnn.pyは問題なく正常実行できました。

# mnist tutorial by keras (train time about 45 minuts) '''Trains a simple convnet on the MNIST dataset. Gets to 99.25% test accuracy after 12 epochs (there is still a lot of margin for parameter tuning). 16 seconds per epoch on a GRID K520 GPU. ''' from __future__ import print_function import keras from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten from keras.layers import Conv2D, MaxPooling2D from keras import backend as K batch_size = 128 num_classes = 10 epochs = 12 # input image dimensions img_rows, img_cols = 28, 28 # the data, split between train and test sets (x_train, y_train), (x_test, y_test) = mnist.load_data() if K.image_data_format() == 'channels_first': x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) input_shape = (1, img_rows, img_cols) else: x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) input_shape = (img_rows, img_cols, 1) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 print('x_train shape:', x_train.shape) print(x_train.shape[0], 'train samples') print(x_test.shape[0], 'test samples') # convert class vectors to binary class matrices y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) model = Sequential() model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape)) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(num_classes, activation='softmax')) model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy']) model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, y_test)) score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1])
  • モデルの保存

一旦作成したモデルを保存してみました。こちらも正常にできました

# save model json_string = model.to_json() open('tutorial_mnist.json', 'w').write(json_string) model.save_weights('tutorial_mnist.h5')
  • モデルをロードして、用意した画像の分析結果を得る

画像はkaggleのDatasetより拝借。https://www.kaggle.com/scolianni/mnistasjpgのtestSample.zipからimg_1.jpgを利用して、predictを実行してみましたが、エラーが発生

import keras from keras.datasets import mnist from keras.models import model_from_json from keras.utils import np_utils from keras.preprocessing import image from PIL import Image import matplotlib.pyplot as plt import numpy # modelのload model = model_from_json(open('tutorial_mnist.json').read()) model.load_weights('tutorial_mnist.h5') model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy']) # predict filepath = "/Users/atg/work/python/tensorflow/jupyter/mnist_test_data/img_1.jpg" img = Image.open(filepath).convert('RGB') ## Gray->L, RGB->RGB img = img.resize((28, 28)) x = numpy.array(img, dtype=numpy.float32) x = x / 255. x = x[None, ...] pred = model.predict(x, batch_size=1, verbose=0) score = numpy.max(pred) pred_label = np.argmax(pred) print("pred", pred) print("score", score) print("pred_label", pred_label)
  • 発生したエラー
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-24-b0c45db13636> in <module>() 23 x = x[None, ...] 24 ---> 25 pred = model.predict(x, batch_size=1, verbose=0) 26 score = numpy.max(pred) 27 pred_label = np.argmax(pred) ~/work/python/tensorflow/lib/python3.6/site-packages/keras/engine/training.py in predict(self, x, batch_size, verbose, steps) 1150 'argument.') 1151 # Validate user data. -> 1152 x, _, _ = self._standardize_user_data(x) 1153 if self.stateful: 1154 if x[0].shape[0] > batch_size and x[0].shape[0] % batch_size != 0: ~/work/python/tensorflow/lib/python3.6/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size) 752 feed_input_shapes, 753 check_batch_axis=False, # Don't enforce the batch size. --> 754 exception_prefix='input') 755 756 if y is not None: ~/work/python/tensorflow/lib/python3.6/site-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix) 134 ': expected ' + names[i] + ' to have shape ' + 135 str(shape) + ' but got array with shape ' + --> 136 str(data_shape)) 137 return data 138 ValueError: Error when checking input: expected conv2d_1_input to have shape (28, 28, 1) but got array with shape (28, 28, 3)

期待している次元が違うというエラーということで、reshapeで次元数を変更してみました。

  • 変更したコード
import keras from keras.datasets import mnist from keras.models import model_from_json from keras.utils import np_utils from keras.preprocessing import image from PIL import Image import matplotlib.pyplot as plt import numpy # modelのload model = model_from_json(open('tutorial_mnist.json').read()) model.load_weights('tutorial_mnist.h5') model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy']) # predict filepath = "/Users/atg/work/python/tensorflow/jupyter/mnist_test_data/img_1.jpg" img = Image.open(filepath).convert('RGB') ## Gray->L, RGB->RGB img = img.resize((28, 28)) x = numpy.array(img, dtype=numpy.float32) x = x / 255. x = x[None, ...] x = numpy.reshape(x, [28,28,1]) pred = model.predict(x, batch_size=1, verbose=0) score = numpy.max(pred) pred_label = np.argmax(pred) print("pred", pred) print("score", score) print("pred_label", pred_label)
  • エラー
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-29-200996341dd9> in <module>() 22 x = x / 255. 23 x = x[None, ...] ---> 24 x = numpy.reshape(x, [28,28,1]) 25 26 pred = model.predict(x, batch_size=1, verbose=0) ~/work/python/tensorflow/lib/python3.6/site-packages/numpy/core/fromnumeric.py in reshape(a, newshape, order) 255 [5, 6]]) 256 """ --> 257 return _wrapfunc(a, 'reshape', newshape, order=order) 258 259 ~/work/python/tensorflow/lib/python3.6/site-packages/numpy/core/fromnumeric.py in _wrapfunc(obj, method, *args, **kwds) 50 def _wrapfunc(obj, method, *args, **kwds): 51 try: ---> 52 return getattr(obj, method)(*args, **kwds) 53 54 # An AttributeError occurs if the object does not have ValueError: cannot reshape array of size 2352 into shape (28,28,1)

今度はサイズでエラーが発生しましたが、そもそもpredictを行う前の画像の読み込みからモデルに適した形に変換する処理の考え方が間違っているのではと思い、teratailに質問を記載しました。

モデル作成まではQiitaや海外のフォーラムでも見かけるのですが、実際に作成したモデルで予測させる際は見るサイトで方法が変わり、かつサンプルコードを写経してもうまくいかず、だんだん何が正しい方法なのかがわからなくなってきました。
参考になるサイトや方法がありましたら、ご教授頂きたいです。

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

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

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

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

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

wakame

2018/06/08 06:39

> エラーが出てうまく進みませんでした。 エラーはどちらになりますか
iarik

2018/06/08 06:40

申し訳ございませんでした。修正致しました
guest

回答1

0

ベストアンサー

質問者さんが作られた予測モデルはMNIST(手書き数字0-9)を何が書かれているかを予測する画像分類モデルなんですね。
とするとこのモデルは以下のコードから入力に(28, 28, 1)の画像(width, height, channel)を入力としていますね。

python

1# input image dimensions 2img_rows, img_cols = 28, 28 3 4# the data, split between train and test sets 5(x_train, y_train), (x_test, y_test) = mnist.load_data() 6 7if K.image_data_format() == 'channels_first': 8 x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) 9 x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) 10 input_shape = (1, img_rows, img_cols) 11else: 12 x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) 13 x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) 14 input_shape = (img_rows, img_cols, 1) 15 16 17# 一部省略 18 19model = Sequential() 20 21# (28, 28, 1) or (1, 28, 28)の画像を入力層に入れる 22# channel first か channel lastによって変わる 23# 質問者さんの場合はchannel lastのようですね 24model.add(Conv2D(32, kernel_size=(3, 3), 25 activation='relu', 26 input_shape=input_shape))

予測時の画像の前処理のコードにコメントをつけてみました。

python

1# predict 2filepath = "/Users/atg/work/python/tensorflow/jupyter/mnist_test_data/img_1.jpg" 3 4# ここはRGBScaleではなくGrayScaleを選択しましょう 5# もともとMNISTはGrayScaleですね 6img = Image.open(filepath).convert('RGB') ## Gray->L, RGB->RGB 7x = numpy.array(img, dtype=numpy.float32) 8x = x / 255. 9x = x[None, ...] 10print(x.shape) 11# (1, 28, 28, 3) 12# RGBScaleで読み込んだためchannelが3になっていますね 13x = numpy.reshape(x, [28,28,1]) 14# 質問者さんが記述されたエラーコードはここでreshapeできずエラーを出しているみたいですね 15# ValueError: cannot reshape array of size 2352 into shape (28,28,1)

とりあえず上の指摘部分を直してみました。

python

1# 上記コード修正版 2# predict 3filepath = "/Users/atg/work/python/tensorflow/jupyter/mnist_test_data/img_1.jpg" 4img = Image.open(filepath).convert('L') ## Gray->L, RGB->RGB 5x = numpy.array(img, dtype=numpy.float32) 6x = x.reshape((28, 28, 1)) 7x = x / 255. 8x = x[None, ...] 9print(x.shape) 10# (1, 28, 28, 1)

投稿2018/06/08 07:19

編集2018/06/08 07:46
wakame

総合スコア1170

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

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

iarik

2018/06/08 07:40

wakameさん、早速の回答ありがとうございます。そもそもGrayScaleだったのですね、出だしから残念なミスを犯しておりました。頂いたコードを実行してエラー解消して正常に実行できました。 実際に実行した際は以下に修正して実行しております。 x = img.reshape((28, 28, 1))→x = x.reshape((28, 28, 1))
wakame

2018/06/08 07:46

失礼しました、掲載したコードも修正しておきました。
iarik

2018/06/08 07:52

1点質問なのですが、channels_firstとchannels_lastの使い分けが今ひとつわかっていないのですが。単にプログラム作成者の使いやすさで、channels_firstかchannels_lastの何方かで設定する程度の考えでしょうか?
wakame

2018/06/08 08:12

kerasの場合はhttps://keras.io/ja/backend/ keras.jsonのimage_data_formatにchannel_firstかchannel_lastかを記述することで一意のフォーマットに保つことができます。
wakame

2018/06/08 08:20

質問の回答としてはおそらく質問者さんの認識で正しいかと、データセットのフォーマットも一意に定まっていないせいかライブラリ側(Keras)がどちらも受け入れられる体制をとっている点からもそのように感じられます。
iarik

2018/06/08 08:31

wakameさん、参考情報ありがとうございます。大変勉強になります。今回、x = x.reshape((28, 28, 1))のように決め打ちで記述しておりましたが、両方のフォーマットに対応できるようにベストなのはif文で入力フォーマットを確認し、それに合わせてreshapeするほうが良さそうですね。 ありがとうございます。
wakame

2018/06/08 08:34

そちらのほうが丁寧ですね、恥ずかしながら私はkeras.jsonのimage_data_formatに記述されているフォーマットでのみ対応できるコードしか書いてないです、勉強になります。
mkgrei

2018/06/08 09:53

一般的なフォーマットの場合、shapeだけが問題ではなくて、軸の入れ替えも必要なので、汎化するのは難しいです。 あらかじめtensorflow/kerasを使うことが決まっているのであれば、channel_lastで揃えた方がいろいろと楽です。 channelの差が大きくモデルの計算速度を影響するのであれば、その差異を吸収するようにtensorflowの方が書き換わっていくのでユーザは意識する必要がありません。 計算速度がクリティカルのならpythonではお話にならないのでC++のAPIに移る必要があります。
wakame

2018/06/08 10:13

mkgreiさんコメントありがとうございます。なんというかシステム上しかたがないのですがコメントのほうが回答より有益な情報になっていきますね。
mkgrei

2018/06/08 12:37

最初の質問に対して回答は適切になされているケースが多いですが、技術者の性として派生した疑問を解決して行くうちにコメントの方が重要な話が展開されることがよくありますね。 私はいつもコメント欄もじっくり楽しみながら読んでいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問