PyTorch를 공부하면서 참고한 NeoWizard(박성호)님의 YouTube영상을 토대로 내용을 정리함.
실제 영상 강의를 보고 싶은 분들은 아래 링크로 ㄱㄱ!
출처: https://www.youtube.com/@NeoWizard
텐서(Tensor)
✔️ 텐서(Tensor)는 파이토치 기본 데이터 타입이며 배열(array)나 행렬(matrix)과 유사한 자료구조
- 일반적으로 1차원 데이터를 벡터(ventor), 2차원 데이터를 행렬(matrix), 3차원 이상의 데이터를 텐서(tensor)라고 말하지만, 파이토치에서는 차원에 관계없이 입력과 출력 그리고 학습에 필요한 모든 데이터를 텐서(Tensor)라고 정의하고 있음.
✔️ 딥러닝에서는 학습파라미터인 가중치W와 바이어스 b에 대한 미분(Differentiation) 계산이 필요한데, 파이토치에서는 모든 텐서(Tensor)데이터에 자동미분(Automatic Differentiation) 기능이 최적화 되어있어, 딥러닝 모델을 구축하고 적용하는데 있어 매우 편리함.
텐서 생성
import torch
import numpy as np
# 파이썬 리스트 데이터로부터 직접 텐서 생성
list_data = [[10, 20], [30, 40]]
tensor1 = torch.Tensor(list_data)
print(tensor1)
print(f"tensor type: {type(tensor1)}, tensor shape: {tensor1.shape}")
print(f"tensor dtype: {type(tensor1.dtype)}, tensor shape: {tensor1.device}")
>> tensor([[10., 20.],
>> [30., 40.]])
>> tensor type: <class 'torch.Tensor'>, tensor shape: torch.Size([2, 2])
>> tensor dtype: <class 'torch.dtype'>, tensor shape: cpu
# Windows GPU
# if torch.cuda.is_available():
# tensor1 = tensor1.to("cuda")
# Mac mps
if torch.backends.mps.is_available():
tensor1 = tensor1.to("mps")
print(f"tensor type: {type(tensor1)}, tensor shape: {tensor1.shape}")
print(f"tensor dtype: {type(tensor1.dtype)}, tensor shape: {tensor1.device}")
>> tensor type: <class 'torch.Tensor'>, tensor shape: torch.Size([2, 2])
>> tensor dtype: <class 'torch.dtype'>, tensor shape: mps:0
✔️ 기본적으로 파이썬 리스트 데이터로부터 직접 텐서를 만들 . 수있음
✔️ 텐서 속성: shape(모양), dtype(자료형), device(저장되는 위치)
✔️ GPU를 사용할 . 수있다면 Windows는 .to("cuda"), Mac는 .to("mps") 메소드를 이요해서 텐서는 이동할 수 있음.
numpy_data = np.array(list_data)
# 파이썬 넘파이 데이터로 부터 텐서 생성
tensor2_1 = torch.from_numpy(numpy_data)
print(tensor2_1)
print(f"tensor type: {type(tensor2_1)}, tensor shape: {tensor2_1.shape}")
print(f"tensor dtype: {tensor2_1.dtype}, tensor device: {tensor2_1.device}")
>> tensor([[10, 20],
>> [30, 40]])
>> tensor type: <class 'torch.Tensor'>, tensor shape: torch.Size([2, 2])
>> tensor dtype: torch.int64, tensor device: cpu
# 넘파이로 부터 만들어진 텐서는 기본적으로 int 타입으로 생성되는데, 딥러닝에서는 기본 데이터 타입이 float이므로
# type casting으로 float() 과정이 필요함
tensor2_2 = torch.from_numpy(numpy_data).float()
print(tensor2_2)
print(f"tensor type: {type(tensor2_2)}, tensor shape: {tensor2_2.shape}")
print(f"tensor dtype: {tensor2_2.dtype}, tensor device: {tensor2_2.device}")
>> tensor([[10., 20.],
>> [30., 40.]])
>> tensor type: <class 'torch.Tensor'>, tensor shape: torch.Size([2, 2])
>> tensor dtype: torch.float32, tensor device: cpu
✔️ 넘파이는 기본적으로 int타입으로 데이터가 생성되는데, 딥러닝에서 기본 데이터 타입은 float이므로 type casting이 필요함
# rand() 매소드는 0~1사이의 균일한 분포의 random 값을 생성함
tensor3 = torch.rand(2, 2)
print(tensor3)
>> tensor([[0.0703, 0.5777],
>> [0.1365, 0.3743]])
# randn() 매소드는 평균이 0, 분산이 1인 정규분포를 갖는 random 값을 생성함
# 딥러닝에서 가중치와 바이어스등을 초기화 할때 가장 많이 사용됨
tensor4 = torch.randn(2, 2)
print(tensor4)
>> tensor([[-1.1871, 0.2887],
>> [-0.3319, -0.6461]])
tensor5 = torch.randn(2, 2)
print(tensor5)
# 텐서와 넘파이 간 변환이 자유로움
numpy_from_tensor = tensor5.numpy()
print(numpy_from_tensor)
✔️ 텐서에서 파이썬의 넘파이 형태가 필요할 때가 있는데 .numpy() 함수로 간단히 변환이 가능함
Indexing / Slicing
tensor6 = torch.Tensor([[1, 2, 3], [4, 5, 6]])
tensor7 = torch.Tensor([[7, 8, 9], [10, 11, 12]])
print(tensor6[0]) # tensor6의 첫번째 행의 모든 데이터
print(tensor6[:, 1:]) # tensor6의 모든 행의 데이터와, 두번째 열 이후의 데이터와의 교집합
print(tensor7[0:2, 0:-1]) # tensor7의 첫번째 행부터 두번째 행까지의 데이터와, 첫번째 열부터 두번째 열까지의 데이터와의 교집합
print(tensor7[-1, -1]) # tensor7의 두번째 행의 모든 데이터와, 마지막 열의 모든 데이터와의 교집합
print(tensor7[... , -2]) # tensor7의 모든 행의 모든 데이터와, 두번째 열의 모든 데이터와의 교집합
>> tensor([1., 2., 3.])
>> tensor([[2., 3.],
>> [5., 6.]])
>> tensor([[ 7., 8.],
>> [10., 11.]])
>> tensor(12.)
>> tensor([ 8., 11.])
텐서 연산 - element-wise product / matrix multiplication
tensor8 = tensor6.mul(tensor7) # tensor8 = tensor6 * tensor7
print(tensor8)
>> tensor([[ 7., 16., 27.],
>> [40., 55., 72.]])
✔️ element-wise product연산은 크기가 같은 행렬의 element끼리 곱하는 연산
✔️ 1*7, 2*8, 3*9 .... 6*12 => (2 x 3) 행렬
# reshap(3,2)와 동일한 기능으로 형태를 3x2로 변환
print(tensor7.view(3, 2))
>> tensor([[ 7., 8.],
>> [ 9., 10.],
>> [11., 12.]])
# 앞 행렬의 열과 뒤 행렬의 행의 shape가 동일할 때 matrix multiplication 계산이 가능함
tensor9 = tensor6.matmul(tensor7.view(3, 2)) # tensor6 @ tensor7.view(3, 2)
# 앞 행렬 tensor6이 2x3, 뒤 행렬이 3x2로 계산이 가능하여 결과값 2x2행렬이 됨
print(tensor9)
>> tensor([[ 58., 64.],
>> [139., 154.]])
✔️ 앞 행렬의 열과 뒤 행렬의 행의 shape가 동일할 때 matrix multiplication 계산이 가능함
✔️ 앞 행렬 tensor6이 2x3, 뒤 행렬이 3x2로 계산이 가능하여 결과값 2x2행렬이 됨
✔️ 앞 행렬의 열과 뒤 행렬의 행의 shape가 다를 때 에러가 발생함
텐서 합치기(Concatenate)
# 열을 기준으로, 세로로 합치라는 의미
tensor_cat = torch.cat([tensor6, tensor7])
print(tensor_cat)
>> tensor([[ 1., 2., 3.],
>> [ 4., 5., 6.],
>> [ 7., 8., 9.],
>> [10., 11., 12.]])
# dim=0 이면 열을 기준으로, 세로로 합치라는 의미
tensor_cat_dim0 = torch.cat([tensor6, tensor7], dim=0)
print(tensor_cat_dim0)
>> tensor([[ 1., 2., 3.],
>> [ 4., 5., 6.],
>> [ 7., 8., 9.],
>> [10., 11., 12.]])
# dim=1 이면 행을 기준으로, 가로로 합치라는 의미
tensor_cat_dim1 = torch.cat([tensor6, tensor7], dim=1)
print(tensor_cat_dim1)
>> tensor([[ 1., 2., 3., 7., 8., 9.],
>> [ 4., 5., 6., 10., 11., 12.]])
✔️ cat은 dim 옵션에 따라 합쳐지는 기준이 달라짐
✔️ dim=0은 세로로 합치라는 의미, dim=1은 가로로 합치라는 의미
✔️ 옵션을 주지 않았을 때 기본적으로 dim=0으로 세로로 합침
'스터디-ing > AI' 카테고리의 다른 글
[PyTorch] PIDNet 논문 리뷰(PIDNet: A Real-time Semantic Segmentation Network Inspired by PIDControllers) (0) | 2025.01.18 |
---|---|
[PyTorch] 로지스틱 회귀(Logistic Regression) (0) | 2024.10.28 |
[PyTorch] 경사하강법(Gradient decent algorithm) (0) | 2024.10.15 |
[PyTorch] 선형회귀(Linear Regression), 손실함수 (0) | 2024.10.15 |
[PyTorch] 모델 구조 (0) | 2024.10.15 |