1.파이토치(Pytorch)
파이토치(PyTorch)는 머신러닝과 딥러닝 분야에서 가장 널리 사용되는 오픈 소스 프레임워크 중 하나로, TensorFlow와 더불어 대중적으로 활용되고 있습니다. 초기에는 "Torch"라는 이름으로 루아(Lua) 언어를 기반으로 만들어졌으나, 파이썬 기반으로 변경된 것이 파이토치입니다. 이 프레임워크는 뉴욕대학교와 페이스북(현재는 메타로 알려져 있음)이 공동으로 개발하였으며, 현재는 머신러닝 및 딥러닝 업계에서 가장 대중적인 도구 중 하나로 자리매김하고 있습니다.
import torch
print(torch.__version__) // 2.1.0+cu121
2. 텐서(Tensor)
텐서(Tensor)는 다차원 배열로, 스칼라, 벡터, 행렬을 포함한 여러 차원의 숫자 데이터를 표현하는 수학적인 개념입니다. 텐서는 데이터를 효과적으로 표현하고 다루기 위한 중요한 도구로서 머신러닝과 딥러닝에서 널리 사용됩니다.
2-1. 스칼라
스칼라(Scalar)는 크기만 있고 방향이 없는 양을 나타내는 수학적 개념입니다. 스칼라는 하나의 실수 값으로만 표현되며, 크기만을 가지고 있어서 벡터나 행렬과 달리 방향이나 위치 정보가 없습니다.
var1 = torch.tensor([1])
var1 // tensor([1])
type(var1) // torch.Tensor
var2 = torch.tensor([10.4])
var2 // tensor([10.4000])
# 두 스칼라의 사칙 연산
print(var1 + var2) // tensor([11.4000])
print(var1 - var2) // tensor([-9.4000])
print(var1 * var2) // tensor([10.4000])
print(var1 / var2) // tensor([0.0962])
2-2. 벡터(Vector)
벡터(Vector)는 크기와 방향을 가지는 양을 나타내는 수학적 개념입니다. 벡터는 화살표로 시각적으로 나타낼 수 있으며, 화살표의 길이가 벡터의 크기를, 화살표의 방향이 벡터의 방향을 나타냅니다. 스칼라는 단일 데이터라면, 상수가 두개 이상 나열된 경우를 벡터라고 할 수 있습니다.
vec1 = torch.tensor([1,2,3])
vec1 // tensor([1, 2, 3])
vec2 = torch.tensor([1.5,2.4,3.3])
vec2 // tensor([1.5000, 2.4000, 3.3000])
print(vec1 + vec2) // tensor([2.5000, 4.4000, 6.3000])
print(vec1 - vec2) // tensor([-0.5000, -0.4000, -0.3000])
print(vec1 * vec2) // tensor([1.5000, 4.8000, 9.9000])
print(vec1 / vec2) // tensor([0.6667, 0.8333, 0.9091])
vec3 = torch.tensor([5, 10, 20, 30])
vec3 // tensor([ 5, 10, 20, 30])
#print(vec1 + vec3)
# 요소의 갯수가 맞지 않아서 에러 발생
# RuntimeError: The size of tensor a (3) must match the size of tensor b (4) at non-singleton dimension 0
vec3 + var1 // tensor([ 6, 11, 21, 31])
# 벡터에 스칼라를 사칙연산 할 경우 벡터의 각 성분에 스칼라를 대입
2-3. 행렬(Matrix)
2개 이상의 벡터값을 가지고 만들어진 값으로 행(row)과 열(column)로 이루어져 있습니다.
mat1 = torch.tensor([[1,2], [3,4]])
print(mat1)
tensor([[1, 2],
[3, 4]])
mat2 = torch.tensor([[7,8], [9,10]])
print(mat2)
tensor([[ 7, 8],
[ 9, 10]])
print(mat1 + mat2)
tensor([[ 8, 10],
[12, 14]])
print(mat1 - mat2)
tensor([[-6, -6],
[-6, -6]])
print(mat1 * mat2)
tensor([[ 7, 16],
[27, 40]])
print(mat1 / mat2)
tensor([[0.1429, 0.2500],
[0.3333, 0.4000]])
- 스칼라 곱셈: 행렬의 각 원소에 스칼라를 곱합니다.
- 행렬 곱셈 (Matrix Multiplication): 두 행렬 A와 B가 곱해질 때, A의 열과 B의 행의 크기가 일치해야 합니다. 결과 행렬 C의 는 A의 i번째 행과 B의 j번째 열의 내적입니다.
2-4. 텐서(Tensor)
텐서는 다차원 배열로, 여러 차원의 데이터를 효과적으로 표현하고 연산할 수 있는 도구로 활용됩니다. 텐서는 여러 개의 행렬이 모여 있는 자료구조로, 배열이나 행렬과 유사한 형태를 갖춘 특수한 데이터 형식입니다. 파이토치(PyTorch)는 모델의 입력과 출력, 그리고 모델의 매개변수들을 처리하기 위해 텐서를 사용합니다.
tensor1 = torch.tensor([[[1,2],[3,4]],[[5,6],[7,8]]])
tensor([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
tensor2 = torch.tensor([[[9,10],[11,12]],[[13,14],[15,16]]])
tensor([[[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16]]])
tensor3 = torch.tensor([[[[9, 10], [11, 12]], [[13, 14], [15, 16]]],[[[1,2],[3,4]], [[5,6],[7,8]]] ])
print(tensor3)
tensor([[[[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16]]],
[[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]]]])
print(tensor3[0])
# = print(tensor3[0, :, :, :])
tensor([[[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16]]])
print(tensor3[1])
tensor([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
print(tensor3[0][0])
tensor([[ 9, 10],
[11, 12]])
print(tensor3[0][0][0][0]) # 4차원
tensor(9)
print(tensor1 + tensor2)
tensor([[[10, 12],
[14, 16]],
[[18, 20],
[22, 24]]])
print(tensor1 - tensor2)
tensor([[[-8, -8],
[-8, -8]],
[[-8, -8],
[-8, -8]]])
print(tensor1 * tensor2)
tensor([[[ 9, 20],
[ 33, 48]],
[[ 65, 84],
[105, 128]]])
print(tensor1 / tensor2)
tensor([[[0.1111, 0.2000],
[0.2727, 0.3333]],
[[0.3846, 0.4286],
[0.4667, 0.5000]]])
print(torch.add(tensor1,tensor2))
tensor([[[10, 12],
[14, 16]],
[[18, 20],
[22, 24]]])
print(torch.subtract(tensor1,tensor2))
tensor([[[-8, -8],
[-8, -8]],
[[-8, -8],
[-8, -8]]])
print(torch.multiply(tensor1,tensor2))
tensor([[[ 9, 20],
[ 33, 48]],
[[ 65, 84],
[105, 128]]])
print(torch.divide(tensor1,tensor2))
tensor([[[0.1111, 0.2000],
[0.2727, 0.3333]],
[[0.3846, 0.4286],
[0.4667, 0.5000]]])
print(torch.matmul(tensor1,tensor2)) # 행렬곱
tensor([[[ 31, 34],
[ 71, 78]],
[[155, 166],
[211, 226]]])
# inplace 사칙연산 함수.
# tensor1에 결과를 다시 저장. 모든 사칙연산자에 _를 붙이면 inplace가 된다.
print(tensor1.add_(tensor2)) # inplace함수. add_ 적용된 값이 저장이 된다.
tensor([[[10, 12],
[14, 16]],
[[18, 20],
[22, 24]]])
print(tensor1)
tensor([[[10, 12],
[14, 16]],
[[18, 20],
[22, 24]]])
3. 텐서의 변환
import numpy as np
data = [[1,2], [3,4]]
print(data) // [[1, 2], [3, 4]]
print(type(data)) // <class 'list'>
x_data = torch.tensor(data)
print(x_data) // tensor([[1, 2],
[3, 4]])
np_array = np.array(x_data)
np_array // array([[1, 2],
[3, 4]])
x_np_1 = torch.tensor(np_array)
x_np_1 // tensor([[1, 2],
[3, 4]])
x_np_1[0,0] = 100
x_np_1
tensor([[100, 2],
[ 3, 4]])
np_array
array([[1, 2],
[3, 4]])
✔️ as_tensor와 from_numpy 함수
- torch.as_tensor : 파이썬 리스트, NumPy 배열, 또는 다른 array-like 객체를 PyTorch 텐서로 변환합니다. 주어진 데이터의 메모리를 공유하며 텐서를 생성합니다. 따라서 원본 데이터의 변화는 새로운 텐서에도 영향을 미칩니다.
- torch.from_numpy : NumPy 배열을 PyTorch 텐서로 변환합니다. NumPy 배열과 PyTorch 텐서 사이에서 데이터를 공유합니다. 따라서 원본 NumPy 배열의 데이터가 변경되면 PyTorch 텐서에도 영향을 미칩니다.
# as_tensor: ndarray와 동일한 메모리 주소를 가리키는 뷰를 만듦
# 자료구조가 다양하게 들어갈 수 있음
x_np_2 = torch.as_tensor(np_array)
print(x_np_2)
tensor([[1, 2],
[3, 4]])
x_np_2[0,0] = 200
print(x_np_2)
tensor([[200, 2],
[ 3, 4]])
print(np_array)
[[200 2]
[ 3 4]]
# from_numpy: ndarray와 동일한 메모리 주소를 가리키는 뷰를 만듦
# ndarray형식만 넣을 수 있음
x_np_3 = torch.from_numpy(np_array)
print(x_np_3)
tensor([[200, 2],
[ 3, 4]])
x_np_3[0,0] = 300
print(x_np_3)
tensor([[300, 2],
[ 3, 4]])
print(np_array)
[[300 2]
[ 3 4]]
.numpy()는 PyTorch 텐서를 NumPy 배열로 변환하는 메서드입니다. 이 메서드를 호출하면 PyTorch 텐서와 NumPy 배열이 같은 메모리를 공유하게 됩니다. 따라서 .numpy()를 통해 얻은 NumPy 배열을 수정하면 해당 변경 사항이 원래의 PyTorch 텐서에도 반영됩니다.
np_again = x_np_1.numpy()
print(np_again, type(np_again))
[[100 2]
[ 3 4]] <class 'numpy.ndarray'>
4.파이토치 주요 함수
a = torch.ones(2,3)
print(a)
tensor([[1., 1., 1.],
[1., 1., 1.]])
b = torch.zeros(2,3)
print(b)
tensor([[0., 0., 0.],
[0., 0., 0.]])
c = torch.full((2,3),10)
print(c)
tensor([[10, 10, 10],
[10, 10, 10]])
d = torch.empty(2,3)
print(d)
tensor([[1.0812e-05, 1.3000e+22, 2.1707e-18],
[4.5447e+30, 7.0062e+22, 2.1715e-18]])
#초기화되지 않은 상태이기 때문에 그 안에 들어있는 값은 메모리 상의 이전 데이터나 쓰레기 값
# 가로,세로 같은 정방행렬만 만듬
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 = torch.arange(10)
print(f) // tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
g = torch.rand(2,3)
print(g)
tensor([[0.8342, 0.6067, 0.6443],
[0.3586, 0.4334, 0.7566]]) # random값(0~1사이)을 채움
# 정규분포식을 따르는 난수 생성
h = torch.randn(2,3)
print(h)
tensor([[-1.2786, -0.5648, -0.7582],
[ 0.1961, -0.3943, 0.9738]])
i = torch.arange(16).reshape(2,2,4) # 맨 앞이 면, 뒤가 행렬
print(i)
tensor([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
# 각 "면"에는 2개의 "행렬"이 있고, 각 "행렬"에는 2개의 "행"과 4개의 "열"이 있음
print(i.shape) // torch.Size([2, 2, 4])
# 차원을 지정한 인덱스로 변환
# 2, 2, 4
j = i.permute((2,0,1)) # 2, 2, 4 -> 4, 2, 2
print(j, j.shape)
tensor([[[ 0, 4],
[ 8, 12]],
[[ 1, 5],
[ 9, 13]],
[[ 2, 6],
[10, 14]],
[[ 3, 7],
[11, 15]]]) torch.Size([4, 2, 2])
# 안에 요소 들어가는 방향은 세로 열방향으로 감
5. 텐서의 인덱싱과 슬라이싱
✔️ 인덱싱은 차원이 낮아지고, 슬라이싱은 유지된다.
a = torch.arange(1,13).reshape(3,4)
print(a)
tensor([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
print(a[1]) // tensor([5, 6, 7, 8])
print(a[0, -1]) // tensor(4)
print(a[1:-1]) //tensor([[5, 6, 7, 8]])
# 차원 유지
print(a[:2, 2:]) // tensor([[3, 4],
[7, 8]])
6. 코랩의 GPU 사용
✔️코랩에서 device 변경하는 방법
[상단 메뉴 -> 런타임 -> 런타임 유형변경 -> 하드웨어 가속기를 GPU로 변경 -> 저장 -> 세션 다시 시작 및 모두 실행]
tensor = torch.rand(3,4)
print(f'shape: {tensor.shape}') // shape: torch.Size([3, 4])
print(f'dtype: {tensor.dtype}') // dtype: torch.float32
print(f'device: {tensor.device}') // device: cpu
# is_available() : gpu 사용할 수 있는지 여부
tensor = tensor.reshape(4,3)
tensor = tensor.int()
if torch.cuda.is_available():
print('GPU를 사용할 수 있음')
tensor = tensor.to('cuda') # GPU로 보내줘야 GPU에서 연산
// GPU를 사용할 수 있음
print(f'shape: {tensor.shape}') // shape: torch.Size([4, 3])
print(f'dtype: {tensor.dtype}') // dtype: torch.int32
print(f'device: {tensor.device}') // device: cuda:0
'AI' 카테고리의 다른 글
기온에 따른 지면 온도 예측 (0) | 2024.01.08 |
---|---|
파이토치로 구현한 선형회귀 (1) | 2024.01.08 |
KMeans (0) | 2024.01.05 |
다양한 모델 적용 (1) | 2024.01.05 |
lightGBM (1) | 2024.01.01 |