[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형 변환

     

     

    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

     

    위 View와 Reshape를 보면 알겠지만, 결과가 똑같이 나온다. 한마디로 공유와 사본을 생각하지 않는다면 아무거나 써도 상관이 없다는 말과 같을 것이다.

     

     

    라이브러리형 호환

    넘파이(numpy) 호환

    Tensor는 numpy와 쉽게 변환이 가능하다.

    numpy to tensor

     

    torch에는 from_numpy라는 펑션을 제공하는데 이 기능을 사용하면 넘파이 어레이를 읽을 수 있다. 반대로 tensor의 값을 numpy로 변환할 수 있다.

     

    tensor to 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

    [2] https://stackoverflow.com/questions/49643225/whats-the-difference-between-reshape-and-view-in-pytorch

    댓글

    Designed by JB FACTORY