All About PyTorch

Jacob Kim·2023년 12월 30일
0
post-thumbnail

파이토치(PyTorch)

페이스북이 초기 루아(Lua) 언어로 개발된 토치(Torch)를 파이썬 버전으로 개발하여 2017년도에 공개
초기에 토치(Torch)넘파이(NumPy) 라이브러리처럼 과학 연산을 위한 라이브러리로 공개
이후 GPU를 이용한 텐서 조작 및 동적 신경망 구축이 가능하도록 딥러닝 프레임워크로 발전시킴
파이썬답게 만들어졌고, 유연하면서도 가속화된 계산 속도를 제공

파이토치 모듈 구조

파이토치의 구성요소

torch: 메인 네임스페이스, 텐서 등의 다양한 수학 함수가 포함
torch.autograd: 자동 미분 기능을 제공하는 라이브러리
torch.nn: 신경망 구축을 위한 데이터 구조나 레이어 등의 라이브러리
torch.multiprocessing: 병럴처리 기능을 제공하는 라이브러리
torch.optim: SGD(Stochastic Gradient Descent)를 중심으로 한 파라미터 최적화 알고리즘 제공
torch.utils: 데이터 조작 등 유틸리티 기능 제공
torch.onnx: ONNX(Open Neural Network Exchange), 서로 다른 프레임워크 간의 모델을 공유할 때 사용

텐서(Tensor)

데이터 표현을 위한 기본 구조로 텐서(tensor)를 사용
텐서는 데이터를 담기위한 컨테이너(container)로서 일반적으로 수치형 데이터를 저장
넘파이(NumPy)의 ndarray와 유사
GPU를 사용한 연산 가속 가능

import torch
torch.__version__
#2.1.0+cu121

텐서 초기화와 초기화와 데이터 타입

초기화 되지 않은 텐서

x = torch.empty(4,2)
print(x)
#tensor([[6.4460e-44, 1.5134e-43],
#        [1.3593e-43, 1.6956e-43],
#        [1.4153e-43, 1.5975e-43],
#        [4.4842e-44, 8.5479e-44]])

무작위로 초기화된 텐서

x = torch.rand(4,2)
print(x)
#tensor([[0.6114, 0.8115],
#        [0.1097, 0.3828],
#       [0.3179, 0.9290],
#       [0.3845, 0.1246]])

데이터 타입(dtype)이 long이고, 0으로 채워진 텐서

x = torch.zeros(4,2, dtype=torch.long)
print(x)
#tensor([[0, 0],
#        [0, 0],
#        [0, 0],
#        [0, 0]])

2X4크기, double 타입, 1로 채워진 텐서

x = x.new_ones(2,4, dtype=torch.double)
print(x)
#tensor([[1., 1., 1., 1.],
#        [1., 1., 1., 1.]], dtype=torch.float64)

x와 같은 크기, float 타입, 무작위로 채워진 텐서

x = torch.randn_like(x, dtype=torch.float)
print(x)
#tensor([[-0.0923, -0.9947, -0.5870, -0.3204],
#        [-1.2466, -0.1598, -0.7607,  0.0678]])

텐서의 크기 계산

print(x.size())
#torch.Size([2, 4])

데이터 타입(Data Type)

ft = torch.FloatTensor([1,2,3])
print(ft)
print(ft.dtype)
#tensor([1., 2., 3.])
#torch.float32
print(ft.short())
print(ft.int())
print(ft.long())
#tensor([1, 2, 3], dtype=torch.int16)
#tensor([1, 2, 3], dtype=torch.int32)
#tensor([1, 2, 3])
it = torch.IntTensor([1,2,3])
print(it)
print(it.dtype)
#tensor([1, 2, 3], dtype=torch.int32)
#torch.int32
print(it.float())
print(it.double())
print(it.half())
#tensor([1., 2., 3.])
#tensor([1., 2., 3.], dtype=torch.float64)
#tensor([1., 2., 3.], dtype=torch.float16)

CUDA Tensors

.to 메소드를 사용하여 텐서를 어떠한 장치(cpu, gpu)로도 옮길 수 있음

x = torch.randn(1)
print(x)
print(x.item())
print(x.dtype)
#tensor([-0.7097])
#-0.7096615433692932
#torch.float32
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)
y = torch.ones_like(x, device=device)
print(y)
x = x.to(device)
print(x)
z = x + y
print(z)
print(z.to('cpu', torch.double))
cpu
#tensor([1.])
#tensor([-0.7097])
#tensor([0.2903])
#tensor([0.2903], dtype=torch.float64)

다차원 텐서 표현

0D Tensor(Scalar)

하나의 숫자를 담고 있는 텐서(tensor)
축과 형상이 없음

t0 = torch.tensor(0)
print(t0.ndim)
print(t0.shape)
print(t0)
#0
#torch.Size([])
#tensor(0)

1D Tensor(Vector)
값들을 저장한 리스트와 유사한 텐서
하나의 축이 존재

t1 = torch.tensor([1,2,3])
print(t1.ndim)
print(t1.shape)
print(t1)
#1
#torch.Size([3])
#tensor([1, 2, 3])

2D Tensor(Matrix)
행렬과 같은 모양으로 두개의 축이 존재
일반적인 수치, 통계 데이터셋이 해당
주로 샘플(samples)특성(features)을 가진 구조로 사용

t2 = torch.tensor([[1,2,3],
                  [4,5,6],
                  [7,8,9]])
print(t2.ndim)
print(t2.shape)
print(t2)
#2
#torch.Size([3, 3])
#tensor([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])

3D Tensor
큐브(cube)와 같은 모양으로 세개의 축이 존재
데이터가 연속된 시퀀스 데이터나 시간 축이 포함된 시계열 데이터에 해당
주식 가격 데이터셋, 시간에 따른 질병 발병 데이터 등이 존재
주로 샘플(samples), 타임스텝(timesteps), 특성(features)을 가진 구조로 사용

t3 = torch.tensor([[[1,2,3],
                  [4,5,6],
                  [7,8,9]],
                   [[1,2,3],
                  [4,5,6],
                  [7,8,9]],
                   [[1,2,3],
                  [4,5,6],
                  [7,8,9]]])
print(t3.ndim)
print(t3.shape)
print(t3)
#3
#torch.Size([3, 3, 3])
#tensor([[[1, 2, 3],
#         [4, 5, 6],
#        [7, 8, 9]],
#
#        [[1, 2, 3],
#        [4, 5, 6],
#         [7, 8, 9]],
#
#        [[1, 2, 3],
#         [4, 5, 6],
#         [7, 8, 9]]])

4D Tensor
4개의 축
컬러 이미지 데이터가 대표적인 사례 (흑백 이미지 데이터는 3D Tensor로 가능)
주로 샘플(samples), 높이(height), 너비(width), 컬러 채널(channel)을 가진 구조로 사용

5D Tensor
5개의 축
비디오 데이터가 대표적인 사례
주로 샘플(samples), 프레임(frames), 높이(height), 너비(width), 컬러 채널(channel)을 가진 구조로 사용

텐서의 연산

텐서에 대한 수학 연산, 삼각 함수, 비트 연산, 비교 연산, 집계등을 제공

import math
a = torch.rand(1,2) * 2 - 1
print(a)
print(torch.abs(a))
print(torch.ceil(a))
print(torch.floor(a))
print(torch.clamp(a, -0.5, 0.5))
#tensor([[-0.1788, -0.3389]])
#tensor([[0.1788, 0.3389]])
#tensor([[-0., -0.]])
#tensor([[-1., -1.]])
#tensor([[-0.1788, -0.3389]])
print(a)
print(torch.min(a))
print(torch.max(a))
print(torch.std(a))
print(torch.prod(a))
print(torch.unique(torch.tensor([1,2,3,1,2,2])))
#tensor([[-0.1788, -0.3389]])
#tensor(-0.3389)
#tensor(-0.1788)
#tensor(0.1132)
#tensor(0.0606)
#tensor([1, 2, 3])

maxmindim 인자를 줄 경우 argmaxargmin도 함께 리턴
argmax: 최대값을 가진 인덱스
argmin: 최소값을 가진 인덱스

x = torch.rand(2,2)
print(x)
print(x.max(dim=0))
print(x.min(dim=1))
# tensor([[0.1849, 0.3840],
#         [0.4086, 0.2098]])
# torch.return_types.max(
# values=tensor([0.4086, 0.3840]),
# indices=tensor([1, 0]))
# torch.return_types.min(
# values=tensor([0.1849, 0.2098]),
# indices=tensor([0, 1]))
print(x)
print(x.max(dim=0))
print(x.min(dim=1))
#tensor([[0.1849, 0.3840],
#        [0.4086, 0.2098]])
#torch.return_types.max(
#values=tensor([0.4086, 0.3840]),
#indices=tensor([1, 0]))
#torch.return_types.min(
#values=tensor([0.1849, 0.2098]),
#indices=tensor([0, 1]))
x = torch.rand(2,2)
print(x)
y = torch.rand(2,2)
print(y)
#tensor([[0.7506, 0.2843],
#        [0.1169, 0.6632]])
#tensor([[0.8958, 0.3545],
#        [0.0266, 0.1434]])

torch.add: 덧셈

print(x + y)
print(torch.add(x,y))
#tensor([[1.6464, 0.6388],
#        [0.1435, 0.8066]])
#tensor([[1.6464, 0.6388],
#        [0.1435, 0.8066]]

결과 텐서를 인자로 제공

result = torch.empty(2,4)
torch.add(x, y, out=result)
print(result)
#tensor([[1.6464, 0.6388],
#        [0.1435, 0.8066]])

in-place 방식
in-place방식으로 텐서의 값을 변경하는 연산 뒤에는 _''가 붙음
x.copy(), x.t()

print(x)
print(y)
y.add_(x)
print(y)
#tensor([[0.7506, 0.2843],
#        [0.1169, 0.6632]])
#tensor([[0.8958, 0.3545],
#        [0.0266, 0.1434]])
#tensor([[1.6464, 0.6388],
#        [0.1435, 0.8066]])

torch.sub: 뺄셈

print(x)
print(y)
print(x-y)
print(torch.sub(x,y))
print(x.sub(y))
#tensor([[0.7506, 0.2843],
#        [0.1169, 0.6632]])
#tensor([[1.6464, 0.6388],
#        [0.1435, 0.8066]])
#tensor([[-0.8958, -0.3545],
#        [-0.0266, -0.1434]])
#tensor([[-0.8958, -0.3545],
#        [-0.0266, -0.1434]])
#tensor([[-0.8958, -0.3545],
#        [-0.0266, -0.1434]])

torch.mul: 곱셉

print(x)
print(y)
print(x*y)
print(torch.mul(x,y))
print(x.mul(y))
#tensor([[0.7506, 0.2843],
#        [0.1169, 0.6632]])
#tensor([[1.6464, 0.6388],
#        [0.1435, 0.8066]])
#tensor([[1.2357, 0.1816],
#        [0.0168, 0.5350]])
#tensor([[1.2357, 0.1816],
#        [0.0168, 0.5350]])
#tensor([[1.2357, 0.1816],
#        [0.0168, 0.5350]])

torch.div: 나눗셈

print(x)
print(y)
print(x/y)
print(torch.div(x,y))
print(x.div(y))
#tensor([[0.7506, 0.2843],
#        [0.1169, 0.6632]])
#tensor([[1.6464, 0.6388],
#        [0.1435, 0.8066]])
#tensor([[0.4559, 0.4450],
#        [0.8146, 0.8222]])
#tensor([[0.4559, 0.4450],
#        [0.8146, 0.8222]])
#tensor([[0.4559, 0.4450],
#        [0.8146, 0.8222]])

torch.mm: 내적(dot product)

print(x)
print(y)
print(torch.matmul(x,y))
z = torch.mm(x,y)
print(z)
print(torch.svd(z))
#tensor([[0.7506, 0.2843],
3        [0.1169, 0.6632]])
#tensor([[1.6464, 0.6388],
#        [0.1435, 0.8066]])
#tensor([[1.2765, 0.7088],
#        [0.2876, 0.6096]])
#tensor([[1.2765, 0.7088],
#        [0.2876, 0.6096]])
#torch.return_types.svd(
#U=tensor([[-0.9284, -0.3715],
#        [-0.3715,  0.9284]]),
#S=tensor([1.5658, 0.3668]),
#V=tensor([[-0.8251, -0.5649],
#        [-0.5649,  0.8251]]))

텐서의 조작(Manipulation)

인덱싱(Indexing) : NumPy처럼 인덱싱 형태로 사용가능

x = torch.Tensor([[1,2],
                  [3,4]])
print(x)
print(x[0,0])
print(x[0,1])
print(x[1,0])
print(x[1,0])
print(x[:,0])
print(x[:,1])
print(x[0, :])
print(x[1, :])
#tensor([[1., 2.],
#        [3., 4.]])
#tensor(1.)
#tensor(2.)
#tensor(3.)
#tensor(3.)
#tensor([1., 3.])
#tensor([2., 4.])
#tensor([1., 2.])
#tensor([3., 4.])

view: 텐서의 크기(size)모양(shape)을 변경
기본적으로 변경 전과 후에 텐서 안의 원소 개수가 유지되어야 함
-1로 설정되면 계산을 통해 해당 크기값을 유추

profile
AI, Information and Communication, Electronics, Computer Science, Bio, Algorithms

0개의 댓글