콘텐츠로 이동

외부 데이터에서 텐서 생성

실무에서 다루는 데이터는 CSV 파일, PNG 이미지, NumPy 배열, pandas DataFrame 등 다양한 형태로 존재합니다. 이 데이터들을 PyTorch 모델에 입력하려면 모두 텐서로 변환해야 합니다. 각 소스별 변환 방법을 정리합니다.


NumPy는 데이터 과학 생태계에서 가장 널리 쓰이는 배열 라이브러리입니다. PyTorch와의 변환은 두 가지 방식으로 가능합니다.

import numpy as np
import torch
np_array = np.array([[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]], dtype=np.float32)
# 방법 1: torch.from_numpy() — 메모리 공유 (빠르지만 주의 필요)
tensor_shared = torch.from_numpy(np_array)
# 방법 2: torch.tensor() — 독립 복사본 (안전)
tensor_copy = torch.tensor(np_array)
print(tensor_shared.shape) # torch.Size([2, 3])
print(tensor_shared.dtype) # torch.float32
# from_numpy()는 메모리를 공유함
np_array[0, 0] = 999.0
print(tensor_shared[0, 0]) # tensor(999.) ← 함께 변경됨
print(tensor_copy[0, 0]) # tensor(1.) ← 변경 없음
# 독립 복사본이 필요하면 .clone() 사용
tensor_safe = torch.from_numpy(np_array).clone()
np_array[0, 0] = 0.0
print(tensor_safe[0, 0]) # tensor(999.) ← clone은 독립적
# numpy float64 → torch float32로 변환
np_f64 = np.array([1.0, 2.0, 3.0], dtype=np.float64)
# from_numpy는 dtype을 그대로 유지
t_f64 = torch.from_numpy(np_f64)
print(t_f64.dtype) # torch.float64
# float32로 변환하려면 .float() 또는 .to() 사용
t_f32 = t_f64.float() # float32로 변환
t_f32 = t_f64.to(dtype=torch.float32) # 동일한 결과
print(t_f32.dtype) # torch.float32

이미지 파일(PNG, JPEG 등)을 텐서로 변환할 때는 torchvision.transforms를 사용합니다.

from PIL import Image
import torchvision.transforms as T
# 기본 변환 파이프라인
transform = T.Compose([
T.Resize((224, 224)), # 크기 조정
T.ToTensor(), # PIL Image → 텐서 (C, H, W), 값 범위 [0, 1]
T.Normalize(
mean=[0.485, 0.456, 0.406], # ImageNet 평균
std=[0.229, 0.224, 0.225] # ImageNet 표준편차
)
])
# 이미지 로드 및 변환
image = Image.open("photo.jpg").convert("RGB")
tensor = transform(image)
print(tensor.shape) # torch.Size([3, 224, 224]) ← (C, H, W)
print(tensor.dtype) # torch.float32
print(tensor.min()) # 정규화 후 음수 가능
print(tensor.max()) # 정규화 후 1 초과 가능
# ToTensor()는 세 가지를 한꺼번에 수행
# 1. PIL Image (H, W, C) → Tensor (C, H, W) ← 축 순서 변환
# 2. uint8 [0, 255] → float32 [0.0, 1.0] ← 값 범위 정규화
# 3. numpy array도 동일하게 변환
# 수동으로 같은 결과를 얻으려면
import numpy as np
pil_img = Image.open("photo.jpg").convert("RGB")
np_img = np.array(pil_img) # (H, W, C), uint8
tensor_manual = torch.from_numpy(np_img) # (H, W, C), uint8
tensor_manual = tensor_manual.permute(2, 0, 1) # (C, H, W)
tensor_manual = tensor_manual.float() / 255.0 # [0, 1]
import torchvision.io as tvio
# 이미지를 바로 텐서로 로드
tensor = tvio.read_image("photo.jpg") # (C, H, W), uint8
print(tensor.shape) # torch.Size([3, 480, 640])
print(tensor.dtype) # torch.uint8
# float32로 변환
tensor_f = tensor.float() / 255.0

테이블 형태의 정형 데이터는 pandas를 거쳐 텐서로 변환하는 것이 일반적입니다.

import pandas as pd
import torch
# CSV 파일 로드
df = pd.read_csv("data.csv")
# 예시 DataFrame
df = pd.DataFrame({
"age": [25, 30, 35, 28, 42],
"salary": [5000, 7000, 9000, 6000, 11000],
"score": [0.82, 0.91, 0.78, 0.95, 0.88],
"label": [0, 1, 0, 1, 1]
})
# 특성(X)과 레이블(y) 분리
X = df[["age", "salary", "score"]].values # numpy array
y = df["label"].values
# 텐서로 변환
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.long)
print(X_tensor.shape) # torch.Size([5, 3])
print(y_tensor.shape) # torch.Size([5])
print(X_tensor.dtype) # torch.float32
print(y_tensor.dtype) # torch.int64
from sklearn.preprocessing import StandardScaler
# 스케일링 후 텐서 변환
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df[["age", "salary", "score"]].values)
X_tensor = torch.tensor(X_scaled, dtype=torch.float32)
print(X_tensor.mean(dim=0)) # ≈ [0., 0., 0.] ← 정규화 확인
print(X_tensor.std(dim=0)) # ≈ [1., 1., 1.]

파일 저장과 로드: torch.save() / torch.load()

섹션 제목: “파일 저장과 로드: torch.save() / torch.load()”

학습된 가중치, 전처리된 텐서, 체크포인트를 파일로 저장하고 불러올 수 있습니다.

# 텐서 저장
data = torch.randn(100, 10)
torch.save(data, "data.pt")
# 텐서 로드
loaded = torch.load("data.pt")
print(loaded.shape) # torch.Size([100, 10])
print(torch.allclose(data, loaded)) # True
# 여러 텐서를 딕셔너리로 한 번에 저장
checkpoint = {
"epoch": 50,
"model_state": {"weight": torch.randn(10, 5),
"bias": torch.zeros(5)},
"optimizer_state": {"lr": 0.001},
"train_loss": torch.tensor(0.234),
}
torch.save(checkpoint, "checkpoint.pt")
# 로드
ckpt = torch.load("checkpoint.pt", weights_only=False)
print(ckpt["epoch"]) # 50
print(ckpt["train_loss"]) # tensor(0.2340)
import torch
import torch.nn as nn
model = nn.Linear(10, 5)
optimizer = torch.optim.Adam(model.parameters())
# 저장
def save_checkpoint(model, optimizer, epoch, loss, path):
torch.save({
"epoch": epoch,
"model_state_dict": model.state_dict(),
"optimizer_state_dict": optimizer.state_dict(),
"loss": loss,
}, path)
# 로드
def load_checkpoint(model, optimizer, path):
ckpt = torch.load(path, weights_only=False)
model.load_state_dict(ckpt["model_state_dict"])
optimizer.load_state_dict(ckpt["optimizer_state_dict"])
return ckpt["epoch"], ckpt["loss"]
# 사용 예
save_checkpoint(model, optimizer, epoch=10, loss=0.15, path="ckpt.pt")
epoch, loss = load_checkpoint(model, optimizer, "ckpt.pt")
print(f"재개 지점: epoch {epoch}, loss {loss:.4f}")

데이터 소스변환 방법핵심 주의사항
NumPy arraytorch.from_numpy() 또는 torch.tensor()from_numpy는 메모리 공유
PIL ImageT.ToTensor()(H,W,C) → (C,H,W), [0,255] → [0,1]
torchvision.iotvio.read_image()uint8 반환, /255 필요
pandas DataFrame.valuestorch.tensor()dtype 명시 권장
파일 (저장)torch.save(obj, path)딕셔너리로 묶어 저장
파일 (로드)torch.load(path)weights_only 설정 확인

  • NumPy → 텐서: from_numpy() (공유) vs torch.tensor() (복사)
  • 이미지 → 텐서: T.ToTensor()로 (C,H,W) float32 [0,1] 변환
  • pandas → 텐서: .values로 numpy 추출 후 torch.tensor()
  • 저장: torch.save(), 로드: torch.load(weights_only=False)
  • 체크포인트는 딕셔너리로 여러 상태를 묶어 한 파일에 저장

퀴즈를 불러오는 중...