Ich erstelle ein vollständig gefaltetes neuronales Netzwerk, das bei einem eingegebenen Bild Zonen darin identifizieren kann (schwarz, 0) und auch Hintergrund (weiß, 255). Meine Ziele sind binärisierte Bilder (zwischen 0 und 255), und ich möchte ein Gleichgewicht zwischen meinen beiden semantischen Klassen (0 oder 255) herstellen. Tatsächlich erhalte ich 1,8-mal mehr "spezielle" Zonen (0) als Hintergrundzonen (255), daher muss ich diesen Effekt ausgleichen, und ich möchte die Tatsache stärker bestrafen, einen Fehler im Hintergrund zu machen, um dies zu vermeiden mit einer Vorhersage von nur speziellen Zonen.

Ich habe versucht, einige Themen zu verfolgen, es scheint nicht sehr schwierig zu sein, aber ich stecke in meiner Implementierung fest, ich weiß nicht wirklich warum.

Jedes Mal, wenn meine Implementierungen in der Kompilierungsphase ausgeführt werden, wird jedoch nur im Anpassungsschritt ein Fehler zurückgegeben.
Folgendes habe ich bisher versucht:

import keras.backend as kb    
def custom_binary_crossentropy(y_true, y_pred):
        """
        Used to reequilibrate the data, as there is more black (0., articles), than white (255., non-articles) on the pages.
        """
        if y_true >=128:   # Half the 0-255 range
            return -1.8*kb.log(y_pred/255.)
        else:
            return -kb.log(1-(y_pred/255.))

Aber es kehrte zurück:

InvalidArgumentError:  The second input must be a scalar, but it has shape [16,256,256]
     [[{{node gradient_tape/custom_binary_crossentropy/cond/StatelessIf/gradient_tape/custom_binary_crossentropy/weighted_loss/Mul/_17}}]] [Op:__inference_train_function_24327]

Function call stack:
train_function

Ich verstehe diesen Fehler nicht wirklich.

Ich hatte vorher versucht:

def custom_binary_crossentropy(y_true, y_pred):
    """
    Used to reequilibrate the data, as there is more black (0., articles), than white (255., non-articles) on the pages.
    """
    if y_true >=128:   # Half the 0-255 range
        return 1.8*keras.losses.BinaryCrossentropy(y_true, y_pred)
    else:
        return keras.losses.BinaryCrossentropy(y_true, y_pred)

Aber ich habe:

TypeError: in user code:

    /Users/axeldurand/opt/anaconda3/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:806 train_function  *
        return step_function(self, iterator)
    <ipython-input-67-7b6815236f63>:6 custom_binary_crossentropy  *
        return -1.8*keras.losses.BinaryCrossentropy(y_true, y_pred)

    TypeError: unsupported operand type(s) for *: 'float' and 'BinaryCrossentropy'

Ich bin ein bisschen verwirrt, Keras macht es immer so einfach, ich muss etwas Leichtes weglassen, aber ich verstehe es nicht wirklich.

0
Durand 5 Okt. 2020 im 16:27

2 Antworten

Beste Antwort

Vielen Dank @qmeeus, Sie haben mir den Weg zum Erfolg gezeigt!
Ich kannte den Unterschied zwischen keras.losses.BinaryCrossentropy und keras.losses.binary_crossentropy nicht, aber es ist ein wichtiger.

So habe ich es gemacht:

def custom_binary_crossentropy(y_true, y_pred):
    """
    Used to reequilibrate the data, as there is more black (0., articles),
    than white (255. (recalibrated to 1.), non-articles) on the pages.
    """
    # I put 0 so that the shape is (batch_size, 256, 256)
    # and not (batch_size, 256, 256, 1)
    is_white = y_true[:,:,:,0]>=0.5 
    white_error = 1.8*keras.losses.binary_crossentropy(y_true, y_pred)
    black_error = keras.losses.binary_crossentropy(y_true, y_pred)
    # Returns the right loss for each type of error.
    # We do make twice the calculation but I did not find a better way for now
    return tf.where(is_white, white_error, black_error)

Ich kannte die Verwendung von tf.where nicht, aber es ist äußerst nützlich. Ich habe dieses Tutorial zu dem hervorragenden Buch von Aurélien Géron, Maschinelles Lernen mit Keras und TensorFlow, gesehen.

Einfach weiter verwenden:

# Compiling using this function
model.compile(optimizer="rmsprop", loss=custom_binary_crossentropy)

Passen Sie dann Ihr Modell mit Ihren Daten und bevorzugten Hyperparametern an und los geht's!

0
Durand 9 Okt. 2020 im 08:22

Sie verwenden keras.losses.BinaryCrossentropy falsch. Sie möchten tatsächlich die funktionale Version dieses Verlusts, nämlich tf.keras.losses.binary_crossentropy

Siehe https://www.tensorflow.org/api_docs/python/tf / keras / loss / BinaryCrossentropy und https: // www .tensorflow.org / api_docs / python / tf / keras / loss / binary_crossentropy

0
qmeeus 5 Okt. 2020 im 15:55