TensorflowバックエンドでKerasを使用して、マルチクラス分類問題(4クラス)のモデルを開発しています。 y_test
の値は2D形式です。
0 1 0 0
0 0 1 0
0 0 1 0
これは、バランスの取れた精度を計算するために使用する関数です。
def my_metric(targ, predict):
val_predict = predict
val_targ = tf.math.argmax(targ, axis=1)
return metrics.balanced_accuracy_score(val_targ, val_predict)
そしてこれがモデルです:
hidden_neurons = 50
timestamps = 20
nb_features = 18
model = Sequential()
model.add(LSTM(
units=hidden_neurons,
return_sequences=True,
input_shape=(timestamps,nb_features),
dropout=0.15
#recurrent_dropout=0.2
)
)
model.add(TimeDistributed(Dense(units=round(timestamps/2),activation='sigmoid')))
model.add(Dense(units=hidden_neurons,
activation='sigmoid'))
model.add(Flatten())
model.add(Dense(units=nb_classes,
activation='softmax'))
model.compile(loss="categorical_crossentropy",
metrics = [my_metric],
optimizer='adadelta')
このコードを実行すると、次のエラーが発生します。
-------------------------------------------------- ------------------------- TypeErrorトレースバック(最新の呼び出しが最後)()30 model.compile(loss = "categorical_crossentropy"、31メトリック= [my_metric]、# 'accuracy'、---> 32 optimizer = 'adadelta')
〜/ anaconda3/lib/python3.6/site-packages/keras/engine/training.py in compile(self、optimizer、loss、metrics、loss_weights、sample_weight_mode、weighted_metrics、target_tensors、** kwargs)449 output_metrics = nested_metrics [i ] 450 output_weighted_metrics = nested_weighted_metrics [i]-> 451 handle_metrics(output_metrics)452 handle_metrics(output_weighted_metrics、weights = weights)453
〜/ anaconda3/lib/python3.6/site-packages/keras/engine/training.py in handle_metrics(metrics、weights)418 metric_result = weighted_metric_fn(y_true、y_pred、419 weights = weights、-> 420 mask = masks [ i])421 422#self.metrics_names、self.metric_tensorsに追加、
〜/ anaconda3/lib/python3.6/site-packages/keras/engine/training_utils.py in weighted(y_true、y_pred、weights、mask)402 "" "403#score_array has ndim> = 2-> 404 score_array = fn(y_true、y_pred)405マスクがNoneでない場合:406#Theanoでfloat64アップキャストを回避するためにマスクをfloatXにキャストします
in my_metric(targ、predict)22 val_predict = predict 23 val_targ = tf.math.argmax(targ、axis = 1)---> 24 return metrics.balanced_accuracy_score(val_targ、val_predict)25 #return 5 26
〜/ anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py in balance_accuracy_score(y_true、y_pred、sample_weight、Adjusted)
1431 1432 "" "-> 1433 C = confusion_matrix(y_true、y_pred、sample_weight = sample_weight)1434 with np.errstate(divide = 'ignore'、invalid = 'ignore'):1435
per_class = np.diag(C)/ C.sum(axis = 1)〜/ anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py in confusion_matrix(y_true、y_pred、labels、sample_weight)251 252 "" "-> 253 y_type、y_true、y_pred = _check_targets(y_true 、y_pred)254 if y_type not in( "binary"、 "multiclass"):255 raise ValueError( "%s is not supported"%y_type)
〜/ anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py in _check_targets(y_true、y_pred)69 y_pred:array or indicator matrix 70 "" "---> 71 check_consistent_length(y_true、y_pred) 72 type_true = type_of_target(y_true)73 type_pred = type_of_target(y_pred)
〜/ anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in check_consistent_length(* arrays)229 "" "230-> 231 lengths = [_num_samples(X)for X in array in X if Xなし] 232一意= np.unique(長さ)233 len(一意)> 1の場合:
〜/ anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in(.0)229 "" "230-> 231 lengths = [_num_samples(X)for X in array in X is not ifなし] 232 uniques = np.unique(lengths)233 len(uniques)> 1の場合:
〜/ anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in _num_samples(x)146 return x.shape [0] 147 else:-> 148 return len(x)149 else:150 len(x)を返す
TypeError:タイプ「Tensor」のオブジェクトにはlen()がありません
Kerasテンソルでsklearn関数を呼び出すことはできません。 Kerasのバックエンド関数、またはTFバックエンドを使用している場合はTensorFlow関数を使用して、機能を自分で実装する必要があります。
balanced_accuracy_score
が定義されている リコールの平均として 各列で取得されます。精度と再現率の実装について このリンク を確認してください。 balanced_accuracy_score
、次のように実装できます。
import keras.backend as K
def balanced_recall(y_true, y_pred):
"""
Computes the average per-column recall metric
for a multi-class classification problem
"""
true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)), axis=0)
possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)), axis=0)
recall = true_positives / (possible_positives + K.epsilon())
balanced_recall = K.mean(recall)
return balanced_recall