Nhiều đến một và nhiều đến nhiều ví dụ LSTM trong Keras


108

Tôi cố gắng hiểu LSTM và cách xây dựng chúng với Keras. Tôi phát hiện ra rằng về cơ bản có 4 chế độ để chạy RNN (4 chế độ bên phải trong hình)

nhập mô tả hình ảnh ở đây Nguồn ảnh: Andrej Karpathy

Bây giờ tôi tự hỏi một đoạn mã tối giản cho mỗi đoạn mã sẽ trông như thế nào trong Keras. Vì vậy, một cái gì đó như

model = Sequential()
model.add(LSTM(128, input_shape=(timesteps, data_dim)))
model.add(Dense(1))

cho mỗi nhiệm vụ trong số 4 nhiệm vụ, có thể với một chút giải thích.

Câu trả lời:


121

Vì thế:

  1. Một-một : bạn có thể sử dụng một Denselớp vì bạn không xử lý các trình tự:

    model.add(Dense(output_size, input_shape=input_shape))
  2. Một-nhiều : tùy chọn này không được hỗ trợ cũng như các mô hình chuỗi không dễ sử dụng Keras, vì vậy phiên bản sau là phiên bản dễ dàng nhất:

    model.add(RepeatVector(number_of_times, input_shape=input_shape))
    model.add(LSTM(output_size, return_sequences=True))
    
  3. Nhiều-một : thực ra, đoạn mã của bạn (gần như) là một ví dụ về phương pháp này:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim)))
    
  4. Nhiều-nhiều : Đây là đoạn mã dễ nhất khi độ dài của đầu vào và đầu ra khớp với số bước lặp lại:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
    
  5. Nhiều-nhiều khi số lượng các bước khác với độ dài đầu vào / đầu ra : điều này thật là khó trong Keras. Không có đoạn mã dễ dàng để viết mã đó.

CHỈNH SỬA: Quảng cáo 5

Trong một trong những ứng dụng gần đây của tôi, chúng tôi đã triển khai một cái gì đó có thể giống với nhiều-nhiều từ hình ảnh thứ 4. Trong trường hợp bạn muốn có một mạng với kiến ​​trúc sau (khi đầu vào dài hơn đầu ra):

                                        O O O
                                        | | |
                                  O O O O O O
                                  | | | | | | 
                                  O O O O O O

Bạn có thể đạt được điều này theo cách sau:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
    model.add(Lambda(lambda x: x[:, -N:, :]

Trong trường hợp Nlà số lượng các bước cuối cùng bạn muốn để trang trải (trên hình N = 3).

Từ thời điểm này đi đến:

                                        O O O
                                        | | |
                                  O O O O O O
                                  | | | 
                                  O O O 

đơn giản như chuỗi đệm nhân tạo có độ dài Nbằng cách sử dụng 0vectơ, ví dụ , để điều chỉnh nó thành kích thước thích hợp.


10
Một giải thích rõ: Ví dụ: đối với nhiều đối một, bạn sử dụng LSTM (1, input_shape = (timesteps, data_dim))) Tôi nghĩ số 1 là viết tắt của số ô LSTM / các nút ẩn, nhưng thực tế không phải vậy. Bạn sẽ viết mã Many- đối với một với giả sử, 512 nút mặc dù hơn? (Vì tôi đọc một cái gì đó simliar nên tôi nghĩ nó sẽ được thực hiện với model.add (LSTM (512, input_shape = ...)) model.add (Dense (1)) cái đó được sử dụng để làm gì?)
Luca Thiede

1
Trong trường hợp này - mã của bạn - sau khi sửa lỗi đánh máy sẽ ổn.
Marcin Możejko

Tại sao chúng ta sử dụng RepeatVector, mà không phải là vectơ có mục nhập đầu tiên 1 = 0 và tất cả các mục nhập khác = 0 (theo hình trên, không có Đầu vào nào cả ở các trạng thái sau và không phải lúc nào đầu vào cũng giống nhau, những gì Lặp Vector sẽ làm gì trong sự hiểu biết của tôi)
Luca Thiede

1
Nếu bạn suy nghĩ kỹ về bức tranh này - nó chỉ là một bản trình bày khái niệm về ý tưởng một-nhiều . Tất cả các đơn vị ẩn này phải chấp nhận một cái gì đó làm đầu vào. Vì vậy - họ có thể chấp nhận cùng một đầu vào cũng như đầu vào với đầu vào đầu tiên bằng xvà khác bằng 0. Nhưng - mặt khác - họ cũng có thể chấp nhận điều tương tự xlặp lại nhiều lần. Cách tiếp cận khác là mô hình chuỗi khó Keras. Tùy chọn tôi đã cung cấp là trường hợp dễ nhất của kiến trúc một-nhiềuKeras .
Marcin Możejko

Đẹp ! Tôi đang suy nghĩ về việc sử dụng LSTM N đến N trong kiến ​​trúc GAN. Tôi sẽ có một trình tạo dựa trên LSTM. Tôi sẽ cung cấp cho bộ lưu trữ này (như được sử dụng trong "Biến tiềm ẩn" trong gans) nửa đầu của chuỗi thời gian và bộ tạo này sẽ tạo ra nửa sau của chuỗi thời gian. Sau đó, tôi sẽ kết hợp hai nửa (thực và tạo) để tạo ra đầu vào "giả" cho gan. Bạn có nghĩ rằng sử dụng poin 4 của bạn giải quyết sẽ hiệu quả? hay nói cách khác, đây có phải là (giải pháp 4) là cách thích hợp để làm điều này?
rjpg

6

Câu trả lời tuyệt vời của @Marcin Możejko

Tôi sẽ thêm phần sau vào NR.5 (nhiều đến nhiều với độ dài vào / ra khác nhau):

A) như Vanilla LSTM

model = Sequential()
model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES)))
model.add(Dense(N_OUTPUTS))

B) như Bộ mã hóa-Bộ giải mã LSTM

model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES))  
model.add(RepeatVector(N_OUTPUTS))
model.add(LSTM(N_BLOCKS, return_sequences=True))  
model.add(TimeDistributed(Dense(1)))
model.add(Activation('linear')) 

1
Bạn có thể vui lòng giải thích các chi tiết của B) Encoder-Decoder LSTMkiến trúc? Tôi đang gặp sự cố khi hiểu vai trò của các bước "RepeatVector" / "TimeDistributed".
Marsellus Wallace
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.