Table of Contents

DeepLearning

텐서 Tensor

꼬꼬마코더 2024. 6. 19. 19:10
728x90

텐서란 무엇인가요?

텐서는 숫자를 정리해서 담을 수 있는 상자와 비슷한 개념입니다. 텐서는 여러 차원의 데이터를 담을 수 있습니다. 예를 들어:

  • 스칼라 (0차원): 단일 숫자 (예: 5)
  • 벡터 (1차원): 숫자들의 리스트 (예: [1, 2, 3])
  • 행렬 (2차원): 숫자들의 2차원 배열 (예: [[1, 2], [3, 4]])
  • 3차원 이상의 텐서: 3차원, 4차원 등 더 높은 차원의 배열을 가질 수 있습니다.

이미지 데이터를 텐서로 변환하는 이유

컴퓨터는 숫자로 된 데이터를 이해할 수 있습니다. 그래서 이미지를 숫자로 변환해야 합니다. PyTorch에서 이미지를 다루기 위해 Tensor라는 특별한 숫자 배열을 사용합니다.

예시 이미지 데이터

가상의 이미지를 생각해봅시다. 이미지는 여러 색깔의 픽셀로 구성됩니다. 각 픽셀은 빨강, 초록, 파랑(RGB) 세 가지 색깔을 가지고 있습니다. 예를 들어:

  • 빨강 채널: 모든 픽셀이 255 (최대값)
  • 초록 채널: 모든 픽셀이 128 (중간값)
  • 파랑 채널: 모든 픽셀이 0 (최소값)

이미지를 텐서로 변환하는 과정

  1. 이미지 생성: 가상의 이미지를 만듭니다.
  2. 텐서로 변환: 이미지를 텐서로 변환합니다.

1. 이미지 생성

가상의 2x2 이미지(2픽셀 x 2픽셀, 총 4픽셀)를 만들겠습니다. 각 픽셀은 RGB 색상을 가집니다.

255, 128, 0 이 RGB 값을 나타내며, 이는 주황색을 의미합니다. 여기서:

  • 255는 빨간색(Red) 성분의 최대 값입니다.
  • 128은 녹색(Green) 성분의 중간 값입니다.
  • 0은 파란색(Blue) 성분이 없음을 나타냅니다.
import numpy as np
from PIL import Image

# 가상의 RGB 이미지 생성 (높이, 너비, 채널) 2픽셀x2픽셀 = 4픽셀 (총 2행 2열)
image_data = np.array([[[255, 128, 0], [255, 128, 0]],  # 첫 번째 행, 2열
                       [[255, 128, 0], [255, 128, 0]]], dtype=np.uint8)  # 두 번째 행, 2열
image = Image.fromarray(image_data)
print(image)

>>>
<PIL.Image.Image image mode=RGB size=2x2 at 0x2EAFE7BAC90>
# 실제 이미지로 확인해보기
import matplotlib.pyplot as plt

plt.imshow(image)
plt.axis('off')  # 축을 표시하지 않음
plt.show()

1-1. 채널이란?

이미지 데이터에서 "채널(Channel)"이라는 용어는 이미지의 색상 정보를 담고 있는 구성 요소를 의미합니다. 이미지 데이터를 컴퓨터가 이해하고 처리할 수 있도록, 각 색상은 채널을 통해 분리되어 표현됩니다. 다음은 주로 사용되는 이미지 채널 형식에 대한 설명입니다:

  1. 그레이스케일 (Grayscale) 이미지:
    • 채널 수: 1개
    • 각 픽셀은 밝기만을 나타내며, 0 (검은색)부터 255 (흰색)까지의 값을 가집니다.
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

# 가상의 그레이스케일 이미지 생성 (높이, 너비)
image_data = np.array([[0, 255],  # 첫 번째 행
                       [10, 40]], dtype=np.uint8)  # 두 번째 행
image = Image.fromarray(image_data, 'L')  # 'L' 모드를 사용하여 그레이스케일 이미지 생성

# 이미지 표시
plt.imshow(image, cmap='gray')  # cmap='gray'를 추가하여 그레이스케일로 표시
plt.axis('off')  # 축을 표시하지 않음
plt.show()

2. RGB (Red, Green, Blue) 컬러 이미지:

  • 채널 수: 3개
  • RGB 이미지는 세 가지 색상 채널이 있으며, 각 채널은 빨간색, 초록색, 파란색을 나타냅니다. 이 채널들의 조합으로 다양한 색상을 표현합니다.
  • 예를 들어, 빨간색은 (255, 0, 0), 초록색은 (0, 255, 0), 파란색은 (0, 0, 255)로 표현됩니다.
# 4개 픽셀을 다른 색상으로 해보자
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

# 가상의 RGB 이미지 생성 (높이, 너비, 채널)
image_data = np.array([[[255, 128, 0], [255, 0, 0]],  # 첫 번째 행
                       [[10, 128, 0], [40, 50, 70]]], dtype=np.uint8)  # 두 번째 행
image = Image.fromarray(image_data)
print(image)

>>>
<PIL.Image.Image image mode=RGB size=2x2 at 0x2EAFF815E90>

plt.imshow(image)
plt.axis('off')  # 축을 표시하지 않음
plt.show()

 

2. 텐서로 변환

이 이미지를 PyTorch의 텐서로 변환합니다.

높이 x 너비 x 채널 (H x W x C) (2 x 2 x 3) 이미지를 채널 x 높이 x 너비 (C x H x W) (3 x 2 x 2)  의 순서로 변환

 (2 x 2 x 3)  ---> (3x 2 x 2)

#주황색 4픽셀 이미지에 대해 totensor
import torchvision.transforms as transforms

# ToTensor 변환 정의
to_tensor = transforms.ToTensor()

# 이미지 텐서로 변환
tensor_image = to_tensor(image)
print(tensor_image)

transforms.ToTensor()는 이미지를 텐서로 변환하는 함수입니다. 변환된 텐서는 다음과 같은 구조를 가집니다:

tensor([[[1.0000, 1.0000],    # 빨강 채널
         [1.0000, 1.0000]],

        [[0.5020, 0.5020],    # 초록 채널
         [0.5020, 0.5020]],

        [[0.0000, 0.0000],    # 파랑 채널
         [0.0000, 0.0000]]])

이 텐서는 세 가지 채널을 가지고 있습니다:

  • 빨강 채널: [1.0, 1.0], [1.0, 1.0]
  • 초록 채널: [0.502, 0.502], [0.502, 0.502]
  • 파랑 채널: [0.0, 0.0], [0.0, 0.0]

여기서 각 값은 원래 값(0-255)을 255로 나눈 결과입니다:

  • 빨강 채널: 255 -> 1.0
  • 초록 채널: 128 -> 128/255 ≈ 0.502
  • 파랑 채널: 0 -> 0.0

 

이번엔 이 회색 이미지를 PyTorch의 텐서로 변환합니다.

높이 x 너비 x 채널 (H x W x C) (2 x 2 x 1) 이미지를 채널 x 높이 x 너비 (C x H x W) (1 x 2 x 2)  의 순서로 변환

 (2 x 2 x 1)  ---> (1 x 2 x 2)

#회색 4픽셀 이미지에 대해 totensor
import torchvision.transforms as transforms

# ToTensor 변환 정의
to_tensor = transforms.ToTensor()

# 이미지 텐서로 변환
tensor_image = to_tensor(image)
print(tensor_image)
tensor([[[0.0000, 1.0000],
         [0.0392, 0.1569]]])

이 텐서는 한 가지 채널을 가지고 있습니다:

  • 그레이스케일 채널: [0.0000, 1.0000], [0.0392, 0.1569]

여기서 각 값은 원래 값(0-255)을 255로 나눈 결과입니다:

  • 0 / 255 ≈ 0.0000
  • 255 / 255 = 1.0000
  • 10 / 255 ≈ 0.0392
  • 40 / 255 ≈ 0.1569

 

2-1. transforms.ToTensor() 의 기능

transforms.ToTensor()는 주로 PyTorch에서 사용되는 함수로, 이미지와 같은 데이터를 PyTorch 텐서로 변환하는 역할을 합니다. 이 함수는 컴퓨터 비전 작업에 중요한 여러 단계를 포함하고 있습니다. 주요 기능은 다음과 같습니다:

  1. 데이터 타입 변환: 일반적으로 이미지는 PIL(Python Imaging Library) 형식이나 NumPy 배열로 저장됩니다. 이러한 형식의 이미지는 보통 0에서 255 사이의 값을 가지는 정수형(uint8) 데이터입니다. transforms.ToTensor()는 이 데이터를 0과 1 사이의 값으로 스케일링하는 부동소수점(float) 타입의 텐서로 변환합니다. 이는 모델 학습에 더 적합한 형태입니다.
  2. 차원 재배열: 이미지 데이터는 흔히 높이 x 너비 x 채널 (H x W x C) 순서로 배열됩니다. PyTorch에서는 텐서를 채널 x 높이 x 너비 (C x H x W)의 순서로 사용합니다. transforms.ToTensor()는 이 차원의 순서를 자동으로 바꿔주어, PyTorch 모델에 바로 사용할 수 있도록 합니다.
  3. 정규화: 이미지 데이터를 0과 1 사이의 값으로 스케일링함으로써, 모델 학습 과정에서 수치적 안정성을 향상시키고, 학습 과정을 더 빠르고 효율적으로 만듭니다.

이러한 변환은 데이터를 신경망에 입력하기 전에 필수적으로 거쳐야 하는 사전 처리 단계로, 데이터를 모델이 처리하기 적합한 형태로 만들어 줍니다. 따라서 transforms.ToTensor()는 PyTorch를 사용한 딥러닝 모델을 학습할 때 거의 필수적으로 사용되는 전처리 단계 중 하나입니다.

 

전체 코드

한번에 보도록 전체 코드를 다시 작성하겠습니다.

import numpy as np
from PIL import Image
import torchvision.transforms as transforms

# 가상의 RGB 이미지 생성 (높이, 너비, 채널)
image_data = np.array([[[255, 128, 0], [255, 128, 0]],  # 첫 번째 행
                       [[255, 128, 0], [255, 128, 0]]], dtype=np.uint8)  # 두 번째 행
image = Image.fromarray(image_data)

# ToTensor 변환 정의
to_tensor = transforms.ToTensor()

# 이미지 텐서로 변환
tensor_image = to_tensor(image)
print(tensor_image)

이 코드를 실행하면, 이미지가 텐서로 변환된 것을 확인할 수 있습니다. 데이터타입이 변환되며, 차원이 재배열되고, 각 채널의 값이 [0, 1] 범위로 정규화되어 저장됩니다.