모델을 배우기 전에, 계산 재료를 다룹니다.
튜토리얼은 생성 → 속성 확인 → 연산 → NumPy 변환 순서입니다. 여기서는 학습용 숫자를 다룹니다. 텐서를 만든 것만으로 모델이 학습되지는 않습니다.
| 표현 | 의미 | 예시 |
|---|---|---|
| 값 | 실제 계산할 숫자 | [[2, 4, 6], [1, 3, 5]] |
| shape | 각 축의 길이 | (2, 3): 2행, 3열 |
| 차원 수 | 축의 개수 | (2, 3)에는 축이 2개 |
학습 연결 · 보충 설명
언어 모델에서는 토큰 ID, 임베딩, Q·K·V도 텐서로 표현합니다. 숫자의 역할은 달라도 shape를 확인하는 습관은 같습니다.
만드는 함수는 목적에 따라 고릅니다.
import torch
import numpy as np
data = [[2, 4, 6], [1, 3, 5]]
x = torch.tensor(data)
ones = torch.ones_like(x)
random = torch.rand_like(x, dtype=torch.float32)
zeros = torch.zeros((2, 3))
| 코드 | 결과 | 읽는 방법 |
|---|---|---|
torch.tensor(data) | 주어진 값, shape (2, 3) | 데이터를 복사해 텐서를 만듭니다. |
torch.ones_like(x) | 모든 값이 1, shape (2, 3) | x의 모양과 자료형을 따라갑니다. |
torch.rand_like(x, dtype=torch.float32) | 0 이상 1 미만의 난수, shape (2, 3) | 모양을 따르되 자료형을 지정합니다. |
torch.zeros((2, 3)) | 모든 값이 0, shape (2, 3) | 원하는 모양을 직접 지정합니다. |
torch.ones((2, 3))는 1로 채웁니다. torch.rand((2, 3))는 난수로 채웁니다. 난수의 실제 값은 실행마다 달라질 수 있습니다.
왜 dtype을 지정할까요?
위 x는 정수형 torch.int64입니다. 기본 설정에서 실수 난수를 만들려면 rand_like에 실수 자료형을 지정해야 합니다. like는 값 복사를 뜻하지 않습니다.
shape · dtype · device를 함께 확인합니다.
x = torch.tensor([[2, 4, 6], [1, 3, 5]])
print(x.shape) # torch.Size([2, 3])
print(x.dtype) # torch.int64
print(x.device) # cpu
shape는 모양, dtype은 숫자의 자료형, device는 저장 장치입니다. 예제는 기본 자료형·장치 설정을 변경하지 않은 환경을 기준으로 합니다.
GPU가 있으면 장치를 옮깁니다.
x = torch.ones((2, 3))
if torch.cuda.is_available():
x = x.to("cuda")
print(x.device) # CUDA 사용 시 cuda:0, 아니면 cpu
한국어 원문의 CUDA 방식을 사용했습니다. 이동한 결과를 x에 다시 받습니다. 이 예제에서 GPU 유무는 shape를 바꾸지 않습니다.
버전 차이 · 현재 공식 영문 튜토리얼은 torch.accelerator로 가속 장치를 선택합니다. 수업 환경에서는 설치된 PyTorch 버전과 장치를 확인하세요.
축을 고르고, 합치고, 곱합니다.
1. 인덱싱: 쉼표 앞은 행, 뒤는 열입니다.
x = torch.tensor([[2, 4, 6], [1, 3, 5]])
print(x[0]) # tensor([2, 4, 6])
print(x[:, 1]) # tensor([4, 3])
print(x[:, 1:2]) # tensor([[4], [3]])
x[:, 1] = 0
print(x) # tensor([[2, 0, 6], [1, 0, 5]])
:는 해당 축 전체입니다. 인덱스 1은 두 번째 위치입니다. 정수로 고르면 해당 축이 없어집니다. 슬라이스로 고르면 해당 축을 유지합니다.
x[:, 1]의 shape는 (2,)입니다. x[:, 1:2]의 shape는 (2, 1)입니다. 슬라이스의 끝 인덱스는 포함하지 않습니다.
2. cat: 기존 축의 길이를 늘립니다.
x = torch.ones((2, 3))
rows = torch.cat([x, x], dim=0)
cols = torch.cat([x, x], dim=1)
batch = torch.stack([x, x], dim=0)
| 연산 | 결과 shape | 변화 |
|---|---|---|
cat(..., dim=0) | (4, 3) | 행이 2 + 2개가 됩니다. |
cat(..., dim=1) | (2, 6) | 열이 3 + 3개가 됩니다. |
stack(..., dim=0) | (2, 2, 3) | 새 축에 2개를 쌓습니다. 보충 예제 |
cat은 합칠 축을 제외한 크기가 같아야 합니다. stack은 입력 텐서의 크기가 모두 같아야 합니다. dim=0을 언제나 ‘세로’라고 외우지 말고 첫 번째 축으로 읽으세요.
3. *는 같은 위치를 곱하고, @는 행렬곱을 합니다.
a = torch.tensor([[1, 2], [3, 4]])
b = torch.tensor([[5, 6], [7, 8]])
print(a * b) # tensor([[ 5, 12], [21, 32]])
print(a @ b) # tensor([[19, 22], [43, 50]])
print(a.T) # tensor([[1, 3], [2, 4]])
요소별 곱의 첫 칸은 1 × 5 = 5입니다. 행렬곱의 첫 칸은 a의 첫 행과 b의 첫 열을 곱해 더한 1 × 5 + 2 × 7 = 19입니다.
a.mul(b)는 a * b와 같습니다. a.matmul(b)는 a @ b와 같습니다. 위 2차원 텐서에서 .T는 행과 열을 바꿉니다.
내부 크기를 먼저 맞추세요.(2, 3) @ (3, 4)는 (2, 4)입니다. (2, 3) @ (2, 3)은 내부 크기 3과 2가 달라 실패합니다. 요소별 곱에는 별도의 브로드캐스팅 규칙이 적용됩니다.
4. 끝의 _는 원본 변경을 뜻합니다.
x = torch.tensor([2., 4.])
y = x.add(3)
print(x) # tensor([2., 4.])
print(y) # tensor([5., 7.])
x.add_(3)
print(x) # tensor([5., 7.])
add는 새 결과를 반환합니다. add_는 x의 값을 직접 바꿉니다. 자동 미분에 필요한 값을 덮어쓰면 역전파 오류가 날 수 있으므로 학습 코드에서 주의합니다.
변환한 두 객체가 같은 메모리를 볼 수 있습니다.
t = torch.tensor([2., 4.])
n = t.numpy()
t.add_(1)
print(n) # [3. 5.]
arr = np.array([2., 4.], dtype=np.float32)
shared = torch.from_numpy(arr)
copied = torch.tensor(arr)
arr[0] = 9
print(shared) # tensor([9., 4.])
print(copied) # tensor([2., 4.])
numpy()는 여기처럼 변환 가능한 CPU 텐서의 저장 공간을 공유합니다. from_numpy도 원래 배열과 저장 공간을 공유합니다. torch.tensor(arr)는 데이터를 복사합니다. 복사 비교는 이해를 위한 보충 예제입니다.
모든 텐서를 바로 numpy()로 바꿀 수는 없습니다.
기본 numpy()는 CPU, requires_grad=False, NumPy가 지원하는 자료형·레이아웃 등의 조건을 요구합니다. GPU 텐서나 미분 추적 중인 텐서는 먼저 조건을 확인하세요.
보충 · 일반적인 실수 텐서는 t.detach().cpu().numpy()로 변환할 수 있습니다. 복사본이 필요하면 NumPy 결과에 .copy()를 사용하세요.
빈칸을 보면 이 순서로 판단하세요.
- 목적: 생성, 선택, 결합, 곱, 변환 중 무엇인가요?
- 입력 shape: 각 축의 길이는 얼마인가요?
- 출력 shape: 늘거나 없어지거나 새로 생기는 축이 있나요?
- 원본:
_연산이나 메모리 공유로 값이 바뀌나요?
암기할 짝: shape / dtype / device, cat / stack, * / @, add / add_, from_numpy / tensor.
코드 빈칸을 채우고, 결과를 설명하세요.
아래 문제는 이 자료를 위해 만든 자체 연습문제입니다. 실제 기출이나 확정 시험 범위를 뜻하지 않습니다. 각 문제는 독립적으로 실행합니다. 먼저 import torch와 import numpy as np를 실행하세요.
01. 데이터에서 생성
x = torch.???([[2, 4], [6, 8]])
assert x.shape == (2, 2)정답과 해설 보기
tensor. 주어진 숫자 목록을 텐서로 만듭니다. 생성 함수와 속성 확인을 구분하는 문제입니다.
02. 모양을 따라 1로 채우기
x = torch.tensor([[2, 4, 6]])
y = torch.???(x)
assert y.tolist() == [[1, 1, 1]]정답과 해설 보기
ones_like. 입력은 크기 튜플이 아니라 x입니다. y의 shape는 (1, 3)입니다.
03. 정수 텐서 모양의 실수 난수
x = torch.tensor([[2, 4, 6]])
y = torch.rand_like(x, dtype=???)
assert y.dtype == torch.float32정답과 해설 보기
torch.float32. 같은 자료형의 별칭 torch.float도 가능합니다. 값은 달라도 shape는 (1, 3)입니다.
04. 속성 읽기
x = torch.zeros((2, 5))
shape = x.???
assert tuple(shape) == (2, 5)정답과 해설 보기
shape. 함수가 아니라 속성이므로 괄호를 붙이지 않습니다. x.size()도 크기를 얻는 다른 표현입니다.
05. 모든 행의 두 번째 열
x = torch.tensor([[2, 4, 6], [1, 3, 5]])
y = x[???, ???]
assert y.tolist() == [4, 3]정답과 해설 보기
왼쪽은 :, 오른쪽은 1입니다. 모든 행에서 열 인덱스 1을 고릅니다. y의 shape는 (2,)입니다.
06. 두 번째 열의 축 유지
x = torch.tensor([[2, 4, 6], [1, 3, 5]])
y = x[:, ???]
assert y.shape == (2, 1)정답과 해설 보기
1:2. 정수 인덱스 대신 슬라이스를 쓰므로 열 축을 유지합니다. 값은 [[4], [3]]입니다.
07. 열을 이어 붙이기
x = torch.ones((2, 3))
y = torch.cat([x, x, x], dim=???)
assert y.shape == (2, 9)정답과 해설 보기
1. 두 번째 축의 크기를 3 + 3 + 3으로 늘립니다. dim=0이면 shape는 (6, 3)입니다.
08. 새 축에 쌓기 · 보충
x = torch.ones((2, 3))
y = torch.???([x, x], dim=0)
assert y.shape == (2, 2, 3)정답과 해설 보기
stack. 새 첫 번째 축의 길이는 입력 텐서 개수인 2입니다. cat은 차원 수를 늘리지 않습니다.
09. 행렬곱 연산자
a = torch.tensor([[1, 2], [3, 4]])
b = torch.tensor([[5, 6], [7, 8]])
y = a ??? b
assert y.tolist() == [[19, 22], [43, 50]]정답과 해설 보기
@. *를 넣으면 첫 칸은 5가 됩니다. @는 행과 열의 대응 원소를 곱해 더합니다.
10. 전치로 내부 크기 맞추기
x = torch.ones((2, 3))
y = x @ x.???
assert y.shape == (2, 2)
assert y.tolist() == [[3., 3.], [3., 3.]]정답과 해설 보기
T. x.T의 shape는 (3, 2)입니다. (2, 3) @ (3, 2)가 됩니다. 각 칸은 1 × 1을 세 번 더한 3입니다.
11. x 자체에 더하기
x = torch.tensor([2., 4.])
x.???(3)
assert x.tolist() == [5., 7.]정답과 해설 보기
add_. add만 쓰고 반환값을 받지 않으면 x는 바뀌지 않습니다.
12. NumPy 변경을 함께 보기
arr = np.array([2., 4.], dtype=np.float32)
t = torch.???(arr)
arr[1] = 9
assert t.tolist() == [2., 9.]정답과 해설 보기
from_numpy. 저장 공간을 공유하므로 배열 변경이 t에 보입니다. tensor를 쓰면 복사본이 생깁니다.
원문과 보충 내용을 구분했습니다.
한국어 원문의 순서를 따라 재구성했습니다. 예제의 숫자는 계산 과정을 보이도록 바꿨습니다. 축 비교, 복사 비교, 언어 모델 연결, 자체 연습문제는 보충 내용입니다.
- 요청한 원문: PyTorch 한국어 텐서 튜토리얼
- 공식 영문 튜토리얼: Tensors
- 공식 API: tensor · cat · stack · matmul
- 공식 API: Tensor.numpy · from_numpy
이 페이지는 독립적으로 작성한 학습 요약입니다. 실제 시험 범위는 강의 안내를 기준으로 확인하세요.