我试图在使用Tensorflow后端的Keras框架内实现一些损失功能,但到目前为止还没有成功(尽管我相信我越来越近了) . 所讨论的损失函数是YOLO算法的损失函数 . 这个函数的问题在于它是$ L_2 $范数,但是根据$ y_true $的值加权一些系数 . 因此,为了 Build 我的损失函数,我必须研究$ y_true $, which Tensorflow seems not to allow 的 Value ......无论如何,到目前为止,我已经提出了这个诀窍:

def defineMarkUp(y_true):
    num_example = y_true.shape[0]
    grid_h, grid_w = config.GRID_H, config.GRID_W
    box_nbr = config.BOX_NBR
    class_nbr = config.CLASS_NBR
    coord_c = config.COORD_C
    noobj_c = config.NOOBJ_C
    s = 5 + class_nbr

    mask = np.zeros(y_true.shape)

    for i in range(num_example):
        for j in range(grid_h):
            for k in range(grid_w):
                for l in range(box_nbr):
                    if np.sum(y_true[i, j, k, l * s + 5 : (l + 1) * s]) > 0:
                        mask[i, j, k, l * s : l * s + 4] = np.sqrt(coord_c)
                        mask[i, j, k, l * s + 4 : (l + 1) * s] = 1.0
                    else:
                        mask[i, j, k, l * s + 4] = np.sqrt(noobj_c)

    return mask



def yoloLoss(markups):
    grid_h, grid_w = config.GRID_H, config.GRID_W
    box_nbr = config.BOX_NBR
    class_nbr = config.CLASS_NBR
    s = 5 + class_nbr

    def loss(y_true, y_pred):

        mask = np.zeros((1,  grid_h, grid_w, box_nbr * s))
        mask = mask.astype(np.float32)
        for k in range(box_nbr):
            mask[:, :, :, k * s + 2 : k * s + 4] = 1.0
        dim_y_true = tf.sqrt(tf.multiply(y_true, mask))
        dim_y_pred = tf.sqrt(tf.multiply(y_pred, mask))

        other_y_true = tf.multiply(y_true, 1 - mask)
        other_y_pred = tf.multiply(y_pred, 1 - mask)

        new_y_true = other_y_true + dim_y_true 
        new_y_pred = other_y_pred + dim_y_pred

        return tf.reduce_mean(tf.square(tf.multiply(tf.cast(markups, tf.float32), (new_y_true - new_y_pred))))

    return loss

一点点解释:这里,函数defineMarkUp查看 the all labels as np.array 并创建一些掩码(根据位置等包含不同的权重等),然后我调用类似的东西:

model.compile(loss = [yoloLoss(Y_train)], optimizer = 'adadelta')

问题是,当使用 batch 时,由于所有数据集与我们的批处理都没有相同的维度,因此在给定 $y_true$ as a tensor 时,掩码不会立即执行't fit anymore, meaning I need to build '标记 . 所以我尝试过这样的事情:

def defineMarkUp(y_true):
    num_example = y_true.get_shape().as_list()[0]
    grid_h, grid_w = config.GRID_H, config.GRID_W
    box_nbr = config.BOX_NBR
    class_nbr = config.CLASS_NBR
    coord_c = config.COORD_C
    noobj_c = config.NOOBJ_C
    s = 5 + class_nbr

    mask = np.zeros(y_true.get_shape().as_list())

    for i in range(num_example):
        for j in range(grid_h):
            for k in range(grid_w):
                for l in range(box_nbr):
                    if np.sum(y_true[i, j, k, l * s + 5 : (l + 1) * s]) > 0:
                        mask[i, j, k, l * s : l * s + 4] = np.sqrt(coord_c)
                        mask[i, j, k, l * s + 4 : (l + 1) * s] = 1.0
                    else:
                        mask[i, j, k, l * s + 4] = np.sqrt(noobj_c)

    return mask

def yoloLossFinal(y_true, y_pred):
    grid_h, grid_w = config.GRID_H, config.GRID_W
    box_nbr = config.BOX_NBR
    class_nbr = config.CLASS_NBR
    s = 5 + class_nbr
    coord_c, noobj_c = config.COORD_C, config.NOOBJ_C

    markups = defineMarkUp(y_true)

    mask = np.zeros((1,  grid_h, grid_w, box_nbr * s))
    mask = mask.astype(np.float32)

    for k in range(box_nbr):
        mask[:, :, :, k * s + 2 : k * s + 4] = 1.0

    dim_y_true = tf.sqrt(tf.multiply(y_true, mask))
    dim_y_pred = tf.sqrt(tf.multiply(y_pred, mask))

    other_y_true = tf.multiply(y_true, 1 - mask)
    other_y_pred = tf.multiply(y_pred, 1 - mask)

    new_y_true = other_y_true + dim_y_true 
    new_y_pred = other_y_pred + dim_y_pred

    return tf.reduce_mean(tf.square(tf.multiply(tf.cast(markups, tf.float32), (new_y_true - new_y_pred))))

但现在我收到了这个错误:

回溯(最近一次调用最后一次):文件“network.py”,第214行,在yolo.compile中(loss = yoloLossFinal,optimizer ='adadelta')文件“/anaconda3/lib/python3.6/site-packages/keras /engine/training.py“,第830行,在编译sample_weight,mask中)文件”/anaconda3/lib/python3.6/site-packages/keras/engine/training.py“,第429行,加权score_array = fn( y_true,y_pred)文件“network.py”,第192行,yoloLossFinal标记= defineMarkUp(y_true)文件“network.py”,第143行,在defineMarkUp中掩码= np.zeros(y_true.get_shape() . as_list()) TypeError:'NoneType'对象不能解释为整数

因此,我尝试了其他的东西:

def defineMarkUp(y_true):
    sess = tf.Session()
    with sess.as_default():
        yy = y_true.eval()

    num_example = yy.shape[0]
    grid_h, grid_w = config.GRID_H, config.GRID_W
    box_nbr = config.BOX_NBR
    class_nbr = config.CLASS_NBR
    coord_c = config.COORD_C
    noobj_c = config.NOOBJ_C
    s = 5 + class_nbr

    mask = np.zeros(y_true.shape)

    for i in range(num_example):
        for j in range(grid_h):
            for k in range(grid_w):
                for l in range(box_nbr):
                    if np.sum(yy[i, j, k, l * s + 5 : (l + 1) * s]) > 0:
                        mask[i, j, k, l * s : l * s + 4] = np.sqrt(coord_c)
                        mask[i, j, k, l * s + 4 : (l + 1) * s] = 1.0
                    else:
                        mask[i, j, k, l * s + 4] = np.sqrt(noobj_c)

    return mask

但现在我收到这个非常长的错误消息:

回溯(最近一次调用最后一次):文件“/anaconda3/lib/python3.6/site-packages/tensorflow/python/client/session.py”,第1322行,在_do_call中返回fn(* args)文件“/ anaconda3 /lib/python3.6/site-packages/tensorflow/python/client/session.py“,第1307行,在_run_fn选项中,feed_dict,fetch_list,target_list,run_metadata)文件”/anaconda3/lib/python3.6/site- packages / tensorflow / python / client / session.py“,第1409行,在_call_tf_sessionrun run_metadata中)tensorflow.python.framework.errors_impl.InvalidArgumentError:你必须为占位符张量'conv2d_4_target'提供一个dtype float和shape [?,? ,?,?] [[节点:conv2d_4_target = Placeholderdtype = DT_FLOAT,shape = [?,?,?,?],_ device =“/ job:localhost / replica:0 / task:0 / device:CPU:0”] ]在处理上述异常期间,发生了另一个异常:Traceback(最近一次调用最后一次):文件“network.py”,第218行,在yolo.compile中(loss = yoloLossFinal,optimizer ='adadelta')文件“/ anaconda3 / LIB / python3.6 /站点包/ keras /发动机/ TRAI ning.py“,第830行,在编译sample_weight,mask中)文件”/anaconda3/lib/python3.6/site-packages/keras/engine/training.py“,第429行,加权score_array = fn(y_true,y_pred )文件“network.py”,第196行,yoloLossFinal标记= defineMarkUp(y_true)文件“network.py”,第137行,在defineMarkUp中yy = y_true.eval()文件“/anaconda3/lib/python3.6/site -packages / tensorflow / python / framework / ops.py“,第710行,在eval返回_eval_using_default_session(self,feed_dict,self.graph,session)文件”/anaconda3/lib/python3.6/site-packages/tensorflow/python /framework/ops.py“,第5180行,在_eval_using_default_session中返回session.run(tensors,feed_dict)文件”/anaconda3/lib/python3.6/site-packages/tensorflow/python/client/session.py“,第900行,在运行run_metadata_ptr)文件“/anaconda3/lib/python3.6/site-packages/tensorflow/python/client/session.py”,第1135行,在_run feed_dict_tensor,options,run_metadata)文件“/ anaconda3 / lib / python3 0.6 /站点包/ tensorflow /蟒蛇/客户/ session.py”第1316行,在_do_run run_metadata中)文件“/anaconda3/lib/python3.6/site-packages/tensorflow/python/client/session.py”,第1335行,在_do_call引发类型(e)(node_def,op,message) tensorflow.python.framework.errors_impl.InvalidArgumentError:您必须为占位符张量'conv2d_4_target'提供一个值,其中dtype为float和shape [?,?,?,?] [[Node:conv2d_4_target = Placeholderdtype = DT_FLOAT,shape = [?, ?,?,?],_ device =“/ job:localhost / replica:0 / task:0 / device:CPU:0”]]由op'conv2d_4_target'引起,定义于:文件“network.py”,第218行,在yolo.compile(loss = yoloLossFinal,optimizer ='adadelta')文件“/anaconda3/lib/python3.6/site-packages/keras/engine/training.py”,第725行,编译dtype = K.dtype (self.outputs [i]))文件“/anaconda3 /lib/python3.6/site-packages/keras/backend/tensorflow_backend.py”,第508行,占位符x = tf.placeholder(dtype,shape = shape,name = name)文件“/ anaconda3 / lib /python3.6/site-packages/tensorflow/python/ops/array_ops.py“,第1808行,在占位符中返回gen_array_ops.placeholder(dtype = dtype,shape = shape,name = name)文件”/ anaconda3 / lib / python3 .6 / site-packages / tensorflow / python / ops / gen_array_ops.py“,第4848行,占位符”占位符“,dtype = dtype,shape = shape,name = name)文件”/anaconda3/lib/python3.6/ site-packages / tensorflow / python / framework / op_def_library.py“,第787行,在_apply_op_helper中op_def = op_def)文件”/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py“,第3392行,在create_op中op_def = op_def)文件“/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py”,第1718行,在init self._traceback = self._graph.extract_stack( )#pylint:disable = protected-access InvalidArgumentError(参见上面的回溯):你必须提供一个占位符张量'conv2d_4_target'的值与dtype float和shape [?,?,?,?] [[节点:conv2d_4_target = Placeholderdtype = DT_FLOAT,shape = [?,?,?,?], device =“/ job:localhost /复制:0 /任务:0 /装置:CPU:0" ]

]

我错了:( . 到目前为止,我还有一个更普遍的问题,其中可能与我的问题有关: how to really implement a loss function in Tensorflow, meaning : what are we allowed to do and what are we not allowed to do

非常感谢!