Parameter adalah tensor bobot dan bias yang nilainya dipelajari selama pelatihan. Topik ini membahas cara menelusuri parameter sebuah model melalui parameters() dan named_parameters(), cara menghitung jumlah parameternya, serta alasan bobot harus terdaftar sebagai nn.Parameter agar dikenali oleh seluruh mekanisme PyTorch. Contoh yang digunakan adalah model klasifikasi dua layer dari topik nn.Module, sehingga seluruh angkanya dapat dihitung ulang dengan mudah, baik per layer maupun untuk model secara keseluruhan.
Apa yang dihitung sebagai parameter#
Satu layer Linear(in_features, out_features) membawa dua tensor yang dipelajari, yaitu matriks bobot berbentuk (out_features, in_features) dan vektor bias berbentuk (out_features,). Dengan demikian, jumlah parameter satu layer adalah sebagai berikut:
Untuk nn.Linear(20, 64), jumlah parameternya , yaitu 1280 elemen bobot ditambah 64 elemen bias. Layer tanpa parameter yang dipelajari, seperti ReLU, tidak menyumbang apa pun. Kode berikut memeriksa hitungan tersebut.
import torch
import torch.nn as nn
torch.manual_seed(0)
linear = nn.Linear(20, 64)
print(linear.weight.shape)
print(linear.bias.shape)
print(linear.weight.numel() + linear.bias.numel())torch.Size([64, 20])
torch.Size([64])
1344Keluarannya sesuai rumus, yaitu bobot torch.Size([64, 20]) dengan 1280 elemen dan bias torch.Size([64]) dengan 64 elemen. Angka semacam ini patut dihitung sebelum pelatihan, karena jumlah parameter menentukan kebutuhan memori dan memberi gambaran awal tentang kapasitas model.
Setiap parameter juga otomatis membawa requires_grad=True, sehingga operasi yang menyentuhnya dicatat oleh autograd dan gradiennya dapat dihitung. Inilah perbedaan parameter dengan tensor biasa pada data: data tidak pernah dipelajari, sedangkan parameter terus diperbarui mengikuti gradien. Ukuran memori yang dibawanya pun mudah dihitung, karena satu elemen float32 menggunakan empat byte, sehingga layer dengan 1344 parameter membutuhkan sekitar 5.376 byte untuk nilai parameternya.
Menelusuri parameter model#
model.parameters() menghasilkan seluruh tensor parameter milik model, sedangkan model.named_parameters() menghasilkan pasangan nama dan tensor. Nama tersebut berasal dari nama atribut layer pada __init__, misalnya fc1 menjadi fc1.weight dan fc1.bias. ReLU tidak membawa parameter yang dipelajari, sehingga tidak muncul sama sekali dalam penelusuran.
import torch
import torch.nn as nn
torch.manual_seed(0)
class KlasifikasiSuhu(nn.Module):
"""Model dua layer untuk klasifikasi tiga kategori suhu."""
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(4, 8)
self.aktivasi = nn.ReLU()
self.fc2 = nn.Linear(8, 3)
def forward(self, x):
return self.fc2(self.aktivasi(self.fc1(x)))
model = KlasifikasiSuhu()
total = 0
for nama, p in model.named_parameters():
jumlah = p.numel()
total += jumlah
print(f"{nama:<14} shape={tuple(p.shape)!s:<10} jumlah={jumlah}")
print(f"total parameter: {total}")fc1.weight shape=(8, 4) jumlah=32
fc1.bias shape=(8,) jumlah=8
fc2.weight shape=(3, 8) jumlah=24
fc2.bias shape=(3,) jumlah=3
total parameter: 67Setiap baris keluaran dapat dihitung ulang dengan rumus satu layer. Untuk fc1, jumlahnya , sedangkan untuk fc2 jumlahnya . Penjumlahan keduanya memberi 67, sesuai baris terakhir. aktivasi tidak muncul di daftar karena ReLU memang tidak memiliki parameter.
Yang dikembalikan oleh parameters() adalah generator, yaitu objek yang memberikan satu tensor pada satu waktu. Bentuk ini efisien untuk perulangan, tetapi tidak cocok untuk dihitung langsung, sehingga pola len(list(model.parameters())) digunakan ketika banyaknya tensor perlu diketahui.
Menghitung total parameter#
Total parameter seluruh model dihitung dengan idiom yang sama di hampir semua proyek PyTorch, yaitu sum(p.numel() for p in model.parameters()). Method numel() menghitung banyak elemen dalam satu tensor, dan fungsi sum() menjumlahkannya untuk seluruh parameter. Model pada kode berikut disusun ulang dengan nn.Sequential, dan totalnya harus cocok dengan penjumlahan manual di atas.
import torch
import torch.nn as nn
torch.manual_seed(0)
model = nn.Sequential(
nn.Linear(4, 8),
nn.ReLU(),
nn.Linear(8, 3),
)
total = sum(p.numel() for p in model.parameters())
print(total)67Totalnya kembali 67, sehingga cara menyusun model tidak mengubah hitungannya. Idiom ini digunakan untuk membandingkan kapasitas dua arsitektur, memeriksa ukuran model sebelum pelatihan, dan menghitung berapa banyak parameter yang terlibat pada suatu eksperimen.
Penelusuran parameters() juga bersifat rekursif, yaitu menelusuri seluruh submodule di dalam model, bukan hanya layer pada tingkat teratas. Karena itu, seluruh parameter model yang bersarang beberapa tingkat tetap ditemukan. Seluruh model, ataupun satu submodule tertentu, dapat dihitung seperti pada kode berikut.
import torch
import torch.nn as nn
torch.manual_seed(0)
model = nn.Sequential(
nn.Linear(4, 8),
nn.ReLU(),
nn.Linear(8, 3),
)
print(len(list(model.parameters())))
print(sum(p.numel() for p in model[0].parameters()))
print(model[0].weight.requires_grad)4
40
TrueBaris pertama menunjukkan empat tensor parameter, yaitu bobot dan bias dari dua Linear, yang semuanya ditemukan tanpa menulis daftar secara manual. Baris kedua menghitung submodule pertama saja dan menghasilkan 40, sesuai . Baris ketiga menegaskan bahwa setiap parameter otomatis membawa requires_grad=True.
Mengapa bobot harus nn.Parameter#
Aturan pendaftarannya sederhana. Ketika sebuah nn.Module atau nn.Parameter ditetapkan sebagai atribut, objek itu beserta isinya terdaftar pada model. Tensor biasa yang ditetapkan sebagai atribut hanya menjadi atribut Python biasa, sehingga tidak muncul di parameters(), tidak ikut dipindahkan oleh model.to(device), dan tidak diserahkan ke optimizer. nn.Parameter adalah pembungkus tensor yang tujuan utamanya membuat tensor tersebut terdaftar.
import torch
import torch.nn as nn
torch.manual_seed(0)
class DenganTensorBiasa(nn.Module):
def __init__(self):
super().__init__()
self.fc = nn.Linear(4, 3)
self.skala = torch.tensor(1.0) # tensor biasa, bukan nn.Parameter
class DenganParameter(nn.Module):
def __init__(self):
super().__init__()
self.fc = nn.Linear(4, 3)
self.skala = nn.Parameter(torch.tensor(1.0)) # terdaftar sebagai parameter
print("Jumlah parameter DenganTensorBiasa:", len(list(DenganTensorBiasa().parameters())))
print("Jumlah parameter DenganParameter :", len(list(DenganParameter().parameters())))
model_t = DenganTensorBiasa()
model_t.to(torch.float64)
print("fc.weight :", model_t.fc.weight.dtype)
print("skala :", model_t.skala.dtype, "(tensor biasa)")
model_p = DenganParameter()
model_p.to(torch.float64)
print("skala :", model_p.skala.dtype, "(nn.Parameter)")Jumlah parameter DenganTensorBiasa: 2
Jumlah parameter DenganParameter : 3
fc.weight : torch.float64
skala : torch.float32 (tensor biasa)
skala : torch.float64 (nn.Parameter)Kedua kelas itu identik kecuali pembungkusnya, tetapi keluarannya berbeda. Kelas dengan tensor biasa hanya memiliki dua parameter, yaitu bobot dan bias fc, sedangkan skala ikut terhitung pada kelas kedua. Setelah to(torch.float64), layer terdaftar berubah tipe menjadi torch.float64, sementara tensor biasa tetap torch.float32 karena to() hanya menelusuri objek yang terdaftar. Pemindahan antara device bekerja dengan mekanisme yang sama.
Daftar yang diberikan ke optimizer pada topik Optimizer juga berupa model.parameters() itu sendiri, sehingga hanya objek terdaftar yang diperbarui selama pelatihan. Dengan kata lain, pendaftaran yang benar menentukan tiga hal sekaligus, yaitu pembaruan oleh optimizer, pemindahan antara device, dan penyimpanan pada state_dict.
Ringkasan#
- Satu
Linear(in, out)membawa parameter, yaitu bobot berbentuk (out,in) dan bias berbentuk (out,). named_parameters()memberikan nama beserta tensor parameternya, dansum(p.numel() for p in model.parameters())menghitung total parameternya.- Hanya
nn.Moduledannn.Parameteryang terdaftar sebagai bagian model, sedangkan tensor biasa tidak ikut padaparameters(), pemindahan device,state_dict, dan optimizer.
Referensi#
- Learn the Basics — PyTorch — Tutorial resmi yang menelusuri parameter model pada bagian Build the Neural Network.
- PyTorch Documentation — PyTorch
— Dokumentasi resmi
nn.Moduledannn.Parameterbeserta mekanisme pendaftarannya.