🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Keras

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

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

Q&A

解決済

1回答

4225閲覧

kerasでaccuracy以外の精度指標を使いたい

---stax---

総合スコア148

Keras

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

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

0グッド

0クリップ

投稿2019/03/12 07:33

編集2019/03/12 07:39

kerasを用いて画像の2値分類を行っています。
jupyter notebookで開発しています。

モデルの評価指標としてaccuracyだけを見て良いモデルか評価するのは良くないと考え
ROC曲線、ROC AUCなどを取得できるようにしたいです。

kerasにはROC曲線、ROC AUCなどは標準でサポートされている評価指標に含まれていないので自分で作成する必要があるのですが何から手をつけてよいか分からず良き詰まっています。

自分なりに調べてみて以下のリンクを真似て記述してみたのですが
How to compute Receiving Operating Characteristic (ROC) and AUC in keras?
関数aucとroc_aucでは処理は行われるのですが結果が違っており、tensolflowなどの記述も含まれていて今の自分には理解ができないので使ったことのあるscikit-learnを使おうと考えたのですが上手く行きません。

コード内の
model.compile
部分で以下のエラーとなります。
compileは設定だけだと理解しているのですがエラーを見た感じは引数の不備かと思うのですが、まだ学習もさせていないので何が現状渡されようとしているのか分からず、関数auc, roc_aucに関してはなぜ問題ないのか分かりません。

自分の記述している内容はどこが間違っているでしょうか?
また、metricsの中でscikit-learnを使う場合はどのように記述すればよいでしょうか?
フレームワークの挙動もまだ理解できておらず初歩的な質問ですがアドバイス頂きたいです。

以下コードになります。
データのフォルダ分けなどの部分は省略させて頂いています。

python

1from keras import layers 2from keras import models 3from keras import optimizers 4 5model = models.Sequential() 6#layers.Conv2D(32, (3, 3)) 7#input_shape = CNNの入力テンソルが(image_height, image_width, image_channels)(バッチ次元を含まない)の形状 8model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(300, 300, 3))) 9model.add(layers.BatchNormalization()) 10model.add(layers.MaxPooling2D((2, 2))) 11 12model.add(layers.Conv2D(64, (3, 3), activation='relu')) 13model.add(layers.BatchNormalization()) 14model.add(layers.MaxPooling2D((2, 2))) 15 16model.add(layers.Conv2D(128, (3, 3), activation='relu')) 17model.add(layers.BatchNormalization()) 18model.add(layers.MaxPooling2D((2, 2))) 19 20model.add(layers.Conv2D(128, (3, 3), activation='relu')) 21model.add(layers.BatchNormalization()) 22model.add(layers.MaxPooling2D((2, 2))) 23 24model.add(layers.Conv2D(128, (3, 3), activation='relu')) 25model.add(layers.BatchNormalization()) 26model.add(layers.MaxPooling2D((2, 2))) 27 28model.add(layers.Flatten()) 29model.add(layers.Dense(512, activation='relu')) 30model.add(layers.BatchNormalization()) 31model.add(layers.Dense(1, activation='sigmoid')) 32 33import keras.backend as K 34from sklearn.metrics import roc_auc_score 35import tensorflow as tf 36from sklearn.metrics import precision_score 37from sklearn.metrics import roc_curve 38 39def auc(y_true, y_pred): 40 auc = tf.metrics.auc(y_true, y_pred)[1] 41 K.get_session().run(tf.local_variables_initializer()) 42 return auc 43 44def roc_auc(y_true, y_pred): 45 roc_auc = tf.py_func(roc_auc_score, (y_true, y_pred), tf.double) 46 return roc_auc 47 48def roc(y_true, y_pred): 49 fpr, tpr, thresholds = roc_curve(y_true, y_pred) 50 return fpr, tpr, thresholds 51 52 53model.compile(loss='binary_crossentropy', 54 optimizer=optimizers.RMSprop(lr=1e-4), 55 metrics=['acc', auc, roc_auc, roc]) 56 57from keras.callbacks import EarlyStopping, ModelCheckpoint, TensorBoard 58from keras.preprocessing.image import ImageDataGenerator 59 60fpath = r'C:\Users\python file\model\DA_BN\{epoch:02d}-{acc:.2f}-{loss:.2f}-{val_acc:.2f}-{val_loss:.2f}.hdf5' 61check_point = ModelCheckpoint(filepath = fpath, monitor='val_loss', verbose=0, save_best_only=True, mode='min', period=1) 62 63train_datagen = ImageDataGenerator( 64 rescale=1./255, 65 brightness_range=[0.4, 1.0], 66 channel_shift_range=3., 67) 68 69test_datagen = ImageDataGenerator(rescale=1./255) 70 71predict_datagen = ImageDataGenerator(rescale=1./255) 72 73train_generator = train_datagen.flow_from_directory( 74 train_dir, #ターゲットディレクトリ 75 target_size = (300, 300), #全ての画像サイズを150*150に変更 76 batch_size = 20, #バッチサイズ 77 class_mode = 'binary', #binary_crossentropyを使用するため2値のラベルが必要, 78 save_to_dir = r'C:\Users\python file\dataAugmentation_DA_BN', 79 save_prefix = 'generated', 80 save_format = 'png') 81 82validation_generator = test_datagen.flow_from_directory( 83 val_dir, 84 target_size = (300, 300), 85 batch_size = 20, 86 class_mode = 'binary') 87 88predict_generator = predict_datagen.flow_from_directory( 89 test_dir, 90 target_size = (300, 300), 91 batch_size = 20, 92 class_mode = 'binary') 93 94history = model.fit_generator(train_generator, 95 steps_per_epoch = 1, 96 epochs = 5, 97 validation_data = validation_generator, 98 validation_steps = 1, 99 callbacks=[check_point])

python

1--------------------------------------------------------------------------- 2ValueError Traceback (most recent call last) 3<ipython-input-38-b90f05e5f8e8> in <module>() 4 3 model.compile(loss='binary_crossentropy', 5 4 optimizer=optimizers.RMSprop(lr=1e-4), 6----> 5 metrics=['acc', auc, roc_auc, roc]) 7 8~\AppData\Local\Continuum\anaconda3\lib\site-packages\keras\engine\training.py in compile(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, weighted_metrics, target_tensors, **kwargs) 9 438 output_metrics = nested_metrics[i] 10 439 output_weighted_metrics = nested_weighted_metrics[i] 11--> 440 handle_metrics(output_metrics) 12 441 handle_metrics(output_weighted_metrics, weights=weights) 13 442 14 15~\AppData\Local\Continuum\anaconda3\lib\site-packages\keras\engine\training.py in handle_metrics(metrics, weights) 16 407 metric_result = weighted_metric_fn(y_true, y_pred, 17 408 weights=weights, 18--> 409 mask=masks[i]) 19 410 20 411 # Append to self.metrics_names, self.metric_tensors, 21 22~\AppData\Local\Continuum\anaconda3\lib\site-packages\keras\engine\training_utils.py in weighted(y_true, y_pred, weights, mask) 23 401 """ 24 402 # score_array has ndim >= 2 25--> 403 score_array = fn(y_true, y_pred) 26 404 if mask is not None: 27 405 # Cast the mask to floatX to avoid float64 upcasting in Theano 28 29<ipython-input-37-3b434b12b89b> in roc(y_true, y_pred) 30 41 31 42 def roc(y_true, y_pred): 32---> 43 fpr, tpr, thresholds = roc_curve(y_true, y_pred) 33 44 return fpr, tpr, thresholds 34 35~\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\metrics\ranking.py in roc_curve(y_true, y_score, pos_label, sample_weight, drop_intermediate) 36 532 """ 37 533 fps, tps, thresholds = _binary_clf_curve( 38--> 534 y_true, y_score, pos_label=pos_label, sample_weight=sample_weight) 39 535 40 536 # Attempt to drop thresholds corresponding to points in between and 41 42~\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\metrics\ranking.py in _binary_clf_curve(y_true, y_score, pos_label, sample_weight) 43 313 """ 44 314 # Check to make sure y_true is valid 45--> 315 y_type = type_of_target(y_true) 46 316 if not (y_type == "binary" or 47 317 (y_type == "multiclass" and pos_label is not None)): 48 49~\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\utils\multiclass.py in type_of_target(y) 50 242 if not valid: 51 243 raise ValueError('Expected array-like (array or non-string sequence), ' 52--> 244 'got %r' % y) 53 245 54 246 sparseseries = (y.__class__.__name__ == 'SparseSeries') 55 56ValueError: Expected array-like (array or non-string sequence), got <tf.Tensor 'dense_2_target_8:0' shape=(?, ?) dtype=float32>

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

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

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

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

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

tiitoi

2019/03/12 10:47

リンク先の前者は tensorflow を使わないやり方だと思いますが、なにか問題があったのでしょうか?
---stax---

2019/03/14 02:10 編集

質問ありがとうございます。 回答遅くなり大変申し訳ありません。 前者の方はTomという方の回答でしょうか(40の評価が付いているものです) かなり初歩的な部分なのですがリンク先の上記の方が回答されている内容にあります、 model.fit(X_train, y_train, validation_data=(X_test, y_test), callbacks=[roc_callback(training_data=(X_train, y_train),validation_data=(X_test, y_test))]) の部分に関して、引数に指定している訓練データや検証データの作成方法が分かりません・・・。 私のコードで訓練データや検証データはflow_from_directoryを使って作成しています。 flow_from_directoryの戻り値として、タプルの形式で各バッチにおける訓練データとラベルが返ってくると理解しています。(1バッチ10サンプルなら10個のデータとラベル) ジェネレータ型の状態からX_train, y_trainやvalidation_data=(X_test, y_test)の部分の引数に指定している部分にあるような訓練セット全体、検証データ全体をどのように作れば良いか分からなくて使用できませんでした。 ジェネレータ型のデータを例えば、X_train=train_generator[0][0]~train_generator[n][0]のようにバッチサイズ分を1つの変数に入れなおす必要があるのでしょうか? 分かりにくくてすいません・・・。
tiitoi

2019/03/14 08:46 編集

sklearn の関数は、numpy 配列を渡す必要がありますが、一方、自作した custom_func(y_true, y_pred) に渡ってくる y_true、y_pred は tf.Tensor 型なので、sklearn の関数は使用できません。 質問のエラーメッセージはそのことを言っています。 エポックごとではなく、学習が終わってから計算したらどうでしょうか https://www.dlology.com/blog/simple-guide-on-how-to-generate-roc-plot-for-keras-classifier/
tiitoi

2019/03/14 08:48

確かに Stackoverflow の方法だと flow_from_directory の場合はちょっとむずかしいですね。
---stax---

2019/03/14 13:21

回答ありがとうございます。 なるほど...tf.Tensorという型になっているのですね。 参考に貼っていただいたようにlossが小さいモデルをまずはスナップショットして、そのモデルに対してのROC AUCを出したほうが実現は可能な気がします。 これに関しても、私の質問文にあります変数predict_generator(テストデータ)は flow_from_directoryで作られたジェネレータ型なので戻り値であるタプルをデータとラベルに分割してnumpy配列に直す処理がないとscikit-learnの関数に渡せないという理解でよろしかったでしょうか? flow_from_directoryはラベルを付けてくれたりすごく便利なのですが理解していないとすごく難しいですね...。
tiitoi

2019/03/14 13:57

> flow_from_directoryで作られたジェネレータ型なので戻り値であるタプルをデータとラベルに分割してnumpy配列に直す処理がないとscikit-learnの関数に渡せないという理解でよろしかったでしょうか? 必要なのは、ジェネレータ型の戻り値のラベル (正解ラベル) と学習したモデルの推論結果 (予測ラベル) の2つですね。 この2つを numpy 配列として得られれば、あとは sklearn の関数にわたすことで各種評価指標の算出が行えます。
---stax---

2019/03/14 14:26

回答ありがとうございます。 勘違いしておりました。自分で予測したデータと正解ラベルですね。 数日間この部分で完全にストップしていたので明日は少し前進できそうです。 いつも丁寧に答えていただいて本当にありがとうございます。
guest

回答1

0

自己解決

以下の実装で対応
コードは抜粋

①各エポックでROC AUCを求める

python

1def roc_auc(y_true, y_pred): 2 roc_auc = tf.py_func(roc_auc_score, (y_true, y_pred), tf.double) 3 return roc_auc 4 5#上記関数をmetricsパラメータの中で指定する 6model.compile(loss='binary_crossentropy', 7 optimizer=optimizers.RMSprop(lr=1e-4), 8 metrics=['acc', roc_auc])

②各エポックで最も良かったモデルをスナップショットし、そのモデルに対して評価する
(各エポックで求めるのではなく、学習後のモデルで評価する)

python

1from keras.models import load_model 2from sklearn.metrics import roc_curve 3from sklearn.metrics import auc 4from sklearn.metrics import roc_auc_score 5import numpy as np 6import matplotlib.pyplot as plt 7 8#モデルの読み込み 9#①のようにmetricsに自作の関数を使う場合custom_objectsパラメータを指定しないと読み込めない 10model_test = load_model(r'C:\Users\python file\model\DA_BN\17-1.00-0.00-0.95-0.10.hdf5', custom_objects={'roc_auc':roc_auc}) 11 12score = model_test.evaluate_generator(predict_generator) 13print('loss={}, accuracy={}, ROC_AUC={}'.format(*score)) 14 15#テストデータジェネレータ 16predict_data = predict_generator[0] 17predicts = [] 18labels = [] 19 20for i in range(40): 21 input_data = predict_data[0][i] 22 input_data = input_data.reshape(1, *input_data.shape) 23 #predict = predict.reshape((1,) + predict.shape) 24 predicts.append(input_data) 25 26 labels.append(predict_data[1][i]) 27 28predicts = np.concatenate(predicts, axis=0) 29 30y_pred_keras = model_test.predict(predicts).ravel() 31print('予測結果:', y_pred_keras) 32 33fpr_keras, tpr_keras, thresholds_keras = roc_curve(labels, y_pred_keras, drop_intermediate=False) 34print('閾値:', thresholds_keras) 35 36auc_keras = auc(fpr_keras, tpr_keras) 37print('aucスコア:', auc_keras) 38 39print(fpr_keras, tpr_keras) 40

投稿2019/03/19 02:55

---stax---

総合スコア148

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問