Idenya
Proyek sungguhan mencampur beberapa library: data datang sebagai DataFrame pandas, preprocessing dilakukan di NumPy atau scikit-learn, model berjalan di PyTorch, dan hasilnya kembali ke DataFrame atau grafik Plotly. Dua hal membuat serah-terima ini mulus:
- tahu kapan konversi menyalin data dan kapan berbagi memori;
- tahu di device mana (CPU atau GPU) sebuah tensor berada.
Dari NumPy ke PyTorch
Datamu biasanya berawal di NumPy atau pandas, jadi langkah pertama sebagian besar proyek PyTorch adalah mengonversinya. Ada dua cara, dan perbedaannya penting:
import numpy as np
import torch
arr = np.array([1.0, 2.0, 3.0])
shared = torch.from_numpy(arr) # shares memory with arr
copied = torch.tensor(arr) # an independent copy
arr[0] = 100.0
print(shared)
print(copied)
print(shared.dtype)
tensor([100., 2., 3.], dtype=torch.float64)
tensor([1., 2., 3.], dtype=torch.float64)
torch.float64
torch.from_numpymembuat tensor yang melihat memori yang sama: mengubah salah satunya mengubah yang lain (modul view NumPy, tetapi lintas library).torch.tensor(arr)selalu menyalin.- dtype-nya berasal dari NumPy:
float64di sini, bukan float32 yang biasa dipakai PyTorch. Konversi dengan.float()sebelum dimasukkan ke model:
X = torch.from_numpy(np.random.default_rng(0).random((3, 2))).float()
print(X.dtype, X.shape)
torch.float32 torch.Size([3, 2])
Dari PyTorch ke NumPy
Dan kembali lagi: setelah pelatihan, kamu sering ingin prediksinya sebagai array NumPy, untuk dibuat grafik atau dimasukkan ke DataFrame:
t = torch.tensor([0.25, 0.5, 0.75])
a = t.numpy() # shares memory (CPU tensors only)
t[0] = 9.0
print(a)
[9. 0.5 0.75]
Dua aturan untuk .numpy():
- Tensor-nya harus berada di CPU:
t.cpu().numpy()untuk tensor di GPU. - Kalau tensor-nya bagian dari perhitungan gradient (
requires_grad=True), lepaskan dulu:t.detach().cpu().numpy(). Kamu akan terus melihat rangkaian persis ini saat mengambil prediksi dari model.
Dari pandas
Sebagian besar data sungguhan datang sebagai DataFrame, seperti tabel churn dari track ML. Jalurnya yang biasa melewati NumPy:
import pandas as pd
df = pd.DataFrame({"tenure_months": [12, 33, 5], "orders_90d": [7, 4, 0], "churned": [0, 0, 1]})
X = torch.tensor(df[["tenure_months", "orders_90d"]].to_numpy(), dtype=torch.float32)
y = torch.tensor(df["churned"].to_numpy(), dtype=torch.float32)
print(X)
print(y)
tensor([[12., 7.],
[33., 4.],
[ 5., 0.]])
tensor([0., 0., 1.])
Jalur yang biasa adalah DataFrame → NumPy (.to_numpy()) → tensor, dengan memilih dtype=torch.float32 secara eksplisit.
Device
Sebuah tensor berada di sebuah device: CPU, GPU NVIDIA ("cuda"), atau GPU Apple Silicon ("mps"). Perhitungan hanya bisa menggabungkan tensor yang berada di device yang sama.
device = (
"cuda" if torch.cuda.is_available()
else "mps" if torch.backends.mps.is_available()
else "cpu"
)
print("using", device)
t = torch.ones(3)
print(t.device)
t = t.to(device) # copies to the device (no-op if it's already there)
using mps
cpu
Device yang tercetak bergantung pada mesinmu: cuda di mesin dengan GPU NVIDIA, mps di Mac dengan Apple Silicon, cpu selain itu.
Pola standarnya: pilih device sekali di bagian atas, lalu pindahkan model dan setiap batch ke sana:
model = MyModel().to(device)
for X_batch, y_batch in loader:
X_batch, y_batch = X_batch.to(device), y_batch.to(device)
predictions = model(X_batch)
Lupa satu .to(device) saja dan kamu mendapat error terkenal "Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu". Bacalah sebagai checklist: tensor mana yang belum dipindahkan?
Pilih device sekali; pindahkan model dan setiap batch ke sana; bawa hasilnya kembali dengan .detach().cpu().numpy(). from_numpy dan .numpy() berbagi memori; torch.tensor(...) menyalin.
Kapan GPU membantu?
GPU cepat untuk perhitungan tensor yang besar dan paralel: perkalian matriks besar atas batch yang besar. Untuk model tabular kecil (beberapa ribu baris, network kecil), waktu yang dihabiskan untuk menyalin data ke GPU bisa melebihi waktu yang dihemat, dan CPU sudah lebih dari cukup. Ukur dulu sebelum berasumsi.
Mengapa ini penting untuk kode yang bersih
Simpan konversi di tepi kodemu: konversi sekali saat data masuk ke kode model, dan sekali saat hasilnya keluar. Variabel device yang didefinisikan di satu tempat (sering dari file konfigurasi) membuat script yang sama bisa berjalan di laptop maupun server GPU tanpa diedit. Panggilan .cuda() yang tersebar adalah versi PyTorch dari path file yang di-hard-code.
Rangkuman
torch.from_numpy(arr)berbagi memori;torch.tensor(arr)menyalin; float64 NumPy tetap float64, jadi panggil.float().t.numpy()berbagi memori dan butuh tensor di CPU; gunakant.detach().cpu().numpy()untuk output model.- pandas →
.to_numpy()→torch.tensor(..., dtype=torch.float32). - Device:
"cpu","cuda","mps"; pilih sekali,.to(device)untuk model dan setiap batch. - Semua tensor dalam satu operasi harus berada di device yang sama.