代码之家  ›  专栏  ›  技术社区  ›  ScalaBoy

类型错误:“tensor”类型的对象在tensorflow中使用自定义度量时没有len()。

  •  0
  • ScalaBoy  · 技术社区  · 5 年前

    我正在开发一个使用带有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')
    

    当我运行此代码时,我得到以下错误:

    —————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 最后)() 30 model.compile(loss=“分类交叉熵”, 31个指标=我的“指标”,“准确度”, --->32优化器='adadelta')

    ~/anaconda3/lib/python3.6/site-packages/keras/engine/training.py输入 编译(self、优化器、loss、metrics、loss-weights, 样本权重模式,加权度量,目标张量,**kwargs) 449 output_metrics=嵌套_metrics[i] 450输出加权度量=嵌套加权度量[I] -->451处理度量(输出度量) 452处理_度量(输出_加权_度量,权重=权重) 四百五十三

    ~/anaconda3/lib/python3.6/site-packages/keras/engine/training.py输入 处理度量(度量、权重) 418 metric_result=加权_metric_fn(y_true,y_pred, 419重量=重量, -->420掩模=掩模[i]) 四百二十一 422附加到self.metrics名称,self.metric张量,

    ~/anaconda3/lib/python3.6/site-packages/keras/engine/training-utils.py 加权(Y_真,Y_pred,权重,遮罩) 402“” 403 score_数组的ndim>=2 -->404分数_数组=fn(y_真,y_pred) 405如果面具不是无: 406将遮罩铸造到floatx,以避免float64向上铸造到ano中。

    在我的度量中(targ,predict) 22 Val_Predict=预测 23 val_targ=tf.math.argmax(targ,轴=1) --->24返回指标。平衡的“准确度”分数(Val_Targ,Val_Predict) 25返回5 二十六

    ~/anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py 平衡精度分数(Y_真,Y_pred,样本重量,调整)
    1431 1432”“” ->1433 c=混淆矩阵(y_true,y_pred,sample_weight=sample_weight)1434 np.errstate(divide='ignore',invalid='ignore'):1435
    每级=np.diag(c)/c.sum(轴=1)

    ~/anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py 混乱中的矩阵(Y_真,Y_pred,标签,样品重量) 二百五十一 252“” -->253 Y_类型,Y_真,Y_pred=_检查目标(Y_真,Y_pred) 254如果y_类型不在(“二进制”,“多类”)中: 255 RAISE VALUEERROR(“%s”不受支持“%y”类型)

    ~/anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py 在检查目标中(是,是pred) 69 y_pred:数组或指示器矩阵 70“” --->71检查“一致”长度(Y_真,Y_pred) 72 type_true=目标类型_(y_true) 73 type_pred=目标类型_(y_pred)

    ~/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py输入 检查“一致”长度(*array) 229“” 二百三十 -->231 lengthes=[_num_samples(x)for x in array if x is not none] 232 uniques=np.unique(长度) 233如果len(uniques)>1:

    ~/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py输入 (0) 229“” 二百三十 -->231 lengthes=[_num_samples(x)for x in array if x is not none] 232 uniques=np.unique(长度) 233如果len(uniques)>1:

    ~/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py输入 样本数(x) 146返回x.shape[0] 147其他: -->148返回长度(x) 149其他: 150返回长度(x)

    类型错误:“tensor”类型的对象没有len()。

    1 回复  |  直到 5 年前
        1
  •  2
  •   sdcbr    5 年前

    不能对角膜张量调用sklearn函数。如果您使用的是tf后端,那么您需要自己使用keras的后端函数或tensorflow函数来实现该功能。

    这个 balanced_accuracy_score 定义 as the average of the recall 在每列中获取。检查 this link 以实现精确性和召回。至于 平衡精度分数 ,可以实现如下:

    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