Trang này được dịch bởi Cloud Translation API.
Switch to English

Mạng thần kinh tái diễn (RNN) với Keras

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải xuống sổ tay

Giới thiệu

Mạng nơ-ron tuần hoàn (RNN) là một lớp mạng nơ-ron mạnh mẽ để mô hình hóa dữ liệu chuỗi như chuỗi thời gian hoặc ngôn ngữ tự nhiên.

Về mặt sơ đồ, một lớp RNN sử dụng vòng lặp for để lặp lại các bước thời gian của một chuỗi, trong khi vẫn duy trì trạng thái bên trong mã hóa thông tin về các bước thời gian mà nó đã thấy cho đến nay.

API Keras RNN được thiết kế tập trung vào:

  • Dễ sử dụng : các lớp keras.layers.RNN , keras.layers.LSTM , keras.layers.GRU cho phép bạn nhanh chóng tạo các mô hình lặp lại mà không phải thực hiện các lựa chọn cấu hình khó khăn.

  • Dễ dàng tùy chỉnh : Bạn cũng có thể xác định lớp ô RNN của riêng mình (phần bên trong của vòng lặp for ) với hành vi tùy chỉnh và sử dụng nó với lớp keras.layers.RNN chung ( for vòng lặp for ). Điều này cho phép bạn nhanh chóng tạo mẫu các ý tưởng nghiên cứu khác nhau một cách linh hoạt với mã tối thiểu.

Thiết lập

import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

Các lớp RNN tích hợp: một ví dụ đơn giản

Có ba lớp RNN tích hợp trong Keras:

  1. keras.layers.SimpleRNN , một RNN được kết nối đầy đủ trong đó đầu ra từ bước thời gian trước đó sẽ được cung cấp cho bước thời gian tiếp theo.

  2. keras.layers.GRU , được đề xuất lần đầu tiên trong Cho et al., 2014 .

  3. keras.layers.LSTM , được đề xuất lần đầu tiên trong Hochreiter & Schmidhuber, 1997 .

Vào đầu năm 2015, Keras đã có bản triển khai Python mã nguồn mở có thể tái sử dụng đầu tiên của LSTM và GRU.

Đây là một ví dụ đơn giản về mô hình Sequential xử lý chuỗi các số nguyên, nhúng mỗi số nguyên vào một vectơ 64 chiều, sau đó xử lý chuỗi các vectơ bằng cách sử dụng một lớp LSTM .

model = keras.Sequential()
# Add an Embedding layer expecting input vocab of size 1000, and
# output embedding dimension of size 64.
model.add(layers.Embedding(input_dim=1000, output_dim=64))

# Add a LSTM layer with 128 internal units.
model.add(layers.LSTM(128))

# Add a Dense layer with 10 units.
model.add(layers.Dense(10))

model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, None, 64)          64000     
_________________________________________________________________
lstm (LSTM)                  (None, 128)               98816     
_________________________________________________________________
dense (Dense)                (None, 10)                1290      
=================================================================
Total params: 164,106
Trainable params: 164,106
Non-trainable params: 0
_________________________________________________________________

RNN tích hợp hỗ trợ một số tính năng hữu ích:

  • Bỏ cuộc định kỳ, thông qua đối số dropoutrecurrent_dropout
  • Khả năng xử lý ngược lại một chuỗi đầu vào, thông qua đối số go_backwards
  • Hủy cuộn vòng lặp (có thể dẫn đến tăng tốc độ lớn khi xử lý các chuỗi ngắn trên CPU), thông qua đối số unroll
  • ...và nhiều hơn nữa.

Để biết thêm thông tin, hãy xem tài liệu RNN API .

Đầu ra và trạng thái

Theo mặc định, đầu ra của lớp RNN chứa một vectơ duy nhất trên mỗi mẫu. Vectơ này là đầu ra của ô RNN tương ứng với bước thời gian cuối cùng, chứa thông tin về toàn bộ chuỗi đầu vào. Hình dạng của đầu ra này là (batch_size, units) trong đó units tương ứng với đối số units được truyền cho hàm tạo của lớp.

Một lớp RNN cũng có thể trả về toàn bộ chuỗi kết quả đầu ra cho mỗi mẫu (một vectơ trên mỗi bước thời gian trên mỗi mẫu), nếu bạn đặt return_sequences=True . Hình dạng của đầu ra này là (batch_size, timesteps, units) .

model = keras.Sequential()
model.add(layers.Embedding(input_dim=1000, output_dim=64))

# The output of GRU will be a 3D tensor of shape (batch_size, timesteps, 256)
model.add(layers.GRU(256, return_sequences=True))

# The output of SimpleRNN will be a 2D tensor of shape (batch_size, 128)
model.add(layers.SimpleRNN(128))

model.add(layers.Dense(10))

model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_1 (Embedding)      (None, None, 64)          64000     
_________________________________________________________________
gru (GRU)                    (None, None, 256)         247296    
_________________________________________________________________
simple_rnn (SimpleRNN)       (None, 128)               49280     
_________________________________________________________________
dense_1 (Dense)              (None, 10)                1290      
=================================================================
Total params: 361,866
Trainable params: 361,866
Non-trainable params: 0
_________________________________________________________________

Ngoài ra, một lớp RNN có thể trả về (các) trạng thái bên trong cuối cùng của nó. Các trạng thái trả về có thể được sử dụng để tiếp tục thực thi RNN sau này hoặc để khởi tạo một RNN khác . Cài đặt này thường được sử dụng trong mô hình tuần tự-trình tự của bộ mã hóa-giải mã, trong đó trạng thái cuối cùng của bộ mã hóa được sử dụng làm trạng thái ban đầu của bộ giải mã.

Để cấu hình một lớp RNN để trả về trạng thái bên trong của nó, hãy đặt tham số return_state thành True khi tạo lớp. Lưu ý rằng LSTM có 2 tenxơ trạng thái, nhưng GRU chỉ có một.

Để cấu hình trạng thái ban đầu của lớp, chỉ cần gọi lớp với đối số từ khóa bổ sung initial_state . Lưu ý rằng hình dạng của trạng thái cần phải phù hợp với kích thước đơn vị của lớp, như trong ví dụ bên dưới.

encoder_vocab = 1000
decoder_vocab = 2000

encoder_input = layers.Input(shape=(None,))
encoder_embedded = layers.Embedding(input_dim=encoder_vocab, output_dim=64)(
    encoder_input
)

# Return states in addition to output
output, state_h, state_c = layers.LSTM(64, return_state=True, name="encoder")(
    encoder_embedded
)
encoder_state = [state_h, state_c]

decoder_input = layers.Input(shape=(None,))
decoder_embedded = layers.Embedding(input_dim=decoder_vocab, output_dim=64)(
    decoder_input
)

# Pass the 2 states to a new LSTM layer, as initial state
decoder_output = layers.LSTM(64, name="decoder")(
    decoder_embedded, initial_state=encoder_state
)
output = layers.Dense(10)(decoder_output)

model = keras.Model([encoder_input, decoder_input], output)
model.summary()
Model: "functional_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, None)]       0                                            
__________________________________________________________________________________________________
input_2 (InputLayer)            [(None, None)]       0                                            
__________________________________________________________________________________________________
embedding_2 (Embedding)         (None, None, 64)     64000       input_1[0][0]                    
__________________________________________________________________________________________________
embedding_3 (Embedding)         (None, None, 64)     128000      input_2[0][0]                    
__________________________________________________________________________________________________
encoder (LSTM)                  [(None, 64), (None,  33024       embedding_2[0][0]                
__________________________________________________________________________________________________
decoder (LSTM)                  (None, 64)           33024       embedding_3[0][0]                
                                                                 encoder[0][1]                    
                                                                 encoder[0][2]                    
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 10)           650         decoder[0][0]                    
==================================================================================================
Total params: 258,698
Trainable params: 258,698
Non-trainable params: 0
__________________________________________________________________________________________________

Các lớp RNN và ô RNN

Ngoài các lớp RNN được tích hợp sẵn, API RNN cũng cung cấp các API cấp độ ô. Không giống như các lớp RNN, xử lý toàn bộ loạt chuỗi đầu vào, ô RNN chỉ xử lý một bước thời gian duy nhất.

Ô là bên trong vòng lặp for của một lớp RNN. Bao bọc một ô bên trong lớp keras.layers.RNN cung cấp cho bạn một lớp có khả năng xử lý hàng loạt chuỗi, ví dụ RNN(LSTMCell(10)) .

Về mặt toán học, RNN(LSTMCell(10)) tạo ra kết quả tương tự như LSTM(10) . Trên thực tế, việc triển khai lớp này trong TF v1.x chỉ là tạo ô RNN tương ứng và gói nó trong một lớp RNN. Tuy nhiên, sử dụng các lớp GRULSTM cho phép sử dụng CuDNN và bạn có thể thấy hiệu suất tốt hơn.

Có ba ô RNN dựng sẵn, mỗi ô tương ứng với lớp RNN phù hợp.

Sự trừu tượng hóa ô, cùng với lớp keras.layers.RNN chung, giúp bạn dễ dàng triển khai các kiến ​​trúc RNN tùy chỉnh cho nghiên cứu của mình.

Trạng thái hàng loạt chéo

Khi xử lý các chuỗi rất dài (có thể là vô hạn), bạn có thể muốn sử dụng mẫu trạng thái hàng loạt chéo .

Thông thường, trạng thái bên trong của một lớp RNN được đặt lại mỗi khi nó nhìn thấy một lô mới (tức là mọi mẫu mà lớp nhìn thấy được giả định là độc lập với quá khứ). Lớp sẽ chỉ duy trì một trạng thái trong khi xử lý một mẫu nhất định.

Tuy nhiên, nếu bạn có các trình tự rất dài, sẽ rất hữu ích khi chia chúng thành các trình tự ngắn hơn và nạp các trình tự ngắn hơn này tuần tự vào một lớp RNN mà không cần đặt lại trạng thái của lớp. Bằng cách đó, lớp có thể giữ lại thông tin về toàn bộ chuỗi, mặc dù nó chỉ nhìn thấy một chuỗi con tại một thời điểm.

Bạn có thể làm điều này bằng cách đặt stateful=True trong hàm tạo.

Nếu bạn có một chuỗi s = [t0, t1, ... t1546, t1547] , bạn sẽ chia nó thành ví dụ

s1 = [t0, t1, ... t100]
s2 = [t101, ... t201]
...
s16 = [t1501, ... t1547]

Sau đó, bạn sẽ xử lý nó qua:

lstm_layer = layers.LSTM(64, stateful=True)
for s in sub_sequences:
  output = lstm_layer(s)

Khi bạn muốn xóa trạng thái, bạn có thể sử dụng layer.reset_states() .

Đây là một ví dụ đầy đủ:

paragraph1 = np.random.random((20, 10, 50)).astype(np.float32)
paragraph2 = np.random.random((20, 10, 50)).astype(np.float32)
paragraph3 = np.random.random((20, 10, 50)).astype(np.float32)

lstm_layer = layers.LSTM(64, stateful=True)
output = lstm_layer(paragraph1)
output = lstm_layer(paragraph2)
output = lstm_layer(paragraph3)

# reset_states() will reset the cached state to the original initial_state.
# If no initial_state was provided, zero-states will be used by default.
lstm_layer.reset_states()

RNN State Reuse

Các trạng thái đã ghi của lớp RNN không được bao gồm trong layer.weights() . Nếu bạn muốn sử dụng lại trạng thái từ một lớp RNN, bạn có thể truy xuất giá trị trạng thái theo layer.states và sử dụng nó làm trạng thái ban đầu cho một lớp mới thông qua API chức năng new_layer(inputs, initial_state=layer.states) như new_layer(inputs, initial_state=layer.states) , hoặc phân lớp mô hình.

Cũng xin lưu ý rằng mô hình tuần tự có thể không được sử dụng trong trường hợp này vì nó chỉ hỗ trợ các lớp có đầu vào và đầu ra duy nhất, đầu vào bổ sung của trạng thái ban đầu khiến nó không thể sử dụng ở đây.

paragraph1 = np.random.random((20, 10, 50)).astype(np.float32)
paragraph2 = np.random.random((20, 10, 50)).astype(np.float32)
paragraph3 = np.random.random((20, 10, 50)).astype(np.float32)

lstm_layer = layers.LSTM(64, stateful=True)
output = lstm_layer(paragraph1)
output = lstm_layer(paragraph2)

existing_state = lstm_layer.states

new_lstm_layer = layers.LSTM(64)
new_output = new_lstm_layer(paragraph3, initial_state=existing_state)

RNN hai chiều

Đối với các trình tự khác với chuỗi thời gian (ví dụ: văn bản), thường là trường hợp mô hình RNN có thể hoạt động tốt hơn nếu nó không chỉ xử lý trình tự từ đầu đến cuối mà còn xử lý ngược lại. Ví dụ, để dự đoán từ tiếp theo trong câu, thường hữu ích khi có ngữ cảnh xung quanh từ đó, không chỉ các từ đứng trước nó.

Keras cung cấp một API dễ dàng để bạn xây dựng các RNN hai chiều như vậy: keras.layers.Bidirectional wrapper.

model = keras.Sequential()

model.add(
    layers.Bidirectional(layers.LSTM(64, return_sequences=True), input_shape=(5, 10))
)
model.add(layers.Bidirectional(layers.LSTM(32)))
model.add(layers.Dense(10))

model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
bidirectional (Bidirectional (None, 5, 128)            38400     
_________________________________________________________________
bidirectional_1 (Bidirection (None, 64)                41216     
_________________________________________________________________
dense_3 (Dense)              (None, 10)                650       
=================================================================
Total params: 80,266
Trainable params: 80,266
Non-trainable params: 0
_________________________________________________________________

Dưới mui xe, Bidirectional sẽ sao chép lớp RNN được chuyển vào và lật trường go_backwards của lớp mới được sao chép, để nó sẽ xử lý các đầu vào theo thứ tự ngược lại.

Theo mặc định, đầu ra của RNN Bidirectional sẽ là tổng của đầu ra lớp tiến và đầu ra lớp lùi. Nếu bạn cần một hành vi hợp nhất khác, ví dụ: nối, hãy thay đổi tham số merge_mode trong hàm tạo trình bao bọc Bidirectional . Để biết thêm chi tiết về Bidirectional , vui lòng kiểm tra tài liệu API .

Tối ưu hóa hiệu suất và hạt nhân CuDNN

Trong TensorFlow 2.0, các lớp LSTM và GRU tích hợp đã được cập nhật để tận dụng hạt nhân CuDNN theo mặc định khi có GPU. Với thay đổi này, các lớp keras.layers.CuDNNLSTM/CuDNNGRU trước đó đã không còn được dùng nữa và bạn có thể xây dựng mô hình của mình mà không cần lo lắng về phần cứng mà mô hình sẽ chạy.

Vì hạt nhân CuDNN được xây dựng với một số giả định nhất định, điều này có nghĩa là lớp sẽ không thể sử dụng hạt nhân CuDNN nếu bạn thay đổi giá trị mặc định của các lớp LSTM hoặc GRU được tích hợp sẵn . Ví dụ:

  • Thay đổi chức năng activation từ tanh sang một thứ khác.
  • Thay đổi hàm recurrent_activation từ sigmoid sang một thứ khác.
  • Sử dụng recurrent_dropout > 0.
  • Đặt unroll thành True, buộc LSTM / GRU phải phân hủy tf.while_loop bên trong thành vòng lặp for cuộn.
  • Đặt use_bias thành False.
  • Sử dụng che khi dữ liệu đầu vào không được đệm đúng (nếu mặt nạ tương ứng với dữ liệu được đệm đúng, vẫn có thể sử dụng CuDNN. Đây là trường hợp phổ biến nhất).

Để biết danh sách chi tiết các ràng buộc, vui lòng xem tài liệu dành cho các lớp LSTMGRU .

Sử dụng hạt nhân CuDNN khi có sẵn

Hãy xây dựng một mô hình LSTM đơn giản để chứng minh sự khác biệt về hiệu suất.

Chúng tôi sẽ sử dụng làm trình tự đầu vào chuỗi các hàng chữ số MNIST (coi mỗi hàng pixel là một bước thời gian) và chúng tôi sẽ dự đoán nhãn của chữ số.

batch_size = 64
# Each MNIST image batch is a tensor of shape (batch_size, 28, 28).
# Each input sequence will be of size (28, 28) (height is treated like time).
input_dim = 28

units = 64
output_size = 10  # labels are from 0 to 9

# Build the RNN model
def build_model(allow_cudnn_kernel=True):
    # CuDNN is only available at the layer level, and not at the cell level.
    # This means `LSTM(units)` will use the CuDNN kernel,
    # while RNN(LSTMCell(units)) will run on non-CuDNN kernel.
    if allow_cudnn_kernel:
        # The LSTM layer with default options uses CuDNN.
        lstm_layer = keras.layers.LSTM(units, input_shape=(None, input_dim))
    else:
        # Wrapping a LSTMCell in a RNN layer will not use CuDNN.
        lstm_layer = keras.layers.RNN(
            keras.layers.LSTMCell(units), input_shape=(None, input_dim)
        )
    model = keras.models.Sequential(
        [
            lstm_layer,
            keras.layers.BatchNormalization(),
            keras.layers.Dense(output_size),
        ]
    )
    return model

Hãy tải tập dữ liệu MNIST:

mnist = keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
sample, sample_label = x_train[0], y_train[0]

Hãy tạo một thể hiện mô hình và đào tạo nó.

Chúng tôi chọn sparse_categorical_crossentropy làm hàm mất mát cho mô hình. Đầu ra của mô hình có dạng [batch_size, 10] . Mục tiêu cho mô hình là một vectơ số nguyên, mỗi số nguyên nằm trong khoảng từ 0 đến 9.

model = build_model(allow_cudnn_kernel=True)

model.compile(
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer="sgd",
    metrics=["accuracy"],
)


model.fit(
    x_train, y_train, validation_data=(x_test, y_test), batch_size=batch_size, epochs=1
)
938/938 [==============================] - 4s 4ms/step - loss: 0.9189 - accuracy: 0.7123 - val_loss: 0.5157 - val_accuracy: 0.8371

<tensorflow.python.keras.callbacks.History at 0x7fc33c67dfd0>

Bây giờ, hãy so sánh với một mô hình không sử dụng nhân CuDNN:

noncudnn_model = build_model(allow_cudnn_kernel=False)
noncudnn_model.set_weights(model.get_weights())
noncudnn_model.compile(
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer="sgd",
    metrics=["accuracy"],
)
noncudnn_model.fit(
    x_train, y_train, validation_data=(x_test, y_test), batch_size=batch_size, epochs=1
)
938/938 [==============================] - 30s 32ms/step - loss: 0.3873 - accuracy: 0.8826 - val_loss: 0.2837 - val_accuracy: 0.9107

<tensorflow.python.keras.callbacks.History at 0x7fc33c072b70>

Khi chạy trên máy có cài đặt GPU NVIDIA và CuDNN, mô hình được xây dựng bằng CuDNN được đào tạo nhanh hơn nhiều so với mô hình sử dụng nhân TensorFlow thông thường.

Cũng có thể sử dụng mô hình hỗ trợ CuDNN tương tự để chạy suy luận trong môi trường chỉ dành cho CPU. Chú thích tf.device bên dưới chỉ là buộc vị trí thiết bị. Mô hình sẽ chạy trên CPU theo mặc định nếu không có sẵn GPU.

Đơn giản là bạn không phải lo lắng về phần cứng mà bạn đang sử dụng nữa. Điều đó không phải là khá tuyệt vời?

import matplotlib.pyplot as plt

with tf.device("CPU:0"):
    cpu_model = build_model(allow_cudnn_kernel=True)
    cpu_model.set_weights(model.get_weights())
    result = tf.argmax(cpu_model.predict_on_batch(tf.expand_dims(sample, 0)), axis=1)
    print(
        "Predicted result is: %s, target result is: %s" % (result.numpy(), sample_label)
    )
    plt.imshow(sample, cmap=plt.get_cmap("gray"))
Predicted result is: [3], target result is: 5

png

RNN với đầu vào danh sách / dict hoặc đầu vào lồng nhau

Các cấu trúc lồng nhau cho phép người triển khai bao gồm nhiều thông tin hơn trong một bước thời gian. Ví dụ: một khung video có thể có đầu vào âm thanh và video cùng một lúc. Hình dạng dữ liệu trong trường hợp này có thể là:

[batch, timestep, {"video": [height, width, channel], "audio": [frequency]}]

Trong một ví dụ khác, dữ liệu chữ viết tay có thể có cả tọa độ x và y cho vị trí hiện tại của bút, cũng như thông tin về áp suất. Vì vậy, biểu diễn dữ liệu có thể là:

[batch, timestep, {"location": [x, y], "pressure": [force]}]

Đoạn mã sau cung cấp một ví dụ về cách tạo một ô RNN tùy chỉnh chấp nhận các đầu vào có cấu trúc như vậy.

Xác định ô tùy chỉnh hỗ trợ đầu vào / đầu ra lồng nhau

Xem Tạo Lớp & Mô hình mới thông qua lớp con để biết chi tiết về cách viết các lớp của riêng bạn.

class NestedCell(keras.layers.Layer):
    def __init__(self, unit_1, unit_2, unit_3, **kwargs):
        self.unit_1 = unit_1
        self.unit_2 = unit_2
        self.unit_3 = unit_3
        self.state_size = [tf.TensorShape([unit_1]), tf.TensorShape([unit_2, unit_3])]
        self.output_size = [tf.TensorShape([unit_1]), tf.TensorShape([unit_2, unit_3])]
        super(NestedCell, self).__init__(**kwargs)

    def build(self, input_shapes):
        # expect input_shape to contain 2 items, [(batch, i1), (batch, i2, i3)]
        i1 = input_shapes[0][1]
        i2 = input_shapes[1][1]
        i3 = input_shapes[1][2]

        self.kernel_1 = self.add_weight(
            shape=(i1, self.unit_1), initializer="uniform", name="kernel_1"
        )
        self.kernel_2_3 = self.add_weight(
            shape=(i2, i3, self.unit_2, self.unit_3),
            initializer="uniform",
            name="kernel_2_3",
        )

    def call(self, inputs, states):
        # inputs should be in [(batch, input_1), (batch, input_2, input_3)]
        # state should be in shape [(batch, unit_1), (batch, unit_2, unit_3)]
        input_1, input_2 = tf.nest.flatten(inputs)
        s1, s2 = states

        output_1 = tf.matmul(input_1, self.kernel_1)
        output_2_3 = tf.einsum("bij,ijkl->bkl", input_2, self.kernel_2_3)
        state_1 = s1 + output_1
        state_2_3 = s2 + output_2_3

        output = (output_1, output_2_3)
        new_states = (state_1, state_2_3)

        return output, new_states

    def get_config(self):
        return {"unit_1": self.unit_1, "unit_2": unit_2, "unit_3": self.unit_3}

Xây dựng mô hình RNN với đầu vào / đầu ra lồng nhau

Hãy xây dựng một mô hình Keras sử dụng lớp keras.layers.RNN và ô tùy chỉnh mà chúng ta vừa xác định.

unit_1 = 10
unit_2 = 20
unit_3 = 30

i1 = 32
i2 = 64
i3 = 32
batch_size = 64
num_batches = 10
timestep = 50

cell = NestedCell(unit_1, unit_2, unit_3)
rnn = keras.layers.RNN(cell)

input_1 = keras.Input((None, i1))
input_2 = keras.Input((None, i2, i3))

outputs = rnn((input_1, input_2))

model = keras.models.Model([input_1, input_2], outputs)

model.compile(optimizer="adam", loss="mse", metrics=["accuracy"])

Đào tạo mô hình với dữ liệu được tạo ngẫu nhiên

Vì không có tập dữ liệu ứng viên tốt cho mô hình này, chúng tôi sử dụng dữ liệu Numpy ngẫu nhiên để trình diễn.

input_1_data = np.random.random((batch_size * num_batches, timestep, i1))
input_2_data = np.random.random((batch_size * num_batches, timestep, i2, i3))
target_1_data = np.random.random((batch_size * num_batches, unit_1))
target_2_data = np.random.random((batch_size * num_batches, unit_2, unit_3))
input_data = [input_1_data, input_2_data]
target_data = [target_1_data, target_2_data]

model.fit(input_data, target_data, batch_size=batch_size)
10/10 [==============================] - 0s 20ms/step - loss: 0.7370 - rnn_1_loss: 0.2622 - rnn_1_1_loss: 0.4748 - rnn_1_accuracy: 0.1016 - rnn_1_1_accuracy: 0.0358

<tensorflow.python.keras.callbacks.History at 0x7fc2b4549358>

Với lớp keras.layers.RNN , Bạn chỉ cần xác định logic toán học cho từng bước trong chuỗi và lớp keras.layers.RNN sẽ xử lý lặp trình tự cho bạn. Đó là một cách cực kỳ mạnh mẽ để nhanh chóng tạo mẫu các loại RNN mới (ví dụ như một biến thể LSTM).

Để biết thêm chi tiết, vui lòng truy cập tài liệu API .