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

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

ただいまの
回答率

91.03%

  • HTML

    7519questions

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

  • Python 3.x

    4078questions

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

  • TensorFlow

    487questions

  • Keras

    117questions

深層学習を行うプログラムでのエラー

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 277

mizu4423

score 2

前提・実現したいこと

深層学習で動物の画像を種類ごとに分類するプログラムをPythonで書いています。「Pythonによるスクレイピング&機械学習」という本のp353を参考に、コマンドラインから入力データを送り、それがどの種類に分類されるか判定するプログラムを作成しましたが、分類を行いません。

発生している問題・エラーメッセージ

訓練したモデルは判別率9割ほどにも関わらず、どの画像を与えても、分類するカテゴリーの一番最初の物にしかならない。(for文が回ってない?)

実行結果
$ python3 getboar-checker.py sample.JPG STC_0232.JPG STC_0280.JPG STC_0141.JPG STC_1442.JPG
Using TensorFlow backend.

  • 入力: sample.JPG
    | 動物: nothing
    | 状態: 0
  • 入力: STC_0232.JPG
    | 動物: nothing
    | 状態: 0
  • 入力: STC_0280.JPG
    | 動物: nothing
    | 状態: 0
  • 入力: STC_0141.JPG
    | 動物: nothing
    | 状態: 0
  • 入力: STC_1442.JPG
    | 動物: nothing
    | 状態: 0

該当のソースコード

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 = ["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/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
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配列に変換し、チューニングするプログラム(getboar-makedata2.py)

from PIL import Image
import os, glob
import numpy as np
import random, math

root_dir = "./image/"
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/hogetboar.npy", xy)
print("ok,", len(y_train))


Python (2)CNNで学習させるプログラム(getboar-keras2.py)

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 = ["nothing", "boar2", "others"]
nb_classes = len(categories)
image_size = 50

# データ読み込み
def main():
    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), 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), padding='same'))
    model.add(Activation('relu'))
    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 = '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, epochs=30)
    #モデル保存
    hdf5_file = "./image/hogetboar-model.hdf5"
    model.save_weights(hdf5_file)
    return model

#モデル評価
def model_eval(model, X, y):
    score = model.evaluate(X, y)
    print('loss=', score[0])
    print('accuracy=', score[1])

if __name__ == "__main__":
    main()
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • quiqui

    2017/09/05 07:04

    せめてエラーやコードは読めるようにしてください。 https://teratail.com/help/question-tips#questionTips3-5-1 インストールしているあとはKerasのバージョンが要りそうに思いますが。

    キャンセル

  • mizu4423

    2017/09/05 14:18

    一応、今回の警告はkerasのバージョンアップによるもので、無視してもプログラムは問題なく動くとのことだったので、放置してました。ただ、quiquiさんの仰ることも尤もだと思いますので、結果は変わりませんでしたが、色々直しました。ご指摘ありがとうございます。

    キャンセル

回答 1

0

CNNの学習で、損失関数を'binary_crossentropy'ではなく'categorical_crossentropy'に変えてみてはどうでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/05 14:15

    変えてみましたが、同じでした。
    ご回答ありがとうございます。

    キャンセル

  • 2017/09/05 14:30

    同じというのは、訓練しなおしても同じ判別率になったということでしょうか?

    キャンセル

  • 2017/09/05 14:49

    いえ、同じというのは上記のプログラムを実行し、コマンドラインから画像を与えても、修正前と同じように分類が行われなかったという点です。どの画像を何枚与えようが、全て、categories("nothing", "others", "boar2")のnothingになってしまいます。
    また、binary_crossentropyからcategorical_crossentropyに変更すると判別率が67%から25%という変化が見られました。修正後のソースコードをあげたので何か間違ってたら仰ってください。

    キャンセル

  • 2017/09/05 16:15

    訓練時はデータを256で割って正規化しているのに、入力画像を予測するときはそのまま入力としているように見えます。X = np.array(X)の後にX = X.astype("float") / 256 を追加してみてはどうでしょうか?

    キャンセル

  • 2017/09/05 17:01

    ご回答ありがとうございます。
    追加してみましたが、解決しませんでした。
    結果は修正前と同じです。

    キャンセル

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

  • ただいまの回答率 91.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    Kerasを用いたCNN3によるcifar10の画像認識

    Keras初心者です。 CNNを理解するためにKerasでモデルを作り、cifar10のデータを元にモデルの認識精度を出力しようとしています。 以下のプログラムに対するエラーの

  • 解決済

    python(2系と3系の違い?) biteとstr型に関するエラー(テキストファイル読み込み時) ...

    前提・実現したいこと ここに質問したいことを詳細に書いてください alice_in_wonderland.txtというテキストファイルを用いてword2vecを試したいのですが エ

  • 解決済

    Kerasで訓練データにIDがある場合のベストプラクティスについて

    前提・実現したいこと 一般的なcsvデータをKerasに食わせて他クラス分類を行おうと思っているのですが、 訓練データに含まれるID系のデータの扱いについて困っております。 ID系

  • 解決済

    画像認識課題での入力画像のサイズ変更

    ディープラーニングで、自分のモデルが200×200のサイズを入力として想定していて、それに対して190×200とか色々なサイズの画像を入力する場合は、直前にリサイズ(例えば、Ker

  • 解決済

    tensorflow+kerasでの分類

    前提・実現したいこと data/testのフォルダの中に三つのフォルダがあり、それぞれアウター、パンツ、シャツの画像を入れています。 この三つの種類の画像自体を一つのフォルダにまと

  • 解決済

    kerasのデータセットを用いた時のcifar100のラベルについて

    前提・実現したいこと cifar100を使用した際のラベルが定義されている場所が知りたい。 発生している問題・エラーメッセージ kerasを用いて画像分類を試しているのですが、

  • 解決済

    データセットの作り方がわからない

     前提・実現したいこと 「ゼロから作るディープラーニング」を読み終えた学生です。 せっかくディープラーニングをかじり始めたため、自分に役に立つことをディープラーニングを利用してやっ

  • 解決済

    CNNの比較、改善点

     知りたいこと cyfer10に使用したCNNでなぜこのような差が出たのか、してはいけないことが含まれていたのか。 aidemyに使われていたCNNと層よりも、より層を増やして適当

同じタグがついた質問を見る

  • HTML

    7519questions

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

  • Python 3.x

    4078questions

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

  • TensorFlow

    487questions

  • Keras

    117questions