質問編集履歴

1 記法を最新のKerasに合わせ、警告がなくなるように修正し、少し見やすくしました。

mizu4423

mizu4423 score 10

2017/09/05 14:38  投稿

深層学習を行うプログラムでのエラー
###前提・実現したいこと
深層学習で動物の画像を種類ごとに分類するプログラムをPythonで書いています。「Pythonによるスクレイピング&機械学習」という本のp353を参考に、コマンドラインから入力データを送り、それがどの種類に分類されるか判定するプログラムを作成しましたが、分類を行いません。
###発生している問題・エラーメッセージ
訓練したモデルは判別率9割ほどにも関わらず、どの画像を与えても、分類するカテゴリーの一番最初の物にしかならない。(for文が回ってない?)
実行結果
$ python3 getboar-checker.py sample.JPG STC_0232.JPG STC_0280.JPG STC_0141.JPG STC_1442.JPG STC_0253.JPG STC_0278.JPG STC_5392.JPG STC_0929.
JPG
$ python3 getboar-checker.py sample.JPG STC_0232.JPG STC_0280.JPG STC_0141.JPG STC_1442.JPG
Using TensorFlow backend.
/Users/nakagawa/Documents/pyprogram/getboar_keras2.py:27: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(32, (3, 3), input_shape=(50, 50, 3...  
, padding="same")`  
  model.add(Conv2D(32, 3, 3, border_mode='same', input_shape=in_shape))  
/Users/nakagawa/Documents/pyprogram/getboar_keras2.py:31: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (3, 3), padding="same")`  
  model.add(Conv2D(64, 3, 3, border_mode='same'))  
/Users/nakagawa/Documents/pyprogram/getboar_keras2.py:33: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (3, 3))`  
  model.add(Conv2D(64, 3, 3))  
+ 入力: sample.JPG
| 動物: boar2
| 動物: nothing
| 状態: 0
+ 入力: STC_0232.JPG
| 動物: boar2
| 動物: nothing
| 状態: 0
+ 入力: STC_0280.JPG
| 動物: boar2
| 動物: nothing
| 状態: 0
+ 入力: STC_0141.JPG
| 動物: boar2
| 動物: nothing
| 状態: 0
+ 入力: STC_1442.JPG
| 動物: boar2
| 状態: 0
+ 入力: STC_0253.JPG
| 動物: boar2
| 状態: 0
+ 入力: STC_0278.JPG
| 動物: boar2
| 状態: 0
+ 入力: STC_5392.JPG
| 動物: boar2
| 状態: 0
+ 入力: STC_0929.JPG
| 動物: boar2
| 動物: nothing
| 状態: 0
###該当のソースコード
 
```Python 3.x
import getboar_keras2 as getboar
import sys, os
import codecs
from PIL import Image
import numpy as np
#ファイル名が入っているかどうかを確認
if len(sys.argv) <= 1:
   print("getboar-checker.py (ファイル名)")
   quit()
#入力画像をNumpy配列にする
image_size = 50
categories = ["boar2", "others", "normal"]
categories = ["nothing", "others", "boar2"]
state = [0, 1, 2]
X = []
files = []
for fname in sys.argv[1:]:
   img = Image.open(fname)
   img = img.convert("RGB")
   img = img.resize((image_size, image_size))
   in_data = np.asarray(img)
   X.append(in_data)
   files.append(fname)
X = np.array(X)
#CNNのモデルを構築
model = getboar.build_model(X.shape[1:])
model.load_weights("./image/getboar2-model.hdf5")
model.load_weights("./image/hogetboar-model.hdf5")
#データを予測
html = ""
pre = model.predict(X)
for i, p in enumerate(pre):
   y = p.argmax()
   print("+ 入力:", files[i])
   print("| 動物:", categories[y])
   print("| 状態:", state[y])
   html += """
       <h3>入力:{0}</h3>
       <div>
         <p><img src="{1}" width=300></p>
         <p>動物 :{2}</p>
         <p>状態 :{3}</p>
       </div>
   """.format(os.path.basename(files[i]),
        files[i],
        categories[y],
        state[y])
#レポートを保存
html = "<html><body style='text-align:center;'>" + \
   "<style> p { margin:0; padding:0; } </style>" + \
   html + "</body></html>"
with codecs.open("getboar-result.html", "w", "shift_jis") as f:
   f.write(html)
```
###試したこと
参考書のサンプルコードを自分の使っているデータセットを使った場合でやってみたが、結果は変わらなかったため、サンプルコードが間違っている可能性も考えられる。
画像データを減らしてやってみたが、効果なし。
binary_crossentropyをcategorical_crossentropyにしたが、効果なし。  
###補足情報(言語/FW/ツール等のバージョンなど)
Python3.6.1を使用。
Python3.6.1
tensorflow (1.3.0)
tensorflow-tensorboard (0.1.5)
Keras (2.0.8)
numpy (1.13.1)
参考書のサンプルコードなど(ch07に入ってます)
http://www.socym.co.jp/download/1079/src.zip
また、以下の2つのプログラムによって、Numpyのデータ生成と、訓練を行った。
(1)データをNumpy配列に変換し、チューニングするプログラム
(1)データをNumpy配列に変換し、チューニングするプログラム(getboar-makedata2.py)
```Python 3.x
from PIL import Image
import os, glob
import numpy as np
import random, math
root_dir = "./image/"
categories = ["normal", "boar2", "others"]
categories = ["nothing", "boar2", "others"]
nb_classes = len(categories)
image_size = 50
X = []
Y = []
def add_sample(cat, fname, is_train):
   img = Image.open(fname)
   img = img.convert("RGB") #カラーモードの変更
   img = img.resize((image_size, image_size)) #画像サイズの変更
   data = np.asarray(img)
   X.append(data)
   Y.append(cat)
   if not is_train: return
   for ang in range(-20, 20, 5):
       img2 = img.rotate(ang)
       data = np.asarray(img2)
       X.append(data)
       Y.append(cat)
       img2 = img2.transpose(Image.FLIP_LEFT_RIGHT)
       data = np.asarray(img2)
       X.append(data)
       Y.append(cat)
def make_sample(files, is_train):
   global X, Y
   X = []; Y = []
   for cat, fname in files:
       add_sample(cat, fname, is_train)
   return np.array(X), np.array(Y)
allfiles = []
for idx, cat in enumerate(categories):
   image_dir = root_dir + "/" + cat
   files = glob.glob(image_dir + "/*.JPG")
   for f in files:
       allfiles.append((idx, f))
random.shuffle(allfiles)
th = math.floor(len(allfiles) * 0.6)
train = allfiles[0:th]
test = allfiles[th:]
X_train, y_train = make_sample(train, True)
X_test, y_test = make_sample(test, False)
xy = (X_train, X_test, y_train, y_test)
np.save("./image/getboar2.npy", xy)
np.save("./image/hogetboar.npy", xy)
print("ok,", len(y_train))
(2)CNNで学習させるプログラム
```
Python (2)CNNで学習させるプログラム(getboar-keras2.py)
```Python 3.x
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.utils import np_utils
import numpy as np
root_dir = "./image/"
categories = ["boar2", "others", "normal"]
categories = ["nothing", "boar2", "others"]
nb_classes = len(categories)
image_size = 50
# データ読み込み  
def main():
   X_train, X_test, y_train, y_test = np.load("./image/getboar2.npy")
   X_train, X_test, y_train, y_test = np.load("./image/hogetboar.npy")
   #データを正規化
   X_train = X_train.astype("float") / 256
   X_test = X_test.astype("float") / 256
   y_train = np_utils.to_categorical(y_train, nb_classes)
   y_test = np_utils.to_categorical(y_test, nb_classes)
   #モデルを訓練 & 評価  
   model = model_train(X_train, y_train)
   model_eval(model, X_test, y_test)
#モデル構築  
def build_model(in_shape):
   model = Sequential()
   model.add(Conv2D(32, 3, 3, border_mode='same', input_shape=in_shape))
   model.add(Conv2D(32, (3, 3), padding='same', input_shape=in_shape))
   model.add(Activation('relu'))
   model.add(MaxPooling2D(pool_size=(2, 2)))
   model.add(Dropout(0.25))
   model.add(Conv2D(64, 3, 3, border_mode='same'))
   model.add(Conv2D(64, (3, 3), padding='same'))
   model.add(Activation('relu'))
   model.add(Conv2D(64, 3, 3))
   model.add(Conv2D(64, (3, 3)))
   model.add(MaxPooling2D(pool_size=(2, 2)))
   model.add(Dropout(0.25))
   model.add(Flatten())
   model.add(Dense(512))
   model.add(Activation('relu'))
   model.add(Dropout(0.5))
   model.add(Dense(nb_classes))
   model.add(Activation('softmax'))
   model.compile(loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics=['accuracy'])
   model.compile(loss = 'categorical_crossentropy', optimizer = 'rmsprop', metrics=['accuracy'])
   return model
# 訓練  
def model_train(X, y):
   model = build_model(X.shape[1:])
   model.fit(X, y, batch_size=32, nb_epoch=30)
   hdf5_file = "./image/getboar2-model.hdf5"
   model.fit(X, y, batch_size=32, epochs=30)
   #モデル保存
   hdf5_file = "./image/hogetboar-model.hdf5"
   model.save_weights(hdf5_file)
   return model
   def model_eval(model, X, y):
#モデル評価
def model_eval(model, X, y):
   score = model.evaluate(X, y)
   print('loss=', score[0])
   print('accuracy=', score[1])
if __name__ == "__main__":
   main()
   main()
```
  • HTML

    17691 questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • Python 3.x

    15410 questions

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

  • Keras

    1019 questions

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

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る