Tensorflow中的一些张量操纵

时间:2018-07-09 13:14:15

标签: python-3.x tensorflow keras yolo

我已经在Tensorflow中的一些张量操纵上停留了几个小时。我正在尝试使用Tensorflow后端在Keras框架中实现一些损失功能,但到目前为止仍未成功(尽管我相信我会越来越近)。所讨论的损失函数是 YOLO 算法的损失函数。此函数的问题在于,它是一个$ L_2 $范数,但根据$ y_true $的值由一些系数加权。因此,为了构建损失函数,我必须研究$ y_true $的值, Tensorflow似乎不允许这样做。。。到目前为止,我想出了这个方法技巧:

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将所有标签视为np.array ,并创建一些蒙版(根据位置等包含不同的权重),以及然后我这样称呼:

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

问题是,当使用批处理时,由于所有数据集的尺寸都与我们的批处理不同,因此遮罩不再合适,这意味着我需要在给定 $ y_true $作为张量。所以我尝试了这样的事情:

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)defineMarkUp中的文件“ network.py”,第143行       mask = 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”,   _do_call中的第1322行       返回fn(* args)文件“ /anaconda3/lib/python3.6/site-packages/tensorflow/python/client/session.py”,   _run_fn中的第1307行       选项,feed_dict,fetch_list,target_list,run_metadata)文件“ /anaconda3/lib/python3.6/site-packages/tensorflow/python/client/session.py”,   _call_tf_sessionrun中的第1409行       run_metadata)tensorflow.python.framework.errors_impl.InvalidArgumentError:您必须   用dtype float输入占位符张量'conv2d_4_target'的值   和形状[?,?,?,?] [[节点:conv2d_4_target =   Placeholderdtype = DT_FLOAT,shape = [?,?,?,?],   _device =“ / job:localhost /副本:0 /任务:0 /设备:CPU:0”]]

     

在处理上述异常期间,发生了另一个异常:

     

回溯(最近一次通话最后一次):文件“ network.py”,第218行,在          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)yoloLossFinal中的文件“ network.py”,第196行       标记= defineMarkUp(y_true)defineMarkUp中的文件“ network.py”,第137行       yy = y_true.eval()文件“ /anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py”,   710行,评估       返回_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”,   _run中的第1135行       feed_dict_tensor,选项,run_metadata)文件“ /anaconda3/lib/python3.6/site-packages/tensorflow/python/client/session.py”,   _do_run中的第1316行       run_metadata)文件“ /anaconda3/lib/python3.6/site-packages/tensorflow/python/client/session.py”,   第1335行,在_do_call中       提高type(e)(node_def,op,message)tensorflow.python.framework.errors_impl.InvalidArgumentError:您必须   用dtype float输入占位符张量'conv2d_4_target'的值   和形状[?,?,?,?] [[节点:conv2d_4_target =   Placeholderdtype = DT_FLOAT,shape = [?,?,?,?],   _device =“ / job:localhost /副本:0 /任务:0 /设备:CPU:0”]]

     

由操作“ 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”,   _apply_op_helper中的第787行       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 =受保护的访问

     

InvalidArgumentError(请参阅上面的回溯):您必须提供一个值   用于dtype float和shape的占位符张量'conv2d_4_target'   [?,?,?,?] [[节点:conv2d_4_target = Placeholderdtype = DT_FLOAT,   shape = [?,?,?,?],   _device =“ / job:localhost /副本:0 / task:0 / device:CPU:0”]

]

我一直在不懈地尝试实现此损失功能,所以我真的希望有人可以帮助我了解发生了什么问题:(。到目前为止,我还有一个更笼统的问题,该问题可能与我的问题有关: 如何在Tensorflow中真正实现损失函数,这意味着:我们可以做什么,我们不能做什么

非常感谢!

0 个答案:

没有答案