반응형
1. Tensor(텐서)의 개념과 상태 조회
Tensor는 파이토치에서 데이터를 저장하고 연산하는 기본 자료구조입니다. NumPy의 ndarray와 사용법이 매우 유사하지만, GPU 가속 연산과 자동 미분 기능이 추가되어 있다는 강력한 장점이 있습니다.
⚠️ 주의: PyTorch의 Tensor는 숫자 데이터 타입만 지원합니다. (문자열 불가)
📊 텐서의 핵심 상태 조회 메서드
- tensor.shape 또는 tensor.size(): 텐서의 형태(구조)를 반환합니다.
- tensor.ndim 또는 tensor.dim(): 텐서가 몇 차원(Rank)인지 반환합니다.
- tensor.numel(): 텐서 안에 들어있는 전체 원소의 개수를 반환합니다.
- tensor.dtype: 데이터의 타입(예: torch.float32)을 알려줍니다.
- tensor.type(): 텐서 객체의 정확한 클래스 타입을 문자열로 반환합니다.
- tensor.device: 현재 텐서가 저장된 메모리의 위치(cpu, cuda, mps)를 나타냅니다.
2. 다양한 텐서 생성 방법
① 원하는 값이나 특정 자료구조로 생성
- torch.tensor(데이터, dtype=...): 리스트나 넘파이 배열을 바탕으로 텐서를 생성합니다.
- 직접 클래스로 생성 (기본 데이터 타입 고정):
- torch.FloatTensor(): float32 (실수형, 딥러닝에서 가장 기본)
- torch.LongTensor(): int64 (정수형, 주로 인덱스나 라벨에 사용)
② 규칙이 있는 특수 텐서 생성
- 특정 값 채우기: * torch.zeros(*size): 0으로 가득 찬 텐서
- torch.ones(*size): 1로 가득 찬 텐서
- torch.full(size, fill_value): 지정한 값으로 가득 찬 텐서
- 기존 텐서 본따기 (_like):
- torch.zeros_like(target_tensor): 다른 텐서와 모양(Shape)과 타입(Dtype)이 완벽히 똑같고 값만 0, 1, 지정값으로 채워진 텐서를 만듭니다.
- 수치 범위 지정:
- torch.arange(start, end, step): 수열 생성 (인덱싱 리버스 용도로 step에 음수 사용 불가)
- torch.linspace(start, end, steps): 시작부터 끝까지 동일한 간격으로 steps 개수만큼 생성
③ 난수(Random) 기반 생성
- torch.rand(*size): 0 ~ 1 사이의 균등분포 실수
- torch.randn(*size): 평균 0, 표준편차 1인 표준정규분포 실수
- torch.randint(low, high, size): 지정 범위 내의 정수 난수
- torch.randperm(n): 0부터 $n-1$까지의 정수를 무작위로 섞은 배열 생성 (데이터 셔플 및 인덱스 섞기에 애용)
3. 핵심 조작 기법 (인덱싱, 모양 변경, 병합)
① Indexing & Slicing 특징
- NumPy와 거의 같지만, 슬라이싱 시 간격(Step)에 음수를 쓸 수 없습니다.
- 🔄 역순(Reverse) 조회가 필요할 때는: .flip(dims=[축번호]) 함수를 사용해야 합니다.
- 조건에 맞는 값만 추출하는 Boolean Indexing이나 .masked_select(조건) 기능도 지원합니다.
② Shape(형태) 변경: reshape() vs view()
- 두 함수 모두 원소 개수를 유지하며 모양을 바꿉니다. 한 축에 -1을 넣으면 컴퓨터가 알아서 계산합니다.
- ⚠️ 중요 (참조 관계): 변환된 텐서의 값을 바꾸면 원본 텐서의 값도 같이 바뀝니다. 원본을 지키려면 .clone()을 붙여서 복사본을 만들어야 합니다.
③ Dummy 축(차원) 늘리기와 줄이기
- 늘리기: tensor.unsqueeze(dim=축번호) 또는 tensor[None, :]를 사용해 크기가 1인 차원을 강제로 끼워 넣습니다.
- 줄이기: tensor.squeeze()를 사용해 크기가 1인 더미 차원들을 전부 제거하거나 특정 축만 골라 제거합니다.
④ 텐서 합치기: torch.cat()
- torch.cat([A, B, ...], dim=축번호): 지정한 축을 기준으로 텐서들을 이어 붙입니다.
- ⚠️ 조건: 합치려는 기준 축을 제외한 나머지 모든 축의 크기(Size)가 완벽히 같아야 합니다.
4. 연산 및 장치(Device) 할당
① 디바이스 이동: CPU ↔ GPU
파이토치는 연산을 수행할 하드웨어를 직접 지정할 수 있습니다. 모델과 데이터가 같은 하드웨어 장치에 있어야만 연산이 가능합니다.
Python
# 내 컴퓨터 환경에 맞는 최적의 가속 장치 자동 지정 규칙
device = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'
t = torch.tensor([1, 2, 3], device=device) # 생성 시 지정
t_cpu = t.to("cpu") # 생성 후 이동
② 원소별(Element-wise) 연산과 브로드캐스팅
- 사칙연산과 비교 연산은 기본적으로 자리가 같은 원소끼리 계산됩니다.
- 만약 두 텐서의 모양이 다르더라도, 특정 축의 크기가 1인 경우 파이토치가 자동으로 데이터를 복사해 모양을 맞춰 연산해 주는데, 이를 브로드캐스팅(Broadcasting)이라고 합니다.
③ 행렬곱 연산
- 일반 행렬곱: @ 연산자 또는 torch.matmul(A, B)를 사용합니다.
- 배치 행렬곱 (torch.bmm): 3차원 텐서가 입력되었을 때, 0번 축(Batch)은 그대로 두고 뒤의 1번, 2번 축끼리만 행렬곱을 수행합니다.
5. 자동 미분 시스템 (Autograd)
딥러닝의 핵심인 역전파(Backpropagation) 시 가중치(Weight)의 미분계수(기울기)를 자동으로 구해주는 시스템입니다.
[Image diagram of PyTorch Autograd computational graph and backward pass]
🔄 역전파가 일어나는 메커니즘
- requires_grad=True: 이 옵션이 켜진 텐서는 파이토치가 "미분해야 하는 대상(가중치)"으로 인지하고 추적하기 시작합니다.
- grad_fn (도함수 저장): 이 변수를 가지고 연산(식)을 수행하면, 결과 텐서에 미분 공식 엔진인 grad_fn이 자동으로 장착됩니다.
- .backward(): 최종 오차(Loss) 점수에서 .backward()를 호출하면, 장착되어 있던 grad_fn들이 역순으로 실행되며 미분 값을 계산합니다.
- .grad: 계산이 완료되면 처음 requires_grad=True를 켰던 변수의 .grad 속성에 최종 미분 결과(기울기)가 저장됩니다.
🚫 torch.no_grad() (미분 엔진 끄기)
- with torch.no_grad(): 블록 안에서 일어나는 모든 연산은 grad_fn을 만들지 않고 미분 추적을 하지 않습니다.
- 이유: 모델을 학습시킬 때가 아닌, 완성된 모델로 테스트(평가)나 추론을 할 때는 미분 계산이 필요 없으므로 메모리와 가속도를 아끼기 위해 필수적으로 사용합니다.
🧹 x.grad = None (기울기 초기화)
- 파이토치는 .backward()를 할 때마다 기존에 계산해 둔 .grad 값에 새로운 값을 더해서 누적하는 성질이 있습니다.
- 따라서 새로운 미분 계산(새로운 학습 라운드)을 하기 전에는 반드시 x.grad = None (또는 과거 방식의 zero_grad())을 통해 기존에 쌓인 기울기를 깨끗이 비워주어야 연산이 꼬이지 않습니다.
반응형
'두두 IT > 딥러닝' 카테고리의 다른 글
| 04. 첫번째 딥러닝-MLP 구현 (0) | 2026.05.26 |
|---|---|
| 03. 선형회귀 pytorch_linear_regression (0) | 2026.05.26 |
| 01. 딥러닝 개요 (Deep Learning Overview) (1) | 2026.05.22 |