Keras自定义损失:想要在每个时期结束时跟踪每个损失值

时间:2019-02-27 09:39:51

标签: debugging keras deep-learning tensor loss

我想在每个时期结束时检查self.losses['RMSE']self.loss['CrossEntropy']self.loss['OtherLoss']的值。目前,我只能检查总损失self.loss['total']

def train_test(self):
    def custom_loss(y_true, y_pred):
        ## (...) Calculate several losses inside this function
        self.losses['total'] = self.losses['RMSE'] + self.losses['CrossEntropy'] + self.losses['OtherLoss']
        return self.losses['total']


    ## (...) Generate Deep learning model & Read Inputs
    logits = keras.layers.Dense(365, activation=keras.activations.softmax)(concat)
    self.model = keras.Model(inputs=[...], outputs=logits)

    self.model.compile(optimizer=keras.optimizers.Adam(0.001),
                       loss=custom_loss)

    self.history = self.model.fit_generator(
        generator=self.train_data,
        steps_per_epoch=train_data_size//FLAGS.batch_size,
        epochs=5,
        callbacks=[CallbackA(self.losses)])

class TrackTestDataPerformanceCallback(keras.callbacks.Callback):
    def __init__(self, losses):
        self.losses = losses

    def on_epoch_end(self, epoch, logs={}):
        for key in self.losses.keys()
            print('Type of loss: {}, Value: {}'.format(key, K.eval(self.losses[key])))

我将self.loss传递给了回调函数CallbackA,以便在每个时期结束时打印子损失值。但是,它给出如下错误消息:

InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'input_3' with dtype float and shape [?,5]
 [[Node: input_3 = Placeholder[dtype=DT_FLOAT, shape=[?,5], _device="/job:localhost/replica:0/task:0/device:GPU:0"]()]]
 [[Node: loss/dense_3_loss/survive_rates/while/LoopCond/_881 = _HostRecv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_360_loss/dense_3_loss/survive_rates/while/LoopCond", tensor_type=DT_BOOL, _device="/job:localhost/replica:0/task:0/device:CPU:0"](^_clooploss/dense_3_loss/survive_rates/while/strided_slice_4/stack_2/_837)]]

我可以再次将训练数据传递给回调函数,并预测自己以跟踪每个损失值。但是我认为可能还有一个我还不知道的更好的解决方案。

摘要:如何在每个时期之后在自定义损失函数中跟踪多个损失值?

约束::为了减少一些计算成本,我现在想在custom_loss函数中管理一些损失。但是,如果我必须将每个损失都包装到每个函数中,那就可以了。

2 个答案:

答案 0 :(得分:0)

编译时可以在列表中使用多个损失。例如,如果要混合交叉熵和mse,可以使用:

"@types/react-router@*", "@types/react-router@4.4.4": version "4.4.4" resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.4.4.tgz#4dbd5588ea6024e0c04519bd8aabe74c0a2b77e5" integrity sha512-TZVfpT6nvUv/lbho/nRtckEtgkhspOQr3qxrnpXixwgQRKKyg5PvDfNKc8Uend/p/Pi70614VCmC0NPAKWF+0g== dependencies: "@types/history" "*" "@types/react" "*" "@types/react@*": version "16.4.14" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.14.tgz#47c604c8e46ed674bbdf4aabf82b34b9041c6a04" integrity sha512-Gh8irag2dbZ2K6vPn+S8+LNrULuG3zlCgJjVUrvuiUK7waw9d9CFk2A/tZFyGhcMDUyO7tznbx1ZasqlAGjHxA== dependencies: "@types/prop-types" "*" csstype "^2.2.0"

历史记录将包含编译模型时使用的不同损失。

答案 1 :(得分:0)

我必须为模型维护一个组合的custom_loss,因此我找到了一种通过将metrics参数放入来跟踪多个子损失的方法。每个损失函数都分别定义为一个函数。

def custom_loss():
    return subloss1() + subloss2() + subloss3()

def subloss1():
    ...
    return value1

def subloss2():
    ...
    return value2

def subloss3():
    ...
    return value3


self.model.compile(optimizer=keras.optimizers.Adam(0.001),
                       loss=custom_loss,
                       metrics=[subloss1, subloss2, subloss3]