![]() | ![]() | ![]() | ![]() |
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ẽ để lập mô hình dữ liệu chuỗi như chuỗi thời gian hoặc ngôn ngữ tự nhiên.
Sơ đồ, một lớp RNN sử dụng for
vòng lặp để lặp qua timesteps của một chuỗi, trong khi duy trì một trạng thái nội bộ mã hóa thông tin về timesteps nó đã thấy cho đến nay.
Keras RNN API được thiết kế tập trung vào:
Dễ sử dụng: được xây dựng trong
keras.layers.RNN
,keras.layers.LSTM
,keras.layers.GRU
lớp cho phép bạn nhanh chóng xây dựng mô hình tái phát mà không cần phải có những lựa chọn cấu hình khó khăn.Dễ tùy biến: Bạn cũng có thể xác định lớp của riêng tế bào RNN (phần bên trong của
for
vòng lặp) với hành vi tùy chỉnh, và sử dụng nó với generickeras.layers.RNN
lớp (cácfor
vòng lặp chính nó). Đ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.
Thành 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:
keras.layers.SimpleRNN
, một RNN đầy đủ kết nối, nơi sản lượng từ timestep trước là để được làm thức ăn cho timestep tới.keras.layers.GRU
, lần đầu tiên được đề xuất trong Chợ et al., 2014 .keras.layers.LSTM
, lần đầu tiên được đề xuất 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.
Dưới đây là một ví dụ đơn giản của một Sequential
mô hình mà các quy trình chuỗi các số nguyên, nhúng từng số nguyên vào một vector 64 chiều, sau đó xử lý các chuỗi các vectơ sử dụng một LSTM
lớp.
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ỏ học thường xuyên, thông qua
dropout
vàrecurrent_dropout
luận - Khả năng xử lý một chuỗi đầu vào theo hướng ngược lại, thông qua
go_backwards
luận - Vòng unrolling (có thể dẫn đến sự tăng tốc lớn khi xử lý chuỗi ngắn trên CPU), thông qua
unroll
lập luận - ...và nhiều hơn nữa.
Để biết thêm thông tin, 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 sản lượng này là (batch_size, units)
nơi units
tương ứng với các units
tham số được truyền cho constructor của lớp.
Một RNN lớp cũng có thể trả lại toàn bộ chuỗi các kết quả đầu ra cho mỗi mẫu (một vector mỗi bước thời gian cho mỗi mẫu), nếu bạn đặt return_sequences=True
. Hình dáng của sản lượng 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ở lại có thể được sử dụng để tiếp tục thực hiện RNN sau, hoặc để khởi tạo một RNN . Cài đặt này thường được sử dụng trong mô hình nối tiếp 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 nội bộ của mình, thiết lập return_state
tham số để True
khi tạo lớp. Lưu ý rằng LSTM
có 2 tensors nhà nước, nhưng GRU
chỉ có một.
Để cấu hình tình trạng ban đầu của lớp, chỉ cần gọi lớp với thêm tham số từ khóa 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: "model" __________________________________________________________________________________________________ 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à các ô 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.
Các tế bào bên trong for
vòng lặp của một lớp RNN. Gói một tế bào bên trong một keras.layers.RNN
lớp mang đến cho bạn một lớp khả năng xử lý các lô trình tự, ví dụ như 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 bằng cách sử dụng built-in GRU
và LSTM
lớp cho phép việc sử dụng các 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.
keras.layers.SimpleRNNCell
tương ứng vớiSimpleRNN
lớp.keras.layers.GRUCell
tương ứng vớiGRU
lớp.keras.layers.LSTMCell
tương ứng vớiLSTM
lớp.
Trừu tượng di động, cùng với generic keras.layers.RNN
lớp, làm cho nó rất dễ dàng để thực hiện tùy chỉnh RNN kiến trúc cho nghiên cứu của bạn.
Trạng thái hàng loạt chéo
Khi xử lý chuỗi rất dài (có thể là vô hạn), bạn có thể muốn sử dụng các mô hình của statefulness cross-lô.
Thông thường, trạng thái bên trong của 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 nếu bạn 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 thiết lập stateful=True
trong constructor.
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 tiểu bang, 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 bao gồm trong layer.weights()
. Nếu bạn muốn sử dụng lại nhà nước từ một lớp RNN, bạn có thể lấy giá trị quốc gia bởi layer.states
và sử dụng nó như tình trạng ban đầu cho một layer mới qua API chức năng Keras 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 một câu, thường hữu ích khi có ngữ cảnh xung quanh từ đó, không chỉ những từ đứng trước nó.
Keras cung cấp một API dễ dàng cho bạn để xây dựng RNNs hai chiều như: các 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 các lớp RNN thông qua tại, và lật go_backwards
lĩnh vực của lớp mới được sao chép, do đó nó sẽ xử lý đầu vào theo thứ tự ngược.
Đầu ra của Bidirectional
RNN sẽ được, theo mặc định, nối các đầu ra lớp phía trước và đầu ra lớp lạc hậu. Nếu bạn cần một hành vi kết hợp khác nhau, ví dụ như nối, thay đổi merge_mode
tham số trong Bidirectional
constructor wrapper. Để biết thêm chi tiết về Bidirectional
, hãy kiểm tra các 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 nhân CuDNN theo mặc định khi có GPU. Với sự thay đổi này, trước keras.layers.CuDNNLSTM/CuDNNGRU
lớp đã bị phản đối, và bạn có thể xây dựng mô hình của bạn mà không cần lo lắng về phần cứng nó sẽ chạy trên.
Kể từ khi kernel CuDNN được xây dựng với một số giả định, các phương tiện này 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 built-in LSTM hay GRU lớp. Ví dụ:
- Thay đổi
activation
chức năng từtanh
đến cái gì khác. - Thay đổi
recurrent_activation
chức năng từsigmoid
đến cái gì khác. - Sử dụng
recurrent_dropout
> 0. - Thiết
unroll
là True, mà lực lượng LSTM / GRU để phân hủy bên trongtf.while_loop
thành một trải rafor
vòng lặp. - Thiết
use_bias
False. - Sử dụng mặt nạ 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).
Để xem danh sách chi tiết những hạn chế, vui lòng xem tài liệu cho LSTM và GRU lớp.
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
như hàm tổn thất cho mô hình. Đầu ra của mô hình có hình dạng của [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 [==============================] - 6s 5ms/step - loss: 0.9510 - accuracy: 0.7029 - val_loss: 0.5633 - val_accuracy: 0.8209 <keras.callbacks.History at 0x7fc9942efad0>
Bây giờ, hãy so sánh với một mô hình không sử dụng hạt 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 [==============================] - 34s 35ms/step - loss: 0.3894 - accuracy: 0.8846 - val_loss: 0.5677 - val_accuracy: 0.8045 <keras.callbacks.History at 0x7fc945fa2650>
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.
Mô hình hỗ trợ CuDNN tương tự cũng có thể được sử dụng để chạy suy luận trong môi trường chỉ dành cho CPU. Các tf.device
chú thích dưới đây chỉ là buộc cá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 phải không?
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
RNN với đầu vào danh sách / dict hoặc đầu vào lồng nhau
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 cây 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 Làm lớp mới & Models qua subclassing để 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 có sử dụng một keras.layers.RNN
lớp và các tế bào tùy chỉnh 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 [==============================] - 1s 26ms/step - loss: 0.7316 - rnn_1_loss: 0.2590 - rnn_1_1_loss: 0.4725 - rnn_1_accuracy: 0.1016 - rnn_1_1_accuracy: 0.0328 <keras.callbacks.History at 0x7fc5686e6f50>
Với Keras keras.layers.RNN
lớp, Bạn chỉ được dự kiến để xác định logic toán cho bước cá nhân trong chuỗi, và keras.layers.RNN
lớp sẽ xử lý lặp chuỗi cho bạn. Đó là một cách cực kỳ hiệu quả để nhanh chóng tạo nguyên 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 .