给定一个序列
<
x
1
,
…
,
x
n
>
<x_1,\dots,x_n>
<x1,…,xn>,想打乱其中 p(
p
∈
[
0
,
1
]
p\in[0,1]
p∈[0,1])比例位置的顺序。这在 noisy label 中用到,如 [1] 中的 PrecompDataset 就用打乱顺序的方式模拟 noisy pair,而 [1] 用的打乱方式简单用 numpy.random.shuffle,可能会导致打乱不彻底,即一些元素还在原来的位置,如:
import numpy as np
b = np.arange(5) # [0, 1, 2, 3, 4]
np.random.shuffle(b)
print(b) # [0, 4, 2, 3, 1],其中 0、2、3 还在原位
以致实际被打乱的位置可能不足 p%,为保证足有 p% 的乱序,可如此写:
import numpy as np
# 示例数据
n = 7 # 数据量
x = np.arange(n * 5).reshape(n, 5) # 二维数据
x_orig = x.copy()
print("original:", x)
p = 0.4 # 乱序比例
noise_length = int(p * n) # 乱序数量
pos_to_shuffle = np.random.permutation(n)[:noise_length] # 随机选 noise_length 个要打乱的位置
# 打乱这些下标:加一个随机偏移
meta_index = np.arange(noise_length) # pos_to_shuffle 的下标
rnd_shift = np.random.randint(1, noise_length) # 随机偏移:[1, noise_length)
# print(rnd_shift)
shuffled_pos = pos_to_shuffle[(meta_index + rnd_shift) % noise_length]
# print(pos_to_shuffle, shuffled_pos)
assert (pos_to_shuffle != shuffled_pos).all()
# 用乱序下标打乱数据
x[pos_to_shuffle] = x[shuffled_pos]
print("shuffled:", x)
# 验证 noise rate 如期
assert (x_orig[:, 0] != x[:, 0]).sum() == noise_length
real_p = round((x_orig[:, 0] != x[:, 0]).sum() / n, 6)
assert real_p > 0
exp_p = round(noise_length / n, 6)
print("real p:", real_p, " v.s. expected p:", exp_p)
本文介绍了一种改进的方法来在Python中打乱数据序列,以在noisylabel中更有效地模拟噪声对标签的影响。原始的shuffle方法可能导致部分元素位置不变,作者提出使用随机排列和偏移确保至少有预定比例的元素被正确打乱。
2530

被折叠的 条评论
为什么被折叠?



