Topik ini membahas cara membuat tensor di PyTorch, mulai dari list bersarang Python, dari array NumPy, hingga konstruktor seperti torch.zeros, torch.ones, dan torch.rand. Setelah membacanya, ketiga sumber tersebut dapat dipilih sesuai data yang tersedia, dan trio atribut bentuk serta dtype yang menyertainya dapat dibaca dengan percaya diri. Seluruh contoh mengikuti konvensi anotasi bentuk yang digunakan secara konsisten di jalur ini, yaitu komentar seperti # (2, 3) di samping setiap operasi untuk menyatakan bentuk tensor yang dihasilkan.
Ketiga jalur pembuatan tersebut dirangkum pada diagram berikut.
Membuat tensor dari list bersarang#
Fungsi torch.tensor menerima data Python yang sudah ada dan menyalinnya menjadi tensor. List bersarang, yakni list yang elemennya juga berupa list, membentuk tensor dua dimensi: list terluar menjadi baris, sedangkan list di dalamnya menjadi isi setiap baris. Kedalaman penyarangan menentukan jumlah dimensi, sedangkan panjang setiap list menentukan ukuran tiap dimensi. Contoh berikut disimpan sebagai file buat_dari_list.py.
import torch
# tensor dua dimensi dari list bersarang
a = torch.tensor([[1, 2, 3], [4, 5, 6]]) # (2, 3), dtype int64
print(a)
print(a.shape)
# tensor satu dimensi dari list biasa
b = torch.tensor([10, 20, 30]) # (3,), dtype int64
print(b)
# list dengan bilangan desimal menghasilkan float32
c = torch.tensor([1.5, 2.5, 3.5]) # (3,), dtype float32
print(c)tensor([[1, 2, 3],
[4, 5, 6]])
torch.Size([2, 3])
tensor([10, 20, 30])
tensor([1.5000, 2.5000, 3.5000])Tipe data ditetapkan secara otomatis pada saat konstruksi. List yang berisi bilangan bulat menghasilkan torch.int64, sedangkan bilangan desimal menghasilkan torch.float32. Bentuknya dapat dibaca langsung dari a.shape yang menampilkan torch.Size([2, 3]), yaitu dua baris dengan tiga kolom. Konstruksi dari list cocok untuk data kecil yang sudah ditulis tangan, misalnya matriks contoh untuk pengujian, karena setiap elemen terlihat jelas di dalam kode.
Dari array NumPy#
Ekosistem data sains Python berpusat pada array NumPy, sehingga PyTorch menyediakan dua fungsi untuk mengonversi array NumPy menjadi tensor. Fungsi torch.tensor menyalin data ke memori baru, sedangkan torch.from_numpy berbagi memori dengan array asalnya. Kedua fungsi menghasilkan tensor dengan bentuk dan dtype yang sama, tetapi perilaku setelahnya berbeda apabila array NumPy diubah. Contoh berikut disimpan sebagai file dari_numpy.py.
import numpy as np
import torch
np_array = np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float32) # (2, 2)
t_salinan = torch.tensor(np_array) # (2, 2), salinan mandiri
t_berbagi = torch.from_numpy(np_array) # (2, 2), memori dipakai bersama
np_array[0, 0] = 100.0
print(t_berbagi) # ikut berubah: memori yang sama
print(t_salinan) # tetap: salinan dibuat saat konstruksitensor([[100., 2.],
[ 3., 4.]])
tensor([[1., 2.],
[3., 4.]])Hasilnya memperlihatkan perbedaan itu dengan jelas. Nilai pertama t_berbagi berubah menjadi 100. karena array NumPy dan tensor tersebut menunjuk memori yang sama, sedangkan t_salinan tetap berisi 1. karena isinya disalin saat konstruksi. Konvensi modern yang dianjurkan adalah torch.tensor untuk sebagian besar kasus, karena salinan mandiri menghindari perubahan tersembunyi, sedangkan from_numpy dipilih bila memori perlu dihemat dan array aslinya memang tidak diubah lagi.
Konstruktor zeros, ones, dan rand#
Konstruktor seperti torch.zeros dan torch.ones membuat tensor baru tanpa memerlukan data awal, dengan bentuk yang diberikan sebagai argumen. Konstruktor semacam ini digunakan setiap kali nilai placeholder diperlukan, misalnya buffer nol untuk akumulasi gradien atau tensor inisialisasi. Fungsi torch.rand mengisi tensor dengan bilangan acak seragam di antara 0 dan 1, sedangkan torch.arange membuat barisan bilangan beraturan sebagaimana fungsi range pada Python. Contoh berikut disimpan sebagai file buat_konstruktor.py.
import torch
torch.manual_seed(0) # benih agar hasil rand dapat direproduksi
nol = torch.zeros(2, 3) # (2, 3), seluruh elemen 0.0
print(nol)
satu = torch.ones(2, 2) # (2, 2), seluruh elemen 1.0
print(satu)
acak = torch.rand(2, 3) # (2, 3), seragam di antara 0 dan 1
print(acak)
barisan = torch.arange(0, 10, 2) # (5,), berisi 0, 2, 4, 6, 8
print(barisan)tensor([[0., 0., 0.],
[0., 0., 0.]])
tensor([[1., 1.],
[1., 1.]])
tensor([[0.4963, 0.7682, 0.0885],
[0.1320, 0.3074, 0.6341]])
tensor([0, 2, 4, 6, 8])Pemanggilan torch.manual_seed(0) sebelum torch.rand menetapkan benih (seed) generator bilangan acak, sehingga keluarannya selalu sama pada setiap eksekusi. Tanpa benih, isi tensor acak berbeda di setiap kali program dijalankan, dan eksperimen menjadi sulit direproduksi. Keluaran di atas berlaku untuk benih 0 pada PyTorch 2.15, sedangkan versi lain dapat menghasilkan bilangan yang berbeda.
dtype dasar#
Setiap tensor menyimpan satu tipe data elemen yang disebut dtype, yaitu tipe angka yang disusun di dalam memori untuk setiap elemennya. Dua dtype yang paling sering ditemui adalah torch.float32 untuk bilangan desimal dan torch.int64 untuk bilangan bulat, dan keduanya menjadi pilihan bawaan PyTorch. Argumen dtype pada konstruktor mengubah pilihan bawaan tersebut, sedangkan metode .to(dtype_baru) mengubah dtype tensor yang sudah ada.
import torch
a = torch.tensor([1, 2, 3], dtype=torch.float32) # (3,), bilangan bulat dipaksa float32
print(a.dtype)
b = torch.tensor([1, 2, 3]) # (3,), default int64
print(b.dtype)
c = torch.tensor([1.5, 2.5]) # (2,), default float32
print(c.dtype)
d = torch.zeros(2, 2, dtype=torch.int64) # (2, 2), dikonstruksi langsung int64
print(d)
e = a.to(torch.int64) # (3,), konversi float32 ke int64
print(e)torch.float32
torch.int64
torch.float32
tensor([[0, 0],
[0, 0]])
tensor([1, 2, 3])Dua tensor hanya dapat dioperasikan secara langsung apabila dtype keduanya kompatibel, sehingga dtype menjadi salah satu hal yang diperiksa setiap kali operasi antara tensor gagal. Pembahasan lengkapnya ada pada topik atribut tensor. Untuk saat ini, kebiasaan yang cukup adalah membaca x.dtype setiap kali tensor baru dibuat, karena satu baris keluaran tersebut menghindari banyak kebingungan di kemudian hari.
Kesalahan umum#
Kesalahan paling lazim saat konstruksi dari list adalah list bersarang yang tidak rata, yaitu list yang anggotanya tidak memiliki panjang yang sama. PyTorch menuntut setiap baris memiliki panjang yang seragam agar bentuk tensor dapat ditentukan, dan menolak data yang melanggar aturan tersebut dengan pesan yang menyebut posisi dimensinya.
import torch
try:
torch.tensor([[1, 2], [3]]) # baris kedua hanya berisi satu elemen
except ValueError as e:
print("ValueError:", e)ValueError: expected sequence of length 2 at dim 1 (got 1)Pesan error tersebut menyebut bahwa dimensi 1 diharapkan berisi dua elemen, tetapi hanya mendapat satu. Perbaikannya adalah melengkapi datanya, atau menata ulang list agar setiap baris sama panjang. Kesalahan kedua yang berhubungan dengan pembuatan adalah lupa menetapkan benih sebelum menggunakan torch.rand, sehingga hasil yang tadinya dapat direproduksi menjadi berbeda pada setiap eksekusi. Kedua kesalahan ini terdeteksi cepat asalkan keluaran program selalu diperiksa setiap kali dijalankan.
Ringkasan#
torch.tensormenyalin list bersarang atau array NumPy menjadi tensor, dengan jumlah dimensi mengikuti kedalaman penyarangan dan dtype yang terdeteksi otomatis.torch.from_numpyberbagi memori dengan array NumPy asalnya, sedangkantorch.tensormembuat salinan mandiri yang kebal terhadap perubahan array tersebut.torch.zeros,torch.ones, dantorch.randmenerima bentuk sebagai argumen, sedangkantorch.arangemembuat barisan beraturan, dantorch.manual_seedmembuat hasil acak dapat direproduksi.- dtype bawaan adalah
int64untuk bilangan bulat danfloat32untuk bilangan desimal, dapat diatur lewat argumendtype, dan diubah dengan.to().
Referensi#
- PyTorch documentation — PyTorch
— Rujukan API untuk
torch.tensor,torch.from_numpy, dan seluruh konstruktor yang dibahas di topik ini. - Learn the Basics — PyTorch — Tutorial resmi yang bagian Tensors memperkenalkan pembuatan tensor dari data Python dan NumPy.