← 학습 홈AI SPECIALIST · 보충 학습

숫자의 모양을 읽으면
텐서 코드가 보인다.

텐서는 모델이 계산에 사용하는 숫자 자료구조입니다. 먼저 무엇을 만들고, 모양이 어떻게 바뀌고, 원본이 바뀌는지 확인하세요.

PyTorch 한국어 텐서 튜토리얼 기반 · 2026.11.02 정리
이해 → 코드 → 결과 → 빈칸 연습 · 실습 코드는 PyTorch와 NumPy가 설치된 Python에서 실행합니다.

START HERE

모델을 배우기 전에, 계산 재료를 다룹니다.

튜토리얼은 생성 → 속성 확인 → 연산 → NumPy 변환 순서입니다. 여기서는 학습용 숫자를 다룹니다. 텐서를 만든 것만으로 모델이 학습되지는 않습니다.

먼저 구분할 세 가지 표현
표현의미예시
값실제 계산할 숫자[[2, 4, 6], [1, 3, 5]]
shape각 축의 길이(2, 3): 2행, 3열
차원 수축의 개수(2, 3)에는 축이 2개

학습 연결 · 보충 설명
언어 모델에서는 토큰 ID, 임베딩, Q·K·V도 텐서로 표현합니다. 숫자의 역할은 달라도 shape를 확인하는 습관은 같습니다.

01 / INITIALIZATION

만드는 함수는 목적에 따라 고릅니다.

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는 값 복사를 뜻하지 않습니다.

02 / ATTRIBUTES

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 버전과 장치를 확인하세요.

03 / OPERATIONS

축을 고르고, 합치고, 곱합니다.

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차원 행렬곱: (m, k) @ (k, n) → (m, n)

내부 크기를 먼저 맞추세요.
(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의 값을 직접 바꿉니다. 자동 미분에 필요한 값을 덮어쓰면 역전파 오류가 날 수 있으므로 학습 코드에서 주의합니다.

04 / NUMPY BRIDGE

변환한 두 객체가 같은 메모리를 볼 수 있습니다.

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()를 사용하세요.

QUICK REVIEW

빈칸을 보면 이 순서로 판단하세요.

  1. 목적: 생성, 선택, 결합, 곱, 변환 중 무엇인가요?
  2. 입력 shape: 각 축의 길이는 얼마인가요?
  3. 출력 shape: 늘거나 없어지거나 새로 생기는 축이 있나요?
  4. 원본: _ 연산이나 메모리 공유로 값이 바뀌나요?

암기할 짝: shape / dtype / device, cat / stack, * / @, add / add_, from_numpy / tensor.

PRACTICE / 12 QUESTIONS

코드 빈칸을 채우고, 결과를 설명하세요.

아래 문제는 이 자료를 위해 만든 자체 연습문제입니다. 실제 기출이나 확정 시험 범위를 뜻하지 않습니다. 각 문제는 독립적으로 실행합니다. 먼저 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를 쓰면 복사본이 생깁니다.

SOURCES & SCOPE

원문과 보충 내용을 구분했습니다.

한국어 원문의 순서를 따라 재구성했습니다. 예제의 숫자는 계산 과정을 보이도록 바꿨습니다. 축 비교, 복사 비교, 언어 모델 연결, 자체 연습문제는 보충 내용입니다.

이 페이지는 독립적으로 작성한 학습 요약입니다. 실제 시험 범위는 강의 안내를 기준으로 확인하세요.