我已经在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中真正实现损失函数,这意味着:我们可以做什么,我们不能做什么?
非常感谢!