파이톨치

[BoostCamp AI Tech] 파이토치 기본 본문

AI&ML/BoostCamp AI Tech

[BoostCamp AI Tech] 파이토치 기본

파이톨치 2024. 8. 9. 13:31
728x90

텐서 생성과 조작

t = torch.tensor([[1, 2, 3], [4, 5, 6])

 

위와 같이 안에 list를 넣어주면 텐서가 생성된다.

 

torch.from_numpy(n_arr).float()

 

넘파이로부터 tensor를 생성할 수도 있다. float() 매서드를 통해서 실수형으로 바꾸어 준다. 

 

t.reshape(1, -1)

 

텐서 모양을 바꿀 수 있다. -1은 가능한 모양으로 알아서 맞춰달라는 뜻으로, 모양이 2x3 텐서 => 1x6이 될 것이다. 

 

t.dtype
t.shape

 

텐서의 모양과 텐서 내부의 타입을 확인할  수 있다. 

 

stack과 cat에 대해

stack과 cat은 유사한 동작을 하지만 다르다. 

cat 은 차원을 늘려주지 않고, 동일한 차원에서 확장하는 느낌이고, stack은 차원을 늘려서 확장해주는 느낌이다. 

 

torch.stack([t1, t3], dim=0)

# result 
tensor([[[0., 1., 2.],
         [3., 4., 5.]],

        [[6., 7., 8.],
         [6., 7., 8.]]])

torch.cat([t1, t3], dim=0)

# result
tensor([[0., 1., 2.],
        [3., 4., 5.],
        [6., 7., 8.],
        [6., 7., 8.]])

 

또 다른 특징으로는, cat은 브로드 캐스팅을 해주지만, stack은 해주지 않다 더 엄격하다. 

참고로, stack을 사용해서 2차원 텐서로부터 RGB 이미지를 만들 수 있다.

 

torch를 이용한 통계값 

print('torch.min: ', torch.min(l))
print('torch.max: ', torch.max(l))
print('torch.sum: ', torch.sum(l))
print('torch.prod: ', torch.prod(l))
print('torch.mean: ', torch.mean(l))
print('torch.var: ', torch.var(l))
print('torch.std: ', torch.std(l))

 

python 내부 함수와 비슷한 느낌을 받는다. 다만, torch 라이브러리에서 가져오고, 더 다양한 연산이 가능하다. 

prod 같은 경우, product의 약자로 모든 요소의 곱을 의미한다. 

 

특정 크기의 tensor 생성

원하는 크기의 텐서를 생성할 수 있다. 모든 값이 0인 행렬을 생성하고 싶다면 다음과 같이 작성한다. 

torch.zeros([2, 3])

 

만약 1로 생성하고 싶다면, ones로 바꾸어 주면 된다. 

또한 크기가 같은 0 행렬을 생성하고 싶다면, 다음과 같다. t는 어떤 텐서를 의미한다. 

torch.zeros_like(t)

 

난수를 생성할 수도 있다. rand와 randn이 있다.

n이 붙으면 정규분포를 따르는 난수가 생성되고, 없으면 0~1 사이 값이 생성된다. 

torch.rand([2,3])
torch.randn([2,3])

 

python range와 비슷한 함수도 있다. (기본적으로, 파이썬 코딩 스타일을 따라가려는 듯하다.) 

arange는 array range의 약자이다. 

torch.arange(0, 10, 2)

 

메모리의 최적화를 위해 빈 텐서를 생성하고 채우기도 한다.  (사실, 최적화는 아직 고려할 문제는 아닌듯 하다.)

여기서 fill_ 는 빈 텐서를 채우는 용도인데, _를 쓰는 순간 in-place 방식으로 동작한다. 

이는 추가적인 메모리를 사용하지 않고, t에 할당된 메모리를 사용한다는 의미이다. 

t= torch.empty(5)
torch.fill_(t, 3.0)

detach()에 대해서 

텐서를 복제할 때는, detach 함수를 사용한다. copy도 유사한 동작을 하지만, 차이점이 있다. 

detach의 경우, 계산 그래프에서 텐서를 분리하여 기울기 계산이 되지 않게 만든다. 

pytorch의 장점 중 하나이 계산 그래프인 점을 생각했을 때, detach 함수의 용도는 중요하다 생각된다. 

 

detach의 목적은 특정 층을 고정하기 위함이라고 한다.

또한, gardient의 전파를 멈추게 하여, 이 뒤에 있는 층까지 학습이 안되게 하는 듯하다. 

이를 통해, 원하는 특정 층만 학습하게 할 수 있을 것이다. 

 

copy()는 python은 list copy와 비슷하지만, 계산 그래프에 포함된다 한다. 

x.detach()

 

expand와 repeat

둘 다 텐서를 확장하는 매서드인데, expand의 경우, veiw만 반환해서 원본 텐서와 메모리를 공유한다고 한다. 

즉, 보여주기만 확장한 것 처럼 보이지 새로운 텐서는 아니다. 또한, 확장시 원본 크기와 호환이 되어야 한다. 

원본 텐서의 크기가 1인 차원(,n)만 확장할 수 있다. 

 

하지만, repeat의 경우 메모리 성능이 조금 떨어지지만 유연한 모습을 모인다. 확장시 제한도 없다. 

 

f = torch.tensor([1, 2, 3])

h = f.repeat(4, 2)

# h 내부 값 
tensor([[1, 2, 3, 1, 2, 3],
        [1, 2, 3, 1, 2, 3],
        [1, 2, 3, 1, 2, 3],
        [1, 2, 3, 1, 2, 3]])

 

728x90

norm

norm, 노름은 원점에서 얼마나 떨어져 있는지에 대한 척도이다. 이것을 차원에 대해서 나눈다. 

1차원은 모든 요소의 절대값의 합이고, 2차원은 모든 요소의 제곱의 합의 제곱근 (원점과 벡터 사이 거리)이다. 

무한대 차원인 경우 값의 최대 값이다. max 값과 연산 결과가 동일하다. 

 

코드 상에선 간단하게 표현이 가능하다. 2번째 인자가 차원이다. 

# L1 norm 
torch.norm(a, 1)

# L2 norm 
torch.norm(a, 2)

# inf norm 
torch.norm(a, float('inf'))

 

유사도 

유사도는 벡터와 벡터가 얼마나 비슷한지를 나타낸다. 

유사도를 구하기 위해서는 먼저 거리를 구해야 한다. 

거리는 norm을 이용하면 쉽게 구할 수 있다. 

 

manhatten_distance = torch.norm(a-b, 1)

 

다음과 같이, 말이다. 

 

이 distance 값에 1/(1+distance)를 하면 된다. 차원이 커지건 동일하다. 

1차원은 맨허튼 유사도라 부르고, 2차원은 유클리드 유사도라 부른다. 

 

다만, 특징적으로 다른 유사도가 하나 있다. 바로 코사인 유사도이다. 

 

코사인 유사도는 수학이 들어가는 개념인데, 어렵진 않다. 두 벡터가 있을 때, 그 사이 코사인 값을 구하는 것이다. 

 

cos_sim = torch.dot(a, b) / (torch.norm(a, 2) * torch.norm(b, 2))

 

내적 값에서 스칼라 값을 나누어준 것과 같다. 기벡 투영 개념으로 이해하면 된다. 

 

dot, matmul, mm, @ 차이점

dot은 1차원 벡터 간의 내적을 계산할 때 사용한다. 

matmul은 다양한 차원의 텐서 간의 곱셈을 수행할 때 사용한다. 브로드캐스팅 또한 지원한다. 

mm은 행렬 간의 곱셈을 수행한다. 

@은 matmul과 동일한 연산을 수행한다. 

torch.dot(a, b)
torch.mm(a, b)
torch.matmul(a, b)
a @ b

 

 

728x90