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

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

ただいまの
回答率

91.05%

tensorflow+kerasでの分類

解決済

回答 1

投稿

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

fica

score 4

前提・実現したいこと

data/testのフォルダの中に三つのフォルダがあり、それぞれアウター、パンツ、シャツの画像を入れています。
この三つの種類の画像自体を一つのフォルダにまとめて、分類するにはどうすればいいですか?

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

エラーメッセージ

該当のソースコード

from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout, Convolution2D, Flatten, MaxPooling2D
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 = []

for dir in os.listdir("data/train"):
if dir == ".DS_Store":
continue

dir1 = "data/train/" + dir 
label = 0

if dir == "outerwear":
label = 0
elif dir == "pants":
label = 1
elif dir == "shirt":
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((100, 100)))
print(filepath)

image = image.transpose(2, 0, 1)
print(image.shape)

image_list.append(image / 255.)

image_list = np.array(image_list)

Y = to_categorical(label_list)

model = Sequential()
model.add(Convolution2D(32, 3, 3, border_mode='same', input_shape=(3, 100, 100)))
model.add(Activation("relu"))
model.add(Convolution2D(32, 3, 3))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2), border_mode=("same")))
model.add(Dropout(0.25))

model.add(Flatten())

model.add(Dense(200))
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"))

opt = Adam(lr=0.0001)

model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])

model.fit(image_list, Y, nb_epoch=100, batch_size=25, validation_split=0.1)

total = 0.
ok_count = 0.

for dir in os.listdir("data/test"):
if dir == ".DS_Store":
continue

dir1 = "data/test/" + dir 
label = 0

if dir == "outerwear":
label = 0
elif dir == "pants":
label = 1
elif dir == "shirt":
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((100, 100)))
print(filepath)
image = image.transpose(2, 0, 1)
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, "%")

試したこと

課題に対してアプローチしたことを記載してください

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

何のために3つのディレクトリに分けているかを考えれば、ほかのやり方がいろいろあることに気が付くと思います。分けている理由は正解かどうかを自動判定するためにあらかじめディレクトリ名に正解を指定してあるわけです。

してみれば、別にディレクトリでなくても、以下のようなテキストファイルに画像ファイル名とラベルの組の一覧であってもいいわけです。

aaaa.png,1
bbbb.png,2
cdef.png,0
xyz.png,2

また、もっと単純に、data/testの中に、outerwear,pants,shirtで始まるファイルがたくさん入っていることにしてもかまいません。例えば、pants-0153.pngようなものです。これを前提にすれば、後半の2重ループは、以下のような単ループになることがわかるでしょう。

total = 0.
ok_count = 0.
dir = "data/test"
for file in os.listdir(dir):
    if file != ".DS_Store":
        if file.startswith("outerwear"):
            label = 0
        elif file.startswith("pants"):
            label = 1
        elif file.startswith("shirt"): 
            label = 2 
        filepath = dir + "/" + file
        image = np.array(Image.open(filepath).resize((100, 100)))
        print(filepath)
        image = image.transpose(2, 0, 1)
        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, "%")

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/01/10 20:34

    詳しく解説していただいでありがとうございました。
    一つ質問なんですが最後に正解率が表示されていたのですが、書いていただいたソースに変えたところ
    0%になってしまいました。こちらの表示を正確に出すことはできなくなってしまったのでしょうか?

    キャンセル

  • 2018/01/10 20:43

    コードは回答のために暫定的に抜粋加工したものですので、動作確認はしていません。
    ちなみに比較の結果はどのようになっていますか。
    totalとok_countをprint()して、状況を確認されてはいかがですか。

    キャンセル

  • 2018/01/10 20:46

    おそらくこのコードの前に以下の2行を入れていないためでしょう。
    total = 0.
    ok_count = 0.

    キャンセル

  • 2018/01/10 22:14

    ファイル名が正しくないせいでラベルが拾えなくて
    if label == result[0]
    が常に偽であるためではないでしょうか?

    totalが足されてないと0割りエラーになるかと。

    キャンセル

  • 2018/01/11 13:28

    大変よく理解することができました。お二人ともありがとうございました。

    キャンセル

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

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

関連した質問

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