web-dev-qa-db-ja.com

TypeError:Tensorflowでカスタム指標を使用すると、タイプ「Tensor」のオブジェクトにlen()がありません

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()がありません

3
ScalaBoy

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
6
sdcbr