如何在很大的火炬张量上执行操作而无需分开操作
我的任务:
我正在尝试计算两个大张量(用于k-nearest-neighbours)中每两个样品之间的成对距离,也就是说 - 给定张量测试
带有形状(B1,C,H,W)
,我需要||测试[I] - Train [J] ||
对于每个i
,j
。 (其中两个test [i]
和train [j]
具有Shape (C,H,W)
,因为这些是批处理中的sampes )。
问题
train 和
test
很大,所以我无法将它们放入RAM
我当前的解决方案
启动时,我没有一次构造这些张量 - 当我构建它们时,我将数据张量分开并分别保存到内存中,因此我最终得到了文件{test \ test_1,...,test \ test_n}
和{train \ train_1,...,Train \ Train_m}
。 然后,我将循环的嵌套加载每个
test \ test \ test_i
和train \ train_j
,计算当前距离并保存。
这次半伪码可以解释
test_files = [f'Test\test_{i}' for i in range(n)]
train_files = [f'Train\train_{j}' for j in range(m)]
dist = lambda t1,t2: torch.cdist(t1.flatten(1), t2.flatten(1))
all_distances = []
for test_i in test_files:
test_i = torch.load(test_i) # shape (c,h,w)
dist_of_i_from_all_j = torch.Tensor([])
for train_j in train_files:
train_j = torch.load(train_j) # shape (c,h,w)
dist_of_i_from_all_j = torch.cat((dist_of_i_from_all_j, dist(test_i,train_j))
all_distances.append(dist_of_i_from_all_j)
# and now I can take the k-smallest from all_distances
我认为可以起作用的
我遇到了 faiss存储库,他们解释说可以使用他们的解决方案加速此过程(也许是?),尽管我不确定如何。无论如何,任何方法都会有所帮助!
My Task:
I'm trying to calculate the pair-wise distance between every two samples in two big tensors (for k-Nearest-Neighbours), That is - given tensor test
with shape (b1,c,h,w)
and tensor train
with shape (b2,c,h,w)
, I need || test[i]-train[j] ||
for every i
,j
. (where both test[i]
and train[j]
have shape (c,h,w)
, as those are sampes in the batch).
The Problem
both train
and test
are very big, so I can't fit them into RAM
My current solution
For a start, I did not construct these tensors in one go - As I build them, I split the data Tensor and save them separately to memory, so I end up with files {Test\test_1,...,Test\test_n}
and {Train\train_1,...,Train\train_m}
.
Then, I load in a nested for
loop every Test\test_i
and Train\train_j
, calculate the current distance, and save it.
This semi-pseudo-code might explain
test_files = [f'Test\test_{i}' for i in range(n)]
train_files = [f'Train\train_{j}' for j in range(m)]
dist = lambda t1,t2: torch.cdist(t1.flatten(1), t2.flatten(1))
all_distances = []
for test_i in test_files:
test_i = torch.load(test_i) # shape (c,h,w)
dist_of_i_from_all_j = torch.Tensor([])
for train_j in train_files:
train_j = torch.load(train_j) # shape (c,h,w)
dist_of_i_from_all_j = torch.cat((dist_of_i_from_all_j, dist(test_i,train_j))
all_distances.append(dist_of_i_from_all_j)
# and now I can take the k-smallest from all_distances
What I thought might work
I came across FAISS repository, in which they explain that this process can be sped up (maybe?) using their solutions, though I'm not quite sure how. Regardless, any approach would help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否检查了 faiss文档?
如果您需要的是L2 NORM(
torch.cidst
使用p = 2
作为默认参数),则非常简单。下面的代码是您示例的FAISS文档的改编:Did you check the FAISS documentation?
If what you need is the L2 norm (
torch.cidst
usesp=2
as default parameter) then it is quite straightforward. Code below is an adaptation of the FAISS docs to your example:因此,我选择实施某种版本的地球移动距离,如以下
ai.stackexchange
post 。 Let me summarize the approach:Given the task as described in "My Task" above, I defined
then, given the tensors
test
andtrain
:For future viewers - bare in mind that:
FAISS
because it does not support windows currently, but most importantly it does not support (as far as I know of) this version of EMD or any其他版本的多维(= Shape(C,H,W)
在我的示例中类似)张量。 To account for the RAM problem I've usedGoogle Colab
and sliced my data to more filesavgpool
)作为激活,那么不使用EMD就可以了,作为avgpool
具有Shape(512,)
Consequently, I chose to implement some version of the Earth-Movers-Distance, as was suggested in the following
ai.StackExchange
post. Let me summarize the approach:Given the task as described in "My Task" above, I defined
then, given the tensors
test
andtrain
:For future viewers - bare in mind that:
FAISS
because it does not support windows currently, but most importantly it does not support (as far as I know of) this version of EMD or any other version of multidimensional (=shape(c,h,w)
like in my example) tensors distance. To account for the RAM problem I've usedGoogle Colab
and sliced my data to more filesavgpool
) as my activations, It would have been fine not using the EMD, as the output right after theavgpool
has shape(512,)