Tensorflow Keras给出';不可序列化的JSON';保存模型时出错

Tensorflow Keras给出';不可序列化的JSON';保存模型时出错,tensorflow,keras,conv-neural-network,image-segmentation,Tensorflow,Keras,Conv Neural Network,Image Segmentation,我正在使用这里定义的unet实现一个用于图像分割的完全卷积神经网络 为了给不同类别的像素赋予不同的权重,我定义了一个额外的Lambda层,如下所示 问题是Keras在保存模型时会引发此错误 ..... self.model.save(filepath, overwrite=True) ..... TypeError: ('Not JSON Serializable:', b'\n\x15clip_by_value/Minimum\x12\x07Minimum\x1a\x12conv2d_23

我正在使用这里定义的unet实现一个用于图像分割的完全卷积神经网络

为了给不同类别的像素赋予不同的权重,我定义了一个额外的Lambda层,如下所示

问题是Keras在保存模型时会引发此错误

.....
self.model.save(filepath, overwrite=True)
.....
TypeError: ('Not JSON Serializable:', b'\n\x15clip_by_value/Minimum\x12\x07Minimum\x1a\x12conv2d_23/Identity\x1a\x17clip_by_value/Minimum/y*\x07\n\x01T\x12\x020\x01')
我的网络是在外部函数中定义的

def weighted_binary_loss(X):
    y_pred, y_true, weights = X
    loss = binary_crossentropy(y_true, y_pred)
    weights_mask = y_true*weights[0] + (1.-y_true)*weights[1]
    loss = multiply([loss, weights_mask])
    return loss    

def identity_loss(y_true, y_pred):
    return y_pred


def net()
.....
....
conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)
w_loss = Lambda(weighted_binary_loss, output_shape=input_size, name='loss_output')([conv10, inputs, weights])
model = Model(inputs = inputs, outputs = w_loss)
model.compile(optimizer = Adam(lr = 1e-5), loss = identity_loss, metrics = ['accuracy'])

我在主函数中调用的

...
model_checkpoint = ModelCheckpoint('temp_model.hdf5', monitor='loss',verbose=1, save_best_only=True)
model.fit_generator(imgs,steps_per_epoch=20,epochs=1,callbacks=[model_checkpoint])
当我擦除Lambda层时,错误消失

...
conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)
model = Model(inputs = inputs, outputs = conv10)
model.compile(optimizer = Adam(lr = 1e-5), loss = 'binary_crossentropy', metrics = ['accuracy'])
我正在使用
Keras==2.2.4,tensorflow gpu==2.0.0b1

您似乎正在计算模型层中的损耗。将损失函数作为一个层来容纳不是一个好的做法。您可以使用自定义损失函数计算加权损失

因此,您的代码可以重写如下:

def weighted_binary_loss(y_true, y_pred):
    weights = [0.5, 0.6]  # Define your weights here
    loss = binary_crossentropy(y_true, y_pred)
    weights_mask = y_true*weights[0] + (1.-y_true)*weights[1]
    loss = multiply([loss, weights_mask])
    return loss  

conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)
model = Model(inputs = inputs, outputs = conv10)
model.compile(optimizer = Adam(lr = 1e-5), loss = weighted_binary_loss, metrics = ['accuracy'])
如果需要将权重作为一个动态属性,并且必须将其作为损失函数中的一个单独参数发送,则可以遵循以下步骤