DataLens

Membangun model dengan nn.Module

Definisikan network sebagai class nn.Module dengan layer dan method forward, pahami apa yang dihitung Linear layer, tambahkan activation, dan hitung jumlah parameter.

Level: Menengah · 7 menit baca

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Idenya

Di modul autograd kamu mengelola w dan b secara manual. Network sungguhan punya banyak layer dan ribuan parameter, jadi PyTorch menyediakan blok-blok penyusun di torch.nn:

Ini modul class dari track Python, dipakai untuk bekerja.

Linear layer adalah X @ W.T + b

Blok penyusun dasar sebuah jaringan saraf adalah linear layer. Isinya "kalikan lalu jumlahkan" yang sama dengan regresi linear, hanya dengan beberapa output sekaligus. Ini satu layer yang menerima 3 fitur dan menghasilkan 2 angka:

import torch
from torch import nn

torch.manual_seed(0)
layer = nn.Linear(in_features=3, out_features=2)
print(layer.weight.shape, layer.bias.shape)

x = torch.tensor([[1.0, 0.0, 2.0]])          # a batch of 1 example with 3 features
print(layer(x))
print(x @ layer.weight.T + layer.bias)       # the same calculation by hand
torch.Size([2, 3]) torch.Size([2])
tensor([[-0.9661,  0.3425]], grad_fn=<AddmmBackward0>)
tensor([[-0.9661,  0.3425]], grad_fn=<AddBackward0>)

grad_fn di output menunjukkan bahwa hasilnya bagian dari graph autograd, siap untuk backward(). nn.Linear(3, 2) menyimpan matriks bobot ber-shape (2, 3) dan bias ber-shape (2,), keduanya dibuat secara acak dan ditandai requires_grad=True. Memanggil layer pada sebuah batch menghitung x @ W.T + b: latihan "layer buatan tangan" dari modul operasi.

Activation: bagian yang non-linear

Menumpuk linear layer saja hanya menghasilkan fungsi linear lainnya (matriks kali matriks tetap matriks). Di antara layer kamu menaruh activation non-linear, yang membuat network bisa melengkung:

z = torch.tensor([-2.0, -0.5, 0.0, 1.5])
print(torch.relu(z))         # max(0, z): the default choice
print(torch.sigmoid(z))      # squashes to (0, 1): for probabilities
print(torch.tanh(z))         # squashes to (-1, 1)
tensor([0.0000, 0.0000, 0.0000, 1.5000])
tensor([0.1192, 0.3775, 0.5000, 0.8176])
tensor([-0.9640, -0.4621,  0.0000,  0.9051])

ReLU (rectified linear unit) adalah standar di antara hidden layer: sederhana, cepat, dan mudah dilatih.

Class model pertamamu

Model churn dengan 5 input, satu hidden layer berisi 16 unit, dan satu output:

class ChurnNet(nn.Module):
    def __init__(self, n_features, hidden=16):
        super().__init__()
        self.hidden = nn.Linear(n_features, hidden)
        self.output = nn.Linear(hidden, 1)

    def forward(self, x):
        x = torch.relu(self.hidden(x))
        return self.output(x)          # a raw score ("logit"); sigmoid turns it into a probability


torch.manual_seed(0)
model = ChurnNet(n_features=5)
batch = torch.randn(4, 5)              # 4 customers, 5 features each
logits = model(batch)
print(logits.shape)
print(torch.sigmoid(logits).squeeze().detach().round(decimals=3))
torch.Size([4, 1])
tensor([0.3920, 0.4280, 0.3520, 0.4480])

Probabilitas dari model yang belum dilatih berada di antara 0,35 dan 0,45: bobot acak, belum ada pengetahuan. (.detach() membuang catatan autograd sebelum dicetak.)

nn.Sequential untuk tumpukan sederhana

Saat data hanya mengalir melewati layer secara berurutan, nn.Sequential menghemat penulisan class:

torch.manual_seed(0)
model = nn.Sequential(
    nn.Linear(5, 16),
    nn.ReLU(),
    nn.Linear(16, 1),
)
print(model)
print(model(batch).shape)
Sequential(
  (0): Linear(in_features=5, out_features=16, bias=True)
  (1): ReLU()
  (2): Linear(in_features=16, out_features=1, bias=True)
)
torch.Size([4, 1])

Gunakan nn.Sequential untuk tumpukan lurus; tulis subclass nn.Module saat forward butuh logika (beberapa input, skip connection, percabangan).

Parameter

Setiap layer yang didaftarkan sebagai atribut dilacak secara otomatis:

for name, p in model.named_parameters():
    print(name, tuple(p.shape))
print("total:", sum(p.numel() for p in model.parameters()))
0.weight (16, 5)
0.bias (16,)
2.weight (1, 16)
2.bias (1,)
total: 113

5×16 + 16 + 16×1 + 1 = 113 parameter. model.parameters() adalah yang kamu serahkan ke optimizer, supaya ia bisa memperbarui semuanya. Ini berfungsi karena layer-layernya di-assign ke self.something di __init__; layer yang disimpan di list Python biasa tidak akan ditemukan (gunakan nn.ModuleList untuk list berisi layer).

Ide utama

Sebuah nn.Module = layer yang dibuat di __init__ + aliran data di forward. Layer memiliki parameternya sendiri; model.parameters() mengumpulkan semuanya untuk optimizer.

Mengapa ini penting untuk kode yang bersih

Class model adalah tempat kode deep learning tetap mudah dibaca atau berubah menjadi spageti. Jaga __init__ tetap deklaratif (hanya layer-layer, dengan nama jelas seperti hidden dan output), jaga forward tetap pendek dan lurus, berikan ukuran sebagai argumen (n_features, hidden) alih-alih di-hard-code, dan kembalikan logit alih-alih mencampur logika probabilitas ke dalam model. Dengan begitu class yang sama bisa dites, dipakai ulang, dan dikonfigurasi ulang.

Rangkuman

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Berikutnya: Fungsi loss dan optimizer →