自定义损失缺少渐变操作

我不太确定该如何处理以及为什么会出现此错误。

    raise ValueError('An operation has `None` for gradient. '
    ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax,K.round,K.eval.

因此,我正在为此博客的损失函数使用自定义三重损失。 https://omoindrot.github.io/triplet-loss,并且我正在keras中运行它,这不应该成为问题。但是我无法使其与我的模型一起正常工作。

所以这是它们的损失函数。它需要的其他代码是直接副本:

def batch_hard_triplet_loss(embeddings,labels,margin = 0.3,squared=False):

    # Get the pairwise distance matrix
    pairwise_dist = pairwise_distances(embeddings,squared=squared)
    mask_anchor_positive = _get_anchor_positive_triplet_mask(labels)
    mask_anchor_positive = tf.to_float(mask_anchor_positive)
    anchor_positive_dist = tf.multiply(mask_anchor_positive,pairwise_dist)
    hardest_positive_dist = tf.reduce_max(anchor_positive_dist,axis=1,keepdims=True)
    mask_anchor_negative = _get_anchor_negative_triplet_mask(labels)
    mask_anchor_negative = tf.to_float(mask_anchor_negative)
    max_anchor_negative_dist = tf.reduce_max(pairwise_dist,keepdims=True)
    anchor_negative_dist = pairwise_dist + max_anchor_negative_dist * (1.0 - mask_anchor_negative)
    hardest_negative_dist = tf.reduce_min(anchor_negative_dist,keepdims=True)
    # Combine biggest d(a,p) and smallest d(a,n) into final triplet loss
    triplet_loss = tf.maximum(hardest_positive_dist - hardest_negative_dist + margin,0.0)
    triplet_loss = tf.reduce_mean(triplet_loss)
#triplet_loss = k.mean(triplet_loss) # use keras mean

    return triplet_loss

现在这是我正在使用的模型。

train_datagen = ImageDataGenerator(
    preprocessing_function=preprocess_input,....
    validation_split=0.2) # set validation split

train_generator = train_datagen.flow_from_directory(
    IMAGE_DIR,target_size=(224,224),batch_size=BATCHSIZE,class_mode='categorical',subset='training') # set as training data

validation_generator = train_datagen.flow_from_directory(
    IMAGE_DIR,# same directory as training data
    target_size=(224,subset='validation') # set as validation data

print("Initializing Model...")
# Get base model
input_layer = preloadmodel.get_layer('model_1').get_layer('input_1').input
layer_output = preloadmodel.get_layer('model_1').get_layer('glb_avg_pool').output
# Make extractor
base_network = Model(inputs=input_layer,outputs=layer_output)

# Define new model
input_images = Input(shape=(224,224,3),name='input_image')  # input layer for images
#input_labels = Input(shape=(num_classes,),name='input_label')  # input layer for labels
embeddings = base_network(input_images)  # output of network -> embeddings
output = Dense(1,activation='sigmoid')(embeddings)
model = Model(inputs=input_images,outputs=output)
# Compile model
model.compile(loss=batch_hard_triplet_loss,optimizer='adam')
jayredie 回答:自定义损失缺少渐变操作

好吧,我通过大量研究解决了这些问题。现在它不能解决我的问题,因为代码仍然无法正常工作,但是损失函数的问题已修复。关注此博客https://medium.com/@Bloomore/how-to-write-a-custom-loss-function-with-additional-arguments-in-keras-5f193929f7a0

我将损失函数更改为此:

def batch_hard_triplet_loss(embeddings,labels,margin = 0.3,squared=False):
    # Get the pairwise distance matrix
    pairwise_dist = pairwise_distances(embeddings,squared=squared)
    mask_anchor_positive = _get_anchor_positive_triplet_mask(labels)
    mask_anchor_positive = tf.to_float(mask_anchor_positive)
    anchor_positive_dist = tf.multiply(mask_anchor_positive,pairwise_dist)
    hardest_positive_dist = tf.reduce_max(anchor_positive_dist,axis=1,keepdims=True)
    mask_anchor_negative = _get_anchor_negative_triplet_mask(labels)
    mask_anchor_negative = tf.to_float(mask_anchor_negative)
    max_anchor_negative_dist = tf.reduce_max(pairwise_dist,keepdims=True)
    anchor_negative_dist = pairwise_dist + max_anchor_negative_dist * (1.0 - mask_anchor_negative)
    hardest_negative_dist = tf.reduce_min(anchor_negative_dist,keepdims=True)
    def loss(y_true,y_pred):

        # Combine biggest d(a,p) and smallest d(a,n) into final triplet loss
        #triplet_loss = tf.maximum(hardest_positive_dist - hardest_negative_dist + margin,0.0)
        #triplet_loss = tf.reduce_mean(triplet_loss)
        triplet_loss = k.maximum(hardest_positive_dist - hardest_negative_dist + margin,0.0)
        triplet_loss = k.mean(triplet_loss) # use keras mean
        return triplet_loss

    return loss

然后在这样的模型中调用它:

batch_loss = batch_hard_triplet_loss(embeddings,input_labels,0.4,False)
model = Model(inputs=input_images,outputs=embeddings)
model.compile(loss=batch_loss,optimizer='adam')

现在它给了我这些问题

tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'input_label' with dtype float and shape [?,99]
 [[{{node input_label}}]]

但是嘿继续前进。 问题是keras仅接受带有2个参数的损失,因此您需要像我在此处那样通过另一个函数调用损失。

本文链接:https://www.f2er.com/3126745.html

大家都在问