Tensor의 생성과 초기화

PyTorch에서 Tensor는 다차원 배열을 나타내며, 이를 통해 다양한 수치 연산을 수행할 수 있습니다. Tensor는 다양한 방법으로 생성하고 초기화할 수 있으며, 그 형태와 데이터 타입은 사용자가 원하는 대로 설정할 수 있습니다. 이 장에서는 Tensor를 생성하고 초기화하는 여러 가지 방법을 다룹니다.

Tensor 생성 방법

1. 기본 생성자 함수

PyTorch에서는 torch.Tensor()를 이용해 Tensor를 생성할 수 있습니다. 이 생성자는 주어진 데이터로부터 Tensor를 생성합니다. 예를 들어, 다음과 같이 Python 리스트로부터 Tensor를 생성할 수 있습니다.

import torch

# 1차원 Tensor 생성
tensor1 = torch.Tensor([1, 2, 3, 4, 5])

# 2차원 Tensor 생성
tensor2 = torch.Tensor([[1, 2, 3], [4, 5, 6]])

위의 코드에서 tensor1은 1차원 Tensor이고, tensor2는 2차원 Tensor입니다. torch.Tensor()는 입력 데이터를 그대로 복사하여 새로운 Tensor를 생성하므로, 원본 데이터가 변경되어도 Tensor에는 영향을 주지 않습니다.

2. Numpy 배열로부터 생성

Numpy 배열을 PyTorch Tensor로 변환하려면 torch.from_numpy() 함수를 사용합니다. 이 함수는 Numpy 배열을 공유 메모리 방식으로 변환하므로, Numpy 배열과 Tensor 간의 데이터 변경이 서로 영향을 미칩니다.

import numpy as np

# Numpy 배열 생성
np_array = np.array([1.0, 2.0, 3.0])

# Tensor로 변환
tensor_from_numpy = torch.from_numpy(np_array)

위의 예제에서 Numpy 배열 np_array와 Tensor tensor_from_numpy는 메모리를 공유하므로, np_array의 값을 변경하면 tensor_from_numpy의 값도 변경됩니다.

3. 특정 값으로 초기화된 Tensor 생성

PyTorch에서는 특정 값으로 초기화된 Tensor를 생성할 수 있는 다양한 함수들이 제공됩니다. 주로 사용되는 함수는 다음과 같습니다.

  • torch.zeros(): 모든 요소가 0인 Tensor 생성

  • torch.ones(): 모든 요소가 1인 Tensor 생성

  • torch.full(): 사용자가 지정한 값으로 모든 요소가 채워진 Tensor 생성

예를 들어, 다음 코드는 모두 크기가 (3 \times 3)인 Tensor를 생성하지만, 초기화 방법이 다릅니다.

4. 랜덤 값으로 초기화된 Tensor 생성

모델 학습 초기 단계에서 랜덤 값으로 Tensor를 초기화하는 것은 일반적인 방법입니다. PyTorch는 다음과 같은 랜덤 초기화 함수들을 제공합니다.

  • torch.randn(): 평균이 0이고 분산이 1인 정규분포에서 샘플링된 값을 가지는 Tensor 생성

  • torch.rand(): ([0, 1)) 범위에서 균등분포로 샘플링된 값을 가지는 Tensor 생성

  • torch.randint(): 지정된 범위 내의 정수 값으로 구성된 Tensor 생성

이와 같이 랜덤 값으로 초기화된 Tensor는 주로 딥러닝 모델의 가중치를 초기화할 때 사용됩니다.

초기화 옵션과 데이터 타입

1. 데이터 타입 지정

PyTorch에서 생성된 Tensor의 데이터 타입은 기본적으로 float32입니다. 다른 데이터 타입을 사용하려면 dtype 인자를 명시적으로 지정해야 합니다. 예를 들어, int64 타입의 Tensor를 생성하려면 다음과 같이 할 수 있습니다.

데이터 타입을 명시적으로 지정하는 것은 메모리 사용량을 줄이거나 계산 속도를 개선하는 데 유용할 수 있습니다. 또한, 딥러닝 모델에서 입력 데이터와 가중치의 데이터 타입이 일치해야 하므로, 이를 조정하는 데도 중요합니다.

2. 장치 옵션

PyTorch는 Tensor를 CPU와 GPU 모두에서 생성할 수 있습니다. GPU를 활용하여 연산 속도를 개선하려면 device 옵션을 지정해야 합니다.

위의 코드에서는 GPU가 사용 가능한 경우 GPU에, 그렇지 않으면 CPU에 Tensor를 생성합니다.

Tensor의 형태와 크기 지정

Tensor를 생성할 때는 그 형태(shape)를 지정할 수 있습니다. 형태는 Tensor의 각 차원의 크기를 의미하며, 일반적으로 다음과 같은 함수들을 통해 원하는 크기의 Tensor를 쉽게 생성할 수 있습니다.

1. torch.empty()

torch.empty()는 초기화되지 않은 Tensor를 생성합니다. 초기화되지 않았다는 것은 메모리의 임의의 값을 그대로 가지고 있기 때문에, 특정 값으로 채워져 있지 않음을 의미합니다. 이는 단순히 메모리를 할당하고 초기화 과정을 생략함으로써 속도를 개선할 수 있습니다.

2. torch.eye()

단위 행렬(identity matrix)을 생성하는 함수입니다. 단위 행렬은 대각선 성분이 1이고 나머지 성분이 0인 정사각 행렬입니다.

[ \mathbf{I}_n = \begin{bmatrix} 1 & 0 & \cdots & 0 \ 0 & 1 & \cdots & 0 \ \vdots & \vdots & \ddots & \vdots \ 0 & 0 & \cdots & 1 \end{bmatrix} ]

다음 코드는 크기가 (4 \times 4)인 단위 행렬을 생성합니다.

3. torch.arange()torch.linspace()

특정 간격으로 값을 채운 1차원 Tensor를 생성할 때 사용되는 함수들입니다.

  • torch.arange(start, end, step): 지정한 간격(step)으로 값을 생성합니다.

  • torch.linspace(start, end, steps): 시작과 끝 값을 포함하여 일정한 간격으로 값을 생성합니다.

torch.arange()는 주로 정수 배열을 생성할 때 사용되며, torch.linspace()는 두 지점 사이를 일정한 간격으로 나눌 때 유용합니다.

Tensor의 형태 변환

생성된 Tensor의 형태를 변경해야 하는 경우가 자주 발생합니다. PyTorch에서는 Tensor의 차원을 재배열하거나 변경할 수 있는 다양한 방법을 제공합니다.

1. torch.reshape()

reshape() 함수는 Tensor의 원소 수를 유지한 채로 새로운 형태를 지정할 수 있게 해줍니다. 예를 들어, (1 \times 12) 형태의 Tensor를 (3 \times 4)로 변환할 수 있습니다.

[ \mathbf{t} = \begin{bmatrix} 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 \end{bmatrix} \rightarrow \mathbf{T} = \begin{bmatrix} 1 & 2 & 3 & 4 \ 5 & 6 & 7 & 8 \ 9 & 10 & 11 & 12 \end{bmatrix} ]

2. torch.view()

view()reshape()와 비슷하지만, 원래 데이터와 메모리를 공유합니다. 따라서, 하나의 Tensor를 변경하면 다른 Tensor에도 영향을 미칩니다. 이 점을 고려하여 사용할 필요가 있습니다.

3. 차원 추가 및 제거: torch.unsqueeze()torch.squeeze()

unsqueeze()는 Tensor에 새로운 차원을 추가합니다. 반대로, squeeze()는 크기가 1인 차원을 제거합니다.

[ \mathbf{x} = \begin{bmatrix} 1 & 2 & 3 \end{bmatrix} \rightarrow \mathbf{y} = \begin{bmatrix} \begin{bmatrix} 1 \end{bmatrix} \ \begin{bmatrix} 2 \end{bmatrix} \ \begin{bmatrix} 3 \end{bmatrix} \end{bmatrix} ]

초기화 전략

모델 학습에서 Tensor의 초기화는 매우 중요한 역할을 합니다. 잘못된 초기화는 학습 속도를 저하시킬 수 있으며, 최적의 가중치를 찾는 것을 어렵게 할 수 있습니다. 초기화 전략에는 여러 가지가 있으며, 각 전략은 특정한 조건에서 더 나은 성능을 발휘할 수 있습니다.

1. Xavier 초기화

Xavier 초기화는 특정 활성화 함수(주로 tanh)를 사용할 때 신경망의 학습을 안정적으로 만들어줍니다. 이 방식은 가중치가 (U(-\sqrt{\frac{6}{n_{in} + n_{out}}}, \sqrt{\frac{6}{n_{in} + n_{out}}}))로 초기화됩니다.

[ W_{i,j} \sim U\left(-\sqrt{\frac{6}{n_{in} + n_{out}}}, \sqrt{\frac{6}{n_{in} + n_{out}}}\right) ]

여기서 (n_{in})은 입력의 크기, (n_{out})은 출력의 크기입니다.

2. He 초기화

He 초기화는 ReLU와 같은 활성화 함수에 적합한 초기화 방법입니다. 이는 Xavier 초기화의 변형으로, 가중치를 (\mathcal{N}(0, \frac{2}{n_{in}})) 분포에서 샘플링하여 초기화합니다. 이 방식은 활성화 함수의 특성상 많은 뉴런이 활성화되지 않는 문제를 완화하는 데 도움이 됩니다.

[ W_{i,j} \sim \mathcal{N}(0, \frac{2}{n_{in}}) ]

여기서 (n_{in})은 입력의 크기입니다.

3. 정규분포 및 균등분포 초기화

가중치를 초기화할 때 기본적인 방법으로 정규분포나 균등분포를 사용할 수도 있습니다. PyTorch는 이를 쉽게 설정할 수 있는 함수들을 제공합니다.

  • torch.nn.init.normal_(tensor, mean=0.0, std=1.0): 평균과 표준편차를 지정한 정규분포로 초기화

  • torch.nn.init.uniform_(tensor, a=0.0, b=1.0): ([a, b]) 범위의 균등분포로 초기화

다양한 형태의 Tensor

1. 스칼라, 벡터, 행렬, 고차원 Tensor

Tensor는 수학에서의 다양한 객체(스칼라, 벡터, 행렬, 고차원 배열)를 일반화한 형태입니다.

  • 스칼라 (Scalar): 차원이 없는 0차원 Tensor [ s = 5 ]

  • 벡터 (Vector): 1차원 Tensor [ \mathbf{v} = \begin{bmatrix} 1 & 2 & 3 \end{bmatrix} ]

  • 행렬 (Matrix): 2차원 Tensor [ \mathbf{M} = \begin{bmatrix} 1 & 2 \ 3 & 4 \end{bmatrix} ]

  • 고차원 Tensor (Higher-Dimensional Tensor): 3차원 이상의 Tensor [ \mathbf{T}_{ijk} = \text{3D Tensor} ]

각 차원에 따라 Tensor의 연산 방법과 응용 분야가 달라지며, PyTorch는 모든 차원의 Tensor를 효율적으로 처리할 수 있도록 설계되었습니다.

2. Batch와 고차원 Tensor

딥러닝에서 고차원 Tensor는 주로 이미지나 시퀀스 데이터와 같은 고차원 데이터를 처리하는 데 사용됩니다. 예를 들어, 이미지는 일반적으로 (C \times H \times W) 형태로 표현되며, 여기서 (C)는 채널 수, (H)는 높이, (W)는 너비를 나타냅니다.

여기서 image_batch는 크기가 ((32, 3, 224, 224))인 Tensor이며, 이는 32개의 RGB 이미지로 구성된 Batch를 나타냅니다. 각 이미지의 크기는 (224 \times 224)이며, 각 픽셀은 3개의 채널(R, G, B)을 가지고 있습니다.

3. Tensor의 복사와 변경

Tensor를 생성하고 초기화한 후에는 데이터를 복사하거나 부분적으로 변경하는 작업이 필요할 수 있습니다. PyTorch에서는 다양한 방법으로 이를 처리할 수 있습니다.

  • clone(): 기존 Tensor의 데이터를 복사하여 새로운 Tensor를 생성

  • copy_(): 기존 Tensor의 값을 다른 Tensor에 복사

clone()copy_()는 Tensor를 다룰 때 자주 사용되며, 데이터의 독립성을 보장하거나 특정 조건을 충족하기 위해 활용됩니다.

Tensor의 초기화 실습

Tensor의 초기화는 다양한 조건에 따라 다르게 적용할 수 있습니다. 예를 들어, 특정 범위 내의 난수를 사용하여 초기화하거나, 복잡한 연산을 통해 초기 값을 결정할 수 있습니다. 이러한 실습을 통해 Tensor 초기화 방법을 구체적으로 이해할 수 있습니다.

위의 코드 예제들은 PyTorch에서 다양한 초기화 방법을 실습하는 과정입니다. 이러한 실습을 통해 Tensor의 생성과 초기화를 명확하게 이해할 수 있으며, 이는 모델 학습의 효율성과 성능 향상에 기여할 수 있습니다.

Last updated