我正在做Udacity深度学习课程,我正在做第一个作业,问题5,你试着计算重复的数量,比如说,你的测试集和训练集。(或验证和培训等)
我看过别人的答案,但出于各种原因,我对他们不满意。例如,我尝试了某人的基于哈希的解决方案。但我觉得返回的结果不太可能是正确的。
因此,主要的想法是,您有一个图像数组,这些图像被格式化为数组。也就是说,您正在尝试比较索引0上的两个三维数组。一个数组是训练数据集,它是200000行,每一行包含一个二维数组,该数组是图像的值。另一个是测试集,是10000行,每行包含一个图像的二维数组。目标是在测试集中找到匹配的所有行(就目前而言,完全匹配是可以的)。因为每一行本身都是一个图像(这是一个二维数组),所以要使这一工作更快,我必须能够对这两个集合进行比较,作为对每一行的元素比较。
我想出了自己相当简单的解决方案,如下所示:
# Find duplicates
# Loop through validation/test set and find ones that are identical matrices to something in the training data
def find_duplicates(compare_set, compare_labels, training_set, training_labels):
dup_count = 0
duplicates = []
for i in range(len(compare_set)):
if i > 100: continue
if i % 100 == 0:
print("i: ", i)
for j in range(len(training_set)):
if compare_labels[i] == training_labels[j]:
if np.array_equal(compare_set[i], training_set[j]):
duplicates.append((i,j))
dup_count += 1
return dup_count, duplicates
#print(len(valid_dataset))
print(len(train_dataset))
valid_dup_count, duplicates = find_duplicates(valid_dataset, valid_labels, train_dataset, train_labels)
print(valid_dup_count)
print(duplicates)
#test_dups = find_duplicates(test_dataset, train_dataset)
#print(test_dups)它之所以在100之后“继续”,是因为光是这一点就需要很长的时间。如果我要尝试将所有10,000行验证集与培训集进行比较,则需要花费很长时间。
原则上,我喜欢我的解决方案,因为它允许我不仅计算副本,而且还可以得到哪些匹配项存在的列表。(我看过的每一个解决方案都缺少一些东西。)这允许我手动测试我是否得到了正确的解决方案。
我真正需要的是一个更快的(即内置于Numpy)的解来比较这样的矩阵矩阵。我玩过“isin”和“where”,但还没有弄清楚如何使用这些来获得我想要的结果。有人能为我找到更快的解决方案吗?
发布于 2017-12-19 08:15:02
您应该能够使用compare_set将training_set中所有图像中的单个图像与使用np.all()的一行代码进行比较。您可以在axis参数中以元组的形式提供多个轴,以检查行和列上的数组相等,并对每个图像进行检查。然后np.where()可以给出你想要的指数。
例如:
n_train = 50
n_validation = 10
h, w = 28, 28
training_set = np.random.rand(n_train, h, w)
validation_set = np.random.rand(n_validation, h, w)
# create some duplicates
training_set[5] = training_set[10]
validation_set[2] = training_set[10]
validation_set[8] = training_set[10]
duplicates = []
for i, img in enumerate(validation_set):
training_dups = np.where(np.all(training_set == img, axis=(1, 2)))[0]
for j in training_dups:
duplicates.append((i, j))
print(duplicates)(2,5),(2,10),(8,5),(8,10)
许多numpy函数(包括np.all() )允许您指定要操作的轴。例如,假设您有两个数组
>>> A = np.array([[1, 2], [3, 4]])
>>> B = np.array([[1, 2], [5, 6]])
>>> A
array([[1, 2],
[3, 4]])
>>> B
array([[1, 2],
[5, 6]])现在,A和B有相同的第一行,但第二行不同。如果我们检查它们是否相等
>>> A == B
array([[ True, True],
[False, False]], dtype=bool)我们得到一个与A和B相同形状的数组。但是,如果我想要行的索引是相等的呢?在这种情况下,我们可以做的是:“如果行中的所有值(即每列中的值)都是True,则只返回True”。因此,我们可以在等式检查之后使用np.all(),并为其提供对应于列的轴。
>>> np.all(A == B, axis=1)
array([ True, False], dtype=bool)因此,这个结果让我们知道,第一行在两个数组中是相等的,而第二行并不都是相等的。然后,我们可以使用np.where()获取行索引。
>>> np.where(np.all(A == B, axis=1))
(array([0]),)这里我们看到了第0行,即A[0]和B[0]是相等的。
现在,在我提出的解决方案中,您有一个3D数组而不是这些2D数组。我们不在乎一行是否相等,我们关心的是所有行和列是否相等。因此,将其分解为上面,让我们创建两个随机的5x5图像。我将获取其中一个图像,并检查两个图像数组之间是否相等:
>>> imgs = np.random.rand(2, 5, 5)
>>> img = imgs[1]
>>> imgs == img
array([[[False, False, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False]],
[[ True, True, True, True, True],
[ True, True, True, True, True],
[ True, True, True, True, True],
[ True, True, True, True, True],
[ True, True, True, True, True]]], dtype=bool)因此,很明显,第二个值是正确的,但我希望将所有这些True值降为一个True值;我只想要与每个值相等的图像对应的索引。
如果我们使用axis=1
>>> np.all(imgs == img, axis=1)
array([[False, False, False, False, False],
[ True, True, True, True, True]], dtype=bool)然后,如果每一行中的所有列都是等效的,则得到每一行的True。实际上,我们也希望通过检查所有行的相等性来进一步减少这种情况。因此,我们可以接受这个结果,将其输入np.all(),并沿着结果数组的行进行检查:
>>> np.all(np.all(imgs == img, axis=1), axis=1)
array([False, True], dtype=bool)这给了我们一个布尔值,其中imgs中的图像等于img,我们可以简单地用np.where()得到结果。但是,实际上不需要像这样两次调用np.all();相反,您可以在一个元组中提供多个轴,以便在一步内减少行和列的大小:
>>> np.all(imgs == img, axis=(1, 2))
array([False, True], dtype=bool)上面的解决方案就是这么做的。希望这能把它弄清楚!
https://stackoverflow.com/questions/47878756
复制相似问题