keras VGG,角膜知觉丧失

w51jfk4q  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(178)

我想知道是否有可能在keras中的损失函数中添加一个自定义模型。例如:

def model_loss(y_true, y_pred):
    inp = Input(shape=(128, 128, 1))
    x = Dense(2)(inp)
    x = Flatten()(x)

    model = Model(inputs=[inp], outputs=[x])
    a = model(y_pred)
    b = model(y_true)

    # calculate MSE
    mse = K.mean(K.square(a - b))
    return mse

这是一个简化的例子,我实际上会在损失中使用VGG网,所以我只是想了解keras的机制.

t30tvxxf

t30tvxxf1#

通常的做法是将VGG附加到模型的末尾,在编译之前确保所有层都有trainable=False
然后重新计算Y_train。
假设您有这些模型:

mainModel - the one you want to apply a loss function    
lossModel - the one that is part of the loss function you want

创建一个新模型,将一个模型附加到另一个模型:

from keras.models import Model

lossOut = lossModel(mainModel.output) #you pass the output of one model to the other

fullModel = Model(mainModel.input,lossOut) #you create a model for training following a certain path in the graph.

该模型将具有与mainModel和lossModel完全相同的权重,并且训练该模型将影响其他模型。
确保lossModel在编译前不可训练:

lossModel.trainable = False
for l in lossModel.layers:
    l.trainable = False

fullModel.compile(loss='mse',optimizer=....)

现在调整训练数据:

fullYTrain = lossModel.predict(originalYTrain)

最后再做训练:

fullModel.fit(xTrain, fullYTrain, ....)
kmbjn2e3

kmbjn2e32#

这是旧的,但我会回答它,因为没有人直接这样做。你肯定可以调用另一个模型在自定义损失,实际上我认为这比添加模型到你的主模型的末尾,并创建一个全新的一个和一个全新的训练标签集容易得多。
下面是一个既调用模型又调用我们定义的外部函数的示例-

def normalize_tensor(in_feat):
    norm_factor = tf.math.sqrt(tf.keras.backend.sum(in_feat**2, axis=-1, keepdims=True))
    return in_feat / (norm_factor + 1e-10)

def VGGLoss(y_true, y_pred):
    true = vgg(preprocess_input(y_true * 255))
    pred = vgg(preprocess_input(y_pred * 255))

    t = normalize_tensor(true[i])
    p = normalize_tensor(pred[i])
    vggLoss = tf.math.reduce_mean(tf.math.square(t - p))

    return vggLoss

vgg()只调用没有头的vgg 16模型。
preprocess_input是一个keras函数,用于对vgg模型中使用的输入进行归一化(这里我们假设您的模型输出0-1范围内的图像,然后乘以255以获得vgg的0-255范围)。
normalize_tensor获取vgg激活并使它们对于每个通道的幅度为1,否则您的损失将是巨大的。

相关问题