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

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

ただいまの
回答率

88.90%

CNNで予測されたラベルを棒グラフで可視化したい [画像分類]

解決済

回答 1

投稿 編集

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

sssan

score 8

前提・実現したいこと

3種類のラベル(画像A, B, C)に判別できる画像群の画像分類モデルをkerasにて構築し、予測モデル(ImageClassifier.h5)を保存しました。
この予測モデルをload_modelで読み込み、あるフォルダ(フォルダ名:predict)の中にある画像150枚すべての判別を実行しようとしています。
その際に各ラベルの画像が何枚フォルダ中に存在したか下記のような棒グラフで可視化したいと考えています。
for文の中で予測したそれぞれの画像のラベル数を集計し、seabornのcounterplot等を使って棒グラフが作成できればと思っていますが、下記コードから進むことができません。
イメージ説明

現在のコード

#ライブラリのインポート
import os
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import keras.models
from keras.models import Model
from keras.models import load_model
from keras.preprocessing.image import img_to_array, load_img

input_image_size     = 224
labels               = ['A','B','C']
model                = load_model('ImageClassifier.h5')

#パスの設定
program_path         = Path(__file__).parent.resolve()
parent_path          = program_path.parent.resolve()
data_path            = parent_path / 'data'
data_processed_path  = data_path / 'processed'
predict_dir          = os.path.join(data_processed_path, 'predict')

#予想する画像が入ったファイル
files                = os.listdir(predict_dir)
n_files              = len(files)

#モデルを使った予測
for i in range(n_files):
    predict_img_path     = os.path.join(predict_dir, files[i])
    predict_img_name     = os.path.basename(predict_img_path)
    predict_img_onlyname = os.path.splitext(predict_img_name)[0]
    temp_img             = load_img(predict_img_path,target_size=(input_image_size,input_image_size))

    #Images normalization
    temp_img_array       = img_to_array(temp_img)
    temp_img_array       = temp_img_array.astype('float32')/255.0
    temp_img_array       = temp_img_array.reshape((1,input_image_size,input_image_size,3))
    #predict results
    img_pred             = model.predict(temp_img_array)
    label_pred           = labels[np.argmax(img_pred)]

    print('画像名:' + predict_img_onlyname + ', 予想ラベル名:' + label_pred +':' + str(round(max(img_pred[0]),2)))

    print(label_pred.count('A'))
    print(label_pred.count('B'))
    print(label_pred.count('C'))

現在の状況

上記コードでフォルダ内の各画像の予測ができていることは確認済みです。
またlabel_pred.countで各ラベルの数も抽出できていると思いますが、
for文で繰り返した全ての画像に対して数を集計しプロットするやり方が思いつきません。

ご助言の程よろしくお願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

以下のようにcollections.Counterを使うと簡潔にグラフのもとになるデータを集計できます。
後は好きに加工して描画すればよいです。イメージ説明

import random
import collections
import matplotlib.pyplot as plt

labels = ['A','B','C']
n_files = 50

random.seed(110)
preds = []
for i in range(n_files):
    # 略
    label_pred = labels[random.randint(0,2)] # ダミー処理
    preds.append(label_pred)

c = collections.Counter(preds)
c = sorted(c.items())
X = [e[0] for e in c]
Y = [e[1] for e in c]

plt.bar(X, Y)
plt.show()

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/20 22:35

    早速ご回答頂きありがとうございます。
    collections.Counterを使うと可能とのことで助かりました。
    まだ最近始めたばかりなので初歩的な質問かもしれず恐縮ですが、
    ・random.seed()で110と設定した理由
    ・ダミー処理を行う理由
    をご教授頂けると助かります。よろしくお願い致します。

    キャンセル

  • 2020/07/20 22:38

    > random.seed()で110と設定した理由
    つねに同じ結果が出るように。

    >・ダミー処理を行う理由
    質問文のコードは第三者はデータなく実行できないので。

    キャンセル

  • 2020/07/20 23:02

    ご教授頂きありがとうございます。
    無事解決しました。

    キャンセル

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

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

関連した質問

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