안녕하세요. 오랜만에 블로그 포스팅 올려보네요.
일하다가 torch.cdist라는 함수와 마주치게 되었는데, 마침 구글링을 해보니 한국어 자료가 0개여서 누군가에게 도움이 되고자 이렇게 포스팅을 만들게 되었습니다.
그럼 시작해보도록 하겠습니다.
torch.cdist의 공식 document의 주소는 다음과 같습니다.
https://pytorch.org/docs/stable/generated/torch.cdist.html
해당 함수에 대해서 설명하는 내용을 읽어보면, 'Computes batched the p-norm distance between each pair of the two collections of row vectors'라고 적혀 있습니다.
쉽게 말씀드리자면, 두 개의 벡터에서 각 행의 pair끼리의 p-norm distance를 구한 것이라는 설명입니다.
물론 이렇게 말씀드리면 이해하기가 어려우실 수 있으니, 이번에도 예시를 통해서 설명드리도록 하겠습니다.
p-norm에 대한 설명은 다른 블로그들이나 자료들을 참고해서 이해해주시고 본 포스팅에서는 별도로 설명드리지 않습니다.
import torch
import numpy as np
먼저 예시를 만들기 위한 library 두개를 import 해줍니다. pytorch와 numpy가 필요합니다.
a = torch.tensor(np.arange(1, 7).reshape(1, 3, 2), dtype=torch.float64)
print(a)
b = torch.tensor(np.arange(0.1, 0.9, 0.1).reshape(1, 4, 2))
print(b)
예시를 위해서 1부터 6까지 구성되는 numpy array를 만들고, (1, 3, 2)로 reshape 한 뒤에 torch tensor로 변환합니다.
또, 0.1부터 0.8까지 구성되는 numpy array를 만들고, (1, 4, 2)로 reshape 한 뒤에 torch tensor로 변환합니다.
참고로 torch.cdist는 column의 size가 동일한 vector끼리만 연산이 가능합니다. 따라서, 두 vector는 2차원으로 만들어두었습니다.
위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다.
print(torch.cdist(a, b))
앞에서 선언한 a와 b를 torch.cdist를 이용해서 연산해줍니다.
이를 이용하면 다음과 같은 결과를 볼 수 있습니다.
값들이 꽤나 복잡하죠? 이에 대한 설명을 드리도록 하겠습니다.
앞에서 정의했던 a와 b는 다음과 같은 vector입니다. shape는 각각 Bx3x2와 Bx4x2로 정의하였습니다. B는 Batch size이며, 현재 예시에서는 1로 적용하였습니다.
torch.cdist에서는 a 벡터의 row와 b 벡터의 row를 각각 pair로 만들고, 이에 대한 distance를 계산하게 됩니다.
a 벡터의 첫 번째 row와 b 벡터의 첫 번째 row, a 벡터의 첫 번째 row와 b 벡터의 두 번째 row.... 이런식으로 해서 a 벡터의 세 번째 row와 b 벡터의 네 번째 row까지 모두 pair를 만들면 총 몇 개의 pair가 만들어질까요?
3x4=12개의 pair가 만들어집니다.
그래서 위에서 보여드린 document에서는 다음과 같은 내용을 담고 있습니다.
만약 x1이 P 개의 row를 가지고 있고, x2가 R 개의 row를 가지고 있으면, 총 P x R 개의 pair가 만들어지므로, 결과값의 shape가 P x R 이라는 얘기입니다.
다시 위 예시로 돌아가서, 직접 한 개씩 연산을 진행해보겠습니다.
먼저 a 벡터의 첫 번째 row와 b 벡터의 첫 번째 row를 pair로 만들고, 이 둘 간의 distance를 계산해줍니다.
이를 output 벡터의 (1, 1) 위치에 적어줍니다.
다음으로는 a 벡터의 첫 번째 row와 b 벡터의 두 번째 row를 pair로 만들고, 이 둘 간의 distance를 계산해줍니다.
이를 output 벡터의 (1, 2) 위치에 적어줍니다.
이러한 방식으로 진행하기 때문에, output 벡터의 column 개수는 b 벡터의 row와 같아지게 됩니다.
왜냐하면 b 벡터의 row 개수 만큼 계산을 진행해서, 이를 가로로 펴는 방식이기 때문이지요.
다음으로 a 벡터의 두 번째 row와 pair를 지어볼까요?
아무래도 수식이 커지다보니 그림이 작아졌네요.
a 벡터의 두 번째 row와 b 벡터의 첫 번째 row가 pair가 되어, 계산 결과가 output의 (2, 1) 위치에 오게 됩니다.
즉, 이러한 방식으로 진행되므로 output 벡터의 row 개수는 a 벡터의 row 개수가 같아지게 됩니다.
앞에서 설명한 방식을 전부 실행하면 다음과 같은 결과를 볼 수 있습니다.
이번 포스팅에서는 간단하게 torch.cdist 함수가 어떻게 작동하는지 예시를 통해서 준비해보았습니다.
감사합니다.
'딥러닝 & 머신러닝 > 이것저것?' 카테고리의 다른 글
[OpenCV 오류] cv2.error: OpenCV(3.4.2) (-209: sizes of input arguments do not match) (0) | 2022.07.30 |
---|---|
scipy.ndimage.label과 skimage.measure.regionprops를 이용한 이미지 내에서 특정값 이상의 값을 가지는 위치 찾기 (1) | 2021.05.06 |
torch.nn.ConvTranspose2d는 어떻게 작동할까요? (5) | 2021.03.24 |
python에서 다중 정렬을 해야할 때 어떻게 할까요?(sorted 이용) (0) | 2020.08.29 |
what is numpy.void type?(numpy.void type은 무엇일까요?) (1) | 2020.08.29 |