我是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 pipeline和How 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]`
答案 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