파이토치에서 다루는 모든 벡터, 행렬, 텐서들에 대해서
덧셈, 뺄셈, 내적, 외적을 할 수 있습니다.
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)
딥러닝 모델에 데이터를 입력하기 위해 텐서의 차원을 정말 잘 다루어야 합니다.
이때 차원을 조작하는 메소드로는 다음과 같습니다. flatten(), reshape(), view()가 있습니다. 1) 차원 축소, 확장 : squeeze(), unsqueeze()
2) 차원 교환 : transpose(), permute()
3) 차원 조정 : flatten(), view() reshape()
4) 텐서 합성 및 적재 : cat() stack()
# 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)
위 메소드들은 주로 데이터를 변환할 때 많이 사용합니다.
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)
위 세 가지 메소드는 주로 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)
마지막으로 텐서를 합성하기 위해 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()
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)