如何使用Inception-v3模型的代码平衡类?

时间:2017-03-17 03:22:13

标签: tensorflow

模型/开始/开始/ image_processing.py

我是tersorflow的初学者。我正在使用TF-Slim中表达的Inception-V3的实现,从头开始使用不同的数据集进行训练。我正在尝试解决5个类的问题,并且数据集完全不平衡。第一类的数据多于其他4类的总数。损失不会下降,并且如预期的那样,不幸的是所有图像都被归类为“1”。

我部分理解张量流是如何工作的,但我现在面临一个问题,不知道如何解决它。我们怎样才能构建按类平衡的批次?我认为,最简单的方法是与数据扩充并行地解决类平衡问题。这包括应用过采样,复制不太受欢迎的类的图像(在扭曲它们之前),以便与人口最多的类平衡。但我不想手动执行此操作(这将占用磁盘中的大量额外空间),我更喜欢动态地执行此操作。

为简洁起见,假设我们分别为1,2和3级有2000个图像,500个图像和100个图像。为了平衡这些类,我们将重复第2类中的每个数据(3份)和3份(19份)。副本(或重复)将在应用图像失真之前完成。

数据采用原生TFRecord格式。有人可以帮我解决这个问题吗?

代码:https://github.com/tensorflow/models/blob/master/inception/inception/image_processing.py

更新:

感谢另外两个类似的线程(Online oversampling in Tensorflow input pipelineHow to duplicate input tensors conditional on a tensor attribute ("oversampling") in a Tensorflow queue?),我有一个问题的解决方案。

与@citrusvanilla一样,我尝试使用tf.case(),但它没有用。 tf.cond()就够了。就我而言,我需要对每个版本的图像应用一些随机扰动。我不知道这是否是最合适的选择,但我正在使用tf.map_fn()来解决这个问题。

`# Example for three classes (class 0 is not used)

def oversample_by_cond(images, label):
   # Oversampling factors per class
   OVERSAMPLE_FACTOR = [1, 1, 4]

   # Set up the predicates
   pred0 = tf.reshape(tf.equal(label, tf.convert_to_tensor([0])), [])
   pred1 = tf.reshape(tf.equal(label, tf.convert_to_tensor([1])), [])
   pred2 = tf.reshape(tf.equal(label, tf.convert_to_tensor([2])), [])

   # Callables functions
   def f0(): return tf.concat([images]*OVERSAMPLE_FACTOR[0], 0), tf.concat([label]*OVERSAMPLE_FACTOR[0], 0)
   def f1(): return tf.concat([images]*OVERSAMPLE_FACTOR[1], 0), tf.concat([label]*OVERSAMPLE_FACTOR[1], 0)
   def f2(): return tf.concat([images]*OVERSAMPLE_FACTOR[2], 0), tf.concat([label]*OVERSAMPLE_FACTOR[2], 0)

   # Exclusive conditionals (one for each class)
   [images, label] = tf.cond(pred0, f0, lambda: [images,label])
   [images, label] = tf.cond(pred1, f1, lambda: [images,label])
   [images, label] = tf.cond(pred2, f2, lambda: [images,label])

   return [images, label]

images = tf.expand_dims(image_decoded, 0)                                                                                                                                                                                                                               

if train:
    # Oversample the train set in order to balance the classes
    [images, labels] = oversample_by_cond(images, label_index)

    # Distort all the concatenated version of the training image
    thread_id = itertools.cycle(range(num_preprocess_threads))
    images = tf.map_fn(lambda img: image_preprocessing(img, bbox, train,
        next(thread_id), summariesFlag=False), images)
    images_and_labels = [images, labels]

else:
    # validation/test set
    image = image_preprocessing(image_decoded, bbox, train, thread_id)
    images_and_labels = [tf.expand_dims(image, 0), label_index]`

1 个答案:

答案 0 :(得分:0)

作为一种初始方法,您是否尝试过减少大型课程中的示例数量,使其与其他课程的数量相同?这至少会让你大致了解这种规模的训练是否可行。

如果你只有一个小的数据集,我也会强烈考虑使用转移学习,这样你就可以建立一个已经在大型训练集上训练另一个问题的网络,并对其进行微调。这里有一些关于做到这一点的信息: https://github.com/tensorflow/models/blob/master/inception/inception/slim/README.md#reusing-the-vgg16-network-defined-in-tf-slim-on-a-different-task-ie-pascal-voc

您还可以查看TensorFlow for Poets教程: https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/index.html#0