콘텐츠로 이동

난수 텐서 생성

딥러닝에서 난수는 두 가지 핵심 역할을 합니다.

  1. 가중치 초기화 — 모든 가중치를 같은 값으로 시작하면 대칭성 문제로 학습이 안 됩니다. 난수로 시작해야 각 뉴런이 다른 특성을 학습합니다.
  2. 데이터 셔플링 및 드롭아웃 — 학습 데이터의 순서를 무작위로 바꾸거나, 드롭아웃으로 뉴런을 무작위로 끕니다.

0 이상 1 미만의 실수를 균일하게 뽑습니다. 모든 구간에서 값이 나올 확률이 동일합니다.

분포 모양:
확률
│████████████████████
│████████████████████
│████████████████████
└─────────────────────▶ 값
0 1
import torch
# 기본 사용
r1 = torch.rand(4)
print(r1) # tensor([0.4963, 0.7682, 0.0885, 0.1320]) ← 실행마다 다름
# 2D 난수 텐서
r2 = torch.rand(3, 4)
print(r2.shape) # torch.Size([3, 4])
print(r2.min()) # ≥ 0.0
print(r2.max()) # < 1.0
# 범위 조정: [a, b) 범위로 변환
a, b = -1.0, 1.0
r_range = torch.rand(5) * (b - a) + a
print(r_range) # -1.0 ~ 1.0 사이 값

주요 사용처: 드롭아웃 마스크, 무작위 샘플링, 균등 초기화


torch.randn() — 표준 정규분포 N(0, 1)

섹션 제목: “torch.randn() — 표준 정규분포 N(0, 1)”

평균 0, 표준편차 1인 **정규분포(가우시안 분포)**에서 뽑습니다. 값들이 0 근처에 몰리고 멀어질수록 드물어집니다.

분포 모양 (종 모양):
확률
│ ▲
│ ██████
│ ██████████
│ ██████████████
│ ████████████████████
└─────────────────────▶ 값
-3 -1 0 1 3
# 기본 사용
n1 = torch.randn(4)
print(n1) # tensor([-0.5557, 0.7085, 0.3604, -1.1529])
# 2D
n2 = torch.randn(3, 4)
print(n2.mean()) # ≈ 0.0
print(n2.std()) # ≈ 1.0
# 평균 μ, 표준편차 σ로 조정
mu, sigma = 5.0, 2.0
n_custom = torch.randn(1000) * sigma + mu
print(n_custom.mean().item()) # ≈ 5.0
print(n_custom.std().item()) # ≈ 2.0
# 또는 torch.normal() 직접 사용
n_normal = torch.normal(mean=5.0, std=2.0, size=(1000,))

주요 사용처: Xavier/He 가중치 초기화의 기반, 가우시안 노이즈 추가


지정한 범위에서 정수를 무작위로 뽑습니다.

# randint(low, high, size) — [low, high) 범위
i1 = torch.randint(0, 10, (5,))
print(i1) # tensor([7, 2, 9, 0, 4])
# low 생략 시 기본값 0
i2 = torch.randint(10, (3, 4))
print(i2)
# tensor([[3, 1, 7, 5],
# [9, 2, 0, 8],
# [4, 6, 3, 1]])
# 실전: 배치 레이블 생성 (클래스 10개)
num_classes = 10
batch_size = 32
labels = torch.randint(0, num_classes, (batch_size,))
print(labels.shape) # torch.Size([32])
print(labels.dtype) # torch.int64

주요 사용처: 무작위 레이블 생성, 인덱스 샘플링, 테스트 데이터 생성


균등분포 vs 정규분포 한눈에 비교

섹션 제목: “균등분포 vs 정규분포 한눈에 비교”
항목torch.rand()torch.randn()
분포균등분포 (Uniform)정규분포 (Normal/Gaussian)
범위[0, 1)이론상 (-∞, +∞)
평균0.50.0
표준편차≈ 0.2891.0
모양평평한 직사각형종 모양 곡선
주 용도드롭아웃, 샘플링가중치 초기화
# 두 분포의 통계 비교 (큰 샘플로)
uniform = torch.rand(10000)
normal = torch.randn(10000)
print(f"균등분포 — 평균: {uniform.mean():.3f}, 표준편차: {uniform.std():.3f}")
print(f"정규분포 — 평균: {normal.mean():.3f}, 표준편차: {normal.std():.3f}")
# 균등분포 — 평균: 0.500, 표준편차: 0.289
# 정규분포 — 평균: 0.002, 표준편차: 0.998

같은 시드(seed)를 설정하면 매 실행마다 동일한 난수 시퀀스가 생성됩니다. 실험 재현성 확보에 필수입니다.

# 시드 없이 실행 — 매번 다른 결과
print(torch.rand(3)) # tensor([0.4963, 0.7682, 0.0885])
print(torch.rand(3)) # tensor([0.1320, 0.3074, 0.6341]) ← 다름
# 시드 설정 후 — 항상 같은 결과
torch.manual_seed(42)
print(torch.rand(3)) # tensor([0.8823, 0.9150, 0.3829])
torch.manual_seed(42) # 다시 같은 시드
print(torch.rand(3)) # tensor([0.8823, 0.9150, 0.3829]) ← 동일!
import torch
import random
import numpy as np
def set_seed(seed: int = 42):
"""모든 난수 생성기의 시드를 고정합니다."""
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed) # 멀티 GPU
np.random.seed(seed)
random.seed(seed)
# 결정론적 연산 강제 (속도 저하 가능)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
set_seed(42)

import torch.nn as nn
# nn.Linear 내부에서 실제로 일어나는 초기화 (단순화)
in_features = 256
out_features = 128
# He 초기화 (ReLU 활성화 함수와 함께 사용)
std = (2.0 / in_features) ** 0.5
weight_he = torch.randn(out_features, in_features) * std
print(f"He init — 평균: {weight_he.mean():.4f}, 표준편차: {weight_he.std():.4f}")
# Xavier 초기화 (sigmoid/tanh 활성화 함수와 함께 사용)
std_xavier = (2.0 / (in_features + out_features)) ** 0.5
weight_xavier = torch.randn(out_features, in_features) * std_xavier
print(f"Xavier — 평균: {weight_xavier.mean():.4f}, 표준편차: {weight_xavier.std():.4f}")
# PyTorch가 제공하는 초기화 함수로 더 간편하게
weight = torch.empty(out_features, in_features)
nn.init.kaiming_normal_(weight, mode='fan_in', nonlinearity='relu')
nn.init.xavier_normal_(weight)

  • torch.rand() → [0, 1) 균등분포, 드롭아웃/샘플링에 사용
  • torch.randn() → 평균 0, 표준편차 1 정규분포, 가중치 초기화에 사용
  • torch.randint(low, high, size) → 정수 난수, 레이블/인덱스 생성에 사용
  • torch.manual_seed(n) → 재현 가능한 실험을 위해 학습 시작 전 한 번 호출
  • 완전한 재현성은 numpy, random 시드도 함께 고정해야 함