1. 파이토치
PyTorch는 파이썬 기반의 오픈소스 딥러닝 프레임워크로, 파이썬 코드로 AI 모델을 직관적으로 만들고 학습할 수 있도록 도와주는 도구입니다. 특히 동적 계산 그래프 방식을 사용하기 때문에 코드 실행 시점에 실시간으로 계산 흐름이 결정되어 디버깅과 수정이 쉽고, GPU 가속과 자동 미분 기능을 통해 대규모 모델도 빠르게 학습할 수 있습니다.
※ 동적 계산 그래프 방식
딥러닝 모델이 학습 및 예측을 수행할 때 계산 그래프를 실행 시점(runtime)에 실시간으로 생성 및 수정하는 방식입니다. 이 방식은 조건문, 반복문 등 복잡한 논리 구조를 유연하게 처리할 수 있으며, 주로 PyTorch와 같은 프레임워크에서 사용됩니다. 계산 그래프는 입력 데이터를 바탕으로 연산을 수행하면서 그래프를 생성하고, 역전파를 통해 미분을 계산하며, 최종적으로 가중치를 업데이트하는 과정을 거칩니다. 이러한 특성 덕분에 디버깅이 용이하고 연구 및 개발 속도가 빠르며 직관적인 코드 작성이 가능합니다.
1. 스칼라
스칼라(Scalar)는 단 하나의 숫자(정수, 실수 등)만을 담는 자료형을 말합니다. 파이토치(PyTorch)에서 스칼라는 0차원 텐서(0-dimensional Tensor)로 표현합니다. 즉, 텐서의 차원(Shape)이 전혀 없는 상태를 의미합니다.
import torch
var1 = torch.tensor(5)
print(var1)
print(var1.shape) # torch.Size([]) -> 0차원 텐서
var2 = torch.tensor([10])
print(var2.shape) # torch.Size([1]) -> 1차원 텐서. 스칼라가 아님
var3 = torch.tensor(3)
result = var1 + var3
print(result) # tensor(8)
print(result.item()) # 8 -> 텐서 값(스칼라)을 파이썬 숫자로 추출함
2. 벡터(Vector)
벡터(Vector)는 하나 이상의 원소가 일렬로 나열된 1차원 텐서(1D Tensor)를 의미합니다. 파이토치(PyTorch)에서 벡터는 일반적으로 torch.tensor([...]) 형태로 만들며, 이때 텐서의 shape(차원)가 (n,) 형태입니다. 즉, 원소가 n개 들어 있으면 1차원 벡터가 됩니다.
var1 = torch.tensor([1.0, 2.0, 3.0])
print(var1)
print(var1.shape) # torch.Size([3]) -> 1차원 텐서
var2 = var1 + 10
print(var2)
var3 = var1 * 2
print(var3)
var4 = torch.tensor([4.0, 5.0, 6.0])
result = var1 + var4
print(result)
3. 행렬
행렬(Matrix)은 2차원 형태의 텐서로, 파이토치(PyTorch)에서는 shape가 (m, n)처럼 2개의 차원을 가진 텐서를 의미합니다. 예를 들어, torch.tensor([[1, 2], [3, 4]])는 2행×2열 형태의 행렬입니다. 행렬 연산에서는 행렬 곱셈, 원소별 연산, 전치(Transpose) 등이 자주 활용되며, 파이토치는 torch.mm 또는 @ 연산자를 통해 행렬 곱셈을 수행할 수 있습니다.
var1 = torch.tensor([[1, 2],
[3, 4]])
var2 = torch.tensor([[5, 6],
[7, 8]])
print(var1)
print(var1.shape) # torch.Size([2, 2]) -> 2차원 텐서
result1 = var1 + var2
print(result1)
result2 = var1 * var2
print(result2)
result3 = torch.mm(var1, var2)
print(result3)
result4 = var1 @ var2
print(result4)
4. 다차원 텐서
파이토치(PyTorch)에서 다차원 텐서란, 여러 축(차원)을 가지는 텐서를 의미합니다. 예를 들어, 0차원 텐서는 “스칼라(Scalar)”, 1차원 텐서는 “벡터(Vector)”, 2차원 텐서는 “행렬(Matrix)”, 그 이상의 3차원, 4차원 텐서 등을 통틀어 “다차원 텐서(Multi-dimensional Tensor)”라고 부릅니다. 다차원 텐서는 이미지, 음성, 동영상, 시계열 데이터를 비롯하여 여러 축을 필요로 하는 다양한 형태의 데이터를 표현할 때 쓰입니다.
var1 = torch.tensor([
[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]
])
print(var1)
print(var1.shape) # torch.Size([2, 2, 2])

2. 텐서
PyTorch의 텐서(Tensor)는 딥러닝 모델에서 데이터를 다룰 때 사용되는 기본 데이터 구조입니다. 텐서는 다차원 배열로, NumPy의 배열과 비슷하지만, GPU에서 연산을 수행할 수 있다는 점에서 차이가 있습니다. PyTorch의 텐서는 데이터의 표현뿐만 아니라, 자동 미분(autograd) 기능을 제공하여 딥러닝 모델의 학습을 도와줍니다.
data = [
[1, 2],
[3, 4]
]
t1 = torch.tensor(data)
print(t1)
t1 = torch.tensor([5])
t2 = torch.tensor([7])
ndarr1 = (t1 + t2).numpy()
print(ndarr1)
print(type(ndarr1))
result = ndarr1 * 10
t3 = torch.from_numpy(result)
print(t3)
print(type(t3))
t1 = torch.tensor([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
print(t1[0])
print(t1[:, 0])
print(t1[:, -1])
print(t1[..., -1])
t1 = torch.tensor([[[1, 2, 3],
[4, 5, 6]],
[[7, 8, 9],
[10, 11, 12]]])
print(t1.shape)
print(t1[..., -1]) # 첫 번째와 두 번째 차원을 유지. 마지막 요소만 선택
3. GPU 사용
GPU (Graphics Processing Unit)는 그래픽 처리 장치로, 주로 이미지 렌더링과 같은 대규모 병렬 계산을 수행하는 데 최적화된 하드웨어입니다. 원래는 그래픽 처리를 위해 설계되었지만, 최근에는 인공지능(AI) 및 딥러닝의 연산 가속기로 널리 사용되고 있습니다. 딥러닝은 수천, 수만 개의 행렬 및 벡터 연산을 필요로 합니다. GPU는 여러 개의 코어를 사용하여 이 연산을 병렬로 처리할 수 있습니다. 따라서 GPU는 딥러닝 에 최적화된 구조를 가지고 있습니다.
Google Colab을 이용하면, 손쉽게 PyTorch를 시작할 수 있습니다.
[런타임] - [런타임 유형 변경] - [원하는 GPU, TPU를 선택]
※ 구글 코랩 GPU, TPU 비교
| T4 | Turing | 2018.9.13 | 15GB | 1.84 단위 | $0.18 | 54시간 20분 |
| V100 | Volta | 2017.6.21 | 16GB | 4.91 단위 | $0.49 | 20시간 21분 |
| L4 | Ada Lovelace | 2023.3.21 | 22.5GB | 4.82 단위 | $0.48 | 20시간 47분 |
| A100 | Ampere | 2020.5.14 | 40GB | 11.77 단위 | $1.18 | 8시간 30분 |
Colab은 T4 GPU를 무료로 제공하고 있습니다.
유료 GPU 옵션은 비용 대비 효과적일 수 있습니다. A100은 비싸지만 속도가 13배 빠릅니다.
A100 GPU: 대규모 학습과 고성능 컴퓨팅에 최적화되어 있으며, 높은 메모리 용량과 대역폭을 제공합니다.
L4 GPU: 에너지 효율성이 높고, 추론 작업에 최적화되어 있습니다.
T4 GPU: 에너지 효율성이 우수하며, 중간 규모의 학습 및 추론 작업에 적합합니다.
TPU v2-8: 대규모 행렬 연산에 최적화되어 있으며, TensorFlow와의 호환성이 높습니다.
TPU v5e-1: 중형 및 대규모 학습, 추론에 필요한 비용 효율성과 성능을 제공하며, 최신 TPU 아키텍처를 기반으로 합니다.
data = [
[1, 2],
[3, 4]
]
t1 = torch.tensor(data)
print(t1.is_cuda)
t1 = t1.cuda() # GPU로 옮기기
print(t1.is_cuda)
t1 = t1.cpu() # CPU로 옮기기
print(t1.is_cuda)
t1 = torch.tensor([
[1, 1],
[2, 2]
]).cuda()
t2 = torch.tensor([
[5, 6],
[7, 8]
])
# print(torch.matmul(t1, t2)) # 오류 발생
print(torch.matmul(t1.cpu(), t2))
print(f"Device: {t1.device}")
4. 텐서의 연산과 함수
t1 = torch.tensor([
[1, 2],
[3, 4]
])
t2 = torch.tensor([
[5, 6],
[7, 8]
])
print(t1 + t2)
print(t1 - t2)
print(t1 * t2)
print(t1 / t2)
t1 = torch.tensor([
[1, 2],
[3, 4]
])
t2 = torch.tensor([
[5, 6],
[7, 8]
])
print(t1.matmul(t2))
print(torch.matmul(t1, t2))
t1 = torch.Tensor([
[1, 2, 3, 4],
[5, 6, 7, 8]
])
print(t1)
print(t1.mean()) # 전체 원소에 대한 평균
print(t1.mean(dim=0)) # 각 열에 대하여 평균 계산
print(t1.mean(dim=1)) # 각 행에 대하여 평균 계산
t1 = torch.Tensor([
[1, 2, 3, 4],
[5, 6, 7, 8]
])
print(t1)
print(t1.sum()) # 전체 원소에 대한 합계
print(t1.sum(dim=0)) # 각 열에 대하여 합계 계산
print(t1.sum(dim=1)) # 각 행에 대하여 합계 계산
t1 = torch.Tensor([
[1, 2, 3, 4],
[5, 6, 7, 8]
])
print(t1)
print(t1.argmax()) # 전체 원소에 대한 최댓값의 인덱스
print(t1.argmax(dim=0)) # 각 열에 대하여 최댓값의 인덱스 계산
print(t1.argmax(dim=1)) # 각 행에 대하여 최댓값의 인덱스 계산
5. 텐서의 차원 조작
t1 = torch.tensor([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
# dim: 텐서를 이어 붙이기 위한 축
# 0번 축(행)을 기준으로 이어 붙이기
result = torch.cat([t1, t1, t1], dim=0)
print(result)
# 1번 축(열)을 기준으로 이어 붙이기
result = torch.cat([t1, t1, t1], dim=1)
print(result)
t1 = torch.tensor([2], dtype=torch.int)
t2 = torch.tensor([5.0])
print(t1.dtype)
print(t2.dtype)
# 텐서 t1는 자동으로 float32형으로 형변환 처리
print(t1 + t2)
# 텐서 t2를 int32형으로 형변환하여 덧셈 수행
print(t1 + t2.type(torch.int32))
# view()는 텐서의 모양을 변경할 때 사용한다.
# 이때, 텐서(tensor)의 순서는 변경되지 않는다.
t1 = torch.tensor([1, 2, 3, 4, 5, 6, 7, 8])
t2 = t1.view(4, 2)
print(t2)
# t1의 값을 변경하면 t2도 변경
t1[0] = 7
print(t1)
print(t2)
# t1의 값을 복사(copy)한 뒤에 변경
t3 = t1.clone().view(4, 2)
t1[0] = 9
print(t3)
t1 = torch.rand((64, 32, 3))
print(t1.shape)
t2 = t1.permute(2, 1, 0) # 차원 자체를 교환
# (2번째 축, 1번째 축, 0번째 축)의 형태가 됨
print(t2.shape)
t1 = torch.Tensor([
[1, 2, 3, 4],
[5, 6, 7, 8]
])
print(t1.shape)
# 첫 번째 축에 차원 추가
t1 = t1.unsqueeze(0)
print(t1)
print(t1.shape)
# 네 번째 축에 차원 추가
t1 = t1.unsqueeze(3)
print(t1)
print(t1.shape)
# 크기가 1인 차원 제거, squeeze(dim): 특정 차원이 1인 경우에만 차원을 제거
t1 = t1.squeeze()
print(t1)
print(t1.shape)
6. 자동 미분과 기울기
import torch
x = torch.tensor([3.0, 4.0], requires_grad=True) # 미분 예정
y = torch.tensor([1.0, 2.0], requires_grad=True) # 미분 예정
z = x + y # 단순 덧셈
out = z.mean() # 평균 계산
# out에 대해서 역으로 계산
# 각각의 입력 값이 이 결과에 얼마나 영향을 줬는지 알려줘!
# 미분값을 자동으로 계산
out.backward()
print("x.grad:", x.grad) # [0.5, 0.5] 평균 계산에서는 각 원소가 결과에 절반 만큼 영향
print("y.grad:", y.grad)
print("z.grad:", z.grad)) # z는 계산 결과로 만들어진 중간 변수
※ 수식으로 분석

x[0] ─┬──► z[0] ───► out
│ ↑ ↑
y[0] ─┘ │ │
│ │
x[1] ─┬──► z[1] ───► out
│
y[1] ─┘
z의 각 항목은 x와 y에서 왔고,
out은 z의 평균이니까 z의 각 항목은 결과에 1/2만큼 기여

'인공지능 > 딥러닝' 카테고리의 다른 글
| Multi-class Weather Dataset (3) | 2025.07.28 |
|---|---|
| 딥러닝 : 퍼셉트론과 다층 퍼셉트론 (3) | 2025.07.28 |
| 손 글씨 숫자 데이터셋 (2) | 2025.07.25 |
| 파이토치로 구현한 논리 회귀 (2) | 2025.07.25 |
| 파이토치로 구현한 선형 회귀 (2) | 2025.07.25 |