1. 파이토치 : GPU에서 텐서 조작 및 동적 신경망 구축이 가능한 프레임워크
- GPU : 빠른 연산속도
- Tensor : 파이토치의 데이터 형태
- 동적 신경망 : 훈련 반복 때마다 네트워크 변경이 가능한 신경망
2. 파이토치의 아키텍쳐
- 파이토치 API : 가장 상위 계층
- 파이토치 엔진 : 다차원 텐서 및 자동 미분(autograd) 처리
- 연산처리 : 텐서에 대한 연산 처리, 텐서의 실질적인 계산을 위한 C, CUDA등 라이브러리가 위치함
2.1 파이토치 API
사용자가 이해하기 쉬운 API를 제공하여 텐서에 대한 처리와 신경망을 구축하고 훈련할 수 있도록 도움.
(실제 계산은 수행하지 않고, 파이토치 엔진으로 그 작업을 전달하는 역할만!)
torch : GPU를 지원하는, 텐서 생성 라이브러리
다차원 텐서 기반으로 다양한 수학적 연산이 가능하도록 함. GPU에서 연산이 가능하므로 빠른 속도로 많은 양의 계산을 할 수 있음
torch.autograd : 자동미분 기능 제공 라이브러리
다른 딥러닝 프레임워크와 가장 차별되는 패키지, '자동 미분'으로 미분 계산을 효율적으로 처리함.
즉, '연산 그래프'가 즉시 계산되기 때문에 다양한 신경망을 적용해 볼 수 있음
torch.nn : 신경망 생성 및 훈련 라이브러리
torch.nn을 사용할 경우 신경망을 쉽게 구축하고 사용할 수 있음 (cnn, rnn, normalization등이 모두 포함)
torch.multiprocessing : 병렬처리 기능 제공 라이브러리
파이토치에서 사용하는 프로세스 전반에 걸쳐 텐서의 메모리 공유가 가능함
따라서 서로 다른 프로세스에서 동일한 데이터(텐서)에 대한 접근 및 사용이 가능함
torch.utils : 데이터로더 및 기타 유틸리티를 제공
모델에 데이터를 제공하기 위해 torch.utils.data.DataLoader 모듈을 자주 사용함
또한, 병목 현상 디버깅하기 위한 torch.utils.bottlenect, 모델 또는 모델의 일부를 검사하기 위한 torch.utils.checkpoint등의 모듈도 있음
2.2 텐서를 메모리에 저장하기
텐서는 그것이 1차원이든 N차원이든 메모리에 저장할 때는 1차원 배열 형태가 됨. 즉, 1차원 배열 형태여야만 메모리에 저장할 수 있음.
그리고 변환된 1차원 배열을 스토리지(storage)라고 한다.
(1) 오프셋(offest) : 텐서에서 첫 번째 요소가 스토리지에 저장된 인덱스
(2) 스트라이드(stride) : 각 차원에 따라 다음 요소를 얻기 위해 건너뛰기(skip)가 필요한 스토리지의 요소 개수, 그런데 요소는 연속적으로 저장되기 때문에 행 중심으로 스트라이드는 항상 1이다.
위의 그림과 같이 offset과 stride는 데이터 자체가 아닌 행렬 / 텐서를 구분하기 위해 사용됨
3.1 텐서의 생성
import torch
torch.__version__
# 무작위 초기화
x = torch.rand(2,4)
>> tensor( [ [ 0.4122, 0.5186, 0.0498, 0.5261 ],
[0.8360, 0.5959, 0.6370, 0.6914 ] ] )
# x와 형태는 동일하게 가져오되, random으로 float값을 가져오기
x = torch.randn_like(x, dtype = torch.float)
print(x)
>> tensor( [ [ -0.2798, -0.6804, -0.2510, -0.3335 ],
[ 1.2007, -0.0221, 1.5868, 1.4176 ] ] )
# 0으로 초기화
t1 = torch.zeros(2,3)
print(t1)
print(t1.shape)
print(t1.dtype)
>> tensor( [ [ 0., 0., 0. ],
[0., 0., 0. ] ])
torch.Size([2, 3])
torch.float32
# 연속되는 값
t2 = torch.arange(4)
print(t2)
print(t2.shape)
print(t2.dtype)
>> tensor( [ 0, 1, 2, 3 ] )
torch.Size([4])
torch.int64
3.2 텐서의 조작
텐서의 크기나 모양을 변경
view
- Returns a new tensor with the same data as the self tensor but of a different shape
https://pytorch.org/docs/stable/generated/torch.Tensor.view.html
x = torch.randn(4,5)
y = x.view(20)
z = x.view(5,-1)
print(x.size())
print(y.size())
print(z.size())
>> torch.Size ( [ 4, 5 ] )
torch.Size ( [ 20 ] )
torch.Size ( [ 5, 4 ] )
squeeze : 차원을 축소 (제거)
- Returns a tensor with all specified dimensions of input of size '1' removed
https://pytorch.org/docs/stable/generated/torch.squeeze.html
# example
t1 = torch.arange(6).reshape(2,1,3)
t1_squeeze = t1.squeeze(dim=1)
t1_reshape = t1.reshape(2,3)
처음에 torch.arange(6) : [0,1,2,3,4,5], size : [6]
reshape (2, 1, 3) 이후 : [ [[ 0, 1, 2 ]] , [[ 3, 4, 5 ]] ] , size : [ 2, 1, 3 ]
squeeze (dim=1) 이후 : [[0, 1, 2] , [3, 4, 5]] , size : [ 2, 3 ]
reshape (2, 3) 이후 : 위와 동일
unsqueeze : 차원을 증가 (생성)
- Returns a new tensor with a dimension of size one inserted at the specified position.
https://pytorch.org/docs/stable/generated/torch.unsqueeze.html
# example 1
t1 = torch.arange(6).reshape(2,3)
t1_unsqueeze = t1.unsqueeze(dim = 1)
처음에 torch.arange(6) : [0,1,2,3,4,5], size : [6]
reshape (2, 3) 이후 : [[ 0, 1, 2 ] , [ 3, 4, 5 ]] , size : [ 2, 3 ]
squeeze (dim=1) 이후 : [ [[ 0, 1, 2 ]] , [[ 3, 4, 5 ]] ] , size : [ 2, 1, 3 ]
# example 2
t2 = torch.rand(1,3,3)
t2 = t2.unsqueeze( dim = 0 )
처음에 torch.rand(1,3,3) : size : [1, 3, 3]
unsqueeze (dim=0) 이후 : size : [ 1, 1, 3, 3 ]
permute : 차원 순서 바꾸기
- Returns a view of the original tensor input with its dimensions permuted
https://pytorch.org/docs/stable/generated/torch.permute.html
x = torch.randn(2, 3, 5)
x_permute = x.permute(2, 0, 1)
처음에 torch.rand(2,3,5) : size : [2, 3, 5]
permute(2, 0, 1) 이후 : size : [ 5, 2, 3 ]
3.2 텐서의 행렬연산
sum, argmax
- 꼭 특정 차원을 정해줘야 함
- 차원이 축소된 결과를 반환해줌 (단, keepdim = True 로 설정하면 축소되지 않음)
- torch.argmax() returns the indices of the maximum value of all elements in the input tensor
https://pytorch.org/docs/stable/generated/torch.argmax.html
t1 = torch.Tensor( [ [3,6,4] , [2,4,7] ] ) # shape : (3,2)
# sum by row (dim=1)
row_argmax = torch.argmax(t1, dim=1)
row_argmax_keepdim = torch.argmax(t1, dim=1, keepdim = True) # 원래의 1_dim(2)을 유지
row_sum = torch.sum(t1, dim=-1)
# sum by col (dim=0)
col_argmax = torch.argmax(t1, dim=0)
col_argmax_keepdim = torch.argmax(t1, dim=0, keepdim = True) # 원래의 0_dim(3)을 유지
col_sum = torch.sum(t1, dim=0)
row_argmax : 같은 행에서 가장 큰 값의 index 반환 : tensor( [1, 2] ) , shape : ( [2] )
row_argmax_keepdim : 위와 같은데, 1차원의 원래 사이즈 유지 : tensor( [[1], [2]] ) , shape : ( [1, 2] )
row_sum : 같은 행의 숫자끼리의 합을 구해줌 : tensor ( [13. , 13.] ), shape : ( [2] )
col_argmax : 같은 열에서 가장 큰 값의 index 반환 : tensor( [0, 0, 1] ) , shape : ( [3] )
col_argmax_keepdim : 위와 같은데, 0차원의 원래 사이즈 유지 : tensor( [[0, 0, 1]] ) , shape : ( [3, 1] )
col_sum : 같은 열의 숫자끼리의 합을 구해줌 : tensor ( [5. , 10., 11. ] ), shape : ( [3] )
stack
- 텐서간 결합
- torch.stack(tensors, dim=0) : concatenates a sequence of tensors along a new dimension, all tensors need to be of the same size
cat
- 텐서간 결합
- concatenates the given sequence of seq tensors in the given dimension. All tensors must either have the same shape (except in the concatenating dimension) or be empty.
(Ex 1 : 위 stack 예제와 x, y, z 동일할 때)
(Ex 2)
(Ex 3)
(Ex 4)
3.3 torch ~ numpy
- torch tensor를 numpy array로 변환
- numpy(), from_numpy()
- ** tensor가 CPU 상에 있다면 Numpy 배열은 메모리 공간을 공유하므로 하나가 변하면, 다른 하나도 변함
- 위 예제와 반대로 numpy array인 b를 조작해도 tensor a의 값이 따라서 변경된다.
'Study > 딥러닝' 카테고리의 다른 글
Regularization (0) | 2023.12.17 |
---|---|
Pytorch Tensorboard (0) | 2023.12.12 |
Weight Initialization (1) | 2023.10.22 |
Data Preprocessing & Augmentation (1) | 2023.10.22 |
Activation Functions (0) | 2023.10.21 |