Các mạng nơ-ron hồi quy tiêu chuẩn gặp khó khăn với trí nhớ. Khi chuỗis vượt quá 20-30 bước thời gian, gradient hoặc thu nhỏ về 0 hoặc bùng nổ trong quá trình lan truyền ngược, và mạng mất khả năng kết nối các phần xa nhau của đầu vào. Hochreiter và Schmidhuber đã giải quyết vấn đề này trong bài báo năm 1997 bằng cách giới thiệu mạng Bộ nhớ Ngắn-Dài hạn (LSTM).
Trong hướng dẫn này, tôi sẽ đi qua phần nội tại của LSTM trước khi chuyển sang triển khai thực tế bằng Python. Các phần cuối sẽ so sánh LSTM với Transformer để bạn có thể chọn kiến trúc phù hợp cho trường hợp sử dụng của mình.
Tôi rất khuyến nghị khóa học Giới thiệu về Học sâu với PyTorch của chúng tôi để có trải nghiệm thực hành sử dụng PyTorch để huấn luyện mạng nơ-ron, vốn là nền tảng cho các mô hình LSTM.
Mô hình LSTM là gì?
LSTM là viết tắt của Long Short-Term Memory (Bộ nhớ Ngắn-Dài hạn), một loại mạng nơ-ron hồi quy (RNN) được thiết kế để xử lý các chuỗi mà ngữ cảnh từ rất sớm trong đầu vào vẫn còn quan trọng.
Ý tưởng cốt lõi đằng sau LSTM là cơ chế cổng (gating) điều tiết luồng thông tin qua mạng. Thay vì để mọi tín hiệu đi qua như nhau, các cổng học khi nào cần giữ ngữ cảnh và khi nào nên bỏ qua.
Bộ nhớ có chọn lọc này cho phép LSTM theo dõi các phụ thuộc qua hàng trăm bước thời gian, điều này tỏ ra hữu ích cho mô hình ngôn ngữ, nhận dạng giọng nói và dự báo chuỗi thời gian. Để hiểu vì sao kiến trúc này tồn tại, sẽ hữu ích khi xem điều gì bị hỏng ở RNN tiêu chuẩn.
Vấn đề gradient biến mất trong RNN
Mạng hồi quy truyền thông tin từ bước thời gian này sang bước tiếp theo thông qua trạng thái ẩn. Mỗi bước nhân trạng thái này với trọng số học được, cập nhật nó, rồi truyền tiếp. Huấn luyện yêu cầu gửi tín hiệu lỗi ngược qua tất cả các bước đó, và mỗi lần lan truyền ngược làm tín hiệu nhỏ đi một chút. Sau đủ nhiều bước, gần như không còn gì.
Nó giống như photocopy một bản photocopy. Làm vài lần thì bản sao vẫn ổn. Làm năm mươi lần, bạn hầu như không đọc được. RNN gặp bức tường này ở khoảng 20-30 bước thời gian, đó là lý do chúng khó xử lý các chuỗi dài hơn.
Cách LSTM giải quyết các phụ thuộc dài hạn
LSTM thêm một đường bộ nhớ riêng, gọi là trạng thái ô (cell state), chạy song song với trạng thái ẩn tiêu chuẩn. Khác biệt nằm ở cấu trúc: thông tin trong trạng thái ô chảy qua phép cộng thay vì nhân lặp đi lặp lại, vì vậy nó không bị suy giảm theo cách cũ.
Để kiểm soát những gì đi vào và đi ra khỏi bộ nhớ này, LSTM sử dụng các cổng. Mỗi cổng là một mạng nơ-ron nhỏ học cách xuất ra giá trị trong khoảng 0 đến 1, hoạt động như một bộ lọc. Giá trị gần 0 chặn thông tin; giá trị gần 1 cho phép thông tin đi qua. Mạng học trong quá trình huấn luyện xem các mẫu nào đáng nhớ qua chuỗi dài và mẫu nào có thể bỏ qua.
Cơ chế cổng này là điều tách biệt LSTM với RNN nguyên bản. Thay vì bắt buộc mọi thông tin đi cùng một đường, LSTM có thể chọn lọc giữ ngữ cảnh qua hàng trăm bước. Phần tiếp theo sẽ phân tích chính xác cách các cổng này hoạt động và cách chúng kết hợp để cập nhật trạng thái ô.
Các trường hợp sử dụng mô hình LSTM
LSTM xuất hiện ở bất cứ nơi nào dữ liệu tuần tự quan trọng. Một vài ví dụ vượt ra ngoài các ứng dụng NLP và dự báo thường thấy:
Ngân hàng chạy chuỗi giao dịch qua LSTM để bắt các mẫu gian lận mà hệ thống dựa trên luật bỏ sót
Bệnh viện giám sát luồng ECG với LSTM hai chiều, phát hiện bất thường tim nhanh hơn so với cảnh báo ngưỡng
Nhà máy theo dõi độ rung thiết bị theo thời gian để lên lịch bảo trì trước khi sự cố xảy ra
Kiến trúc LSTM: Các cổng và ô nhớ
Phần này trình bày chi tiết nội tại của LSTM. Nếu bạn muốn nhảy thẳng đến triển khai, hãy chuyển sang phần tiếp theo. Chi tiết kiến trúc ở đây không bắt buộc để sử dụng LSTM, nhưng hữu ích khi gỡ lỗi hoặc tinh chỉnh.
Để hiểu LSTM hoạt động thế nào, chúng ta sẽ truy vết một ví dụ cụ thể: xử lý chuỗi "The clouds are dark..." để dự đoán từ tiếp theo. Mỗi thành phần sẽ dễ hiểu hơn khi bạn thấy nó làm gì với dữ liệu thực.
Trạng thái ô và trạng thái ẩn trong LSTM
Một LSTM duy trì hai vector riêng biệt chảy xuyên suốt mạng: trạng thái ô và trạng thái ẩn.
Trạng thái ô đóng vai trò lưu trữ dài hạn. Nó mang thông tin qua các bước thời gian với các điều chỉnh có kiểm soát ở mỗi bước. Khi xử lý chuỗi của chúng ta, trạng thái ô có thể lưu "xuất hiện danh từ liên quan đến thời tiết" sau khi thấy "clouds" và giữ ngữ cảnh đó qua "are", cho đến khi "dark" củng cố mẫu này.
Trạng thái ẩn là đầu ra của ô tại mỗi bước thời gian. Nó đi vào dự đoán và vào phép tính của bước tiếp theo. Sau khi xử lý "dark," trạng thái ẩn mã hóa điều gì đó như "tính từ mô tả điều kiện thời tiết" mà một tầng dự đoán có thể sử dụng.
Vì sao có hai đường riêng? Một trạng thái đơn lẻ sẽ cần đồng thời giữ ngữ cảnh dài hạn và tạo ra đầu ra hữu ích. Hai mục tiêu này mâu thuẫn: bộ nhớ ổn định cần thay đổi tối thiểu, trong khi đầu ra hữu ích cần biến đổi. Tách chúng ra cho phép mỗi đường tối ưu cho mục đích riêng.
Ở mỗi bước thời gian, ô nhận ba đầu vào và tạo ra hai đầu ra:
Đầu vào:
Trạng thái ô trước đó (C_{t-1}): những gì mạng đã nhớ đến hiện tại
Trạng thái ẩn trước đó (h_{t-1}): đầu ra của bước trước
Đầu vào hiện tại (x_t): token mới, như "clouds" hoặc "dark"
Đầu ra:
Trạng thái ô đã cập nhật (C_t): bộ nhớ sau khi xử lý token này
Trạng thái ẩn mới (h_t): đầu ra của bước thời gian này
Cách các cổng của LSTM tính toán
Bốn thành phần kiểm soát những gì xảy ra bên trong ô. Ba trong số đó là các cổng xuất giá trị trong khoảng 0 đến 1, hoạt động như bộ lọc. Thành phần thứ tư là ứng viên (candidate), đề xuất nội dung mới.
Khi "are" đến sau "clouds," mỗi thành phần có một nhiệm vụ:
Cổng quên (f_t): Chúng ta có nên giữ ngữ cảnh "clouds" không? Danh từ thời tiết theo sau động từ nối thường quan trọng, nên cổng quên xuất các giá trị gần 1 để giữ phần lớn trạng thái ô.
Cổng vào (i_t): "are" nên đóng góp vào bộ nhớ bao nhiêu? Động từ nối mang tín hiệu dự đoán thấp hơn, nên cổng vào xuất giá trị thấp.
Ứng viên (C̃_t): "are" có thể thêm thông tin gì? Ứng viên đề xuất nội dung, nhưng cổng vào sẽ giảm cường độ nó.
Cổng ra (o_t): Trạng thái ẩn nên hiển thị gì? Cổng ra lọc trạng thái ô để tạo h_t.
Mỗi thành phần tính đầu ra theo cùng một cách:
Nối h_{t-1} và x_t thành một vector
Nhân với một ma trận trọng số học được
Cộng một hằng số độ lệch (bias)
Áp dụng hàm kích hoạt
Các cổng dùng kích hoạt sigmoid, nén giá trị vào khoảng 0-1. Ứng viên dùng tanh, xuất ra các giá trị giữa -1 và 1, nên có thể đề xuất cả tăng và giảm cho trạng thái ô.
Các phương trình
Cổng quên (sigmoid → 0 đến 1):
Cổng vào (sigmoid → 0 đến 1):
Cổng ra (sigmoid → 0 đến 1):
Ứng viên (tanh → -1 đến +1):
Mỗi thành phần có ma trận trọng số riêng (W_f, W_i, W_c, W_o), nên chúng học phản hồi với các mẫu khác nhau trong đầu vào.
Cách hoạt động của lọc
Đầu ra của cổng nhân với các vector theo từng vị trí (nhân từng phần tử, ký hiệu ⊙). Mỗi chiều được lọc độc lập.
Nếu một cổng xuất 0.9 cho vị trí 1, chiều đó giữ 90% giá trị. Nếu nó xuất 0.0 cho vị trí 4, chiều đó bị xóa. Khi xử lý "dark" sau "clouds are," cổng quên có thể xuất giá trị cao cho các chiều lưu ngữ cảnh danh từ/thời tiết và giá trị thấp hơn cho các chiều chứa ngữ cảnh trước đó không liên quan.
Dòng chảy thông tin giữa các cổng quên, cộng và ra
Các thành phần kết hợp trong ba bước để cập nhật trạng thái ô và tạo ra trạng thái ẩn.
Bước 1: Quên
Cổng quên lọc trạng thái ô trước đó:
Khi xử lý "dark," cổng quên giữ ngữ cảnh thời tiết từ "clouds" đồng thời xóa các chiều theo dõi mạo từ "The."
Bước 2: Cộng
Cổng vào co giãn đề xuất của ứng viên, rồi cộng nó vào trạng thái ô đã được lọc:
Ứng viên có thể đề xuất "tính từ bổ nghĩa danh từ thời tiết," và cổng vào quyết định mức độ ghi điều đó vào bộ nhớ. Cập nhật dạng cộng (không phải nhân) này giúp gradient chảy tốt hơn trong huấn luyện.
Bước 3: Ra
Trạng thái ô đi qua tanh, sau đó cổng ra lọc phần trở thành trạng thái ẩn:
Hàm tanh giữ giá trị trong giới hạn. Cổng ra chọn những khía cạnh nào của bộ nhớ tích lũy sẽ hiển thị để dự đoán ở bước thời gian này.
Trình tự hoàn chỉnh:
Dưới đây là một truy vết giản lược với trạng thái ô có 4 chiều:
Bước
Đầu vào
Trạng thái ô (giản lược)
Điều xảy ra
1
"The"
[0.1, 0.0, 0.2, 0.0]
Lưu trữ tối thiểu; mạo từ mang ít tín hiệu dự đoán
2
"clouds"
[0.1, 0.7, 0.2, 0.3]
Cổng vào mở cho các chiều 2,4; lưu mẫu danh từ
3
"are"
[0.1, 0.6, 0.2, 0.3]
Cổng quên ≈ 0.9 giữ ngữ cảnh; động từ nối thêm rất ít
4
"dark"
[0.1, 0.8, 0.5, 0.6]
Tính từ làm mạnh tín hiệu ở các chiều 2,3,4
Đến bước thời gian 4, các chiều 2-4 đã tích lũy được một mẫu. Trạng thái ẩn h_4 đi vào một tầng dự đoán (không phải phần của LSTM), tầng này sinh ra xác suất từ vựng. Mẫu tích lũy đó giúp mô hình ưu tiên các từ như "rain" hoặc "sky."
Mạng không hiểu về thời tiết. Nó học các tương quan thống kê: một số chuỗi đầu vào có xu hướng đi trước một số đầu ra nhất định.
Dòng chảy gradient trong huấn luyện
Cấu trúc cộng của trạng thái ô cung cấp một đường dẫn gradient trực tiếp hơn so với RNN tiêu chuẩn. Nếu bạn chưa quen với cách gradient lan truyền qua mạng nơ-ron, hướng dẫn lan truyền ngược bao gồm các nền tảng cơ bản.
Trong RNN tiêu chuẩn, gradient chảy qua ma trận trọng số ở mỗi bước. Phép nhân lặp lại cộng dồn: sau 100 bước với trọng số trung bình 0.9, gradient thu nhỏ còn 0.9^100 ≈ 0.00003.
LSTM cung cấp một đường dẫn thay thế dọc theo trạng thái ô. Đạo hàm của C_t theo C_{t-1}:
Đây là giá trị cổng quên, không phải ma trận trọng số. Khi cổng quên duy trì gần 1, gradient đi qua với ít suy giảm hơn. Nếu cổng trung bình 0.95, sau 100 bước: 0.95^100 ≈ 0.006. Vẫn giảm, nhưng có thể sử dụng.
Khía cạnh
RNN
LSTM
Đường gradient
Chỉ qua ma trận trọng số
Đường bổ sung dọc theo trạng thái ô
Gradient 100 bước
~10^-5 (biến mất)
~10^-2 đến 10^-1 (dùng được)
Bộ nhớ thực tế
~10-20 bước thời gian
~50-200 bước thời gian
Ghi chú thực tiễn: Bias của cổng quên thường được khởi tạo ở 1.0 hoặc cao hơn, đẩy đầu ra ban đầu về phía "ghi nhớ mọi thứ." Điều này giúp mạng học các mẫu dài hạn sớm trong quá trình huấn luyện.
LSTM giảm thiểu vấn đề gradient biến mất chứ không loại bỏ hoàn toàn. Cải thiện đến từ cập nhật trạng thái ô dạng cộng, cung cấp một "đường cao tốc" cho gradient song song với các đường dẫn tiêu chuẩn.
Cách triển khai mô hình LSTM trong Python
Phần trước đã trình bày những gì diễn ra trong một ô LSTM: các cổng lọc thông tin, trạng thái ô giữ ngữ cảnh, và trạng thái ẩn tạo ra đầu ra. Giờ chúng ta sẽ xem nn.LSTM của PyTorch gói gọn tất cả vào một mô-đun đơn và dùng nó để phân loại đánh giá phim là tích cực hay tiêu cực.
Mẹo để chạy mã: Huấn luyện 50 epoch trên CPU sẽ rất lâu. Hãy dùng Google Colab hoặc Kaggle Notebooks với tăng tốc GPU để có kết quả nhanh hơn. Toàn bộ script có sẵn dưới dạng GitHub Gist.
Xây dựng bộ phân loại LSTM với PyTorch
Phân loại văn bản với LSTM theo một khuôn mẫu: chuyển từ thành vector, để LSTM xử lý tuần tự, sau đó dùng đầu ra cuối cùng cho dự đoán.
Nhúng từ thành vector
Mạng nơ-ron hoạt động trên các số liên tục, còn từ là ký hiệu rời rạc. Ta không thể đưa trực tiếp "terrible" vào phép nhân ma trận. Giải pháp là một tầng embedding: một bảng truy xuất nơi mỗi từ ánh xạ tới một vector có thể học được.
self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=padding_idx)Được hỗ trợ bởi
Nếu bạn chọn embedding_dim=32, mỗi từ trở thành một vector 32 chiều. Ở đầu quá trình huấn luyện, các vector này là ngẫu nhiên. Khi mô hình học, các từ có sắc thái cảm xúc tương tự sẽ xích lại gần nhau trong không gian vector này. "Terrible," "awful," và "boring" có thể ở gần nhau, trong khi "excellent" và "amazing" tụ lại nơi khác.
Tham số padding_idx báo cho tầng giữ các token đệm ở vector 0, để chúng không ảnh hưởng đến mô hình.
Định nghĩa kiến trúc LSTM
self.lstm = nn.LSTM(
input_size=embedding_dim,
hidden_size=hidden_size,
num_layers=num_layers,
batch_first=True,
dropout=dropout if num_layers >1else0,
bidirectional=bidirectional,)Được hỗ trợ bởi
Chỉ một dòng này tạo ra toàn bộ cơ chế cổng từ phần trước. hidden_size quyết định lượng thông tin trạng thái ô và trạng thái ẩn có thể mang. Giá trị lớn hơn cho phép mô hình theo dõi nhiều mẫu hơn nhưng tốn tính toán hơn.
Thiết lập batch_first=True nghĩa là đầu vào có dạng (batch, sequence_length, embedding_dim). LSTM xử lý từng vị trí từ trái sang phải, cập nhật trạng thái nội tại ở mỗi bước.
Xử lý chuỗi
Sau khi xử lý "This movie was absolutely terrible," LSTM đã thấy mọi từ. Trạng thái ẩn cuối cùng đã tích lũy những gì mô hình học được từ chuỗi đó. Với cảm xúc, điều này có thể mã hóa điều gì đó như "tính từ tiêu cực mạnh ở cuối, phủ định nội dung trung tính trước đó."
LSTM trả về cả đầu ra theo từng bước (lstm_out) và trạng thái cuối cùng (h_n, c_n). Với phân loại, ta chỉ cần h_n[-1], trạng thái ẩn sau token cuối. Một tầng tuyến tính sau đó ánh xạ nó thành điểm lớp.
Truy vết một đánh giá qua mô hình
Khi "This movie was terrible" đi vào bộ phân loại:
Mỗi từ nhận embedding của nó: bốn vector dạng (32,)
LSTM xử lý chúng tuần tự. "This" khởi tạo một phần trạng thái ô. "Movie" cập nhật nó một chút. "Was" trung tính và thay đổi ít. "Terrible" kích hoạt cổng quên để xóa ngữ cảnh không liên quan và cổng vào để ghi tín hiệu tiêu cực mạnh.
Trạng thái ẩn cuối cùng nắm bắt mẫu tích lũy.
Tầng tuyến tính ánh xạ nó thành hai điểm: một cho tích cực, một cho tiêu cực
Mô hình không hiểu ngôn ngữ. Nó học các mẫu thống kê: một số chuỗi từ tương quan với một số nhãn nhất định.
Lớp mô hình đầy đủ
Bên dưới là toàn bộ lớp LSTMClassifier mà chúng ta vừa tạo từng bước:
Tùy chọn hai chiều chạy hai LSTM: một từ trái sang phải, một từ phải sang trái. Trạng thái ẩn cuối của chúng được nối lại, cung cấp cho mô hình ngữ cảnh từ cả hai hướng. Điều này hữu ích khi ý nghĩa phụ thuộc vào những gì đến sau, như "not bad," nơi "not" chỉ có ý nghĩa khi có "bad."
Chuẩn bị văn bản cho mô hình
LSTM cần các chuỗi số nguyên, không phải chuỗi ký tự. Tiền xử lý chuyển văn bản thô qua ba bước:
Xây dựng từ vựng ánh xạ từ sang chỉ số
Chuyển mỗi đánh giá thành một chuỗi chỉ số
Đệm chuỗi về độ dài đồng nhất
defbuild_vocab(texts, max_vocab_size=10000):
counter = Counter()for text in texts:
counter.update(text.lower().split())
vocab ={"<pad>":0,"<unk>":1}for word, _ in counter.most_common(max_vocab_size -2):
vocab[word]=len(vocab)return vocabĐược hỗ trợ bởi
Chúng ta dành chỉ số 0 cho đệm và chỉ số 1 cho từ không biết. Giới hạn kích thước từ vựng giúp lọc các từ hiếm không có đủ ví dụ để học embedding có ý nghĩa.
deftokenize_and_pad(texts, vocab, max_length=200):
sequences =[]for text in texts:
tokens = text.lower().split()
ids =[vocab.get(t, vocab["<unk>"])for t in tokens[:max_length]]
ids = ids +[vocab["<pad>"]]*(max_length -len(ids))
sequences.append(ids)return torch.tensor(sequences, dtype=torch.long)Được hỗ trợ bởi
Cắt ngắn ở max_length giới hạn mức độ LSTM phải nhớ ngược về sau. Chuỗi dài hơn giữ nhiều ngữ cảnh hơn nhưng tăng chi phí tính toán và bộ nhớ. Với đánh giá phim, 100-200 token thường nắm bắt được các tín hiệu cảm xúc chính.
Đệm đảm bảo mọi chuỗi có cùng độ dài, cho phép PyTorch gom chúng thành một tensor duy nhất. Các token đệm trở thành vector 0 sau khi embedding và hầu như không đóng góp vào trạng thái cuối.
Xây dựng từ vựng chỉ từ dữ liệu huấn luyện giúp ngăn rò rỉ thông tin. Nếu một từ hiếm chỉ xuất hiện trong đánh giá kiểm tra, mô hình nên coi nó là không biết thay vì đã học embedding của nó trong huấn luyện.
Huấn luyện LSTM và siêu tham số
Vòng lặp huấn luyện cập nhật trọng số mô hình dựa trên độ sai khác giữa dự đoán và giá trị đúng. Với LSTM, một chi tiết quan trọng hơn thường lệ: cắt gradient.
Trước đó, chúng ta đã giải thích cách LSTM giảm gradient biến mất qua cập nhật cộng vào trạng thái ô. Nhưng gradient bùng nổ vẫn là rủi ro. Khi gradient quá lớn, cập nhật trọng số sẽ vượt quá và làm bất ổn huấn luyện.
clip_grad_norm_ giới hạn tổng độ lớn gradient. Nếu gradient vượt max_norm=5.0, chúng sẽ được co giãn xuống tương ứng. Điều này giữ cập nhật ổn định mà không loại bỏ hoàn toàn tín hiệu gradient.
model.eval() tắt dropout trong đánh giá. torch.no_grad() bỏ qua tính toán gradient vì chúng ta không cập nhật trọng số, giúp tiết kiệm bộ nhớ và tăng tốc suy luận.
hidden_size=32: Đủ nhỏ để lặp nhanh. Mô hình sản xuất thường dùng 128-512, nhưng khi kích thước tăng, lợi ích giảm dần và huấn luyện chậm lại.
embedding_dim=32: Khớp với kích thước ẩn là phổ biến nhưng không bắt buộc. Embedding lớn hơn nắm bắt phân biệt từ tốt hơn với chi phí nhiều tham số hơn.
max_length=100: Phần lớn tín hiệu cảm xúc xuất hiện sớm trong đánh giá. Chuỗi dài hơn giúp các trường hợp tinh tế, nhưng bộ nhớ tăng gấp bốn khi max_length tăng gấp đôi.
batch_size=64: Lô lớn hơn cho ước lượng gradient ổn định hơn. Lô nhỏ hơn có thể giúp thoát cực tiểu cục bộ. 32-128 là điển hình.
lr=0.001: Mặc định của Adam hiệu quả cho hầu hết tác vụ LSTM. Nếu loss dao động, thử 0.0001. Nếu học chậm, thử 0.01.
n_epochs=50: Đủ để mô hình hội tụ. Theo dõi khi độ chính xác kiểm tra đi ngang hoặc giảm trong khi độ chính xác huấn luyện vẫn tăng, báo hiệu quá khớp.
Độ chính xác huấn luyện đạt khoảng 82% trong khi độ chính xác kiểm tra ổn định gần 80%. Mô hình học các mẫu từ dự đoán cảm xúc. Các tính từ mạnh gần cuối có trọng lượng. Phủ định như "not" đảo chiều sắc thái. Một số cụm từ ("waste of time," "highly recommend") trở thành tín hiệu mạnh. Không có gì trong số này được lập trình; nó xuất hiện từ tương quan trong dữ liệu huấn luyện.
Với tinh chỉnh tối thiểu và mô hình nhỏ, độ chính xác 80% là hợp lý. Khoảng cách nhỏ giữa huấn luyện và kiểm tra cho thấy mô hình khái quát tốt mà không quá khớp nghiêm trọng. Thêm dropout, dùng embedding tiền huấn luyện như GloVe, hoặc huấn luyện trên nhiều dữ liệu hơn có thể đẩy độ chính xác lên mức cuối 80%.
Cải thiện hiệu năng mô hình LSTM
Kiến trúc LSTM cơ bản ở phần trước hoạt động tốt, nhưng một số kỹ thuật có thể đẩy độ chính xác cao hơn mà không cần chuyển sang họ mô hình khác. Các cách tiếp cận này đã được kiểm chứng qua hàng nghìn triển khai sản xuất và bài báo nghiên cứu.
LSTM hai chiều
LSTM tiêu chuẩn xử lý chuỗi từ trái sang phải, chỉ xây dựng ngữ cảnh từ quá khứ. LSTM hai chiều (BiLSTM) chạy hai lượt song song: một tiến, một lùi. Biểu diễn cuối cùng tại mỗi bước kết hợp cả những gì đến trước và sau.
self.lstm = nn.LSTM(
input_size=embedding_dim,
hidden_size=hidden_size,
bidirectional=True,# Run both directions
batch_first=True,)# Output size doubles: hidden_size * 2Được hỗ trợ bởi
Với phân tích cảm xúc, điều này quan trọng khi phủ định xuất hiện sau từ mà nó bổ nghĩa: "the movie was not bad" cần ngữ cảnh tiến để biết có "bad," và ngữ cảnh lùi để biết "not" đứng trước nó.
BiLSTM thường vượt trội hơn mô hình một chiều trong nhận dạng thực thể có tên (NER), phân tích cảm xúc và nhận dạng giọng nói, với mức cải thiện điển hình 5-15%.
Đánh đổi: bạn cần toàn bộ chuỗi khi suy luận. Ứng dụng streaming nhận token từng cái một không thể dùng xử lý hai chiều.
Thêm attention
Attention cho phép mô hình gán trọng số cho các bước thời gian quan trọng nhất với một dự đoán. Thay vì nén cả chuỗi vào một trạng thái ẩn cuối cùng, attention tính một tổ hợp có trọng số của tất cả trạng thái ẩn.
Trong một đánh giá như "The acting was wooden, the plot made no sense, but the cinematography was stunning," attention học cách tập trung vào các cụm mang cảm xúc thay vì coi mọi từ là ngang nhau. Mô hình gán trọng số cao hơn cho "wooden," "no sense," và "stunning" trong khi giảm trọng số cho "the" và "was."
Attention thêm chi phí tính toán tối thiểu và thường mang lại cải thiện 2-5% độ chính xác cho các tác vụ phân loại. Với các bài toán chuỗi-đến-chuỗi như dịch máy, attention giữa bộ mã hóa và giải mã gần như bắt buộc để đạt hiệu năng tốt.
Xếp chồng các tầng LSTM
Một tầng LSTM đơn nắm bắt các mẫu ở một mức trừu tượng. Xếp chồng nhiều tầng cho phép mạng học đặc trưng phân cấp: tầng đầu có thể phát hiện mẫu cụm từ cục bộ, còn các tầng cao hơn kết hợp chúng thành hiểu biết cấp tài liệu.
self.lstm = nn.LSTM(
input_size=embedding_dim,
hidden_size=hidden_size,
num_layers=3,# Stack three layers
dropout=0.3,# Dropout between layers (not within)
batch_first=True,)Được hỗ trợ bởi
Hướng dẫn về độ sâu:
1 tầng: Tác vụ đơn giản, dữ liệu nhỏ, lặp nhanh
2 tầng: Đa số ứng dụng sản xuất
3-4 tầng: Phụ thuộc thời gian phức tạp, dữ liệu lớn
Trên 4: Lợi ích giảm dần, huấn luyện kém ổn định
Mỗi tầng bổ sung gần như nhân đôi thời gian huấn luyện. Bắt đầu nông và chỉ thêm độ sâu nếu chỉ số xác thực đi ngang.
Kỹ thuật điều chuẩn
LSTM dễ quá khớp, đặc biệt trên dữ liệu nhỏ. Ba kỹ thuật điều chuẩn hoạt động tốt cùng nhau:
Dropout
Cắt gradient
Dừng sớm
Dropout
Dropout ngẫu nhiên đưa một số nơ-ron về 0 trong huấn luyện, buộc mạng phân tán việc học qua nhiều đường dẫn. Áp dụng dropout giữa các tầng LSTM, không phải bên trong kết nối hồi quy (vì có thể làm gián đoạn học theo thời gian).
# PyTorch applies dropout between stacked layers automatically
self.lstm = nn.LSTM(..., num_layers=2, dropout=0.3)# For single-layer LSTMs, add dropout after
self.dropout = nn.Dropout(0.3)Được hỗ trợ bởi
Tỷ lệ dropout 0.2-0.5 hiệu quả cho hầu hết tác vụ. Giá trị cao hơn giúp khi quá khớp nghiêm trọng nhưng làm chậm hội tụ.
Cắt gradient
Cắt gradient giới hạn độ lớn gradient trong lan truyền ngược. Dù LSTM giảm gradient biến mất, gradient bùng nổ vẫn xảy ra, đặc biệt với chuỗi dài hoặc mạng sâu.
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=5.0)Được hỗ trợ bởi
Giá trị giữa 1.0 và 5.0 là điển hình. Nếu loss huấn luyện tăng đột biến hoặc cho ra giá trị NaN, hãy giảm ngưỡng.
Dừng sớm
Dừng sớm theo dõi loss xác thực và dừng huấn luyện khi nó ngừng cải thiện. Điều này ngăn mô hình ghi nhớ dữ liệu huấn luyện làm giảm khả năng khái quát.
Để xem hướng dẫn đầy đủ về vòng lặp huấn luyện, chỉ số đánh giá và gỡ lỗi các vấn đề thường gặp trong LSTM, hãy xem hướng dẫn NLP với PyTorch.
Embedding tiền huấn luyện
Khởi tạo embedding ngẫu nhiên hoạt động được, nhưng các embedding tiền huấn luyện như GloVe hoặc Word2Vec cho mô hình một xuất phát điểm tốt. Các embedding này mã hóa quan hệ ngữ nghĩa học từ hàng tỷ từ: "king" và "queen" ở gần nhau, cũng như "terrible" và "awful."
import numpy as np
defload_glove_embeddings(glove_path, vocab, embedding_dim):
embeddings = np.random.randn(len(vocab), embedding_dim)*0.01withopen(glove_path,'r')as f:for line in f:
parts = line.split()
word = parts[0]if word in vocab:
embeddings[vocab[word]]= np.array(parts[1:], dtype=np.float32)return torch.tensor(embeddings, dtype=torch.float32)# Load and freeze or fine-tune
pretrained = load_glove_embeddings('glove.6B.100d.txt', vocab,100)
model.embedding.weight.data.copy_(pretrained)
model.embedding.weight.requires_grad =True# Fine-tune during trainingĐược hỗ trợ bởi
Embedding tiền huấn luyện hữu ích nhất khi dữ liệu huấn luyện hạn chế. Với hàng triệu ví dụ, embedding khởi tạo ngẫu nhiên cuối cùng sẽ bắt kịp. Với hầu hết ứng dụng thực tế có 10k-100k mẫu, kỳ vọng tăng 3-8% độ chính xác nhờ khởi tạo tiền huấn luyện.
Kết hợp các kỹ thuật
Các cách tiếp cận này có thể xếp chồng. Một bộ phân loại văn bản cấp sản xuất có thể dùng:
BiLSTM để có ngữ cảnh hai chiều
2 tầng xếp chồng để có đặc trưng phân cấp
Attention pooling thay cho trạng thái ẩn cuối
Embedding GloVe được tinh chỉnh trong huấn luyện
Dropout 0.3 giữa các tầng
Cắt gradient ở 5.0
Dừng sớm với patience 5 epoch
Mỗi bổ sung làm tăng độ phức tạp và thời gian huấn luyện. Bắt đầu với LSTM một tầng cơ bản, đo hiệu năng, sau đó thêm từng kỹ thuật một để xem cái nào mang lại lợi ích cho tác vụ cụ thể của bạn.
LSTM so với Transformer: Chọn kiến trúc phù hợp
LSTM thống trị mô hình hóa chuỗi từ cuối những năm 1990 đến giữa những năm 2010. Bài báo 2017 "Attention Is All You Need" đã thay đổi điều đó. Transformer giờ đang vận hành hầu hết các mô hình ngôn ngữ lớn, nhưng LSTM chưa biến mất. Chúng phù hợp với những ngách khác nhau.
Hạn chế của LSTM
Các phần trước đã nói về cách LSTM xử lý chuỗi từng token một và vì sao cơ chế cổng đó hiệu quả. Ở quy mô lớn, sự phụ thuộc tuần tự này trở thành nút thắt cổ chai. GPU của bạn có thể có hàng nghìn lõi, nhưng phần lớn nhàn rỗi trong khi chuỗi trạng thái ẩn hoàn tất. Một đầu vào 500 token nghĩa là 500 phép toán nối tiếp.
Transformer không có ràng buộc này. Self-attention tính mối quan hệ giữa mọi vị trí đồng thời, nên cùng một chuỗi 500 token được xử lý song song. Trên phần cứng hiện đại với kích thước batch lớn, điều này chuyển thành tăng tốc huấn luyện 10-100 lần.
Giới hạn độ dài chuỗi cũng quan trọng. Ta đã thấy LSTM giữ gradient tốt hơn RNN nguyên bản, nhưng "tốt hơn" không có nghĩa là "hoàn hảo." Hiệu năng vẫn giảm ở khoảng 200-500 token, tùy tác vụ.
Transformer tính attention giữa mọi cặp vị trí trực tiếp, nên token 1 chú ý đến token 1000 một cách dễ dàng như nhau. Đánh đổi là bộ nhớ: ma trận attention tăng theo bình phương độ dài chuỗi.
Kích hoạt cổng cũng khiến việc diễn giải trở nên khó khăn. Giá trị trong khoảng 0 đến 1 mà không có ranh giới rõ ràng. Trọng số attention trong Transformer cũng không phải lời giải thích hoàn hảo, nhưng chúng cho tín hiệu rõ ràng hơn về token đầu vào nào quan trọng với mỗi đầu ra.
Khi nào dùng LSTM so với Transformer
Transformer hợp lý khi:
Dữ liệu huấn luyện vượt 100K ví dụ, và bạn có GPU
Tác vụ liên quan đến phụ thuộc trải dài hàng trăm token
Tốc độ huấn luyện quan trọng cho vòng lặp lặp lại
Có thể tinh chỉnh các mô hình tiền huấn luyện như GPT cho trường hợp của bạn
LSTM vẫn phù hợp khi:
Thiết bị mục tiêu bị giới hạn bộ nhớ (edge, nhúng, di động)
Dự đoán cần diễn ra trên chuỗi một phần trước khi nhận đủ đầu vào
Yêu cầu độ trễ buộc phải dùng mô hình gọn nhẹ
Dự báo chuỗi thời gian nằm đâu đó ở giữa. Các benchmark gần đây cho thấy cả hai kiến trúc có hiệu năng tương tự trên dữ liệu đơn biến với mẫu đều đặn. Transformer vượt trội khi nhiều đặc trưng tương tác phức tạp, còn LSTM trụ vững khi dữ liệu khan hiếm hoặc tài nguyên tính toán hạn hẹp.
Thiết kế lai pha trộn hai cách tiếp cận. Một số kiến trúc xếp chồng tầng LSTM với cơ chế attention. xLSTM, công bố năm 2024, xem xét lại thiết kế gốc với cổng hàm mũ và bộ nhớ ma trận, cho kết quả cạnh tranh với Transformer ở quy mô nhỏ hơn.
Khía cạnh
LSTM
Transformer
Xử lý
Tuần tự (từng token)
Song song (mọi vị trí cùng lúc)
Tốc độ huấn luyện
Chậm hơn (hạn chế song song hóa)
Nhanh hơn trên GPU
Phụ thuộc tầm xa
Suy giảm sau 200-500 token
Xử lý hàng nghìn token
Tỷ lệ bộ nhớ
O(n) theo độ dài chuỗi
O(n²) cho ma trận attention
Hiệu năng với dữ liệu nhỏ
Tốt (ít tham số hơn)
Dễ quá khớp
Triển khai biên
Phù hợp (dấu chân bộ nhớ thấp)
Thách thức (mô hình lớn)
Streaming/thời gian thực
Hỗ trợ tự nhiên
Cần toàn bộ chuỗi
Hệ sinh thái tiền huấn luyện
Hạn chế
Rộng lớn (BERT, GPT, v.v.)
Quyết định thường phụ thuộc vào ràng buộc. Tài nguyên tính toán và dữ liệu không giới hạn? Transformer thắng ở hầu hết tác vụ NLP. Vi điều khiển với 10K ví dụ huấn luyện? LSTM vẫn thực tế.
Kết luận
LSTM đã giải một vấn đề thực khi ra đời năm 1997. Cơ chế cổng do Hochreiter và Schmidhuber giới thiệu cho phép mạng cuối cùng học từ các chuỗi dài hơn vài chục token. Kiến trúc đó đã thúc đẩy dịch máy, nhận dạng giọng nói và dự báo chuỗi thời gian trong gần hai thập kỷ.
Transformer hiện xử lý hầu hết tác vụ NLP quy mô lớn, nhưng LSTM chưa lỗi thời. Chúng vẫn hợp lý cho triển khai biên, ứng dụng streaming và tình huống dữ liệu huấn luyện hạn chế.
Nếu bạn bắt đầu một dự án mô hình hóa chuỗi mới, hãy thử một LSTM đơn giản trước. Đo lường hiệu năng, hiểu các chế độ thất bại của nó, rồi quyết định liệu vấn đề có thực sự cần Transformer hay không. Các khái niệm từ hướng dẫn này (cổng, trạng thái ô, dòng chảy gradient) chuyển giao trực tiếp sang việc hiểu các kiến trúc phức tạp hơn.
Để luyện tập thực hành, tôi khuyên bạn tham gia khóa học Mạng nơ-ron hồi quy, khóa học này hướng dẫn thêm về các ứng dụng LSTM với bài tập có hướng dẫn.
Câu hỏi thường gặp về LSTM
Sự khác biệt giữa LSTM và RNN thông thường là gì?⌄
RNN thông thường gặp khó với chuỗi dài vì gradient thu nhỏ trong quá trình lan truyền ngược, làm mất khả năng học từ ngữ cảnh xa. LSTM thêm trạng thái ô với cơ chế cổng kiểm soát luồng thông tin, cho phép mạng giữ ngữ cảnh liên quan qua hàng trăm bước thời gian thay vì chỉ 20-30.
Khi nào tôi nên dùng LSTM thay vì Transformer?⌄
LSTM hoạt động tốt hơn khi bạn có dữ liệu huấn luyện hạn chế (dưới 10K ví dụ), cần chạy trên thiết bị hạn chế bộ nhớ như di động hoặc hệ nhúng, yêu cầu dự đoán thời gian thực trên dữ liệu streaming trước khi nhận đủ chuỗi, hoặc có yêu cầu độ trễ nghiêm ngặt khiến các mô hình lớn bị loại trừ.
hidden_size trong PyTorch LSTM có ý nghĩa gì?⌄
Tham số hidden_size xác định số chiều của cả vector trạng thái ẩn và trạng thái ô. Giá trị lớn hơn cho phép mô hình theo dõi nhiều mẫu hơn, nhưng tăng chi phí tính toán và bộ nhớ. Phổ biến là 32-512, với 128-256 thường dùng trong ứng dụng văn bản sản xuất.
Làm sao để ngăn mô hình LSTM bị quá khớp?⌄
Dùng dropout giữa các tầng LSTM (tỷ lệ 0.2-0.5), áp dụng cắt gradient để ngăn gradient bùng nổ, triển khai dừng sớm để dừng huấn luyện khi loss xác thực ngừng cải thiện, và cân nhắc dùng embedding tiền huấn luyện như GloVe nếu bộ dữ liệu nhỏ.
LSTM hai chiều là gì và khi nào nên dùng?⌄
LSTM hai chiều chạy hai lượt qua chuỗi: một tiến và một lùi. Điều này cho mỗi vị trí ngữ cảnh từ cả hai hướng, hữu ích khi ý nghĩa phụ thuộc vào các token tương lai (như "not bad" nơi "not" cần thấy "bad"). Hãy dùng cho các tác vụ phân loại và gán nhãn nơi bạn có toàn bộ chuỗi khi suy luận, nhưng tránh dùng cho ứng dụng streaming.
Tôi là người sáng tạo nội dung về khoa học dữ liệu với hơn 2 năm kinh nghiệm và là một trong những tài khoản có lượng người theo dõi lớn nhất trên Medium. Tôi thích viết các bài chuyên sâu về AI và ML với chút giọng điệu mỉa mai, vì bạn cũng phải làm gì đó để chúng bớt khô khan. Tôi đã xuất bản hơn 130 bài viết và một khóa học trên DataCamp, cùng với một khóa nữa đang được thực hiện. Nội dung của tôi đã được hơn 5 triệu lượt xem, trong đó 20 nghìn người đã trở thành người theo dõi trên cả Medium và LinkedIn.
Học cách xây dựng mạng nơ-ron đầu tiên của bạn, điều chỉnh các tham số siêu (hyperparameters) và giải quyết các vấn đề phân loại và hồi quy trong PyTorch.
Các mạng nơ-ron hồi quy tiêu chuẩn gặp khó khăn với trí nhớ. Khi chuỗis vượt quá 20-30 bước thời gian, gradient hoặc thu nhỏ về 0 hoặc bùng nổ trong quá trình lan truyền ngược, và mạng mất khả năng kết nối các phần xa nhau của đầu vào. Hochreiter và Schmidhuber đã giải quyết vấn đề này trong bài báo năm 1997 bằng cách giới thiệu mạng Bộ nhớ Ngắn-Dài hạn (LSTM).
Trong hướng dẫn này, tôi sẽ đi qua phần nội tại của LSTM trước khi chuyển sang triển khai thực tế bằng Python. Các phần cuối sẽ so sánh LSTM với Transformer để bạn có thể chọn kiến trúc phù hợp cho trường hợp sử dụng của mình.
Tôi rất khuyến nghị khóa học Giới thiệu về Học sâu với PyTorch của chúng tôi để có trải nghiệm thực hành sử dụng PyTorch để huấn luyện mạng nơ-ron, vốn là nền tảng cho các mô hình LSTM.
Mô hình LSTM là gì?
LSTM là viết tắt của Long Short-Term Memory (Bộ nhớ Ngắn-Dài hạn), một loại mạng nơ-ron hồi quy (RNN) được thiết kế để xử lý các chuỗi mà ngữ cảnh từ rất sớm trong đầu vào vẫn còn quan trọng.
Ý tưởng cốt lõi đằng sau LSTM là cơ chế cổng (gating) điều tiết luồng thông tin qua mạng. Thay vì để mọi tín hiệu đi qua như nhau, các cổng học khi nào cần giữ ngữ cảnh và khi nào nên bỏ qua.
Bộ nhớ có chọn lọc này cho phép LSTM theo dõi các phụ thuộc qua hàng trăm bước thời gian, điều này tỏ ra hữu ích cho mô hình ngôn ngữ, nhận dạng giọng nói và dự báo chuỗi thời gian. Để hiểu vì sao kiến trúc này tồn tại, sẽ hữu ích khi xem điều gì bị hỏng ở RNN tiêu chuẩn.
Vấn đề gradient biến mất trong RNN
Mạng hồi quy truyền thông tin từ bước thời gian này sang bước tiếp theo thông qua trạng thái ẩn. Mỗi bước nhân trạng thái này với trọng số học được, cập nhật nó, rồi truyền tiếp. Huấn luyện yêu cầu gửi tín hiệu lỗi ngược qua tất cả các bước đó, và mỗi lần lan truyền ngược làm tín hiệu nhỏ đi một chút. Sau đủ nhiều bước, gần như không còn gì.
Nó giống như photocopy một bản photocopy. Làm vài lần thì bản sao vẫn ổn. Làm năm mươi lần, bạn hầu như không đọc được. RNN gặp bức tường này ở khoảng 20-30 bước thời gian, đó là lý do chúng khó xử lý các chuỗi dài hơn.
Cách LSTM giải quyết các phụ thuộc dài hạn
LSTM thêm một đường bộ nhớ riêng, gọi là trạng thái ô (cell state), chạy song song với trạng thái ẩn tiêu chuẩn. Khác biệt nằm ở cấu trúc: thông tin trong trạng thái ô chảy qua phép cộng thay vì nhân lặp đi lặp lại, vì vậy nó không bị suy giảm theo cách cũ.
Để kiểm soát những gì đi vào và đi ra khỏi bộ nhớ này, LSTM sử dụng các cổng. Mỗi cổng là một mạng nơ-ron nhỏ học cách xuất ra giá trị trong khoảng 0 đến 1, hoạt động như một bộ lọc. Giá trị gần 0 chặn thông tin; giá trị gần 1 cho phép thông tin đi qua. Mạng học trong quá trình huấn luyện xem các mẫu nào đáng nhớ qua chuỗi dài và mẫu nào có thể bỏ qua.
Cơ chế cổng này là điều tách biệt LSTM với RNN nguyên bản. Thay vì bắt buộc mọi thông tin đi cùng một đường, LSTM có thể chọn lọc giữ ngữ cảnh qua hàng trăm bước. Phần tiếp theo sẽ phân tích chính xác cách các cổng này hoạt động và cách chúng kết hợp để cập nhật trạng thái ô.
Các trường hợp sử dụng mô hình LSTM
LSTM xuất hiện ở bất cứ nơi nào dữ liệu tuần tự quan trọng. Một vài ví dụ vượt ra ngoài các ứng dụng NLP và dự báo thường thấy:
Kiến trúc LSTM: Các cổng và ô nhớ
Phần này trình bày chi tiết nội tại của LSTM. Nếu bạn muốn nhảy thẳng đến triển khai, hãy chuyển sang phần tiếp theo. Chi tiết kiến trúc ở đây không bắt buộc để sử dụng LSTM, nhưng hữu ích khi gỡ lỗi hoặc tinh chỉnh.
Để hiểu LSTM hoạt động thế nào, chúng ta sẽ truy vết một ví dụ cụ thể: xử lý chuỗi "The clouds are dark..." để dự đoán từ tiếp theo. Mỗi thành phần sẽ dễ hiểu hơn khi bạn thấy nó làm gì với dữ liệu thực.
Trạng thái ô và trạng thái ẩn trong LSTM
Một LSTM duy trì hai vector riêng biệt chảy xuyên suốt mạng: trạng thái ô và trạng thái ẩn.
Trạng thái ô đóng vai trò lưu trữ dài hạn. Nó mang thông tin qua các bước thời gian với các điều chỉnh có kiểm soát ở mỗi bước. Khi xử lý chuỗi của chúng ta, trạng thái ô có thể lưu "xuất hiện danh từ liên quan đến thời tiết" sau khi thấy "clouds" và giữ ngữ cảnh đó qua "are", cho đến khi "dark" củng cố mẫu này.
Trạng thái ẩn là đầu ra của ô tại mỗi bước thời gian. Nó đi vào dự đoán và vào phép tính của bước tiếp theo. Sau khi xử lý "dark," trạng thái ẩn mã hóa điều gì đó như "tính từ mô tả điều kiện thời tiết" mà một tầng dự đoán có thể sử dụng.
Vì sao có hai đường riêng? Một trạng thái đơn lẻ sẽ cần đồng thời giữ ngữ cảnh dài hạn và tạo ra đầu ra hữu ích. Hai mục tiêu này mâu thuẫn: bộ nhớ ổn định cần thay đổi tối thiểu, trong khi đầu ra hữu ích cần biến đổi. Tách chúng ra cho phép mỗi đường tối ưu cho mục đích riêng.
Ở mỗi bước thời gian, ô nhận ba đầu vào và tạo ra hai đầu ra:
Đầu vào:
Trạng thái ô trước đó (
C_{t-1}): những gì mạng đã nhớ đến hiện tạiTrạng thái ẩn trước đó (
h_{t-1}): đầu ra của bước trướcĐầu vào hiện tại (
x_t): token mới, như "clouds" hoặc "dark"Đầu ra:
Trạng thái ô đã cập nhật (
C_t): bộ nhớ sau khi xử lý token nàyTrạng thái ẩn mới (
h_t): đầu ra của bước thời gian nàyCách các cổng của LSTM tính toán
Bốn thành phần kiểm soát những gì xảy ra bên trong ô. Ba trong số đó là các cổng xuất giá trị trong khoảng 0 đến 1, hoạt động như bộ lọc. Thành phần thứ tư là ứng viên (candidate), đề xuất nội dung mới.
Khi "are" đến sau "clouds," mỗi thành phần có một nhiệm vụ:
Cổng quên (
f_t): Chúng ta có nên giữ ngữ cảnh "clouds" không? Danh từ thời tiết theo sau động từ nối thường quan trọng, nên cổng quên xuất các giá trị gần 1 để giữ phần lớn trạng thái ô.Cổng vào (
i_t): "are" nên đóng góp vào bộ nhớ bao nhiêu? Động từ nối mang tín hiệu dự đoán thấp hơn, nên cổng vào xuất giá trị thấp.Ứng viên (
C̃_t): "are" có thể thêm thông tin gì? Ứng viên đề xuất nội dung, nhưng cổng vào sẽ giảm cường độ nó.Cổng ra (
o_t): Trạng thái ẩn nên hiển thị gì? Cổng ra lọc trạng thái ô để tạoh_t.Mỗi thành phần tính đầu ra theo cùng một cách:
Nối
h_{t-1}vàx_tthành một vectorNhân với một ma trận trọng số học được
Cộng một hằng số độ lệch (bias)
Áp dụng hàm kích hoạt
Các cổng dùng kích hoạt sigmoid, nén giá trị vào khoảng 0-1. Ứng viên dùng tanh, xuất ra các giá trị giữa -1 và 1, nên có thể đề xuất cả tăng và giảm cho trạng thái ô.
Các phương trình
Cổng quên (sigmoid → 0 đến 1):
Cổng vào (sigmoid → 0 đến 1):
Cổng ra (sigmoid → 0 đến 1):
Ứng viên (tanh → -1 đến +1):
Mỗi thành phần có ma trận trọng số riêng (
W_f,W_i,W_c,W_o), nên chúng học phản hồi với các mẫu khác nhau trong đầu vào.Cách hoạt động của lọc
Đầu ra của cổng nhân với các vector theo từng vị trí (nhân từng phần tử, ký hiệu
⊙). Mỗi chiều được lọc độc lập.Nếu một cổng xuất 0.9 cho vị trí 1, chiều đó giữ 90% giá trị. Nếu nó xuất 0.0 cho vị trí 4, chiều đó bị xóa. Khi xử lý "dark" sau "clouds are," cổng quên có thể xuất giá trị cao cho các chiều lưu ngữ cảnh danh từ/thời tiết và giá trị thấp hơn cho các chiều chứa ngữ cảnh trước đó không liên quan.
Dòng chảy thông tin giữa các cổng quên, cộng và ra
Các thành phần kết hợp trong ba bước để cập nhật trạng thái ô và tạo ra trạng thái ẩn.
Bước 1: Quên
Cổng quên lọc trạng thái ô trước đó:
Khi xử lý "dark," cổng quên giữ ngữ cảnh thời tiết từ "clouds" đồng thời xóa các chiều theo dõi mạo từ "The."
Bước 2: Cộng
Cổng vào co giãn đề xuất của ứng viên, rồi cộng nó vào trạng thái ô đã được lọc:
Ứng viên có thể đề xuất "tính từ bổ nghĩa danh từ thời tiết," và cổng vào quyết định mức độ ghi điều đó vào bộ nhớ. Cập nhật dạng cộng (không phải nhân) này giúp gradient chảy tốt hơn trong huấn luyện.
Bước 3: Ra
Trạng thái ô đi qua tanh, sau đó cổng ra lọc phần trở thành trạng thái ẩn:
Hàm tanh giữ giá trị trong giới hạn. Cổng ra chọn những khía cạnh nào của bộ nhớ tích lũy sẽ hiển thị để dự đoán ở bước thời gian này.
Trình tự hoàn chỉnh:
Dưới đây là một truy vết giản lược với trạng thái ô có 4 chiều:
Bước
Đầu vào
Trạng thái ô (giản lược)
Điều xảy ra
1
"The"
[0.1, 0.0, 0.2, 0.0]
Lưu trữ tối thiểu; mạo từ mang ít tín hiệu dự đoán
2
"clouds"
[0.1, 0.7, 0.2, 0.3]
Cổng vào mở cho các chiều 2,4; lưu mẫu danh từ
3
"are"
[0.1, 0.6, 0.2, 0.3]
Cổng quên ≈ 0.9 giữ ngữ cảnh; động từ nối thêm rất ít
4
"dark"
[0.1, 0.8, 0.5, 0.6]
Tính từ làm mạnh tín hiệu ở các chiều 2,3,4
Đến bước thời gian 4, các chiều 2-4 đã tích lũy được một mẫu. Trạng thái ẩn
h_4đi vào một tầng dự đoán (không phải phần của LSTM), tầng này sinh ra xác suất từ vựng. Mẫu tích lũy đó giúp mô hình ưu tiên các từ như "rain" hoặc "sky."Mạng không hiểu về thời tiết. Nó học các tương quan thống kê: một số chuỗi đầu vào có xu hướng đi trước một số đầu ra nhất định.
Dòng chảy gradient trong huấn luyện
Cấu trúc cộng của trạng thái ô cung cấp một đường dẫn gradient trực tiếp hơn so với RNN tiêu chuẩn. Nếu bạn chưa quen với cách gradient lan truyền qua mạng nơ-ron, hướng dẫn lan truyền ngược bao gồm các nền tảng cơ bản.
Trong RNN tiêu chuẩn, gradient chảy qua ma trận trọng số ở mỗi bước. Phép nhân lặp lại cộng dồn: sau 100 bước với trọng số trung bình 0.9, gradient thu nhỏ còn
0.9^100 ≈ 0.00003.LSTM cung cấp một đường dẫn thay thế dọc theo trạng thái ô. Đạo hàm của
C_ttheoC_{t-1}:Đây là giá trị cổng quên, không phải ma trận trọng số. Khi cổng quên duy trì gần 1, gradient đi qua với ít suy giảm hơn. Nếu cổng trung bình 0.95, sau 100 bước:
0.95^100 ≈ 0.006. Vẫn giảm, nhưng có thể sử dụng.Khía cạnh
RNN
LSTM
Đường gradient
Chỉ qua ma trận trọng số
Đường bổ sung dọc theo trạng thái ô
Gradient 100 bước
~10^-5 (biến mất)
~10^-2 đến 10^-1 (dùng được)
Bộ nhớ thực tế
~10-20 bước thời gian
~50-200 bước thời gian
Ghi chú thực tiễn: Bias của cổng quên thường được khởi tạo ở 1.0 hoặc cao hơn, đẩy đầu ra ban đầu về phía "ghi nhớ mọi thứ." Điều này giúp mạng học các mẫu dài hạn sớm trong quá trình huấn luyện.
LSTM giảm thiểu vấn đề gradient biến mất chứ không loại bỏ hoàn toàn. Cải thiện đến từ cập nhật trạng thái ô dạng cộng, cung cấp một "đường cao tốc" cho gradient song song với các đường dẫn tiêu chuẩn.
Cách triển khai mô hình LSTM trong Python
Phần trước đã trình bày những gì diễn ra trong một ô LSTM: các cổng lọc thông tin, trạng thái ô giữ ngữ cảnh, và trạng thái ẩn tạo ra đầu ra. Giờ chúng ta sẽ xem
nn.LSTMcủa PyTorch gói gọn tất cả vào một mô-đun đơn và dùng nó để phân loại đánh giá phim là tích cực hay tiêu cực.Mẹo để chạy mã: Huấn luyện 50 epoch trên CPU sẽ rất lâu. Hãy dùng Google Colab hoặc Kaggle Notebooks với tăng tốc GPU để có kết quả nhanh hơn. Toàn bộ script có sẵn dưới dạng GitHub Gist.
Xây dựng bộ phân loại LSTM với PyTorch
Phân loại văn bản với LSTM theo một khuôn mẫu: chuyển từ thành vector, để LSTM xử lý tuần tự, sau đó dùng đầu ra cuối cùng cho dự đoán.
Nhúng từ thành vector
Mạng nơ-ron hoạt động trên các số liên tục, còn từ là ký hiệu rời rạc. Ta không thể đưa trực tiếp "terrible" vào phép nhân ma trận. Giải pháp là một tầng embedding: một bảng truy xuất nơi mỗi từ ánh xạ tới một vector có thể học được.
Nếu bạn chọn
embedding_dim=32, mỗi từ trở thành một vector 32 chiều. Ở đầu quá trình huấn luyện, các vector này là ngẫu nhiên. Khi mô hình học, các từ có sắc thái cảm xúc tương tự sẽ xích lại gần nhau trong không gian vector này. "Terrible," "awful," và "boring" có thể ở gần nhau, trong khi "excellent" và "amazing" tụ lại nơi khác.Tham số
padding_idxbáo cho tầng giữ các token đệm ở vector 0, để chúng không ảnh hưởng đến mô hình.Định nghĩa kiến trúc LSTM
Chỉ một dòng này tạo ra toàn bộ cơ chế cổng từ phần trước.
hidden_sizequyết định lượng thông tin trạng thái ô và trạng thái ẩn có thể mang. Giá trị lớn hơn cho phép mô hình theo dõi nhiều mẫu hơn nhưng tốn tính toán hơn.Thiết lập
batch_first=Truenghĩa là đầu vào có dạng(batch, sequence_length, embedding_dim). LSTM xử lý từng vị trí từ trái sang phải, cập nhật trạng thái nội tại ở mỗi bước.Xử lý chuỗi
Sau khi xử lý "This movie was absolutely terrible," LSTM đã thấy mọi từ. Trạng thái ẩn cuối cùng đã tích lũy những gì mô hình học được từ chuỗi đó. Với cảm xúc, điều này có thể mã hóa điều gì đó như "tính từ tiêu cực mạnh ở cuối, phủ định nội dung trung tính trước đó."
LSTM trả về cả đầu ra theo từng bước (
lstm_out) và trạng thái cuối cùng (h_n,c_n). Với phân loại, ta chỉ cầnh_n[-1], trạng thái ẩn sau token cuối. Một tầng tuyến tính sau đó ánh xạ nó thành điểm lớp.Truy vết một đánh giá qua mô hình
Khi "This movie was terrible" đi vào bộ phân loại:
Mỗi từ nhận embedding của nó: bốn vector dạng
(32,)LSTM xử lý chúng tuần tự. "This" khởi tạo một phần trạng thái ô. "Movie" cập nhật nó một chút. "Was" trung tính và thay đổi ít. "Terrible" kích hoạt cổng quên để xóa ngữ cảnh không liên quan và cổng vào để ghi tín hiệu tiêu cực mạnh.
Trạng thái ẩn cuối cùng nắm bắt mẫu tích lũy.
Tầng tuyến tính ánh xạ nó thành hai điểm: một cho tích cực, một cho tiêu cực
Mô hình không hiểu ngôn ngữ. Nó học các mẫu thống kê: một số chuỗi từ tương quan với một số nhãn nhất định.
Lớp mô hình đầy đủ
Bên dưới là toàn bộ lớp
LSTMClassifiermà chúng ta vừa tạo từng bước:Tùy chọn hai chiều chạy hai LSTM: một từ trái sang phải, một từ phải sang trái. Trạng thái ẩn cuối của chúng được nối lại, cung cấp cho mô hình ngữ cảnh từ cả hai hướng. Điều này hữu ích khi ý nghĩa phụ thuộc vào những gì đến sau, như "not bad," nơi "not" chỉ có ý nghĩa khi có "bad."
Chuẩn bị văn bản cho mô hình
LSTM cần các chuỗi số nguyên, không phải chuỗi ký tự. Tiền xử lý chuyển văn bản thô qua ba bước:
Chúng ta dành chỉ số 0 cho đệm và chỉ số 1 cho từ không biết. Giới hạn kích thước từ vựng giúp lọc các từ hiếm không có đủ ví dụ để học embedding có ý nghĩa.
Cắt ngắn ở
max_lengthgiới hạn mức độ LSTM phải nhớ ngược về sau. Chuỗi dài hơn giữ nhiều ngữ cảnh hơn nhưng tăng chi phí tính toán và bộ nhớ. Với đánh giá phim, 100-200 token thường nắm bắt được các tín hiệu cảm xúc chính.Đệm đảm bảo mọi chuỗi có cùng độ dài, cho phép PyTorch gom chúng thành một tensor duy nhất. Các token đệm trở thành vector 0 sau khi embedding và hầu như không đóng góp vào trạng thái cuối.
Xây dựng từ vựng chỉ từ dữ liệu huấn luyện giúp ngăn rò rỉ thông tin. Nếu một từ hiếm chỉ xuất hiện trong đánh giá kiểm tra, mô hình nên coi nó là không biết thay vì đã học embedding của nó trong huấn luyện.
Huấn luyện LSTM và siêu tham số
Vòng lặp huấn luyện cập nhật trọng số mô hình dựa trên độ sai khác giữa dự đoán và giá trị đúng. Với LSTM, một chi tiết quan trọng hơn thường lệ: cắt gradient.
Vì sao cắt gradient quan trọng với LSTM
Trước đó, chúng ta đã giải thích cách LSTM giảm gradient biến mất qua cập nhật cộng vào trạng thái ô. Nhưng gradient bùng nổ vẫn là rủi ro. Khi gradient quá lớn, cập nhật trọng số sẽ vượt quá và làm bất ổn huấn luyện.
clip_grad_norm_giới hạn tổng độ lớn gradient. Nếu gradient vượtmax_norm=5.0, chúng sẽ được co giãn xuống tương ứng. Điều này giữ cập nhật ổn định mà không loại bỏ hoàn toàn tín hiệu gradient.model.eval()tắt dropout trong đánh giá.torch.no_grad()bỏ qua tính toán gradient vì chúng ta không cập nhật trọng số, giúp tiết kiệm bộ nhớ và tăng tốc suy luận.Chọn siêu tham số
Các giá trị này phản ánh đánh đổi:
hidden_size=32: Đủ nhỏ để lặp nhanh. Mô hình sản xuất thường dùng 128-512, nhưng khi kích thước tăng, lợi ích giảm dần và huấn luyện chậm lại.embedding_dim=32: Khớp với kích thước ẩn là phổ biến nhưng không bắt buộc. Embedding lớn hơn nắm bắt phân biệt từ tốt hơn với chi phí nhiều tham số hơn.max_length=100: Phần lớn tín hiệu cảm xúc xuất hiện sớm trong đánh giá. Chuỗi dài hơn giúp các trường hợp tinh tế, nhưng bộ nhớ tăng gấp bốn khimax_lengthtăng gấp đôi.batch_size=64: Lô lớn hơn cho ước lượng gradient ổn định hơn. Lô nhỏ hơn có thể giúp thoát cực tiểu cục bộ. 32-128 là điển hình.lr=0.001: Mặc định của Adam hiệu quả cho hầu hết tác vụ LSTM. Nếu loss dao động, thử 0.0001. Nếu học chậm, thử 0.01.n_epochs=50: Đủ để mô hình hội tụ. Theo dõi khi độ chính xác kiểm tra đi ngang hoặc giảm trong khi độ chính xác huấn luyện vẫn tăng, báo hiệu quá khớp.Mô hình học được gì
Chạy cấu hình này cho ra đầu ra như:
Độ chính xác huấn luyện đạt khoảng 82% trong khi độ chính xác kiểm tra ổn định gần 80%. Mô hình học các mẫu từ dự đoán cảm xúc. Các tính từ mạnh gần cuối có trọng lượng. Phủ định như "not" đảo chiều sắc thái. Một số cụm từ ("waste of time," "highly recommend") trở thành tín hiệu mạnh. Không có gì trong số này được lập trình; nó xuất hiện từ tương quan trong dữ liệu huấn luyện.
Với tinh chỉnh tối thiểu và mô hình nhỏ, độ chính xác 80% là hợp lý. Khoảng cách nhỏ giữa huấn luyện và kiểm tra cho thấy mô hình khái quát tốt mà không quá khớp nghiêm trọng. Thêm dropout, dùng embedding tiền huấn luyện như GloVe, hoặc huấn luyện trên nhiều dữ liệu hơn có thể đẩy độ chính xác lên mức cuối 80%.
Cải thiện hiệu năng mô hình LSTM
Kiến trúc LSTM cơ bản ở phần trước hoạt động tốt, nhưng một số kỹ thuật có thể đẩy độ chính xác cao hơn mà không cần chuyển sang họ mô hình khác. Các cách tiếp cận này đã được kiểm chứng qua hàng nghìn triển khai sản xuất và bài báo nghiên cứu.
LSTM hai chiều
LSTM tiêu chuẩn xử lý chuỗi từ trái sang phải, chỉ xây dựng ngữ cảnh từ quá khứ. LSTM hai chiều (BiLSTM) chạy hai lượt song song: một tiến, một lùi. Biểu diễn cuối cùng tại mỗi bước kết hợp cả những gì đến trước và sau.
Với phân tích cảm xúc, điều này quan trọng khi phủ định xuất hiện sau từ mà nó bổ nghĩa: "the movie was not bad" cần ngữ cảnh tiến để biết có "bad," và ngữ cảnh lùi để biết "not" đứng trước nó.
BiLSTM thường vượt trội hơn mô hình một chiều trong nhận dạng thực thể có tên (NER), phân tích cảm xúc và nhận dạng giọng nói, với mức cải thiện điển hình 5-15%.
Đánh đổi: bạn cần toàn bộ chuỗi khi suy luận. Ứng dụng streaming nhận token từng cái một không thể dùng xử lý hai chiều.
Thêm attention
Attention cho phép mô hình gán trọng số cho các bước thời gian quan trọng nhất với một dự đoán. Thay vì nén cả chuỗi vào một trạng thái ẩn cuối cùng, attention tính một tổ hợp có trọng số của tất cả trạng thái ẩn.
Trong một đánh giá như "The acting was wooden, the plot made no sense, but the cinematography was stunning," attention học cách tập trung vào các cụm mang cảm xúc thay vì coi mọi từ là ngang nhau. Mô hình gán trọng số cao hơn cho "wooden," "no sense," và "stunning" trong khi giảm trọng số cho "the" và "was."
Attention thêm chi phí tính toán tối thiểu và thường mang lại cải thiện 2-5% độ chính xác cho các tác vụ phân loại. Với các bài toán chuỗi-đến-chuỗi như dịch máy, attention giữa bộ mã hóa và giải mã gần như bắt buộc để đạt hiệu năng tốt.
Xếp chồng các tầng LSTM
Một tầng LSTM đơn nắm bắt các mẫu ở một mức trừu tượng. Xếp chồng nhiều tầng cho phép mạng học đặc trưng phân cấp: tầng đầu có thể phát hiện mẫu cụm từ cục bộ, còn các tầng cao hơn kết hợp chúng thành hiểu biết cấp tài liệu.
Hướng dẫn về độ sâu:
Mỗi tầng bổ sung gần như nhân đôi thời gian huấn luyện. Bắt đầu nông và chỉ thêm độ sâu nếu chỉ số xác thực đi ngang.
Kỹ thuật điều chuẩn
LSTM dễ quá khớp, đặc biệt trên dữ liệu nhỏ. Ba kỹ thuật điều chuẩn hoạt động tốt cùng nhau:
Dropout
Dropout ngẫu nhiên đưa một số nơ-ron về 0 trong huấn luyện, buộc mạng phân tán việc học qua nhiều đường dẫn. Áp dụng dropout giữa các tầng LSTM, không phải bên trong kết nối hồi quy (vì có thể làm gián đoạn học theo thời gian).
Tỷ lệ dropout 0.2-0.5 hiệu quả cho hầu hết tác vụ. Giá trị cao hơn giúp khi quá khớp nghiêm trọng nhưng làm chậm hội tụ.
Cắt gradient
Cắt gradient giới hạn độ lớn gradient trong lan truyền ngược. Dù LSTM giảm gradient biến mất, gradient bùng nổ vẫn xảy ra, đặc biệt với chuỗi dài hoặc mạng sâu.
Giá trị giữa 1.0 và 5.0 là điển hình. Nếu loss huấn luyện tăng đột biến hoặc cho ra giá trị
NaN, hãy giảm ngưỡng.Dừng sớm
Dừng sớm theo dõi loss xác thực và dừng huấn luyện khi nó ngừng cải thiện. Điều này ngăn mô hình ghi nhớ dữ liệu huấn luyện làm giảm khả năng khái quát.
Để xem hướng dẫn đầy đủ về vòng lặp huấn luyện, chỉ số đánh giá và gỡ lỗi các vấn đề thường gặp trong LSTM, hãy xem hướng dẫn NLP với PyTorch.
Embedding tiền huấn luyện
Khởi tạo embedding ngẫu nhiên hoạt động được, nhưng các embedding tiền huấn luyện như GloVe hoặc Word2Vec cho mô hình một xuất phát điểm tốt. Các embedding này mã hóa quan hệ ngữ nghĩa học từ hàng tỷ từ: "king" và "queen" ở gần nhau, cũng như "terrible" và "awful."
Embedding tiền huấn luyện hữu ích nhất khi dữ liệu huấn luyện hạn chế. Với hàng triệu ví dụ, embedding khởi tạo ngẫu nhiên cuối cùng sẽ bắt kịp. Với hầu hết ứng dụng thực tế có 10k-100k mẫu, kỳ vọng tăng 3-8% độ chính xác nhờ khởi tạo tiền huấn luyện.
Kết hợp các kỹ thuật
Các cách tiếp cận này có thể xếp chồng. Một bộ phân loại văn bản cấp sản xuất có thể dùng:
Mỗi bổ sung làm tăng độ phức tạp và thời gian huấn luyện. Bắt đầu với LSTM một tầng cơ bản, đo hiệu năng, sau đó thêm từng kỹ thuật một để xem cái nào mang lại lợi ích cho tác vụ cụ thể của bạn.
LSTM so với Transformer: Chọn kiến trúc phù hợp
LSTM thống trị mô hình hóa chuỗi từ cuối những năm 1990 đến giữa những năm 2010. Bài báo 2017 "Attention Is All You Need" đã thay đổi điều đó. Transformer giờ đang vận hành hầu hết các mô hình ngôn ngữ lớn, nhưng LSTM chưa biến mất. Chúng phù hợp với những ngách khác nhau.
Hạn chế của LSTM
Các phần trước đã nói về cách LSTM xử lý chuỗi từng token một và vì sao cơ chế cổng đó hiệu quả. Ở quy mô lớn, sự phụ thuộc tuần tự này trở thành nút thắt cổ chai. GPU của bạn có thể có hàng nghìn lõi, nhưng phần lớn nhàn rỗi trong khi chuỗi trạng thái ẩn hoàn tất. Một đầu vào 500 token nghĩa là 500 phép toán nối tiếp.
Transformer không có ràng buộc này. Self-attention tính mối quan hệ giữa mọi vị trí đồng thời, nên cùng một chuỗi 500 token được xử lý song song. Trên phần cứng hiện đại với kích thước batch lớn, điều này chuyển thành tăng tốc huấn luyện 10-100 lần.
Giới hạn độ dài chuỗi cũng quan trọng. Ta đã thấy LSTM giữ gradient tốt hơn RNN nguyên bản, nhưng "tốt hơn" không có nghĩa là "hoàn hảo." Hiệu năng vẫn giảm ở khoảng 200-500 token, tùy tác vụ.
Transformer tính attention giữa mọi cặp vị trí trực tiếp, nên token 1 chú ý đến token 1000 một cách dễ dàng như nhau. Đánh đổi là bộ nhớ: ma trận attention tăng theo bình phương độ dài chuỗi.
Kích hoạt cổng cũng khiến việc diễn giải trở nên khó khăn. Giá trị trong khoảng 0 đến 1 mà không có ranh giới rõ ràng. Trọng số attention trong Transformer cũng không phải lời giải thích hoàn hảo, nhưng chúng cho tín hiệu rõ ràng hơn về token đầu vào nào quan trọng với mỗi đầu ra.
Khi nào dùng LSTM so với Transformer
Transformer hợp lý khi:
LSTM vẫn phù hợp khi:
Dự báo chuỗi thời gian nằm đâu đó ở giữa. Các benchmark gần đây cho thấy cả hai kiến trúc có hiệu năng tương tự trên dữ liệu đơn biến với mẫu đều đặn. Transformer vượt trội khi nhiều đặc trưng tương tác phức tạp, còn LSTM trụ vững khi dữ liệu khan hiếm hoặc tài nguyên tính toán hạn hẹp.
Thiết kế lai pha trộn hai cách tiếp cận. Một số kiến trúc xếp chồng tầng LSTM với cơ chế attention. xLSTM, công bố năm 2024, xem xét lại thiết kế gốc với cổng hàm mũ và bộ nhớ ma trận, cho kết quả cạnh tranh với Transformer ở quy mô nhỏ hơn.
Khía cạnh
LSTM
Transformer
Xử lý
Tuần tự (từng token)
Song song (mọi vị trí cùng lúc)
Tốc độ huấn luyện
Chậm hơn (hạn chế song song hóa)
Nhanh hơn trên GPU
Phụ thuộc tầm xa
Suy giảm sau 200-500 token
Xử lý hàng nghìn token
Tỷ lệ bộ nhớ
O(n) theo độ dài chuỗi
O(n²) cho ma trận attention
Hiệu năng với dữ liệu nhỏ
Tốt (ít tham số hơn)
Dễ quá khớp
Triển khai biên
Phù hợp (dấu chân bộ nhớ thấp)
Thách thức (mô hình lớn)
Streaming/thời gian thực
Hỗ trợ tự nhiên
Cần toàn bộ chuỗi
Hệ sinh thái tiền huấn luyện
Hạn chế
Rộng lớn (BERT, GPT, v.v.)
Quyết định thường phụ thuộc vào ràng buộc. Tài nguyên tính toán và dữ liệu không giới hạn? Transformer thắng ở hầu hết tác vụ NLP. Vi điều khiển với 10K ví dụ huấn luyện? LSTM vẫn thực tế.
Kết luận
LSTM đã giải một vấn đề thực khi ra đời năm 1997. Cơ chế cổng do Hochreiter và Schmidhuber giới thiệu cho phép mạng cuối cùng học từ các chuỗi dài hơn vài chục token. Kiến trúc đó đã thúc đẩy dịch máy, nhận dạng giọng nói và dự báo chuỗi thời gian trong gần hai thập kỷ.
Transformer hiện xử lý hầu hết tác vụ NLP quy mô lớn, nhưng LSTM chưa lỗi thời. Chúng vẫn hợp lý cho triển khai biên, ứng dụng streaming và tình huống dữ liệu huấn luyện hạn chế.
Nếu bạn bắt đầu một dự án mô hình hóa chuỗi mới, hãy thử một LSTM đơn giản trước. Đo lường hiệu năng, hiểu các chế độ thất bại của nó, rồi quyết định liệu vấn đề có thực sự cần Transformer hay không. Các khái niệm từ hướng dẫn này (cổng, trạng thái ô, dòng chảy gradient) chuyển giao trực tiếp sang việc hiểu các kiến trúc phức tạp hơn.
Để luyện tập thực hành, tôi khuyên bạn tham gia khóa học Mạng nơ-ron hồi quy, khóa học này hướng dẫn thêm về các ứng dụng LSTM với bài tập có hướng dẫn.