Mô hình chuỗi và RNN với BPTT
Dữ liệu tuần tự, bốn kiểu one-to-many many-to-one many-to-many, cell nhớ hidden state và lan truyền ngược theo thời gian.
KhóThuật toán ~60 phút
Ôn lại trước khi học
Giới thiệu
Bài này học xử lý chuỗi có thứ tự và cell nhớ RNN. Dùng để dịch câu, chấm cảm xúc và gán nhãn từ.
Kiến thức cần nhớ
Bốn kiểu chuỗi
- One-to-many: 1 ảnh sinh ra 1 câu mô tả.
- Many-to-one: 1 câu cho ra 1 nhãn cảm xúc.
- Many-to-many đồng bộ: gán nhãn từng từ một.
- Many-to-many lệch: dịch máy, vào dài khác ra.
- Ví dụ đời thường: như nghe cả câu mới hiểu ý.
| Kiểu | Input | Output |
|---|---|---|
| One-to-many | 1 ảnh | 1 câu |
| Many-to-one | 1 câu | 1 nhãn |
| Đồng bộ | N từ | N nhãn |
| Lệch | N từ | M từ khác |
Cell RNN
- Định nghĩa: trộn đầu vào mới với trí nhớ cũ mỗi bước.
- Trọng số dùng chung nên dài bao nhiêu cũng đủ.
- Ví dụ đời thường: như ghi chú lề cập nhật từng trang.
- Viết đè toàn bộ trí nhớ nên hay quên xa.
- Dữ liệu xếp thành batch, bước thời gian, đặc trưng.
BPTT
- Định nghĩa: lan truyền ngược mở ra theo thời gian.
- Lỗi cuối chuỗi chảy ngược về từng bước trước.
- Ví dụ đời thường: như truy lại băng ghi hình từng phút.
- Chuỗi dài thì gradient teo hoặc nổ dần.
- Cần cắt ngắn và kẹp gradient để chạy ổn.
Ví dụ
- Input: "phim hay quá" -> Output: nhãn khen.
- Giải thích: many-to-one đọc cả chuỗi rồi chốt 1 nhãn.
# Cell RNN cập nhật trí nhớ mỗi bước
h = tanh(x @ Wx + h_cu @ Wh + b) # trộn mới và cũ
print(h) # trí nhớ mới
💻 Bài tập
Ngôn ngữ: Python 3 với NumPy cho Bài 1-2, PyTorch cho Bài 3. Nộp vào day-100/.
Bài 1: RNN cell tự cài
class RNNCell:
def __init__(self, input_size, hidden_size, seed=0): ...
def forward(self, xs: np.ndarray, h0=None) -> tuple[np.ndarray, list]:
"""xs: (T, input_size). h_t = tanh(x_t Wx + h_{t-1} Wh + b). Trả (hs: (T, hidden), cache)."""
def backward(self, dhs, cache) -> dict: ... # BPTT, trả dWx, dWh, db
- Gradient check với sai phân trung tâm trên chuỗi
T = 5. - Xác nhận số tham số không đổi khi
Ttừ 5 lên 100.
input_size=3, hidden=4 -> số tham số = 3*4 + 4*4 + 4 = 32, bất kể T
Bài 2: Gradient teo và nổ
- Chuỗi
T = 50. Đặt loss chỉ ở bước cuối. In chuẩn cho từngt. Vẽ theot(trục y log). - Nhân
Whvới 0.5 và với 2.0. Vẽ lại. Chỉ ra trường hợp teo và trường hợp nổ. - Cài gradient clipping theo chuẩn: nếu thì .
Bài 3: Các kiểu bài toán chuỗi (nâng cao)
Dùng torch.nn.RNN:
- Many-to-one: đếm số chữ
atrong chuỗi ngẫu nhiên dài 10-30 ký tự{a, b}. Hồi quy ra số lượng. - Many-to-many đồng bộ: với chuỗi bit, xuất tại mỗi bước tổng các bit tới đó mod 2 (parity chạy).
- Chuẩn bị batch chuỗi khác độ dài: pad bằng 0 và dùng
pack_padded_sequence. Kiểm tra kết quả không phụ thuộc phần pad. - Trong
README.md, viết mỗi kiểu (one-to-many, many-to-one, many-to-many đồng bộ, lệch) 1 ví dụ bài toán thật.
✅ Tiêu chí hoàn thành
- Gradient check BPTT pass.
- Có hình chuẩn gradient theo bước thời gian cho 3 mức
Wh. - 2 bài many-to-one và many-to-many đạt accuracy trên 95%.
- Kết quả không đổi khi thay độ dài pad.
❓ Câu hỏi ôn tập
- Thứ tự từ vì sao quan trọng?
- 4 kiểu chuỗi khác nhau sao?
- Cell RNN nhớ bằng gì?
- BPTT khác backprop thường ở đâu?
🌕 Bạn đã hoàn thành ngày 100. Làm hết bài tập phía trên rồi sang ngày tiếp theo.