কেরাসের সাথে পুনরাবৃত্ত নিউরাল নেটওয়ার্ক (আরএনএন)

TensorFlow.org-এ দেখুন Google Colab-এ চালান GitHub-এ উৎস দেখুন নোটবুক ডাউনলোড করুন

ভূমিকা

পৌনঃপুনিক নিউরাল নেটওয়ার্ক (RNN) হল এক শ্রেণীর নিউরাল নেটওয়ার্ক যা মডেলিং সিকোয়েন্স ডেটা যেমন টাইম সিরিজ বা প্রাকৃতিক ভাষার জন্য শক্তিশালী।

Schematically, একটি 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 স্তর: একটি সাধারণ উদাহরণ

কেরাসে তিনটি বিল্ট-ইন আরএনএন স্তর রয়েছে:

  1. keras.layers.SimpleRNN , একটি সম্পূর্ণ সংযুক্ত RNN যেখানে পূর্ববর্তী timestep থেকে আউটপুট পরবর্তী timestep খাওয়ানো হবে।

  2. keras.layers.GRU , প্রথম প্রস্তাব চো এট আল।, 2014

  3. keras.layers.LSTM , প্রথম প্রস্তাব Hochreiter & Schmidhuber, 1997

2015 সালের প্রথম দিকে, কেরাসে 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 যুক্তি
  • লুপ unrolling (যা যখন CPU তে সংক্ষিপ্ত সিকোয়েন্স প্রক্রিয়া বৃহৎ speedup হতে পারে), মাধ্যমে unroll যুক্তি
  • ...এবং আরো

আরো তথ্যের জন্য, দেখুন RNN এপিআই ডকুমেন্টেশন

আউটপুট এবং রাজ্য

ডিফল্টরূপে, একটি RNN স্তরের আউটপুটে নমুনা প্রতি একটি একক ভেক্টর থাকে। এই ভেক্টরটি হল RNN সেল আউটপুট যা শেষ টাইমস্টেপের সাথে সম্পর্কিত, যা সম্পূর্ণ ইনপুট ক্রম সম্পর্কে তথ্য ধারণ করে। এই আউটপুট আকৃতি হয় (batch_size, units) যেখানে units সাথে সঙ্গতিপূর্ণ units যুক্তি লেয়ারটির কন্সট্রাকটর প্রেরণ।

একজন 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 রাষ্ট্র tensors আছে, কিন্তু 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 স্তরগুলি ছাড়াও, RNN API সেল-স্তরের API প্রদান করে। আরএনএন স্তরগুলির বিপরীতে, যা ইনপুট সিকোয়েন্সের পুরো ব্যাচগুলি প্রক্রিয়া করে, আরএনএন সেল শুধুমাত্র একটি একক টাইমস্টেপ প্রক্রিয়া করে।

কক্ষের ভেতরে 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 ও এর মত Keras কার্মিক API এর মাধ্যমে একটি নতুন স্তরের জন্য প্রাথমিক অবস্থায় হিসাবে ব্যবহার 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)

দ্বিমুখী RNNs

টাইম সিরিজ (যেমন টেক্সট) ব্যতীত অন্য সিকোয়েন্সের জন্য, এটি প্রায়শই এমন হয় যে একটি RNN মডেল আরও ভাল পারফর্ম করতে পারে যদি এটি শুধুমাত্র শুরু থেকে শেষ পর্যন্ত ক্রম প্রক্রিয়া না করে, তবে পিছনের দিকেও। উদাহরণস্বরূপ, একটি বাক্যে পরবর্তী শব্দের ভবিষ্যদ্বাণী করার জন্য, শব্দের চারপাশে প্রসঙ্গ থাকা প্রায়শই কার্যকর হয়, কেবলমাত্র এর আগে আসা শব্দগুলিই নয়।

: Keras একটি সহজ এপিআই আপনি এই ধরনের দ্বিমুখী 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 , চেক দয়া করে এপিআই ডক্স

কর্মক্ষমতা অপ্টিমাইজেশান এবং 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 একটি unrolled মধ্যে 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 GPU এবং CuDNN ইনস্টল করা একটি মেশিনে চালানোর সময়, নিয়মিত TensorFlow কার্নেল ব্যবহার করে এমন মডেলের তুলনায় CuDNN দিয়ে নির্মিত মডেলটি প্রশিক্ষণের জন্য অনেক দ্রুত।

একই CuDNN-সক্ষম মডেল শুধুমাত্র CPU-র পরিবেশে অনুমান চালানোর জন্য ব্যবহার করা যেতে পারে। tf.device নিচে টীকা শুধু ডিভাইস বসানো অত্যাচার করা হয়। মডেলটি ডিফল্টরূপে CPU-তে চলবে যদি কোনো GPU উপলব্ধ না হয়।

আপনি যে হার্ডওয়্যারটি চালাচ্ছেন তা নিয়ে আপনাকে আর চিন্তা করতে হবে না। যে সুন্দর সুন্দর না?

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 ভেরিয়েন্ট)।

অধিক বিবরণের জন্য, অনুগ্রহ করে পরিদর্শন করুন এপিআই ডক্স