شبکه های عصبی راجعه (RNN) با کراس

با مجموعه‌ها، منظم بمانید ذخیره و دسته‌بندی محتوا براساس اولویت‌های شما.

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در GitHub دانلود دفترچه یادداشت

معرفی

شبکه‌های عصبی بازگشتی (RNN) دسته‌ای از شبکه‌های عصبی هستند که برای مدل‌سازی داده‌های توالی مانند سری‌های زمانی یا زبان طبیعی قدرتمند هستند.

خلاصه، یک لایه RNN با استفاده از یک for حلقه به تکرار بیش از timesteps از یک دنباله، در حالی که حفظ یک حالت درونی است که اطلاعات را کد مورد timesteps آن تا کنون دیده است.

Keras RNN API با تمرکز بر موارد زیر طراحی شده است:

  • سهولت استفاده: ساخته شده در keras.layers.RNN ، keras.layers.LSTM ، keras.layers.GRU لایه شما را قادر به سرعت ساخت مدل های مکرر بدون نیاز به انتخاب پیکربندی سخت.

  • سهولت سفارشی: شما همچنین می توانید خود لایه سلول RNN خود را (قسمت داخلی تعریف for حلقه) با رفتار های سفارشی، و استفاده از آن با عمومی keras.layers.RNN لایه (به for حلقه خود را). این به شما امکان می‌دهد تا به سرعت ایده‌های تحقیقاتی مختلف را به روشی انعطاف‌پذیر با حداقل کد نمونه‌سازی کنید.

برپایی

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

لایه های داخلی RNN: یک مثال ساده

سه لایه RNN داخلی در Keras وجود دارد:

  1. keras.layers.SimpleRNN ، یک RNN کامل متصل که در آن خروجی از timestep قبلی است که به timestep بعدی تغذیه می شود.

  2. keras.layers.GRU ، برای اولین بار در پیشنهاد چو و همکاران، 2014 .

  3. keras.layers.LSTM ، برای اولین بار در پیشنهاد Hochreiter و Schmidhuber است، 1997 .

در اوایل سال 2015، Keras اولین پیاده‌سازی Python منبع باز قابل استفاده مجدد از LSTM و GRU را داشت.

در اینجا یک مثال ساده از یک است Sequential مدل است که فرآیندهای ترتیبی از اعداد، جاسازی هر عدد صحیح را به یک بردار 64 بعدی، پس از آن پردازش دنباله از بردارهای با استفاده از یک 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 های داخلی از تعدادی ویژگی مفید پشتیبانی می کنند:

  • ترک تحصیل راجعه، از طریق dropout و recurrent_dropout استدلال
  • توانایی پردازش یک توالی ورودی در جهت معکوس، از طریق go_backwards استدلال
  • حلقه نورد (که می تواند به تسریع بزرگ در هنگام پردازش از توالی های کوتاه بر روی CPU منجر)، از طریق unroll بحث
  • ...و بیشتر.

برای اطلاعات بیشتر، نگاه کنید به مستندات API RNN .

خروجی ها و حالات

به طور پیش فرض، خروجی یک لایه RNN شامل یک بردار در هر نمونه است. این بردار خروجی سلول RNN مربوط به آخرین مرحله زمانی است که حاوی اطلاعاتی در مورد کل توالی ورودی است. شکل این خروجی است (batch_size, units) که در آن units مربوط به units آرگومان به سازنده لایه.

لایه A RNN همچنین می توانید تمام دنباله ای از خروجی برای هر نمونه (یک بردار در هر timestep در نمونه) بازگشت، اگر به شما در تنظیم return_sequences=True . شکل این خروجی است (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
_________________________________________________________________

علاوه بر این، یک لایه RNN می تواند حالت(های) داخلی نهایی خود را برگرداند. کشورهای بازگشت می توان مورد استفاده برای از سرگیری اعدام RNN بعد، و یا به مقداردهی اولیه RNN دیگر . این تنظیم معمولاً در مدل توالی به دنباله رمزگذار-رمزگشا استفاده می شود، که در آن حالت نهایی رمزگذار به عنوان حالت اولیه رمزگشا استفاده می شود.

برای پیکربندی یک لایه RNN به بازگشت وضعیت داخلی است، مجموعه ای return_state پارامتر به True در هنگام ایجاد لایه. توجه داشته باشید که LSTM دارای 2 تانسورها دولت، بلکه GRU فقط یک.

برای پیکربندی حالت اولیه لایه، فقط لایه با اضافی استدلال کلمه کلیدی پاسخ initial_state . توجه داشته باشید که شکل حالت باید با اندازه واحد لایه مطابقت داشته باشد، مانند مثال زیر.

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
__________________________________________________________________________________________________

لایه های RNN و سلول های RNN

علاوه بر لایه‌های RNN داخلی، API RNN APIهای سطح سلولی را نیز ارائه می‌کند. برخلاف لایه‌های RNN که دسته‌ای کامل از توالی‌های ورودی را پردازش می‌کنند، سلول RNN فقط یک مرحله زمانی واحد را پردازش می‌کند.

سلول داخل است for حلقه از یک لایه RNN. بسته بندی یک سلول در داخل یک keras.layers.RNN لایه به شما می دهد یک لایه قادر به پردازش دسته از توالی، به عنوان مثال RNN(LSTMCell(10)) .

ریاضی، RNN(LSTMCell(10)) به همان نتیجه تولید LSTM(10) . در واقع، اجرای این لایه در TF v1.x فقط ایجاد سلول RNN مربوطه و پیچیده شدن آن در یک لایه RNN بود. با این حال با استفاده از ساخته شده است در GRU و LSTM لایه فعال کردن استفاده از CuDNN و شما ممکن است عملکرد بهتر را ببینید.

سه سلول RNN داخلی وجود دارد که هر کدام مربوط به لایه RNN منطبق است.

تجرید همراه، همراه با کلی keras.layers.RNN کلاس، آن را بسیار آسان برای پیاده سازی معماری سفارشی RNN برای تحقیقات خود را.

حالت متقاطع دسته ای

هنگامی که پردازش توالی بسیار طولانی (احتمالا بی نهایت)، شما ممکن است مایل به استفاده از الگوی statefulness متقابل دسته ای.

به طور معمول، هر بار که یک لایه RNN یک دسته جدید می بیند، وضعیت داخلی آن بازنشانی می شود (یعنی هر نمونه ای که توسط لایه دیده می شود مستقل از گذشته فرض می شود). لایه تنها در حین پردازش یک نمونه معین حالت را حفظ می کند.

اگر دنباله‌های بسیار طولانی دارید، مفید است که آنها را به دنباله‌های کوتاه‌تر تقسیم کنید و این توالی‌های کوتاه‌تر را به‌طور متوالی در یک لایه RNN بدون تنظیم مجدد وضعیت لایه تغذیه کنید. به این ترتیب، لایه می تواند اطلاعات مربوط به کل دنباله را حفظ کند، حتی اگر فقط یک زیر دنباله را در یک زمان ببیند.

شما می توانید این را با تنظیم انجام stateful=True در سازنده.

اگر شما یک توالی s = [t0, t1, ... t1546, t1547] ، شما می توانید آن را به عنوان مثال تقسیم

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

سپس آن را از طریق:

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

هنگامی که شما می خواهید برای روشن دولت، شما می توانید استفاده layer.reset_states() .

در اینجا یک مثال کامل است:

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

کشورهای ثبت شده از لایه RNN در شامل نمی layer.weights() . اگر شما می خواهم به استفاده مجدد از دولت را از یک لایه RNN، شما می توانید مقدار ایالت بازیابی layer.states و استفاده از آن به عنوان حالت اولیه برای یک لایه جدید از طریق API کاربردی Keras مانند new_layer(inputs, initial_state=layer.states) ، یا زیر طبقه بندی مدل.

لطفاً همچنین توجه داشته باشید که مدل ترتیبی ممکن است در این مورد استفاده نشود زیرا فقط از لایه‌هایی با ورودی و خروجی تک پشتیبانی می‌کند، ورودی اضافی حالت اولیه استفاده از آن را در اینجا غیرممکن می‌کند.

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 های دو طرفه

برای دنباله‌هایی غیر از سری‌های زمانی (مثلاً متن)، اغلب این اتفاق می‌افتد که یک مدل RNN می‌تواند عملکرد بهتری داشته باشد اگر نه تنها دنباله را از ابتدا تا انتها پردازش کند، بلکه به عقب نیز پردازش کند. به عنوان مثال، برای پیش بینی کلمه بعدی در یک جمله، اغلب مفید است که بافت اطراف کلمه را داشته باشید، نه فقط کلماتی که قبل از آن آمده اند.

است: Keras یک API برای شما آسان برای ساخت چنین RNNs دو طرفه فراهم می کند keras.layers.Bidirectional لفاف بسته بندی.

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
_________________________________________________________________

در زیر هود، Bidirectional لایه RNN گذشت در کپی، و تلنگر go_backwards زمینه لایه تازه کپی، به طوری که آن را به ورودی را در جهت معکوس را پردازش کند.

خروجی Bidirectional RNN خواهد بود، به طور پیش فرض، از الحاق خروجی لایه رو به جلو و خروجی لایه رو به عقب. اگر شما نیاز به یک رفتار ادغام مختلف، به عنوان مثال الحاق، تغییر merge_mode پارامتر در Bidirectional سازنده لفاف بسته بندی. برای جزئیات بیشتر در مورد Bidirectional ، لطفا اسناد API را .

بهینه سازی عملکرد و هسته های CuDNN

در TensorFlow 2.0، لایه‌های داخلی LSTM و GRU برای استفاده از هسته‌های CuDNN به‌طور پیش‌فرض زمانی که یک GPU در دسترس است، به‌روزرسانی شده‌اند. با این تغییر، قبل از keras.layers.CuDNNLSTM/CuDNNGRU لایه بد دانسته شده است، و شما می توانید مدل خود را بدون هیچ گونه نگرانی در مورد سخت افزار آن را اجرا خواهد کرد ساخت.

از آنجا که هسته CuDNN با فرضیات خاصی ساخته شده است، این به این معنی لایه قادر نخواهد بود به استفاده از هسته CuDNN اگر شما به صورت پیش فرض از ساخته شده است در لایه های LSTM یا GRU را تغییر دهید. به عنوان مثال:

  • تغییر activation تابع از tanh به چیز دیگری.
  • تغییر recurrent_activation تابع از sigmoid به چیز دیگری.
  • با استفاده از recurrent_dropout > 0.
  • تنظیم unroll به درست است، که نیروهای LSTM / GRU به تجزیه درونی tf.while_loop به یک نعوظ for حلقه.
  • تنظیم use_bias به غلط.
  • استفاده از پوشاندن زمانی که داده‌های ورودی کاملاً درست نیستند (اگر ماسک با داده‌های کاملاً سمت راست مطابقت دارد، هنوز هم می‌توان از CuDNN استفاده کرد. این رایج‌ترین مورد است).

برای لیست مفصل از محدودیت، لطفا مستندات مربوط به دیدن LSTM و GRU لایه.

استفاده از هسته های CuDNN در صورت وجود

بیایید یک مدل LSTM ساده بسازیم تا تفاوت عملکرد را نشان دهیم.

ما به عنوان دنباله های ورودی از دنباله ردیف های ارقام MNIST استفاده می کنیم (هر ردیف از پیکسل ها را به عنوان یک مرحله زمانی در نظر می گیریم)، ​​و برچسب رقم را پیش بینی می کنیم.

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

بیایید مجموعه داده 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]

بیایید یک نمونه مدل ایجاد کنیم و آن را آموزش دهیم.

ما را انتخاب کنید sparse_categorical_crossentropy به عنوان تابع از دست دادن برای مدل. خروجی این مدل شکل [batch_size, 10] . هدف برای مدل یک بردار عدد صحیح است که هر یک از اعداد صحیح در محدوده 0 تا 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>

حالا بیایید با مدلی مقایسه کنیم که از هسته 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>

وقتی روی ماشینی با پردازنده گرافیکی NVIDIA و CuDNN نصب شده اجرا می‌شود، آموزش مدل ساخته شده با CuDNN در مقایسه با مدلی که از هسته معمولی TensorFlow استفاده می‌کند، بسیار سریع‌تر است.

از همان مدل CuDNN فعال می‌توان برای اجرای استنتاج در یک محیط فقط CPU استفاده کرد. tf.device حاشیه نویسی زیر فقط مجبور قرار دادن دستگاه. اگر GPU در دسترس نباشد، مدل به طور پیش‌فرض روی CPU اجرا می‌شود.

دیگر لازم نیست نگران سخت افزاری که روی آن کار می کنید باشید. این خیلی باحال نیست؟

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 با ورودی های لیست/دیکت یا ورودی های تو در تو

ساختارهای تودرتو به پیاده‌کنندگان اجازه می‌دهند تا اطلاعات بیشتری را در یک مرحله زمانی واحد بگنجانند. به عنوان مثال، یک فریم ویدئو می تواند ورودی صوتی و تصویری را همزمان داشته باشد. شکل داده در این مورد می تواند باشد:

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

در مثالی دیگر، داده‌های دست‌نویس می‌توانند مختصات x و y را برای موقعیت فعلی قلم و همچنین اطلاعات فشار داشته باشند. بنابراین نمایش داده ها می تواند به صورت زیر باشد:

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

کد زیر نمونه ای از نحوه ساخت یک سلول RNN سفارشی را ارائه می دهد که چنین ورودی های ساختاری را می پذیرد.

یک سلول سفارشی را تعریف کنید که از ورودی/خروجی تودرتو پشتیبانی می کند

مشاهده ساخت لایه های جدید و مدل های از طریق subclassing برای جزئیات بیشتر در نوشتن لایه های خود را.

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}

یک مدل RNN با ورودی/خروجی تودرتو بسازید

بیایید ساخت یک مدل Keras که با استفاده از keras.layers.RNN لایه و سلول های سفارشی ما فقط تعریف شده است.

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"])

مدل را با داده های تولید شده به صورت تصادفی آموزش دهید

از آنجایی که مجموعه داده نامزد مناسبی برای این مدل وجود ندارد، از داده‌های تصادفی Numpy برای نمایش استفاده می‌کنیم.

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>

با Keras keras.layers.RNN لایه، شما تنها انتظار می رود برای تعریف منطق ریاضی برای مرحله فرد در توالی و keras.layers.RNN لایه تکرار توالی برای شما اداره کند. این یک راه فوق‌العاده قدرتمند برای نمونه‌سازی سریع انواع جدید RNN است (به عنوان مثال یک نوع LSTM).

برای جزئیات بیشتر، لطفا به بازدید اسناد API .