반응형
LEARN THE BASICS
- ML 프로세스: 데이터 처리, 모델 생성, 모델 파라미터 최적화, 학습된 모델 저장
- PyTorch를 사용한 완전한 ML 흐름 소개
- FashionMNIST 데이터셋 사용, 이미지의 클래스 예측(T-shirt/top, Trouser, Pullover, Dress, Coat, Sandal, Shirt, Sneaker, Bag, Ankle boot)
- 기본 Python 지식, DL 개념 필요
Running the Tutorial Code
- 튜토리얼 실행 방법: 클라우드와 로컬에서 실행 가능
- 클라우드: 각 섹션에 "Run in Microsoft Learn" 링크를 통해 쉽게 실행 가능, 코드를 포함한 노트북 제공
- 로컬: PyTorch, TorchVision 설치 필요, 노트북 다운로드 혹은 코드를 선호하는 IDE에 복사
How to Use this Guide
- 기존 DL 프레임워크에 익숙한 경우 0번 Quickstart부터 시작
- DL 프레임워크 새로 접하는 경우 1번 Tensors부터 시작
- 0. Quickstart
1. Tensors3. Transforms4. Build Model
1. Tensors
- 텐서: 행렬과 비슷한 특수 데이터 구조
- PyTorch에서는 모델의 입력, 출력, 파라미터를 인코딩하는데 텐서 사용
- NumPy의 ndarray와 유사하며, 텐서는 GPU 또는 기타 하드웨어 가속기에서 실행 가능
- 텐서와 ndarray는 동일한 메모리를 공유할 수 있어 데이터 복사 필요 없음 (Bridge with NumPy 참조)
- 텐서는 자동 미분에 최적화 (Autograd 섹션에서 더 알아볼 것)
- ndarray에 익숙하다면 Tensor API에 익숙할 것, 아니라면 함께 진행하면서 익혀보기
import torch # root package
import numpy as np # numpy for initializing tensor
Initializing a Tensor
- 텐서는 다양한 방법으로 초기화 가능
데이터를 통한 초기화
- 데이터를 직접 사용하여 텐서 생성, 데이터 타입은 자동으로 추론
data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)
NumPy 배열을 통한 초기화
- NumPy 배열을 사용하여 텐서 생성 (그 역도 가능- Bridge with NumPy 참조)
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
print(f"Numpy np_array value: \n {np_array} \n")
print(f"Tensor x_np value: \n {x_np} \n")
np.multiply(np_array, 2, out=np_array)
print(f"Numpy np_array after * 2 operation: \n {np_array} \n")
print(f"Tensor x_np value after modifying numpy array: \n {x_np} \n")
Numpy np_array value:
[[1 2]
[3 4]]
Tensor x_np value:
tensor([[1, 2],
[3, 4]])
Numpy np_array after * 2 operation:
[[2 4]
[6 8]]
Tensor x_np value after modifying numpy array:
tensor([[2, 4],
[6, 8]])
다른 텐서를 통한 초기화
- 텐서를 생성 할 수 있는 함수로는 torch.ones_like, torch.rand_like 같은 것들이 있다.
- 새로운 텐서는 명시적으로 덮어쓰지 않는 한 인수 텐서의 속성(모양, 데이터 타입)을 그대로 유지
x_ones = torch.ones_like(x_data) # retains the properties of x_data
print(f"Ones Tensor: \n {x_ones} \n")
x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data
print(f"Random Tensor: \n {x_rand} \n")
Ones Tensor:
tensor([[1, 1],
[1, 1]])
Random Tensor:
tensor([[0.2028, 0.7590],
[0.0497, 0.7373]])
난수 또는 상수 값을 사용한 초기화
- shape는 텐서 차원의 튜플
- 아래 함수에서는 출력 텐서의 차원을 결정
- Shape는 텐서의 행과 열의 수를 나타냄. 예를 들어, shape = (# of rows, # of columns)
- torch.rand, torch.ones, torch.zeros 함수를 사용하여 텐서를 생성할 수 있다.
shape = (2,3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)
print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
Random Tensor:
tensor([[0.3399, 0.3765, 0.5898],
[0.8886, 0.2441, 0.2653]])
Ones Tensor:
tensor([[1., 1., 1.],
[1., 1., 1.]])
Zeros Tensor:
tensor([[0., 0., 0.],
[0., 0., 0.]])
Attributes of a Tensor
- 텐서 속성은 모양, 데이터 유형, 저장된 장치 출력
tensor = torch.rand(3,4)
print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")
Shape of tensor: torch.Size([3, 4])
Datatype of tensor: torch.float32
Device tensor is stored on: cpu
Operations on Tensors
- Pytorch 에는 100개 이상의 tensor 연산이 있음, 산술, 선형대수, 행렬조작(transpose, indexing, slicing) 포함.
- 상세 설명은 여기 참조
- 이러한 연산들은 GPU에서도 실행 가능 (CPU보다 빠름)
- CPU는 보통 16개의 코어를 가지며, 각 코어는 순차적으로 작업을 처리
- GPU는 보통 1000개 이상의 코어를 가지며, 병렬 처리를 하여 작업을 분할 처리
- GPU는 대용량 데이터에서 더 빠름. 그래픽 또는 신경망 계산에 사용.
- Pytorch는 Nvidia CUDA library를 이용하여 GPU 카드를 사용 가능
- tensor는 기본적으로 CPU에서 생성되며, .to method를 이용하여 GPU로 이동 가능
- 큰 tensor를 이동하는 것은 시간과 메모리에 영향을 줄 수 있음
Standard numpy-like indexing and slicing
tensor = torch.ones(4, 4)
print('First row: ',tensor[0])
print('First column: ', tensor[:, 0])
print('Last column:', tensor[..., -1])
tensor[:,1] = 0
print(tensor)
First row: tensor([1., 1., 1., 1.])
First column: tensor([1., 1., 1., 1.])
Last column: tensor([1., 1., 1., 1.])
tensor([[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]])
Joining tensors
- 아래 두 함수 이용하여 텐서 병합 가능
- torch.cat: 주어진 차원을 따라 텐서를 concaternate
- torch.stack: 새로운 차원을 따라 텐서를 stack
t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)
tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])
Arithmetic opreations
# This computes the matrix multiplication between two tensors. y1, y2, y3 will have the same value
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)
y3 = torch.rand_like(tensor)
torch.matmul(tensor, tensor.T, out=y3)
print(y3)
# This computes the element-wise product. z1, z2, z3 will have the same value
z1 = tensor * tensor
z2 = tensor.mul(tensor)
z3 = torch.rand_like(tensor)
torch.mul(tensor, tensor, out=z3)
print(z3)
tensor([[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.]])
tensor([[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]])
Single-element tensors
텐서의 모든 값을 하나의 값으로 연산하여 하나의 요소 텐서를 가진 경우, item()을 사용하여 파이썬 수치로 변환 가능
agg = tensor.sum()
agg_item = agg.item()
print(agg_item, type(agg_item))
12.0 <class 'float'>
In-place operations
- in-place 연산: 결과를 피연산자에 저장하는 연산
- 접미사 _ 를 사용
- 예: x.copy_(y), x.t_() 는 x의 값을 변경
- 주의! 인플레이스 연산은 메모리를 절약, 결과 계산할 때 히스토리의 즉각적인 손실로 인해 문제가 될 수 있음
- 사용 권장하지 않음
print(tensor, "\n")
tensor.add_(5)
print(tensor)
tensor([[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]])
tensor([[6., 5., 6., 6.],
[6., 5., 6., 6.],
[6., 5., 6., 6.],
[6., 5., 6., 6.]])
Bridge with NumPy
- CPU 및 NumPy 어레이의 텐서는 기본 메모리 위치를 공유할 수 있으며 하나를 변경하면 다른 하나가 변경됨
Tensor to Numpy array - torch.Tensor.numpy()
t = torch.ones(5)
print(f"t: {t}")
n = t.numpy()
print(f"n: {n}")
t: tensor([1., 1., 1., 1., 1.])
n: [1. 1. 1. 1. 1.]
t.add_(1)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.])
n: [2. 2. 2. 2. 2.]
NumPy array to Tensor - torch.from_numpy(numpy.ndarray)
n = np.ones(5)
t = torch.from_numpy(n)
np.add(n, 1, out=n)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
n: [2. 2. 2. 2. 2.]
반응형