[Pytorch] 파이토치의 텐서(Tensor) 이해 및 예제
텐서(Tensor)라고 하면 텐서플로우를 떠올리기 쉽지만, 사실 딥러닝에서는 데이터를 처리하기 위한 데이터의 형태라고 이해하면 된다.
0차원의 데이터는 보통 스칼라(Scalar)라고 하는데 파이토치에서는 0-Tensor(랭크 0)이며, 스칼라 데이터의 나열인 벡터는 1-Tensor(랭크 1), 행렬은 2-Tensor(랭크 2)이다. 텐서는 파이썬의 대표적인 라이브러리인 넘파이(numpy)와 유사하고 넘파이와 데이터를 쉽게 서로 변환 할 수도 있다.
위 내용들을 좀 더 쉽게 설명하자면, 우리가 프로그램으로 사용하는 변수들을 딥러닝으로 처리하기 위해서는 변환을 해야 하는데 그 단위가 바로 텐서라고 생각하면 된다.
텐서 데이터타입 [1]
데이터 타입 | dtype | CPU tensor | GPU tensor |
32-bit floating point | torch.float32 or torch.float | torch.FloatTensor | torch.cuda.FloatTensor |
64-bit floating point | torch.float64 or torch.double | torch.DoubleTensor | torch.cuda.DoubleTensor |
16-bit floating point | torch.float16 or torch.half | torch.HalfTensor | torch.cuda.HalfTensor |
16-bit floating point | torch.bfloat16 | torch.BFloat16Tensor | torch.cuda.BFloat16Tensor |
32-bit complex | torch.complex32 | ||
64-bit complex | torch.complex64 | ||
128-bit complex | torch.complex128 or torch.cdouble | ||
8-bit integer (unsigned) | torch.uint8 | torch.ByteTensor | torch.cuda.ByteTensor |
8-bit integer (signed) | torch.int8 | torch.CharTensor | torch.cuda.CharTensor |
16-bit integer (signed) | torch.int16 or torch.short | torch.ShortTensor | torch.cuda.ShortTensor |
32-bit integer (signed) | torch.int32 or torch.int | torch.IntTensor | torch.cuda.IntTensor |
64-bit integer (signed) | torch.int64 or torch.long | torch.LongTensor | torch.cuda.LongTensor |
Boolean | torch.bool | torch.BoolTensor | torch.cuda.BoolTensor |
quantized 8-bit integer (unsigned) | torch.quint8 | torch.ByteTensor | / |
quantized 8-bit integer (signed) | torch.qint8 | torch.CharTensor | / |
quantized 32-bit integer (signed) | torch.qfint32 | torch.IntTensor | / |
quantized 4-bit integer (unsigned) | torch.quint4x2 | torch.ByteTensor | / |
백문이 불여일타라고, 소스를 보면서 이해를 해보도록 한다.
dtype과 type의 이해
1부터 5까지의 정수 리스트를 tensor로 변환하여 받은 것의 dtype과 type을 호출해보았다.
결과는 dtype은 torch.int64로 나오며, 현재 cpu로 돌리고 있기 때문에 type은 torch.LongTensor로 출력이 되고 있다. dtype은 한마디로 좀 더 개념적인 타입이라고 한다면, type의 경우는 현재 시스템 상황에 맞게 implement 된 type이라 생각하면 좋을 것 같다.
float형은 dtype은 torch.float32, type은 torch.FloatTensor로 변환되었다.
형변환과 차원체크
이번에는 강제로 형변환을 시도해 본다. 우선 float형의 리스트를 만들고, tensor로 넣을 때, dtype=int64로 형변환 시켜서 넣어보는 것이다. 그리고 결과는 보다시피, torch.int64, torch.LongTensor로 정상적으로 형변환이 된 것을 알 수 있다.
그리고 float_int_tensor 텐서 변수의 차원을 체크하기 위해서 ndimension() 펑션을 호출해보니, 1(랭크 1은 벡터)이라는 값이 나오는 것을 확인하였다.
차원변경(view)
1차원의 벡터로 되어있는 값을 2차원의 값으로 변경을 해보도록 하자. 반대로 2차원의 데이터 역시 1차원의 데이터로 변경을 할 수 있으며, view는 reshape과 모양이 유사하지만, view는 데이터가 공유되는 반면, reshape의 경우 별개의 데이터 즉 사본으로 생성되는 차이[2]로 보인다.
View와 Reshape
위 View와 Reshape를 보면 알겠지만, 결과가 똑같이 나온다. 한마디로 공유와 사본을 생각하지 않는다면 아무거나 써도 상관이 없다는 말과 같을 것이다.
라이브러리형 호환
넘파이(numpy) 호환
Tensor는 numpy와 쉽게 변환이 가능하다.
torch에는 from_numpy라는 펑션을 제공하는데 이 기능을 사용하면 넘파이 어레이를 읽을 수 있다. 반대로 tensor의 값을 numpy로 변환할 수 있다.
Pandas 호환
torch.from_numpy로 판다스의 series 데이터도 텐서로 변환시킬 수 있다.
Tensor to List
tensor의 tolist() 펑션을 사용하면, 텐서의 값을 리스트형으로 변환이 가능하다
포스팅에 사용한 코드
import torch
# 정수형 리스트를 텐서로 변환
ints_to_tensor = torch.tensor([1, 2, 3, 4, 5])
print("ints_to_tensor dtype : ", ints_to_tensor.dtype)
print("ints_to_tensor type : ", ints_to_tensor.type())
# Float형 텐서 생성
float_to_tensor = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0])
print("floats_to_tensor dtype : ", float_to_tensor.dtype)
print("floats_to_tensor type() : ", float_to_tensor.type())
list_float=[1.0, 2.0, 3.0, 4.0, 5.0]
float_int_tensor=torch.tensor(list_float, dtype=torch.int64)
print("float_int_tensor dtype: ", float_int_tensor.dtype)
print("float_int_tensor type: ", float_int_tensor.type())
print("float_int_tensor n-dimension : ", float_int_tensor.ndimension())
float_tensor_matrix_view = float_int_tensor.view(5, 1)
print(float_tensor_matrix_view)
float_tensor_matrix_reshape = float_int_tensor.reshape(5, 1)
print(float_tensor_matrix_reshape)
import numpy as np
# 넘파이 배열을 텐서로 변환
numpy_array = np.array([0.0, 1.0, 2.0, 3.0, 4.0])
numpy_to_tensor = torch.from_numpy(numpy_array)
print(numpy_to_tensor)
# 텐서 값을 넘파이 배열로 변환
tensor_to_numpy = numpy_to_tensor.numpy()
print(tensor_to_numpy)
import pandas as pd
# 판다스 series를 텐서로 변환
pandas_series=pd.Series([1.0, 3, 1.7, 5.2])
pandas_to_torch=torch.from_numpy(pandas_series.values)
print("pandas_to_torch : ", pandas_to_torch)
torch_to_list=pandas_to_torch.tolist()
print('tensor:', pandas_to_torch,"\nlist:",torch_to_list)
References
[1] TORCH.TENSOR, https://pytorch.org/docs/stable/tensors.html