将retinanet和HEM(难例挖掘)相结合2

我的想法是训练完成后,搜集每个样本的loss,将它们降序排序,选取其中最大的10%。然后挑出这10%loss对应的图片和标签,将这些图片和标签加入数据集。
使用 tf.keras 的 Model.predict() 方法来获取每个样本的损失值。在训练过程中,可以在每个epoch结束时调用 predict() 方法,获取每个样本的预测值和标签,并计算每个样本的损失值。然后将所有损失值保存到一个列表中,并按照损失值降序排列:

class CustomCallback(tf.keras.callbacks.Callback):
    def __init__(self, log_dir, train_dataset):
        super().__init__()
        self.log_dir = log_dir
        self.loss_file = "loss.txt"
        self.top20percent_file = "top20percent.txt"
        self.train_dataset = train_dataset

    def on_epoch_end(self, epoch, logs=None):
        if epoch == 499:
            all_losses = []
            for x, y in self.train_dataset:
                y_pred = self.model.predict(x)
                loss = self.model.loss_functions[0](y, y_pred).numpy()
                all_losses.append(loss)

            with open(self.loss_file, "w") as f:
                for loss in all_losses:
                    f.write(str(loss) + '\n')

            sorted_losses = sorted(all_losses)
            top20_index = int(len(all_losses) * 0.1)
            top20_losses = sorted_losses[:top20_index]
            top20_image_paths = []
            for i, (x, y) in enumerate(self.train_dataset):
                y_pred = self.model.predict(x)
                loss = self.model.loss_functions[0](y, y_pred).numpy()
                if loss in top20_losses:
                    top20_image_paths.append(str(i) + ".jpg")
            with open(self.top20percent_file, "w") as f:
                for line in top20_image_paths:
                    f.write(line + '\n')

我传递的训练数据集是这种格式的,通过print (self.train_dataset)知道:
‘/root/autodl-tmp/AI2/yolo3-tf2-main/VOCdevkit/VOC2007/JPEGImages/D_P_F1_CK_F_LA_WB_F_S_front_0907140855.jpg 155,375,194,495,5 269,173,315,243\n’,
‘/root/autodl-tmp/AI2/yolo3-tf2-main/VOCdevkit/VOC2007/JPEGImages/D_P_F1_CL_V_LA_LW_V_RA_back_0907141116.jpg\n’,
‘/root/autodl-tmp/AI2/yolo3-tf2-main/VOCdevkit/VOC2007/JPEGImages/D_P_F1_CL_V_LA_LW_V_RA_front_0907141116.jpg 257,193,295,249,8\n’,
‘/root/autodl-tmp/AI2/yolo3-tf2-main/VOCdevkit/VOC2007/JPEGImages/D_P_F1_GA_F_C_KK_F_S_back_0907140445.jpg\n',
’/root/autodl-tmp/AI2/yolo3-tf2-main/VOCdevkit/VOC2007/JPEGImages/D_P_F1_GA_F_C_KK_F_S_front_0907140445.jpg 144,340,207,421,0 137,426,220,567,1\n’ 等等
包括图片地址和标签(目标框坐标)。
我运行代码,但是有报错:
for x, y in self.train_dataset:
ValueError: too many values to unpack (expected 2)
这个数据集好像格式有问题,不知道如何处理。
我想请问如何解决这个问题,最好是在给出代码基础上的解决方案。我是用的是tensorflow1.15。
感谢各位的帮助!

“Devil组”引证GPT后的撰写:

  • 似乎每个样本都包含了图片地址和标签信息,而在训练过程中,要用到图片数据和标签数据,因此要对数据集进行处理,将每个样本拆分成图片数据和标签数据。
  • 可以使用 tf.data 库提供的方法进行数据集处理。首先,用 tf.data.TextLineDataset 读取数据集文件,然后用 map() 方法对每个样本进行处理,将其拆分为图片数据和标签数据。最后,用 batch() 方法对数据集进行批次处理,方便后续的训练过程。

以下是一个示例代码,可以尝试将其集成到你的自定义回调函数中:

def parse_data(line):
    # 解析每个样本,将其拆分为图片地址和标签数据
    parts = tf.strings.split(line, ' ')
    image_path = parts[0]
    label = parts[1:]
    return image_path, label

def preprocess_data(image_path, label):
    # 读取图片数据并进行预处理
    image = tf.io.read_file(image_path)
    image = tf.image.decode_jpeg(image, channels=3)
    image = tf.image.resize(image, [224, 224]) / 255.0

    # 处理标签数据
    label = tf.strings.to_number(label, out_type=tf.float32)
    label = tf.reshape(label, [-1, 5])  # 假设每个样本最多包含 5 个目标框
    return image, label

train_dataset = tf.data.TextLineDataset(train_file)
train_dataset = train_dataset.map(parse_data)
train_dataset = train_dataset.map(preprocess_data)
train_dataset = train_dataset.batch(batch_size)

# 在训练过程中使用该数据集进行训练
model.fit(train_dataset, epochs=num_epochs, callbacks=[CustomCallback(log_dir, train_dataset)])


运行后有报错,请问有什么方式解决呢?

Traceback (most recent call last):
  File "/root/autodl-tmp/AI2/retinanet-keras-master/train.py", line 261, in <module>
    train_dataset = train_dataset.map(parse_data)
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/data/ops/dataset_ops.py", line 2000, in map
    MapDataset(self, map_func, preserve_cardinality=False))
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/data/ops/dataset_ops.py", line 3527, in __init__
    self._map_func = StructuredFunctionWrapper(
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/data/ops/dataset_ops.py", line 2810, in __init__
    self._function = wrapper_fn._get_concrete_function_internal()
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/eager/function.py", line 1852, in _get_concrete_function_internal
    graph_function = self._get_concrete_function_internal_garbage_collected(
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/eager/function.py", line 1847, in _get_concrete_function_internal_garbage_collected
    graph_function, _, _ = self._maybe_define_function(args, kwargs)
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/eager/function.py", line 2147, in _maybe_define_function
    graph_function = self._create_graph_function(args, kwargs)
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/eager/function.py", line 2028, in _create_graph_function
    func_graph_module.func_graph_from_py_func(
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/framework/func_graph.py", line 915, in func_graph_from_py_func
    func_outputs = python_func(*func_args, **func_kwargs)
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/data/ops/dataset_ops.py", line 2804, in wrapper_fn
    ret = _wrapper_helper(*args)
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/data/ops/dataset_ops.py", line 2749, in _wrapper_helper
    ret = autograph.tf_convert(func, ag_ctx)(*nested_args)
  File "/root/miniconda3/lib/python3.8/site-packages/tensorflow_core/python/autograph/impl/api.py", line 237, in wrapper
    raise e.ag_error_metadata.to_exception(e)
AttributeError: in converted code:
    relative to /root:

    autodl-tmp/AI2/retinanet-keras-master/train.py:242 parse_data  *
        parts = tf.strings.split(line, ' ')
    miniconda3/lib/python3.8/site-packages/tensorflow_core/python/ops/ragged/ragged_string_ops.py:642 strings_split_v1
        return ragged_result.to_sparse()

    AttributeError: 'Tensor' object has no attribute 'to_sparse'