Pytoch Master - (2)

raziel·2022년 1월 23일
0

PytorchMaster

목록 보기
2/3

5. 텐서의 연산

파이토치에서 다루는 모든 벡터, 행렬, 텐서들에 대해서
덧셈, 뺄셈, 내적, 외적을 할 수 있습니다.

import torch as th
from torch import tensor
vec1 = tensor([1, 2, 3])
vec2 = tensor([4, 5, 6])
# 벡터의 dot product를 위해서는 dot 메소드를 활용합니다. 
vec3 = vec1.dot(vec2) # 5 + 12 + 21
print(vec3)
# 벡터의 cross product를 위해서는 cross 메소드를 활용하며 벡터의 길이는 3차원이어야 합니다.
cvec = th.cross(vec1, vec2)
print(cvec)
# 에스터리스크(asterisk) * 기호는 element wise prodict를 수행합니다. 
vec4 = vec1 * vec2
print(vec4)
mat1 = tensor([[1, 2],
               [3, 4]])
mat2 = tensor([[5, 6],
               [7, 8]])
# 행렬에서도 마찬가지로 원소곱을 수행합니다. 
mat3 = mat1 * mat2
print(mat3)
# at sign @ 기호는 행렬곱을 수행하게 됩니다. 
# matmul 함수를 통해서도 행렬곱을 계산할 수 있습니다. 
mat4 = mat1 @ mat2
mat5 = mat1.matmul(mat2) 
print(mat4)
print(mat5)
ten1 = tensor([[[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]], 
              [[10, 11, 12],
                [13, 14, 15],
                [16, 17, 18]], 
              [[19, 20, 21],
                [22, 23, 24],
                [25, 26, 27]], 
                ])
ten2 = 2 * tensor([[[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]], 
              [[10, 11, 12],
                [13, 14, 15],
                [16, 17, 18]], 
              [[19, 20, 21],
                [22, 23, 24],
                [25, 26, 27]], 
                ])
ten3 = ten1 * ten2
print(ten3)
ten4 = ten1 @ ten2
print(ten4)

6. 텐서 차원 조작 * 중요!!! *

딥러닝 모델에 데이터를 입력하기 위해 텐서의 차원을 정말 잘 다루어야 합니다.
이때 차원을 조작하는 메소드로는 다음과 같습니다. flatten(), reshape(), view()가 있습니다. 1) 차원 축소, 확장 : squeeze(), unsqueeze()
2) 차원 교환 : transpose(), permute()
3) 차원 조정 : flatten(), view() reshape()
4) 텐서 합성 및 적재 : cat() stack()

6.1 차원 축소, 확장 : squeeze(), unsqueeze()

# torch.ones(shape) 를 통해 모든 값이 1인 텐서를 쉽게 만들 수 있습니다. 
# 마찬가지로 torch.zeros(shape)도 가능합니다. 
tensor_7d = th.ones([10, 32, 1, 1, 64, 64, 3])
print(tensor_7d.shape)
# torch.squeeze() 함수는 차원의 크기가 1인 축을 제거합니다. 
tensor_6d = tensor_7d.squeeze(axis=2) # shape에서 2번째 인덱스를 제거
tensor_5d = tensor_7d.squeeze() # axis를 넣지 않으면 모든 축을 제거합니다.
print(tensor_6d.shape)
print(tensor_5d.shape)
tensor_4d = th.ones([32, 3, 64, 64])
print(tensor_4d.shape)
# torch.unsqueeze(axis=m) 텐서의 m번째 축에 크기가 1인 차원을 추가합니다. 
tensor_5d = tensor_4d.unsqueeze(0)
print(tensor_5d.shape)

6.2 차원 교환 : transpose(), permute()

위 메소드들은 주로 데이터를 변환할 때 많이 사용합니다.

matrix = th.ones([2,3])
print(matrix.shape)
# transpose(input, dim0, dim2)는 인풋 텐서의 두 차원을 바꿉니다. 
transposed = th.transpose(matrix, 0, 1)
print(transposed.shape)

ten = th.ones([4, 2, 6, 11])
trans_ten = ten.transpose(0, 2)
print(trans_ten.shape)
permuted_ten = th.permute(ten, (1, 0, 2, 3))
print(permuted_ten.shape)

6.3 차원 조정 : flatten(), reshape(), view()

위 세 가지 메소드는 주로 CNN 레이어에서 FC 레이어로 오고 갈 때 자주 사용합니다.

# flatten() 메소드는 텐서 전체를 1차원 벡터로 변환합니다. 
t = tensor([[[1, 2],
             [3, 4]],
             [[5, 6],
             [7, 8]]])
print(t.shape)
flattend_t = th.flatten(t)
print(flattend_t.shape)
# 만약 start_dim, end_dim이 주어지면 해당하는 차원만 평탄화하게 됩니다.
flattend_t2 = th.flatten(t, start_dim=1)
print(flattend_t2)
print(flattend_t2.shape)
# reshape()는 텐서를 원하는 모양을 가지도록 차원을 조정합니다. 
# 단 이때, 각각 차원의 총 곱이 원래의 차원과 일치해야 합니다 27 = 9 * 3 = 3 * 3 * 3
t2 = th.arange(27)
t2.shape
reshaped_t2 = t2.reshape(3, 3, 3)
print(reshaped_t2.shape)
reshaped_t2 = t2.reshape(9, 3)
print(reshaped_t2.shape)
# view()는 차원의 크기가 아주 커서 reshape를 통해 계산하기 힘들 때 주로 사용합니다. 
t3 = th.arange(24940)
# 이때 -1 값이 들어가면 해당 축의 차원 크기를 자동으로 계산합니다. 
viewed_t1 = t3.view(-1, 5, 4) 
viewed_t2 = t3.view(2, -1, 5) 
viewed_t3 = t3.view(5, 1, -1) 
print(viewed_t1.shape)
print(viewed_t2.shape)
print(viewed_t3.shape)

6.4 텐서 합성 및 적재 : cat() stack()

마지막으로 텐서를 합성하기 위해 cat()과 stack()을 활용합니다.
cat() 함수는 모델 내부에서 다음 은닉층에 들어가는 텐서들을 조합하기 위해 주로 사용합니다.

stack() 함수는 데이터를 쌓아서 미니배치를 구성할 때 주로 사용합니다.

# cat() 함수는 두 개 이상의 텐서들은 합치게 됩니다. 해당 텐서들의 차원은 반드시 같아야 합니다. 
vec1 = tensor([1, 2, 3])
vec2 = tensor([4, 5, 6])
vec3 = tensor([7, 8, 9])
vec4 = th.cat([vec1, vec2, vec3])
print(vec4)
# stack() 메소드는 두 개 이상의 텐서들을 특정 축을 기준으로 쌓게 됩니다. 마찬가지로 차원이 같아야 합니다.
batch_vec = th.stack([vec1, vec2, vec3], dim=0)
print(batch_vec)
print(batch_vec.shape)

batch_vec2 = th.stack([vec1, vec2, vec3], dim=1)
print(batch_vec2)
print(batch_vec2.shape)
a = th.linspace(start=-10, end=10, steps=100)
print(a)
import torch.nn.init as init
x = init.uniform_(th.Tensor(100, 1), -10, 10)
print(x)
th.mean()
th.sum()
th.min()
th.argmin()
th.max()
th.argmax()

퀴즈 (Hard)

1) 길이가 4096인 랜덤벡터를 하나 생성하세요.
2) 벡터를 위에서 배운 메소드들 중 하나를 이용해 (64x64) 정사각행렬로 차원을 조정하세요. 3) 1, 2의 과정을 반복해서 정사각행렬을 세 개 만든다음, 각각 텐서의 0번째 축에 크기가 1인 잉여차원을 추가하세요.
4) 0번째 축과 마지막 축을 교환하세요.
5) 리스트에 세 개의 정사각행렬을 담아서 마지막 축을 기준으로 텐서를 합성하세요 -> 64x64x3 텐서가 나와야함
6) 위의 과정을 4번 반복해서 64x64x3 를 쌓아서 4 x 64 x 64 x 3 텐서를 만드세요

더보기

# 1)
rand_vec1 = th.randn(4096)
rand_vec2 = th.randn(4096)
rand_vec3 = th.randn(4096)

#2)
reshape_vec1 = rand_vec1.reshape(64, 64)
reshape_vec2 = rand_vec2.reshape(64, 64)
reshape_vec3 = rand_vec3.reshape(64, 64)

# 3)
unsqueeze_vec1 = reshape_vec1.unsqueeze(axis=0)
unsqueeze_vec2 = reshape_vec2.unsqueeze(axis=0)
unsqueeze_vec3 = reshape_vec3.unsqueeze(axis=0)

# 4)
trans_vec1 = unsqueeze_vec1.transpose(0, -1)
trans_vec2 = unsqueeze_vec2.transpose(0, -1)
trans_vec3 = unsqueeze_vec3.transpose(0, -1)
print(trans_vec1.shape)

# 5)
list_vec = [trans_vec1, trans_vec2, trans_vec3]

cat_ten = [th.cat(list_vec, dim=-1) for i in range(4)]
print(cat_ten[0].shape)

# 6)
stack_ten = th.stack(cat_tenm dim=0)

print(stack_ten.shape)

Data representation with tensor

Tensor Operation, Manipulation

profile
DA/DA/AE

0개의 댓글