산술 연산
사칙연산 기초
섹션 제목: “사칙연산 기초”PyTorch는 Python의 연산자 오버로딩을 지원하므로 일반 수식처럼 텐서 연산을 작성할 수 있습니다. 모든 산술 연산은 원소별(element-wise) 로 동작합니다.
import torch
a = torch.tensor([1.0, 2.0, 3.0])b = torch.tensor([4.0, 5.0, 6.0])
# 연산자 방식print(a + b) # tensor([5., 7., 9.])print(a - b) # tensor([-3., -3., -3.])print(a * b) # tensor([ 4., 10., 18.])print(a / b) # tensor([0.2500, 0.4000, 0.5000])함수형 API
섹션 제목: “함수형 API”연산자 방식과 함수형 API는 동일한 결과를 만들어냅니다. 함수형 API는 추가 옵션( out, alpha 등)을 지원합니다.
| 연산자 | 함수형 API | 설명 |
|---|---|---|
a + b | torch.add(a, b) | 덧셈 |
a - b | torch.sub(a, b) | 뺄셈 |
a * b | torch.mul(a, b) | 곱셈 |
a / b | torch.div(a, b) | 나눗셈 |
a // b | torch.div(a, b, rounding_mode='floor') | 정수 나눗셈 |
a % b | torch.remainder(a, b) | 나머지 |
a ** b | torch.pow(a, b) | 거듭제곱 |
x = torch.tensor([10.0, 20.0, 30.0])y = torch.tensor([3.0, 4.0, 5.0])
# alpha 파라미터: torch.add(a, b, alpha=k) → a + k*bresult = torch.add(x, y, alpha=2)print(result) # tensor([16., 28., 40.])
# out 파라미터: 결과를 기존 텐서에 저장out = torch.empty(3)torch.add(x, y, out=out)print(out) # tensor([13., 24., 35.])스칼라 연산
섹션 제목: “스칼라 연산”텐서와 스칼라(단일 숫자) 간의 연산은 자동으로 브로드캐스팅됩니다. 스칼라가 모든 원소에 적용됩니다.
t = torch.tensor([1.0, 2.0, 3.0, 4.0])
print(t + 10) # tensor([11., 12., 13., 14.])print(t * 2) # tensor([2., 4., 6., 8.])print(t / 2) # tensor([0.5000, 1.0000, 1.5000, 2.0000])print(t ** 2) # tensor([ 1., 4., 9., 16.])print(10 - t) # tensor([9., 8., 7., 6.]) — 순서도 유효in-place 연산: 언더스코어 규칙
섹션 제목: “in-place 연산: 언더스코어 규칙”a = torch.tensor([1.0, 2.0, 3.0])
# out-of-place: 새 텐서 반환, 원본 유지b = a.add(10)print(a) # tensor([1., 2., 3.]) — 변화 없음print(b) # tensor([11., 12., 13.])
# in-place: 원본을 직접 수정a.add_(10)print(a) # tensor([11., 12., 13.]) — 변경됨주요 in-place 연산 목록:
| in-place | out-of-place | 설명 |
|---|---|---|
a.add_(b) | a.add(b) | 덧셈 |
a.sub_(b) | a.sub(b) | 뺄셈 |
a.mul_(b) | a.mul(b) | 곱셈 |
a.div_(b) | a.div(b) | 나눗셈 |
a.fill_(v) | — | 값 채우기 |
a.zero_() | — | 0으로 초기화 |
원소별(element-wise) 연산의 이해
섹션 제목: “원소별(element-wise) 연산의 이해”PyTorch의 모든 산술 연산은 기본적으로 원소별 로 수행됩니다. 같은 위치의 원소끼리 연산이 이루어집니다.
a = torch.tensor([[1, 2], [3, 4]])b = torch.tensor([[10, 20], [30, 40]])
# 원소별 곱셈 — 행렬 곱이 아님!print(a * b)# tensor([[ 10, 40],# [ 90, 160]])
# 행렬 곱은 @ 또는 torch.matmul()print(a @ b)# tensor([[ 70, 100],# [150, 220]])원소별 곱셈 (a * b) — 결과 셀에 마우스를 올려보세요
A
1
2
3
4
*
B
10
20
30
40
=
결과
10
40
90
160
원소별 연산이 유용한 이유는 벡터화(vectorization) 때문입니다. Python for 루프보다 수십~수백 배 빠르게 동작합니다.
import time
n = 1_000_000a = torch.randn(n)b = torch.randn(n)
# for 루프 방식 (느림)start = time.time()result = torch.zeros(n)for i in range(n): result[i] = a[i] + b[i]print(f"for 루프: {time.time() - start:.3f}초")
# 텐서 연산 방식 (빠름)start = time.time()result = a + bprint(f"텐서 연산: {time.time() - start:.4f}초")