1. 파이토치(Pytorch)
* Python을 기반으로 한 오픈 소스 기계 학습 라이브러리
* 텐서플로우(Tensorflow)와 함께 머신러닝, 딥러닝에서 가장 널리 사용되는 프레임워크
* 초기에는 Torch라는 이름으로 Lua언어 기반으로 만들어졌으나, 파이썬 기반으로 변경한 것이 Pytorch
* 뉴욕대학교와 페이스북이 공동으로 개발하였고, 현재 가장 대중적이고 널리 사용됨int32)
주요 특징 |
|
주요 구성 요소 |
|
- 파이토치 import
버전보기
import torch
print(torch.__version__)
|
2.3.0+cu121 |
1-1. 스칼라(Scalar)
* 하나의 상수를 의미
* 수학적으로 크기만 있고 방향이 없는 양
- 단일 요소 1차원 텐서 생성
var1 = torch.tensor([1])
type(var1)
|
torch.Tensor --------------------------------------------------------------------- 이 경우, [1]이라는 리스트를 텐서로 변환 |
- 단일 요소 1차원 텐서 생성
var2 = torch.tensor([10.5])
type(var2)
|
torch.Tensor ------------------------------------------------------------------ 이 경우, [10.5]이라는 리스트를 텐서로 변환 |
✅ 추가적인 설명 : var1 var2 은 torch.Tensor 타입의 객체로 생성 PyTorch는 NumPy의 ndarray와 유사한 구조를 가지고 있지만, GPU 가속과 자동 미분 등의 추가적인 기능을 제공하기 때문에 변환 |
- 두 개의 텐서(var1과 var2) 간의 기본 산술 연산
# 두 스칼라의 사칙 연산
print(var1 + var2)
print(var1 - var2)
print(var1 * var2)
print(var1 / var2)
|
tensor([11.5000]) tensor([-9.5000]) tensor([10.5000]) tensor([0.0952]) |
1-2. 벡터(Vector)
* 상수가 두 개 이상 나열되었을 경우
* 크기와 방향을 가지는 양
* 벡터는 공간상의 한 점에서 다른 점으로의 방향과 거리를 표현합니다
- 세개의 요소를 가진 1차원 벡터 생성
vec1 = torch.tensor([1, 2, 3])
vec1
|
tensor([1, 2, 3]) ----------------------------------------------------------- [1, 2, 3]이라는 리스트를 텐서로 변환 |
- vec1의 데이터 타입
type(vec1)
|
torch.Tensor -------------------------------- vec1은 1차원 PyTorch 텐서 |
- 부동 소수점 숫자를 포함하는 1차원 벡터를 생성
vec2 = torch.tensor([1.5, 2.4, 3.3])
vec2
|
tensor([1.5000, 2.4000, 3.3000]) |
- 벡터(vec1과 vec2) 간의 기본 산술 연산
# 두 벡터의 사칙 연산
print(vec1 + vec2)
print(vec1 - vec2)
print(vec1 * vec2)
print(vec1 / vec2)
|
tensor([2.5000, 4.4000, 6.3000]) tensor([-0.5000, -0.4000, -0.3000]) tensor([1.5000, 4.8000, 9.9000]) tensor([0.6667, 0.8333, 0.9091]) |
- 네개의 요소를 가진 1차원 벡터 생성
vec3 = torch.tensor([5, 10, 15,20])
vec3
|
tensor([ 5, 10, 15, 20]) -------------------------------- [5, 10, 15, 20]이라는 리스트를 텐서로 변환 |
- vec1 와 vec3 덧셈 연산
vec1 + vec3 # 오류 : cannot assign to expression |
vec1과 vec3이 서로 다른 길이의 벡터 vec1은 길이가 3인 벡터이고, vec3은 길이가 4인 벡터 |
1-3. 행렬(Matrix)
* 2차원 배열
* 2개 이상의 벡터 값을 가지고 만들어진 값으로 행과 열의 개념을 가진 숫자의 나열
* 숫자를 직사각형 모양으로 배열, 주로 수학적인 연산에 사용됩니다
*행렬은 행(row)과 열(column)로 이루어져 있으며, 각 원소는 위치를 나타내는 두 개의 인덱스로 접근할 수 있습니다
- 'mat1', 'mat2' 두개의 2차원 행렬을 생성하고 사칙 연산을 수행
mat1 = torch.tensor([[1,2], [3,4]])
print(mat1)
mat2 = torch.tensor([[7,8], [9,10]])
print(mat2)
# 두 행렬의 사칙 연산
print(mat1 + mat2)
print(mat1 - mat2)
print(mat1 * mat2)
print(mat1 / mat2)
|
tensor([[1, 2], [3, 4]]) -------------------------------- tensor([[ 7, 8], [ 9, 10]]) -------------------------------- tensor([[ 8, 10], [12, 14]]) tensor([[-6, -6], [-6, -6]]) tensor([[ 7, 16], [27, 40]]) tensor([[0.1429, 0.2500], [0.3333, 0.4000]]) |
1-4. 텐서(Tensor)
* 다수의 행렬이 모이면 텐서라고 부름
* 배열이나 행렬과 매우 유사한 특수한 자료구조
* 파이토치는 텐서를 사용하여 모델의 입력과 출력, 모델의 매개변수들을 처리 사용됨
- 0차원 텐서(스칼라): 하나의 숫자로 이루어진 텐서로, 크기가 없는 차원입니다.
- 1차원 텐서(벡터): 여러 숫자가 일렬로 배열된 텐서로, 크기가 있는 한 차원입니다.
- 2차원 텐서(행렬): 여러 벡터가 직사각형 모양으로 배열된 텐서로, 행과 열을 가지는 두 차원입니다.
- 고차원 텐서: 3차원 이상의 다차원 배열을 의미하며, 여러 차원을 가질 수 있습니다.
- 'tensor1' 'tensor2' 3차원 텐서를 생성하고 출력
tensor1 = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(tensor1)
tensor2 = torch.tensor([[[9, 10], [11, 12]], [[13, 14], [15, 16]]])
print(tensor2)
|
tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) -------------------------- tensor([[[ 9, 10], [11, 12]], [[13, 14], [15, 16]]]) |
- 'tensor1' 'tensor2' 사칙연산
# 두 텐서의 사칙연산 print(tensor1 + tensor2)
print(tensor1 - tensor2)
print(tensor1 * tensor2)
print(tensor1 / tensor2)
|
tensor([[[10, 12], [14, 16]], [[18, 20], [22, 24]]]) tensor([[[-8, -8], [-8, -8]], [[-8, -8], [-8, -8]]]) tensor([[[ 9, 20], [ 33, 48]], [[ 65, 84], [105, 128]]]) tensor([[[0.1111, 0.2000], [0.2727, 0.3333]], [[0.3846, 0.4286], [0.4667, 0.5000]]]) |
- PyTorch를 사용하여 다양한 텐서 연산을 수행
print(torch.add(tensor1,tensor2))
print(torch.subtract(tensor1,tensor2))
print(torch.multiply(tensor1,tensor2))
print(torch.divide(tensor1,tensor2))
print(torch.matmul(tensor1,tensor2)) # 행렬곱 연산
|
tensor([[[10, 12], [14, 16]], [[18, 20], [22, 24]]]) tensor([[[-8, -8], [-8, -8]], [[-8, -8], [-8, -8]]]) tensor([[[ 9, 20], [ 33, 48]], [[ 65, 84], [105, 128]]]) tensor([[[0.1111, 0.2000], [0.2727, 0.3333]], [[0.3846, 0.4286], [0.4667, 0.5000]]]) tensor([[[ 31, 34], [ 71, 78]], [[155, 166], [211, 226]]]) |
- 연산을 수행하고, 결과를 원래 텐서에 바로 저장
# replace 연산
print(tensor1.add_(tensor2)) # tensor1에 결과를 다시 저장, 모든 사칙 연산자에 _ 를 붙여 사용할 수 있음
print(tensor1)
print(tensor1.subtract_(tensor2)) # 모든 사칙연산자에 _를 붙이면 inplace=True가 됨
|
tensor([[[10, 12], [14, 16]], [[18, 20], [22, 24]]]) tensor([[[10, 12], [14, 16]], [[18, 20], [22, 24]]]) tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) |
2. 텐서의 변환
* 다수의 행렬이 모이면 텐서라고 부름
* 배열이나 행렬과 매우 유사한 특수한 자료구조
* 파이토치는 텐서를 사용하여 모델의 입력과 출력, 모델의 매개변수들을 처리 사용됨
- 파이썬 리스트 x_data를 정의하고 출력
x_data = [[1,2], [3,4]]
print(x_data)
|
[[1, 2], [3, 4]] |
- 파이썬 리스트(x_data)를 numpy 배열(np_array)로 변환
import numpy as np
np_array = np.array(x_data)
np_array
|
array([[1, 2], [3, 4]]) |
- numpy 배열(np_array)을 PyTorch 텐서(x_np_1)로 변환
x_np_1 = torch.tensor(np_array)
x_np_1
|
tensor([[1, 2], [3, 4]]) |
- 텐서(x_np_1) 첫 번째 원소를 100으로 변경
x_np_1[0, 0] = 100
print(x_np_1)
print(np_array)
|
tensor([[100, 2], [ 3, 4]]) [[1 2] [3 4]] |
'x_np_1' 텐서의 첫 번째 원소를 100으로 수정 NumPy 배열 'np_array'는 그대로 유지 * PyTorch 텐서는 NumPy 배열과 유사한 방식으로 인덱싱 및 값 할당이 가능하다. |
- torch.as_tensor()는 PyTorch 텐서로 변환하며, 원본 데이터를 공유
# torch.as_tensor(): ndarray와 동일한 메모리 주소를 가리키는 뷰를 만드는 함수
x_np_2 = torch.as_tensor(np_array)
print(x_np_2)
x_np_2[0, 0] = 200
print(x_np_2)
print(np_array)
|
tensor([[200, 2], [ 3, 4]]) tensor([[200, 2], [ 3, 4]]) [[200 2] [ 3 4]] torch.as_tensor가 np_array와 동일한 메모리 주소를 가리키는 텐서를 생성하기 때문에 발생합니다. 따라서 텐서의 값을 변경하면 원본 NumPy 배열의 값도 함께 변경 |
- torch.from_numpy()를 사용하여 NumPy 배열을 PyTorch 텐서로 변환,
변환된 텐서의 값을 변경하여 원본 NumPy 배열의 값도 변경
# from_numpy() : ndarray와 동일한 메모리 주소를 가리키는 뷰를 만듬
x_np_3 = torch.from_numpy(np_array)
print(x_np_3)
x_np_3[0, 0] = 400 # 기존 메모리 주소의 ndarray 값을 변경하게 됨
print(x_np_3)
print(np_array)
|
tensor([[200, 2], [ 3, 4]]) tensor([[400, 2], [ 3, 4]]) [[400 2] [ 3 4]] |
torch.as_tensor() / from_numpy() 의 차이 |
|
- 텐서 x_np_3를 NumPy 배열로 변환한 np_again과 그 데이터 타입을 출력
np_again = x_np_3.numpy()
print(np_again, type(np_again))
|
[[400 2] [ 3 4]] <class 'numpy.ndarray'> |
3. 파이토치 주요함수
* 다수의 행렬이 모이면 텐서라고 부름
* 배열이나 행렬과 매우 유사한 특수한 자료구조
* 파이토치는 텐서를 사용하여 모델의 입력과 출력, 모델의 매개변수들을 처리 사용됨
- 텐서 a _ 모든 값이 1로 채워짐
a = torch.ones(2, 3)
print(a)
|
tensor([[1., 1., 1.], [1., 1., 1.]]) |
- 텐서 b _ 모든 요소가 0으로 채워짐
b = torch.zeros(2, 3)
print(b)
|
tensor([[0., 0., 0.], [0., 0., 0.]]) |
- 텐서 c _ 내가 원하는 값으로 채우기
c = torch.full((2,3), 10)
print(c)
|
tensor([[10, 10, 10], [10, 10, 10]]) |
- 텐서 d _ 무작위 값 넣기
d = torch.empty(2,3) # 실수 무작위값을 넣어줌
print(d)
|
tensor([[2.1085e-07, 6.7703e+22, 3.3356e-09], [2.1707e-18, 7.1450e+31, 6.1970e-04]]) |
- 단위 행렬(identity matrix) e _ 대각선을 1로 채우기
# 대각선을 1로 채우기
e = torch.eye(5)
print(e)
|
tensor([[1., 0., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 0., 1., 0.], [0., 0., 0., 0., 1.]]) |
- 텐서 f _ 0부터 9까지의 정수
f = torch.arange(10)
print(f)
|
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) |
- 텐서 g _0과 1 사이의 무작위 실수
g = torch.rand(2, 3) # 랜덤한 숫자를 나열해줌, 0~1 사이의 양수만 출력
print(g)
|
tensor([[0.6799, 0.8935, 0.9098], [0.9568, 0.1631, 0.3808]]) |
- 텐서 h _평균이 0이고 표준편차가 1인 정규 분포에서 추출한 무작위 수로 구성
h = torch.randn(2, 3) # 평균이 0이고 표준편차가 1인 정규 분포에서 난수로 이루어진 텐서
print(h)
|
tensor([[ 1.0582, -0.1366, -2.2529], [ 0.6362, -0.2156, 0.6600]]) |
- 텐서 i _ 0부터 15까지의 정수
i = torch.arange(16).reshape(2, 2, 4) # 2행 4열 2개
print(i, i.shape)
|
tensor([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]]) torch.Size([2, 2, 4]) |
차원 바꾸기 .reshape(2, 2, 4)는 이를 2x2x4 크기의 텐서로 재구성합니다. 즉, 2개의 2x4 행렬로 구성됩니다. |
- 텐서 i의 차원을 변경
# 차원을 인덱스로 변환
# i = {2, 2, 4} 2행 4열 두개
k = i.permute((2, 0, 1))
# 2, 2, 4 -> 4, 2, 2 : 2행 2열짜리 네개
print(k, k.shape)
|
tensor([[[ 0, 4], [ 8, 12]], [[ 1, 5], [ 9, 13]], [[ 2, 6], [10, 14]], [[ 3, 7], [11, 15]]]) torch.Size([4, 2, 2]) |
|
4. 텐서의 인덱싱과 슬라이싱
* 다수의 행렬이 모이면 텐서라고 부름
* 배열이나 행렬과 매우 유사한 특수한 자료구조
* 파이토치는 텐서를 사용하여 모델의 입력과 출력, 모델의 매개변수들을 처리 사용됨
- 1부터 12까지의 정수로 구성된 1차원 텐서_ 3x4 크기의 텐서로 재구성
a = torch.arange(1, 13).reshape(3, 4)
print(a)
|
tensor([[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12]]) |
- 텐서 a의 특정 부분을 인덱싱하여 출력
print(a[1])
print(a[0, -1])
print(a[1:-1])
print(a[:2, 2:])
|
tensor([5, 6, 7, 8]) tensor(4) tensor([[5, 6, 7, 8]]) tensor([[3, 4], [7, 8]]) |
|
@. 코렙에서 GPU 사용하기
* 코랩에서 device 변경하는 방법
* 상단 메뉴 -> 런타임 -> 런타임 유형변경 -> 하드웨어 가속기를 GPU로 변경 -> 저장 -> 다시 시작 및 모두 실행
- PyTorch 텐서 생성 및 속성 출력
tensor = torch.rand(3, 4)
print(tensor)
print(f'shape: {tensor.shape}')
print(f'type: {type(tensor)}')
print(f'dtype: {tensor.dtype}')
print(f'device: {tensor.device}'
|
tensor([[0.7024, 0.5153, 0.5479, 0.8518], [0.9010, 0.1850, 0.0758, 0.7326], [0.7646, 0.0624, 0.5765, 0.8787]]) shape: torch.Size([3, 4]) type: <class 'torch.Tensor'> dtype: torch.float32 device: cpu |
|
- PyTorch 텐서 속성 및 GPU 사용 확인
CPU 의 경우
# is_available() : gpu를 사용할 수 있는지 여부
tensor = tensor.reshape(4, 3)
tensor = tensor.int()
print(f'shape: {tensor.shape}')
print(f'type: {type(tensor)}')
print(f'dtype: {tensor.dtype}')
if torch.cuda.is_available():
print('GPU를 사용할 수 있음')
tensor = tensor.to('cuda')
print(f'device: {tensor.device}')
|
tensor([[0.1793, 0.0093, 0.8758, 0.2619], [0.8945, 0.8254, 0.6933, 0.6634], [0.2428, 0.1457, 0.1283, 0.5310]]) shape: torch.Size([3, 4]) type: <class 'torch.Tensor'> dtype: torch.float32 device: cpu |
- PyTorch 텐서 속성 및 GPU 사용 확인
GPU로 설정
# is_available() : gpu를 사용할 수 있는지 여부
tensor = tensor.reshape(4, 3)
tensor = tensor.int()
print(f'shape: {tensor.shape}')
print(f'type: {type(tensor)}')
print(f'dtype: {tensor.dtype}')
if torch.cuda.is_available():
print('GPU를 사용할 수 있음')
tensor = tensor.to('cuda')
print(f'device: {tensor.device}')
|
shape: torch.Size([4, 3]) type: <class 'torch.Tensor'> dtype: torch.int32 GPU를 사용할 수 있음 device: cuda:0 |
만약 GPU가 사용 불가능하면, 텐서는 그대로 CPU에 남아있을 것입니다. |
'AI > 딥러닝' 카테고리의 다른 글
06. 비선형 활성화 함수 (0) | 2024.06.20 |
---|---|
05. 딥러닝 (0) | 2024.06.20 |
04. 데이터로더(Data Loader) (0) | 2024.06.20 |
03. 논리회귀 (단항, 다중) | 시그모이드(sigmoid) 함수 (0) | 2024.06.19 |
02. 선형 회귀(단항, 다중) | 경사하강법 (0) | 2024.06.18 |