কেরাসে কাস্টম পারফরম্যান্স মেট্রিক কীভাবে সংজ্ঞায়িত করবেন?


12

আমি নিম্নলিখিত অনুসারে কেরাসে একটি কাস্টম মেট্রিক ফিউশন (এফ 1-স্কোর) সংজ্ঞায়নের চেষ্টা করেছি:

def f1_score(tags, predicted):

    tags = set(tags)
    predicted = set(predicted)

    tp = len(tags & predicted)
    fp = len(predicted) - tp 
    fn = len(tags) - tp

    if tp>0:
        precision=float(tp)/(tp+fp)
        recall=float(tp)/(tp+fn)
        return 2*((precision*recall)/(precision+recall))
    else:
        return 0

এখন পর্যন্ত, এত ভাল, তবে আমি যখন এটি মডেল সংকলনে প্রয়োগ করার চেষ্টা করব:

model1.compile(loss="binary_crossentropy", optimizer=Adam(), metrics=[f1_score])

এটি ত্রুটি দেয়:

TypeError                                 Traceback (most recent call last)
<ipython-input-85-4eca4def003f> in <module>()
      5 model1.add(Dense(output_dim=10, activation="sigmoid"))
      6 
----> 7 model1.compile(loss="binary_crossentropy", optimizer=Adam(), metrics=[f1_score])
      8 
      9 h=model1.fit(X_train, Y_train, batch_size=500, nb_epoch=5, verbose=True, validation_split=0.1)

/home/buda/anaconda2/lib/python2.7/site-packages/keras/models.pyc in compile(self, optimizer, loss, metrics, sample_weight_mode, **kwargs)
    522                            metrics=metrics,
    523                            sample_weight_mode=sample_weight_mode,
--> 524                            **kwargs)
    525         self.optimizer = self.model.optimizer
    526         self.loss = self.model.loss

/home/buda/anaconda2/lib/python2.7/site-packages/keras/engine/training.pyc in compile(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, **kwargs)
    664                 else:
    665                     metric_fn = metrics_module.get(metric)
--> 666                     self.metrics_tensors.append(metric_fn(y_true, y_pred))
    667                     if len(self.output_names) == 1:
    668                         self.metrics_names.append(metric_fn.__name__)

<ipython-input-84-b8a5752b6d55> in f1_score(tags, predicted)
      4     #tf.convert_to_tensor(img.eval())
      5 
----> 6     tags = set(tags)
      7     predicted = set(predicted)
      8 

/home/buda/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/ops.pyc in __iter__(self)
    493       TypeError: when invoked.
    494     """
--> 495     raise TypeError("'Tensor' object is not iterable.")
    496 
    497   def __bool__(self):

TypeError: 'Tensor' object is not iterable.

এখানে কি সমস্যা? আমার f1_score ফাংশন ইনপুটগুলি টেনস্রফ্লো অ্যারে নয়? যদি তা হয় তবে আমি কোথায় / কীভাবে তাদের সঠিকভাবে রূপান্তর করতে পারি?


হুঁ, ত্রুটি বার্তাটি বোঝায় যে আপনি টেনসর অবজেক্টগুলি পাচ্ছেন। সম্ভবত আপনি পরে সর্বোপরি প্রয়োজন! যদি তাই হয় তবে আপনার ভুলটি সম্ভবত আপনি evalযখন ব্যবহার করছেন ব্যবহার করার সম্ভাবনা রয়েছেeval()
নীল স্লেটার

উত্তর:


17

আপনাকে কেরাস ব্যাকএন্ড ফাংশন ব্যবহার করতে হবে । দুর্ভাগ্যক্রমে তারা- &পরিচালককে সমর্থন করে না , যাতে আপনাকে একটি কার্যনির্বাহ তৈরি করতে হবে: আমরা মাত্রার ম্যাট্রিক্স উত্পন্ন করি batch_size x 3, যেখানে (যেমন সত্য পজিটিভ জন্য) প্রথম কলামটি গ্রাউন্ড ট্রুথ ভেক্টর, দ্বিতীয় প্রকৃত পূর্বাভাস এবং তৃতীয়টি লেবেল-সহায়ক কলামের ধরণ, এটিতে কেবল সত্যিকারের ইতিবাচক বিষয় রয়েছে। তারপরে আমরা চেক করি যে কোন দৃষ্টান্তগুলি ইতিবাচক উদাহরণ, ইতিবাচক হিসাবে পূর্বাভাস দেওয়া হয় এবং লেবেল-সহায়কও ইতিবাচক। তারাই প্রকৃত ইতিবাচক।

আমরা এই এনালগটিকে লেবেলের কিছু বিপরীত গণনা সহ মিথ্যা ধনাত্মক, মিথ্যা নেতিবাচক এবং সত্য নেতিবাচক দিয়ে তৈরি করতে পারি।

আপনার F1- মেট্রিক নীচের হিসাবে দেখতে পারে:

def f1_score(y_true, y_pred):
    """
    f1 score

    :param y_true:
    :param y_pred:
    :return:
    """
    tp_3d = K.concatenate(
        [
            K.cast(y_true, 'bool'),
            K.cast(K.round(y_pred), 'bool'),
            K.cast(K.ones_like(y_pred), 'bool')
        ], axis=1
    )

    fp_3d = K.concatenate(
        [
            K.cast(K.abs(y_true - K.ones_like(y_true)), 'bool'),
            K.cast(K.round(y_pred), 'bool'),
            K.cast(K.ones_like(y_pred), 'bool')
        ], axis=1
    )

    fn_3d = K.concatenate(
        [
            K.cast(y_true, 'bool'),
            K.cast(K.abs(K.round(y_pred) - K.ones_like(y_pred)), 'bool'),
            K.cast(K.ones_like(y_pred), 'bool')
        ], axis=1
    )

    tp = K.sum(K.cast(K.all(tp_3d, axis=1), 'int32'))
    fp = K.sum(K.cast(K.all(fp_3d, axis=1), 'int32'))
    fn = K.sum(K.cast(K.all(fn_3d, axis=1), 'int32'))

    precision = tp / (tp + fp)
    recall = tp / (tp + fn)
    return 2 * ((precision * recall) / (precision + recall))

যেহেতু কেরাস-ব্যাকএন্ড ক্যালকুলেটর শূন্য দ্বারা বিভাজনের জন্য ন্যানকে দেয়, আমাদের রিটার্নের স্টেটমেন্টের জন্য যদি-অন্য-বিবৃতিটির প্রয়োজন হয় না।

সম্পাদনা: সঠিক বাস্তবায়নের জন্য আমি খুব সুন্দর ধারণা পেয়েছি। আমাদের প্রথম পদ্ধতির সমস্যাটি হ'ল এটি কেবল "আনুমানিক", যেহেতু এটি ব্যাচওয়ালা গণনা করা হয় এবং পরে গড় হয়। keras.callbackএস এর সাথে প্রতিটি যুগের পরে একটি এটি গণনাও করতে পারে । দয়া করে এখানে ধারণাটি সন্ধান করুন: https://github.com/fchollet/keras/issues/5794

একটি উদাহরণ বাস্তবায়ন হবে:

import keras
import numpy as np
import sklearn.metrics as sklm


class Metrics(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.confusion = []
        self.precision = []
        self.recall = []
        self.f1s = []
        self.kappa = []
        self.auc = []

    def on_epoch_end(self, epoch, logs={}):
        score = np.asarray(self.model.predict(self.validation_data[0]))
        predict = np.round(np.asarray(self.model.predict(self.validation_data[0])))
        targ = self.validation_data[1]

        self.auc.append(sklm.roc_auc_score(targ, score))
        self.confusion.append(sklm.confusion_matrix(targ, predict))
        self.precision.append(sklm.precision_score(targ, predict))
        self.recall.append(sklm.recall_score(targ, predict))
        self.f1s.append(sklm.f1_score(targ, predict))
        self.kappa.append(sklm.cohen_kappa_score(targ, predict))

        return

এই ফাংশনটি কল করার জন্য নেটওয়ার্কটি তৈরি করতে আপনি নিজের কলব্যাকগুলিতে কেবল এটিকে যুক্ত করেন

metrics = Metrics()
model.fit(
    train_instances.x,
    train_instances.y,
    batch_size,
    epochs,
    verbose=2,
    callbacks=[metrics],
    validation_data=(valid_instances.x, valid_instances.y),
)

তারপরে আপনি কেবল metricsভেরিয়েবলের সদস্যদের অ্যাক্সেস করতে পারবেন ।


4
আপনাকে ধন্যবাদ, এটি ইতিমধ্যে সত্যিই দরকারী হয়েছে। আপনি কী জানেন কীভাবে কাস্টম মেট্রিকগুলি একটি টেনসরবোর্ড কলব্যাকের সাথে অন্তর্ভুক্ত করা যায় যাতে প্রশিক্ষণের সময় তাদের পর্যবেক্ষণ করা যায়?
এন কাইজার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.