Tensorflow, Keras: в классификации нескольких классов точность высока, но точность, отзыв и f1-оценка равны нулю для большинства классов - PullRequest
1 голос
/ 18 марта 2020

Общее объяснение: Мои коды работают нормально, но результаты связаны. Я не знаю, проблема в

  • структуре сети,
  • или способе подачи данных в сеть,
  • или чем-то еще.

Я борюсь с этой ошибкой несколько недель, и до сих пор я изменил функцию потерь, оптимизатор, генератор данных и т. Д. c., Но я не смог ее решить. Я ценю любую помощь. Если следующей информации недостаточно, дайте мне знать, пожалуйста.

Область исследования: Я использую тензорный поток, керас для мультиклассовой классификации. Набор данных имеет 36 двоичных человеческих атрибутов. Я использовал resnet50, затем для каждой части тела (голова, верхняя часть тела, нижняя часть тела, туфли, аксессуары) я добавил отдельную ветку в сеть. В сети имеется 1 входное изображение с 36 метками и 36 выходными узлами (36 слоев denes с сигмовидной активацией).

Проблема: Проблема в том, что точность, о которой сообщает keras, высока, но f1-балл очень низок или равен нулю для большинства выходных данных (даже когда я использую f1-балл как metri c при компиляции сети, f1-socre для проверки очень плох).

aПосле обучения, когда я использую сеть в режиме прогнозирования, она возвращает всегда один / ноль для некоторых классов. Это означает, что сеть не может обучаться (даже когда я использую взвешенную функцию потерь или функцию фокусных потерь).

Почему это странно? Потому что современные методы сообщают о высоком значении f1 даже после первой эпохи (например, https://github.com/chufengt/iccv19_attribute, что я запустил его в своем P C и получил хорошие результаты после одной эпохи) .

Части кодов:

        print("setup model ...")
        input_image = KL.Input(args.img_input_shape, name= "input_1")
        C1, C2, C3, C4, C5 = resnet_graph(input_image, architecture="resnet50", stage5=False, train_bn=True)
        output_layers = merged_model (input_features=C4)
        model = Model(inputs=input_image, outputs=output_layers, name='SoftBiometrics_Model')

...

        print("model compiling ...")
        OPTIM = optimizers.Adadelta(lr=args.learning_rate, rho=0.95)
        model.compile(optimizer=OPTIM, loss=binary_focal_loss(alpha=.25, gamma=2), metrics=['acc',get_f1])
        plot_model(model, to_file='model.png')

...

        img_datagen = ImageDataGenerator(rotation_range=6, width_shift_range=0.03, height_shift_range=0.03, brightness_range=[0.85,1.15], shear_range=0.06, zoom_range=0.09, horizontal_flip=True, preprocessing_function=preprocess_input_resnet, rescale=1/255.)
        img_datagen_test = ImageDataGenerator(preprocessing_function=preprocess_input_resnet, rescale=1/255.)

        def multiple_outputs(generator, dataframe, batch_size, x_col):
          Gen = generator.flow_from_dataframe(dataframe=dataframe,
                                               directory=None,
                                               x_col = x_col,
                                               y_col = args.Categories,
                                               target_size = (args.img_input_shape[0],args.img_input_shape[1]),
                                               class_mode = "multi_output",
                                               classes=None,
                                               batch_size = batch_size,
                                               shuffle = True)
          while True:
            gnext = Gen.next()
            # return image batch and 36 sets of lables
            labels = gnext[1]
            output_dict = {"{}_output".format(Category): np.array(labels[index]) for index, Category in enumerate(args.Categories)}
            yield {'input_1':gnext[0]}, output_dict

    trainGen = multiple_outputs (generator = img_datagen, dataframe=Train_df_img, batch_size=args.BATCH_SIZE, x_col="Train_Filenames")
    testGen = multiple_outputs (generator = img_datagen_test, dataframe=Test_df_img, batch_size=args.BATCH_SIZE, x_col="Test_Filenames")

    STEP_SIZE_TRAIN = len(Train_df_img["Train_Filenames"]) // args.BATCH_SIZE
    STEP_SIZE_VALID = len(Test_df_img["Test_Filenames"]) // args.BATCH_SIZE

    ...

    print("Fitting the model to the data ...")
            history = model.fit_generator(generator=trainGen,
                                         epochs=args.Number_of_epochs,
                                         steps_per_epoch=STEP_SIZE_TRAIN,
                                         validation_data=testGen,
                                         validation_steps=STEP_SIZE_VALID,
                                         callbacks= [chekpont],
                                         verbose=1)

1 Ответ

0 голосов
/ 20 марта 2020

Существует вероятность того, что вы передаете двоичный f1-счет в функцию compile. Это должно решить проблему -

pip install tensorflow-addons

...

import tensorflow_addons as tfa 

f1 = tfa.metrics.F1Score(36,'micro' or 'macro')

model.compile(...,metrics=[f1])

Вы можете узнать больше о том, как вычисляются f1-micro и f1-macro и что может быть полезно здесь .

...