Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tensorflow数据集API中的过采样功能_Python_Tensorflow_Sampling_Tensorflow Datasets - Fatal编程技术网

Python Tensorflow数据集API中的过采样功能

Python Tensorflow数据集API中的过采样功能,python,tensorflow,sampling,tensorflow-datasets,Python,Tensorflow,Sampling,Tensorflow Datasets,我想问一下,当前的数据集API是否允许实现过采样算法?我处理高度不平衡的班级问题。我在想,在数据集解析(即在线生成)过程中对特定类进行过采样会很好。我已经看到了rejection_resample函数的实现,但是这会删除样本,而不是复制样本,并且会减慢批处理生成(当目标分布与初始分布大不相同时)。我想实现的是:举个例子,看看它的类概率,决定是否复制它。然后调用dataset.shuffle(…)dataset.batch(…)并获取迭代器。在我看来,最好的方法是对低概率类进行过抽样,对最可能类进

我想问一下,当前的数据集API是否允许实现过采样算法?我处理高度不平衡的班级问题。我在想,在数据集解析(即在线生成)过程中对特定类进行过采样会很好。我已经看到了rejection_resample函数的实现,但是这会删除样本,而不是复制样本,并且会减慢批处理生成(当目标分布与初始分布大不相同时)。我想实现的是:举个例子,看看它的类概率,决定是否复制它。然后调用
dataset.shuffle(…)
dataset.batch(…)
并获取迭代器。在我看来,最好的方法是对低概率类进行过抽样,对最可能类进行次抽样。我想在网上做,因为它更灵活

这个问题已在问题中得到解决。 只是在这里发布anwser,让其他开发人员更容易看到它

示例代码对低频类进行过采样,对高频类进行欠采样,在我的例子中,
class\u target\u prob
只是均匀分布。我想检查一下最近手稿中的一些结论

特定类的过采样通过调用:

dataset = dataset.flat_map(
    lambda x: tf.data.Dataset.from_tensors(x).repeat(oversample_classes(x))
)
以下是完成所有工作的完整片段:

# sampling parameters
oversampling_coef = 0.9  # if equal to 0 then oversample_classes() always returns 1
undersampling_coef = 0.5  # if equal to 0 then undersampling_filter() always returns True

def oversample_classes(example):
    """
    Returns the number of copies of given example
    """
    class_prob = example['class_prob']
    class_target_prob = example['class_target_prob']
    prob_ratio = tf.cast(class_target_prob/class_prob, dtype=tf.float32)
    # soften ratio is oversampling_coef==0 we recover original distribution
    prob_ratio = prob_ratio ** oversampling_coef 
    # for classes with probability higher than class_target_prob we
    # want to return 1
    prob_ratio = tf.maximum(prob_ratio, 1) 
    # for low probability classes this number will be very large
    repeat_count = tf.floor(prob_ratio)
    # prob_ratio can be e.g 1.9 which means that there is still 90%
    # of change that we should return 2 instead of 1
    repeat_residual = prob_ratio - repeat_count # a number between 0-1
    residual_acceptance = tf.less_equal(
                        tf.random_uniform([], dtype=tf.float32), repeat_residual
    )

    residual_acceptance = tf.cast(residual_acceptance, tf.int64)
    repeat_count = tf.cast(repeat_count, dtype=tf.int64)

    return repeat_count + residual_acceptance


def undersampling_filter(example):
    """
    Computes if given example is rejected or not.
    """
    class_prob = example['class_prob']
    class_target_prob = example['class_target_prob']
    prob_ratio = tf.cast(class_target_prob/class_prob, dtype=tf.float32)
    prob_ratio = prob_ratio ** undersampling_coef
    prob_ratio = tf.minimum(prob_ratio, 1.0)

    acceptance = tf.less_equal(tf.random_uniform([], dtype=tf.float32), prob_ratio)

    return acceptance


dataset = dataset.flat_map(
    lambda x: tf.data.Dataset.from_tensors(x).repeat(oversample_classes(x))
)

dataset = dataset.filter(undersampling_filter)

dataset = dataset.repeat(-1)
dataset = dataset.shuffle(2048)
dataset = dataset.batch(32)

sess.run(tf.global_variables_initializer())

iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()
更新#1 下面是一个在玩具模型上实现上述过采样/欠采样的简单示例

似乎是一种更好的方法,因为它不需要“class\u prob”和“class\u target\u prob”功能。

虽然它是欠采样而不是过采样,但目标分布和训练步骤相同,但效果也一样。

这个QnA对我非常有用。因此,我写了一篇博客文章,介绍了我的相关经验

我希望对Tensorflow输入管道优化和重新采样感兴趣的人可以从中获得一些想法

有些老年退休金可能是不必要的冗余,但在我个人的情况下,并不是太大的性能下降因素

 dataset = dataset.map(undersample_filter_fn, num_parallel_calls=num_parallel_calls) 
 dataset = dataset.flat_map(lambda x : x) 
带有identity lambda函数的平面映射仅用于合并幸存(和空)记录


请举例说明
dataset.flat\u map(lambda x:tf.data.dataset.from\u tensors(x).repeat(oversample\u classes(x))
中的
数据集的内容应该是什么样子?看看我添加的原始帖子中的更新。谢谢。笔记本真的很有用。谢谢!该实现的速度是否与从过采样数据构造tfrecords然后将其提供给Dataset API的速度相当?问题是数据集通常是从tf_记录文件读取的,该文件不包含“class_pro”和“class_target_pro”属性。如果它不需要编写新的tfrecord文件,那么它将非常有用,否则为什么您在编写新的tfrecord文件时不进行过采样呢?您应该接受您的答案:)
# Pseudo-code for understanding of flat_map after maps
#parallel calls of map('A'), map('B'), and map('C')
map('A') = 'AAAAA' # replication of A 5 times
map('B') = ''      # B is dropped
map('C') = 'CC'    # replication of C twice
# merging all map results
flat_map('AAAA,,CC') = 'AAAACC'