自定义指标中的Keras to_categorical给出错误

时间:2018-08-16 05:12:41

标签: keras metrics

我试图在lstm-crf模型中使用来自keras.utils的to_categorical时使用自定义(f-1分数)度量。我正在测试来自keras.contrib conll2000_chunking_crf的示例。但是,我通过指标的y_true没有形状,因此to_categorical不起作用。我可以做些什么来将y_true转换为度量标准中的一种热表示形式? 这是f-1分数的代码,几乎是Keras删除之前使用的代码。 这是train_x,test_x

的形状
print(train_x.shape)
print(train_x)
print(train_y.shape)
print(train_y)
(8936, 78)
[[   0    0    0 ...   33    1   34]
 [   0    0    0 ...   50   51   34]
 [   0    0    0 ...   68   69   34]
 ...
 [   0    0    0 ... 5164  102   34]
 [   0    0    0 ...    1 2948   34]
 [   0    0    0 ... 1673 1382   34]]
(8936, 78, 1)
[[[-1]
  [-1]
  [-1]
  ...
  [16]
  [16]
  [22]]

 [[-1]
  [-1]
  [-1]
  ...
  [16]
  [16]
  [22]]

 [[-1]
  [-1]
  [-1]
  ...
  [ 5]
  [16]
  [22]]

 ...

 [[-1]
  [-1]
  [-1]
  ...
  [16]
  [10]
  [22]]

 [[-1]
  [-1]
  [-1]
  ...
  [ 5]
  [16]
  [22]]

 [[-1]
  [-1]
  [-1]
  ...
  [16]
  [ 1]
  [22]]]

这是模特和总结:

model = Sequential()
model.add(Embedding(len(vocab),EMBED_DIM,mask_zero = True))
model.add(Bidirectional(LSTM(BiRNN_UNITS, return_sequences=True)))
crf = CRF(len(class_labels), sparse_target=True)
model.add(crf)
model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_1 (Embedding)      (None, None, 200)         1787200   
_________________________________________________________________
bidirectional_1 (Bidirection (None, None, 256)         336896    
_________________________________________________________________
crf_1 (CRF)                  (None, None, 23)          6486      
=================================================================
Total params: 2,130,582
Trainable params: 2,130,582
Non-trainable params: 0
_________________________________________________________________

以下是指标的代码:

 def f1(y_true, y_pred):
    def recall(y_true, y_pred):
        """Recall metric.

        Only computes a batch-wise average of recall.

        Computes the recall, a metric for multi-label classification of
        how many relevant items are selected.
        """
        true_positives = K.sum(K.round(y_true * y_pred))
        possible_positives = K.sum(K.round(y_true))
        recall = true_positives / (possible_positives + K.epsilon())
        return recall

    def precision(y_true, y_pred):
        """Precision metric.

        Only computes a batch-wise average of precision.

        Computes the precision, a metric for multi-label classification of
        how many selected items are relevant.
        """
        true_positives = K.sum(K.round(y_true * y_pred))
        predicted_positives = K.sum(K.round(y_pred))
        precision = true_positives / (predicted_positives + K.epsilon())
        return precision
    y_true = to_categorical(y_true)  
    precision = precision(y_true, y_pred)
    recall = recall(y_true, y_pred)
    f1_score = 2*((precision*recall)/(precision+recall+K.epsilon()))
    f1_score = K.eval(f1_score)

    return f1_score

这是我尝试编译模型时收到的错误消息:

model.compile('adam', loss=crf.loss_function, metrics=[f1])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-54-d498ba26f571> in <module>()
----> 1 model.compile('adam', loss=crf.loss_function, metrics=[f1])

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\engine\training.py in compile(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, weighted_metrics, target_tensors, **kwargs)
    438                 output_metrics = nested_metrics[i]
    439                 output_weighted_metrics = nested_weighted_metrics[i]
--> 440                 handle_metrics(output_metrics)
    441                 handle_metrics(output_weighted_metrics, weights=weights)
    442 

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\engine\training.py in handle_metrics(metrics, weights)
    407                     metric_result = weighted_metric_fn(y_true, y_pred,
    408                                                        weights=weights,
--> 409                                                        mask=masks[i])
    410 
    411                 # Append to self.metrics_names, self.metric_tensors,

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\engine\training_utils.py in weighted(y_true, y_pred, weights, mask)
    401         """
    402         # score_array has ndim >= 2
--> 403         score_array = fn(y_true, y_pred)
    404         if mask is not None:
    405             # Cast the mask to floatX to avoid float64 upcasting in Theano

<ipython-input-53-83f49b6ba707> in f1(y_true, y_pred)
     27         precision = true_positives / (predicted_positives + K.epsilon())
     28         return precision
---> 29     y_true = to_categorical(y_true)
     30     precision = precision(y_true, y_pred)
     31     recall = recall(y_true, y_pred)

~\Anaconda3\envs\tensorflow\lib\site-packages\keras\utils\np_utils.py in to_categorical(y, num_classes)
     21         is placed last.
     22     """
---> 23     y = np.array(y, dtype='int')
     24     input_shape = y.shape
     25     if input_shape and input_shape[-1] == 1 and len(input_shape) > 1:

ValueError: setting an array element with a sequence.

我尝试运行以下代码,并获得了预期的结果,所以我猜该错误发生在编译步骤中。

y1 = model.predict(test_x)
f1(test_y,y1)
0.3058861

任何帮助将不胜感激。预先感谢。

0 个答案:

没有答案