কার্যকরী এপিআই

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

সেটআপ

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

ভূমিকা

Keras কার্মিক এপিআই মডেলের যে বেশী নমনীয় তৈরি করতে একটি উপায় tf.keras.Sequential API- টি। কার্যকরী API নন-লিনিয়ার টপোলজি, ভাগ করা স্তর এবং এমনকি একাধিক ইনপুট বা আউটপুট সহ মডেলগুলি পরিচালনা করতে পারে।

মূল ধারণা হল যে একটি গভীর শিক্ষার মডেল সাধারণত স্তরগুলির একটি নির্দেশিত অ্যাসাইক্লিক গ্রাফ (DAG)। ক্রিয়ামূলক এপিআই সুতরাং স্তর গ্রাফ নির্মাণ করা একটি উপায়।

নিম্নলিখিত মডেল বিবেচনা করুন:

(input: 784-dimensional vectors)
       ↧
[Dense (64 units, relu activation)]
       ↧
[Dense (64 units, relu activation)]
       ↧
[Dense (10 units, softmax activation)]
       ↧
(output: logits of a probability distribution over 10 classes)

এটি তিনটি স্তর সহ একটি মৌলিক গ্রাফ। কার্যকরী API ব্যবহার করে এই মডেলটি তৈরি করতে, একটি ইনপুট নোড তৈরি করে শুরু করুন:

inputs = keras.Input(shape=(784,))

ডেটার আকৃতি একটি 784-মাত্রিক ভেক্টর হিসাবে সেট করা হয়েছে। ব্যাচের আকার সবসময় বাদ দেওয়া হয় যেহেতু প্রতিটি নমুনার আকৃতি নির্দিষ্ট করা হয়।

যদি, উদাহরণস্বরূপ, আপনি একটি আকৃতি সঙ্গে একটি চিত্র ইনপুট আছে (32, 32, 3) , আপনি ব্যবহার করবেন:

# Just for demonstration purposes.
img_inputs = keras.Input(shape=(32, 32, 3))

inputs যে ফিরিয়ে দেওয়া হয় আকৃতি এবং সম্পর্কে তথ্য রয়েছে dtype ইনপুট ডেটা যা আপনি আপনার মডেলের ভোজন। এখানে আকৃতি আছে:

inputs.shape
TensorShape([None, 784])

এখানে dtype আছে:

inputs.dtype
tf.float32

আপনি এই উপর একটি স্তর কল করে স্তর গ্রাফ একটি নতুন নোড তৈরি inputs বস্তু:

dense = layers.Dense(64, activation="relu")
x = dense(inputs)

"লেয়ার কল" ক্রিয়াটি আপনার তৈরি করা এই স্তরটিতে "ইনপুট" থেকে একটি তীর আঁকার মতো। তুমি থেকে "পাশ করার" ইনপুট dense স্তর, এবং আপনি পেতে x আউটপুট।

লেয়ারের গ্রাফে আরও কয়েকটি স্তর যোগ করা যাক:

x = layers.Dense(64, activation="relu")(x)
outputs = layers.Dense(10)(x)

এই মুহুর্তে, আপনি একটি তৈরি করতে পারেন Model স্তর গ্রাফ তার ইনপুট এবং আউটপুট নির্দিষ্ট করে:

model = keras.Model(inputs=inputs, outputs=outputs, name="mnist_model")

আসুন মডেল সারাংশ দেখতে কেমন তা পরীক্ষা করে দেখুন:

model.summary()
Model: "mnist_model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 784)]             0         
_________________________________________________________________
dense (Dense)                (None, 64)                50240     
_________________________________________________________________
dense_1 (Dense)              (None, 64)                4160      
_________________________________________________________________
dense_2 (Dense)              (None, 10)                650       
=================================================================
Total params: 55,050
Trainable params: 55,050
Non-trainable params: 0
_________________________________________________________________

আপনি একটি গ্রাফ হিসাবে মডেল প্লট করতে পারেন:

keras.utils.plot_model(model, "my_first_model.png")

png

এবং, ঐচ্ছিকভাবে, প্লট করা গ্রাফে প্রতিটি স্তরের ইনপুট এবং আউটপুট আকারগুলি প্রদর্শন করুন:

keras.utils.plot_model(model, "my_first_model_with_shape_info.png", show_shapes=True)

png

এই চিত্র এবং কোড প্রায় অভিন্ন. কোড সংস্করণে, সংযোগ তীরগুলি কল অপারেশন দ্বারা প্রতিস্থাপিত হয়।

একটি "স্তরগুলির গ্রাফ" একটি গভীর শিক্ষার মডেলের জন্য একটি স্বজ্ঞাত মানসিক চিত্র, এবং কার্যকরী API হল মডেলগুলি তৈরি করার একটি উপায় যা এটি ঘনিষ্ঠভাবে প্রতিফলিত করে।

প্রশিক্ষণ, মূল্যায়ন, এবং অনুমান

প্রশিক্ষণ, মূল্যায়ন, এবং অনুমান কাজ ঠিক যেমন কার্মিক API ব্যবহার করে নির্মিত মডেলের জন্য একই ভাবে Sequential মডেল।

Model বর্গ অফার একটি বিল্ট-ইন প্রশিক্ষণ লুপ ( fit() পদ্ধতি) এবং একটি বিল্ট-ইন মূল্যায়ন লুপ ( evaluate() পদ্ধতি)। মনে রাখবেন আপনি সহজে করতে পারেন এই লুপ কাস্টমাইজ প্রশিক্ষণ রুটিন তত্ত্বাবধানে থাকা শেখার পরেও (যেমন বাস্তবায়ন Gans )।

এখানে, MNIST ইমেজ ডেটা লোড করুন, এটিকে ভেক্টরে আকার দিন, ডেটাতে মডেলটি ফিট করুন (একটি বৈধতা বিভাজনে কর্মক্ষমতা পর্যবেক্ষণ করার সময়), তারপর পরীক্ষার ডেটাতে মডেলটিকে মূল্যায়ন করুন:

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

x_train = x_train.reshape(60000, 784).astype("float32") / 255
x_test = x_test.reshape(10000, 784).astype("float32") / 255

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

history = model.fit(x_train, y_train, batch_size=64, epochs=2, validation_split=0.2)

test_scores = model.evaluate(x_test, y_test, verbose=2)
print("Test loss:", test_scores[0])
print("Test accuracy:", test_scores[1])
Epoch 1/2
750/750 [==============================] - 3s 3ms/step - loss: 0.3430 - accuracy: 0.9035 - val_loss: 0.1851 - val_accuracy: 0.9463
Epoch 2/2
750/750 [==============================] - 2s 3ms/step - loss: 0.1585 - accuracy: 0.9527 - val_loss: 0.1366 - val_accuracy: 0.9597
313/313 - 0s - loss: 0.1341 - accuracy: 0.9592
Test loss: 0.13414572179317474
Test accuracy: 0.9592000246047974

আরো পড়ার জন্য, দেখুন প্রশিক্ষণ ও মূল্যায়ন গাইড।

সংরক্ষণ করুন এবং সিরিয়াল করুন

সংরক্ষণ করা হচ্ছে মডেল এবং ধারাবাহিকতাতে কাজ কার্মিক API ব্যবহার করে তারা জন্য কি নির্মিত মডেলের জন্য একই ভাবে Sequential মডেল। একটি কার্মিক মডেল সংরক্ষণ করতে আদর্শ উপায় কল হয় model.save() একটি একক ফাইল হিসেবে সমগ্র মডেল সংরক্ষণ করুন। আপনি পরে এই ফাইল থেকে একই মডেল পুনরায় তৈরি করতে পারেন, এমনকি যদি মডেলটি তৈরি করা কোডটি আর উপলব্ধ না থাকে।

এই সংরক্ষিত ফাইলের মধ্যে রয়েছে:

  • মডেল আর্কিটেকচার
  • মডেল ওজন মান (যা প্রশিক্ষণের সময় শেখা হয়েছিল)
  • মডেল প্রশিক্ষণ কনফিগ, যদি থাকে (প্রেরণ যেমন compile )
  • অপ্টিমাইজার এবং তার অবস্থা, যদি থাকে (আপনি যেখান থেকে প্রশিক্ষণ ছেড়েছিলেন সেখানে পুনরায় শুরু করতে)
model.save("path_to_my_model")
del model
# Recreate the exact same model purely from the file:
model = keras.models.load_model("path_to_my_model")
2021-08-25 17:50:55.989736: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: path_to_my_model/assets

বিস্তারিত জানার জন্য, মডেল পড়া ধারাবাহিকতাতে & সংরক্ষণ গাইড।

একাধিক মডেল সংজ্ঞায়িত করতে স্তরগুলির একই গ্রাফ ব্যবহার করুন

কার্যকরী API-এ, মডেলগুলি স্তরগুলির একটি গ্রাফে তাদের ইনপুট এবং আউটপুটগুলি নির্দিষ্ট করে তৈরি করা হয়। এর মানে হল যে স্তরগুলির একটি একক গ্রাফ একাধিক মডেল তৈরি করতে ব্যবহার করা যেতে পারে।

নীচের উদাহরণে, আপনি দুই মডেলের instantiate করার স্তর একই স্ট্যাকের ব্যবহার করুন: একটি encoder মডেল যে 16-মাত্রিক ভেক্টর মধ্যে সক্রিয় ইমেজ ইনপুট, এবং একটি এন্ড-টু-এন্ড autoencoder প্রশিক্ষণের জন্য মডেল।

encoder_input = keras.Input(shape=(28, 28, 1), name="img")
x = layers.Conv2D(16, 3, activation="relu")(encoder_input)
x = layers.Conv2D(32, 3, activation="relu")(x)
x = layers.MaxPooling2D(3)(x)
x = layers.Conv2D(32, 3, activation="relu")(x)
x = layers.Conv2D(16, 3, activation="relu")(x)
encoder_output = layers.GlobalMaxPooling2D()(x)

encoder = keras.Model(encoder_input, encoder_output, name="encoder")
encoder.summary()

x = layers.Reshape((4, 4, 1))(encoder_output)
x = layers.Conv2DTranspose(16, 3, activation="relu")(x)
x = layers.Conv2DTranspose(32, 3, activation="relu")(x)
x = layers.UpSampling2D(3)(x)
x = layers.Conv2DTranspose(16, 3, activation="relu")(x)
decoder_output = layers.Conv2DTranspose(1, 3, activation="relu")(x)

autoencoder = keras.Model(encoder_input, decoder_output, name="autoencoder")
autoencoder.summary()
Model: "encoder"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
img (InputLayer)             [(None, 28, 28, 1)]       0         
_________________________________________________________________
conv2d (Conv2D)              (None, 26, 26, 16)        160       
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 24, 24, 32)        4640      
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 8, 8, 32)          0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 6, 6, 32)          9248      
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 4, 4, 16)          4624      
_________________________________________________________________
global_max_pooling2d (Global (None, 16)                0         
=================================================================
Total params: 18,672
Trainable params: 18,672
Non-trainable params: 0
_________________________________________________________________
Model: "autoencoder"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
img (InputLayer)             [(None, 28, 28, 1)]       0         
_________________________________________________________________
conv2d (Conv2D)              (None, 26, 26, 16)        160       
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 24, 24, 32)        4640      
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 8, 8, 32)          0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 6, 6, 32)          9248      
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 4, 4, 16)          4624      
_________________________________________________________________
global_max_pooling2d (Global (None, 16)                0         
_________________________________________________________________
reshape (Reshape)            (None, 4, 4, 1)           0         
_________________________________________________________________
conv2d_transpose (Conv2DTran (None, 6, 6, 16)          160       
_________________________________________________________________
conv2d_transpose_1 (Conv2DTr (None, 8, 8, 32)          4640      
_________________________________________________________________
up_sampling2d (UpSampling2D) (None, 24, 24, 32)        0         
_________________________________________________________________
conv2d_transpose_2 (Conv2DTr (None, 26, 26, 16)        4624      
_________________________________________________________________
conv2d_transpose_3 (Conv2DTr (None, 28, 28, 1)         145       
=================================================================
Total params: 28,241
Trainable params: 28,241
Non-trainable params: 0
_________________________________________________________________

এখানে, ডিকোডিং স্থাপত্য তাই আউটপুট আকৃতি ইনপুট আকৃতি হিসাবে একই, কঠোরভাবে এনকোডিং স্থাপত্যে প্রতিসম হয় (28, 28, 1)

একটি বিপরীত Conv2D স্তর একটি হল Conv2DTranspose স্তর, এবং একটি বিপরীত MaxPooling2D স্তর একটি হল UpSampling2D স্তর।

সমস্ত মডেল কলযোগ্য, ঠিক স্তরের মত

আপনি যে কোনো মডেল চিকিৎসা করতে পারে যেমন যদি এটা একটি তে এটি আবাহন করার মাধ্যমে একটি স্তর ছিল Input বা অন্য স্তর আউটপুট উপর। একটি মডেলকে কল করার মাধ্যমে আপনি কেবল মডেলটির আর্কিটেকচার পুনঃব্যবহার করছেন না, আপনি এর ওজনও পুনরায় ব্যবহার করছেন।

এটিকে কার্যকরভাবে দেখতে, এখানে অটোএনকোডার উদাহরণের একটি ভিন্ন পদক্ষেপ যা একটি এনকোডার মডেল, একটি ডিকোডার মডেল তৈরি করে এবং অটোএনকোডার মডেল পাওয়ার জন্য দুটি কলে চেইন করে:

encoder_input = keras.Input(shape=(28, 28, 1), name="original_img")
x = layers.Conv2D(16, 3, activation="relu")(encoder_input)
x = layers.Conv2D(32, 3, activation="relu")(x)
x = layers.MaxPooling2D(3)(x)
x = layers.Conv2D(32, 3, activation="relu")(x)
x = layers.Conv2D(16, 3, activation="relu")(x)
encoder_output = layers.GlobalMaxPooling2D()(x)

encoder = keras.Model(encoder_input, encoder_output, name="encoder")
encoder.summary()

decoder_input = keras.Input(shape=(16,), name="encoded_img")
x = layers.Reshape((4, 4, 1))(decoder_input)
x = layers.Conv2DTranspose(16, 3, activation="relu")(x)
x = layers.Conv2DTranspose(32, 3, activation="relu")(x)
x = layers.UpSampling2D(3)(x)
x = layers.Conv2DTranspose(16, 3, activation="relu")(x)
decoder_output = layers.Conv2DTranspose(1, 3, activation="relu")(x)

decoder = keras.Model(decoder_input, decoder_output, name="decoder")
decoder.summary()

autoencoder_input = keras.Input(shape=(28, 28, 1), name="img")
encoded_img = encoder(autoencoder_input)
decoded_img = decoder(encoded_img)
autoencoder = keras.Model(autoencoder_input, decoded_img, name="autoencoder")
autoencoder.summary()
Model: "encoder"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
original_img (InputLayer)    [(None, 28, 28, 1)]       0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 26, 26, 16)        160       
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 24, 24, 32)        4640      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 8, 8, 32)          0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 6, 6, 32)          9248      
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 4, 4, 16)          4624      
_________________________________________________________________
global_max_pooling2d_1 (Glob (None, 16)                0         
=================================================================
Total params: 18,672
Trainable params: 18,672
Non-trainable params: 0
_________________________________________________________________
Model: "decoder"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
encoded_img (InputLayer)     [(None, 16)]              0         
_________________________________________________________________
reshape_1 (Reshape)          (None, 4, 4, 1)           0         
_________________________________________________________________
conv2d_transpose_4 (Conv2DTr (None, 6, 6, 16)          160       
_________________________________________________________________
conv2d_transpose_5 (Conv2DTr (None, 8, 8, 32)          4640      
_________________________________________________________________
up_sampling2d_1 (UpSampling2 (None, 24, 24, 32)        0         
_________________________________________________________________
conv2d_transpose_6 (Conv2DTr (None, 26, 26, 16)        4624      
_________________________________________________________________
conv2d_transpose_7 (Conv2DTr (None, 28, 28, 1)         145       
=================================================================
Total params: 9,569
Trainable params: 9,569
Non-trainable params: 0
_________________________________________________________________
Model: "autoencoder"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
img (InputLayer)             [(None, 28, 28, 1)]       0         
_________________________________________________________________
encoder (Functional)         (None, 16)                18672     
_________________________________________________________________
decoder (Functional)         (None, 28, 28, 1)         9569      
=================================================================
Total params: 28,241
Trainable params: 28,241
Non-trainable params: 0
_________________________________________________________________

আপনি দেখতে পাচ্ছেন, মডেলটি নেস্ট করা যেতে পারে: একটি মডেলে সাব-মডেল থাকতে পারে (যেহেতু একটি মডেল একটি স্তরের মতো)। মডেল পাখির জন্য একটি সাধারণ ব্যবহারের ক্ষেত্রে ensembling করা হয়। উদাহরণস্বরূপ, এখানে মডেলগুলির একটি সেটকে একটি একক মডেলের সাথে সংযুক্ত করতে হয় যা তাদের ভবিষ্যদ্বাণীগুলির গড় করে:

def get_model():
    inputs = keras.Input(shape=(128,))
    outputs = layers.Dense(1)(inputs)
    return keras.Model(inputs, outputs)


model1 = get_model()
model2 = get_model()
model3 = get_model()

inputs = keras.Input(shape=(128,))
y1 = model1(inputs)
y2 = model2(inputs)
y3 = model3(inputs)
outputs = layers.average([y1, y2, y3])
ensemble_model = keras.Model(inputs=inputs, outputs=outputs)

জটিল গ্রাফ টপোলজি ম্যানিপুলেট করুন

একাধিক ইনপুট এবং আউটপুট সহ মডেল

কার্যকরী API একাধিক ইনপুট এবং আউটপুট ম্যানিপুলেট করা সহজ করে তোলে। এই নিয়ে নাড়াচাড়া করা যাবে না Sequential API- টি।

উদাহরণস্বরূপ, আপনি যদি গ্রাহকের ইস্যু টিকিটকে অগ্রাধিকার দিয়ে র‌্যাঙ্ক করার জন্য একটি সিস্টেম তৈরি করেন এবং সেগুলিকে সঠিক বিভাগে রাউটিং করেন, তাহলে মডেলটিতে তিনটি ইনপুট থাকবে:

  • টিকিটের শিরোনাম (টেক্সট ইনপুট),
  • টিকিটের টেক্সট বডি (টেক্সট ইনপুট), এবং
  • ব্যবহারকারীর দ্বারা যোগ করা কোনো ট্যাগ (বিষয়ক ইনপুট)

এই মডেলের দুটি আউটপুট থাকবে:

  • 0 এবং 1 এর মধ্যে অগ্রাধিকার স্কোর (স্কেলার সিগমায়েড আউটপুট), এবং
  • যে বিভাগটি টিকিট পরিচালনা করবে (বিভাগের সেটের উপর সফটম্যাক্স আউটপুট)।

আপনি কার্যকরী API এর সাথে কয়েকটি লাইনে এই মডেলটি তৈরি করতে পারেন:

num_tags = 12  # Number of unique issue tags
num_words = 10000  # Size of vocabulary obtained when preprocessing text data
num_departments = 4  # Number of departments for predictions

title_input = keras.Input(
    shape=(None,), name="title"
)  # Variable-length sequence of ints
body_input = keras.Input(shape=(None,), name="body")  # Variable-length sequence of ints
tags_input = keras.Input(
    shape=(num_tags,), name="tags"
)  # Binary vectors of size `num_tags`

# Embed each word in the title into a 64-dimensional vector
title_features = layers.Embedding(num_words, 64)(title_input)
# Embed each word in the text into a 64-dimensional vector
body_features = layers.Embedding(num_words, 64)(body_input)

# Reduce sequence of embedded words in the title into a single 128-dimensional vector
title_features = layers.LSTM(128)(title_features)
# Reduce sequence of embedded words in the body into a single 32-dimensional vector
body_features = layers.LSTM(32)(body_features)

# Merge all available features into a single large vector via concatenation
x = layers.concatenate([title_features, body_features, tags_input])

# Stick a logistic regression for priority prediction on top of the features
priority_pred = layers.Dense(1, name="priority")(x)
# Stick a department classifier on top of the features
department_pred = layers.Dense(num_departments, name="department")(x)

# Instantiate an end-to-end model predicting both priority and department
model = keras.Model(
    inputs=[title_input, body_input, tags_input],
    outputs=[priority_pred, department_pred],
)

এখন মডেল প্লট করুন:

keras.utils.plot_model(model, "multi_input_and_output_model.png", show_shapes=True)

png

এই মডেলটি কম্পাইল করার সময়, আপনি প্রতিটি আউটপুটে বিভিন্ন ক্ষতি নির্ধারণ করতে পারেন। এমনকি আপনি প্রতিটি ক্ষতির জন্য বিভিন্ন ওজন নির্ধারণ করতে পারেন -- মোট প্রশিক্ষণের ক্ষতিতে তাদের অবদানকে সংশোধন করতে।

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[
        keras.losses.BinaryCrossentropy(from_logits=True),
        keras.losses.CategoricalCrossentropy(from_logits=True),
    ],
    loss_weights=[1.0, 0.2],
)

যেহেতু আউটপুট স্তরগুলির বিভিন্ন নাম রয়েছে, আপনি সংশ্লিষ্ট স্তরের নামগুলির সাথে ক্ষতি এবং ক্ষতির ওজনও নির্দিষ্ট করতে পারেন:

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={
        "priority": keras.losses.BinaryCrossentropy(from_logits=True),
        "department": keras.losses.CategoricalCrossentropy(from_logits=True),
    },
    loss_weights={"priority": 1.0, "department": 0.2},
)

ইনপুট এবং লক্ষ্যগুলির NumPy অ্যারেগুলির তালিকা পাস করে মডেলকে প্রশিক্ষণ দিন:

# Dummy input data
title_data = np.random.randint(num_words, size=(1280, 10))
body_data = np.random.randint(num_words, size=(1280, 100))
tags_data = np.random.randint(2, size=(1280, num_tags)).astype("float32")

# Dummy target data
priority_targets = np.random.random(size=(1280, 1))
dept_targets = np.random.randint(2, size=(1280, num_departments))

model.fit(
    {"title": title_data, "body": body_data, "tags": tags_data},
    {"priority": priority_targets, "department": dept_targets},
    epochs=2,
    batch_size=32,
)
Epoch 1/2
40/40 [==============================] - 5s 9ms/step - loss: 1.2899 - priority_loss: 0.7186 - department_loss: 2.8564
Epoch 2/2
40/40 [==============================] - 0s 9ms/step - loss: 1.2668 - priority_loss: 0.6991 - department_loss: 2.8389
<keras.callbacks.History at 0x7fc1a66dc790>

যখন একটি সঙ্গে হইয়া কলিং Dataset বস্তু, এটা হয় মত তালিকার একটি tuple উত্পাদ উচিত ([title_data, body_data, tags_data], [priority_targets, dept_targets]) বা মত অভিধান একটি tuple ({'title': title_data, 'body': body_data, 'tags': tags_data}, {'priority': priority_targets, 'department': dept_targets})

আরো বিস্তারিত ব্যাখ্যার জন্য দেখুন, পড়ুন প্রশিক্ষণ ও মূল্যায়ন গাইড।

একটি খেলনা ResNet মডেল

একাধিক ইনপুট এবং আউটপুট সঙ্গে মডেল ছাড়াও, ক্রিয়ামূলক এপিআই এটা সহজ অ রৈখিক সংযোগ ভূ নিপূণভাবে করে তোলে - এই তিনটি স্তরের যে ক্রমানুসারে সংযুক্ত করা হয় না, যা দিয়ে মডেল আছে Sequential এপিআই হ্যান্ডেল করতে পারে না।

এটির জন্য একটি সাধারণ ব্যবহারের ক্ষেত্রে অবশিষ্ট সংযোগগুলি। আসুন এটি প্রদর্শনের জন্য CIFAR10 এর জন্য একটি খেলনা ResNet মডেল তৈরি করি:

inputs = keras.Input(shape=(32, 32, 3), name="img")
x = layers.Conv2D(32, 3, activation="relu")(inputs)
x = layers.Conv2D(64, 3, activation="relu")(x)
block_1_output = layers.MaxPooling2D(3)(x)

x = layers.Conv2D(64, 3, activation="relu", padding="same")(block_1_output)
x = layers.Conv2D(64, 3, activation="relu", padding="same")(x)
block_2_output = layers.add([x, block_1_output])

x = layers.Conv2D(64, 3, activation="relu", padding="same")(block_2_output)
x = layers.Conv2D(64, 3, activation="relu", padding="same")(x)
block_3_output = layers.add([x, block_2_output])

x = layers.Conv2D(64, 3, activation="relu")(block_3_output)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(256, activation="relu")(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(10)(x)

model = keras.Model(inputs, outputs, name="toy_resnet")
model.summary()
Model: "toy_resnet"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
img (InputLayer)                [(None, 32, 32, 3)]  0                                            
__________________________________________________________________________________________________
conv2d_8 (Conv2D)               (None, 30, 30, 32)   896         img[0][0]                        
__________________________________________________________________________________________________
conv2d_9 (Conv2D)               (None, 28, 28, 64)   18496       conv2d_8[0][0]                   
__________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D)  (None, 9, 9, 64)     0           conv2d_9[0][0]                   
__________________________________________________________________________________________________
conv2d_10 (Conv2D)              (None, 9, 9, 64)     36928       max_pooling2d_2[0][0]            
__________________________________________________________________________________________________
conv2d_11 (Conv2D)              (None, 9, 9, 64)     36928       conv2d_10[0][0]                  
__________________________________________________________________________________________________
add (Add)                       (None, 9, 9, 64)     0           conv2d_11[0][0]                  
                                                                 max_pooling2d_2[0][0]            
__________________________________________________________________________________________________
conv2d_12 (Conv2D)              (None, 9, 9, 64)     36928       add[0][0]                        
__________________________________________________________________________________________________
conv2d_13 (Conv2D)              (None, 9, 9, 64)     36928       conv2d_12[0][0]                  
__________________________________________________________________________________________________
add_1 (Add)                     (None, 9, 9, 64)     0           conv2d_13[0][0]                  
                                                                 add[0][0]                        
__________________________________________________________________________________________________
conv2d_14 (Conv2D)              (None, 7, 7, 64)     36928       add_1[0][0]                      
__________________________________________________________________________________________________
global_average_pooling2d (Globa (None, 64)           0           conv2d_14[0][0]                  
__________________________________________________________________________________________________
dense_6 (Dense)                 (None, 256)          16640       global_average_pooling2d[0][0]   
__________________________________________________________________________________________________
dropout (Dropout)               (None, 256)          0           dense_6[0][0]                    
__________________________________________________________________________________________________
dense_7 (Dense)                 (None, 10)           2570        dropout[0][0]                    
==================================================================================================
Total params: 223,242
Trainable params: 223,242
Non-trainable params: 0
__________________________________________________________________________________________________

মডেল প্লট করুন:

keras.utils.plot_model(model, "mini_resnet.png", show_shapes=True)

png

এখন মডেলকে প্রশিক্ষণ দিন:

(x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data()

x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=keras.losses.CategoricalCrossentropy(from_logits=True),
    metrics=["acc"],
)
# We restrict the data to the first 1000 samples so as to limit execution time
# on Colab. Try to train on the entire dataset until convergence!
model.fit(x_train[:1000], y_train[:1000], batch_size=64, epochs=1, validation_split=0.2)
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170500096/170498071 [==============================] - 11s 0us/step
170508288/170498071 [==============================] - 11s 0us/step
13/13 [==============================] - 2s 29ms/step - loss: 2.3364 - acc: 0.1063 - val_loss: 2.2986 - val_acc: 0.0850
<keras.callbacks.History at 0x7fc19df22610>

ভাগ করা স্তর

ক্রিয়ামূলক API- এর জন্য আরেকটি ভাল ব্যবহার মডেলের ভাগ স্তর ব্যবহার করে। ভাগ করা স্তরগুলি এমন স্তরের দৃষ্টান্ত যা একই মডেলে একাধিকবার পুনরায় ব্যবহার করা হয় -- তারা এমন বৈশিষ্ট্যগুলি শিখে যা গ্রাফ-অফ-লেয়ারের একাধিক পাথের সাথে মিলে যায়৷

ভাগ করা স্তরগুলি প্রায়শই একই স্পেস থেকে ইনপুটগুলিকে এনকোড করতে ব্যবহৃত হয় (বলুন, দুটি ভিন্ন অংশের পাঠ্য যা একই রকম শব্দভান্ডার বৈশিষ্ট্যযুক্ত)। তারা এই বিভিন্ন ইনপুট জুড়ে তথ্য ভাগাভাগি সক্ষম করে, এবং তারা কম ডেটাতে এই জাতীয় মডেলকে প্রশিক্ষণ দেওয়া সম্ভব করে তোলে। যদি একটি প্রদত্ত শব্দ একটি ইনপুট দেখা যায়, তাহলে এটি শেয়ার করা স্তরের মধ্য দিয়ে যাওয়া সমস্ত ইনপুটগুলির প্রক্রিয়াকরণের জন্য উপকৃত হবে৷

কার্যকরী API এ একটি স্তর ভাগ করতে, একই স্তরের উদাহরণ একাধিকবার কল করুন। উদাহরণস্বরূপ, এখানে একটি ব্যাপার Embedding স্তর দুটি ভিন্ন টেক্সট ইনপুট জুড়ে ভাগ করেছে:

# Embedding for 1000 unique words mapped to 128-dimensional vectors
shared_embedding = layers.Embedding(1000, 128)

# Variable-length sequence of integers
text_input_a = keras.Input(shape=(None,), dtype="int32")

# Variable-length sequence of integers
text_input_b = keras.Input(shape=(None,), dtype="int32")

# Reuse the same layer to encode both inputs
encoded_input_a = shared_embedding(text_input_a)
encoded_input_b = shared_embedding(text_input_b)

স্তরগুলির গ্রাফে নোডগুলি বের করুন এবং পুনরায় ব্যবহার করুন

কারণ আপনি যে স্তরগুলির গ্রাফটি ম্যানিপুলেট করছেন তা একটি স্ট্যাটিক ডেটা স্ট্রাকচার, এটি অ্যাক্সেস এবং পরিদর্শন করা যেতে পারে। এবং এইভাবে আপনি ইমেজ হিসাবে কার্যকরী মডেল প্লট করতে সক্ষম হন।

এর মানে হল যে আপনি মধ্যবর্তী স্তরগুলির সক্রিয়করণগুলি অ্যাক্সেস করতে পারেন (গ্রাফে "নোড") এবং সেগুলি অন্য কোথাও পুনরায় ব্যবহার করতে পারেন -- যা বৈশিষ্ট্য নিষ্কাশনের মতো কিছুর জন্য খুব দরকারী।

এর একটি উদাহরণ তাকান. এটি একটি VGG19 মডেল যার ওজন ইমেজনেটে ​​আগে থেকে প্রশিক্ষিত:

vgg19 = tf.keras.applications.VGG19()
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/vgg19/vgg19_weights_tf_dim_ordering_tf_kernels.h5
574717952/574710816 [==============================] - 15s 0us/step
574726144/574710816 [==============================] - 15s 0us/step

এবং এইগুলি হল মডেলের মধ্যবর্তী অ্যাক্টিভেশনগুলি, গ্রাফ ডেটা স্ট্রাকচার অনুসন্ধান করে প্রাপ্ত:

features_list = [layer.output for layer in vgg19.layers]

একটি নতুন বৈশিষ্ট্য-নিষ্কাশন মডেল তৈরি করতে এই বৈশিষ্ট্যগুলি ব্যবহার করুন যা মধ্যবর্তী স্তর সক্রিয়করণের মান প্রদান করে:

feat_extraction_model = keras.Model(inputs=vgg19.input, outputs=features_list)

img = np.random.random((1, 224, 224, 3)).astype("float32")
extracted_features = feat_extraction_model(img)

এই মত কাজের জন্য উপকারে আসে নিউরাল শৈলী হস্তান্তর , অন্যান্য বিষয়ের মধ্যে।

কাস্টম স্তরগুলি ব্যবহার করে API প্রসারিত করুন

tf.keras বিস্তৃত রয়েছে বিল্ট-ইন স্তর, উদাহরণস্বরূপ:

  • Convolutional স্তর: Conv1D , Conv2D , Conv3D , Conv2DTranspose
  • পুলিং স্তর: MaxPooling1D , MaxPooling2D , MaxPooling3D , AveragePooling1D
  • RNN স্তর: GRU , LSTM , ConvLSTM2D
  • BatchNormalization , Dropout , Embedding , ইত্যাদি

কিন্তু যদি আপনি আপনার যা প্রয়োজন তা খুঁজে না পান, আপনার নিজস্ব স্তর তৈরি করে API প্রসারিত করা সহজ। সকল স্তরের উপশ্রেণী Layer শ্রেণী এবং বাস্তবায়ন:

  • call পদ্ধতি, যে নির্দিষ্ট করে গুনতি স্তর দ্বারা সম্পন্ন।
  • build পদ্ধতি, যে স্তরের ওজন তৈরি করে (যেহেতু আপনি ওজন তৈরি করতে পারেন শুধু এই একটি শৈলী কনভেনশন __init__ , ভাল হিসাবে)।

গোড়া থেকে স্তর তৈরি করা সম্পর্কে আরো জানতে, পড়তে কাস্টম স্তর এবং মডেল গাইড।

নিম্নলিখিত একটি মৌলিক বাস্তবায়ন tf.keras.layers.Dense :

class CustomDense(layers.Layer):
    def __init__(self, units=32):
        super(CustomDense, self).__init__()
        self.units = units

    def build(self, input_shape):
        self.w = self.add_weight(
            shape=(input_shape[-1], self.units),
            initializer="random_normal",
            trainable=True,
        )
        self.b = self.add_weight(
            shape=(self.units,), initializer="random_normal", trainable=True
        )

    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b


inputs = keras.Input((4,))
outputs = CustomDense(10)(inputs)

model = keras.Model(inputs, outputs)

আপনার কাস্টম স্তরে ধারাবাহিকতাতে সমর্থনের জন্য একটি সংজ্ঞায়িত get_config পদ্ধতি যা স্তর উদাহরণস্বরূপ প্রস্ততকর্তার আর্গুমেন্ট ফেরৎ:

class CustomDense(layers.Layer):
    def __init__(self, units=32):
        super(CustomDense, self).__init__()
        self.units = units

    def build(self, input_shape):
        self.w = self.add_weight(
            shape=(input_shape[-1], self.units),
            initializer="random_normal",
            trainable=True,
        )
        self.b = self.add_weight(
            shape=(self.units,), initializer="random_normal", trainable=True
        )

    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b

    def get_config(self):
        return {"units": self.units}


inputs = keras.Input((4,))
outputs = CustomDense(10)(inputs)

model = keras.Model(inputs, outputs)
config = model.get_config()

new_model = keras.Model.from_config(config, custom_objects={"CustomDense": CustomDense})

বৈকল্পিকভাবে, বর্গ পদ্ধতি বাস্তবায়ন from_config(cls, config) যা recreating একটি স্তর উদাহরণস্বরূপ তার কনফিগ অভিধান প্রদত্ত ব্যবহার করা হয়। ডিফল্ট বাস্তবায়ন from_config হল:

def from_config(cls, config):
  return cls(**config)

কখন কার্যকরী API ব্যবহার করবেন

যদি আপনি একটি নতুন মডেল তৈরি করতে, বা শুধু উপশ্রেণী Keras কার্মিক API- টি ব্যবহার করা উচিত Model সরাসরি বর্গ? সাধারণভাবে, কার্যকরী API উচ্চ-স্তরের, সহজ এবং নিরাপদ, এবং এতে অনেকগুলি বৈশিষ্ট্য রয়েছে যা উপশ্রেণীভুক্ত মডেলগুলি সমর্থন করে না।

যাইহোক, স্তরগুলির নির্দেশিত অ্যাসাইক্লিক গ্রাফ হিসাবে সহজেই প্রকাশযোগ্য নয় এমন মডেলগুলি তৈরি করার সময় মডেল সাবক্লাসিং আরও বেশি নমনীয়তা প্রদান করে। উদাহরণস্বরূপ, যদি আপনি কার্মিক এপিআই সঙ্গে একটি গাছ-RNN বাস্তবায়ন করতে পারেনি এবং উপশ্রেণী করতে হবে Model সরাসরি।

ক্রিয়ামূলক এপিআই এবং মডেল subclassing মধ্যে পার্থক্য একটি মধ্যে গভীরতা বর্ণন জন্য, পড়া TensorFlow 2.0 প্রতীকী এবং অনুজ্ঞাসূচক API গুলি কি কি? .

কার্যকরী API শক্তি:

নিম্নলিখিত বৈশিষ্ট্যগুলি অনুক্রমিক মডেলগুলির জন্যও সত্য (যা ডেটা স্ট্রাকচারও), তবে সাবক্লাসড মডেলগুলির জন্য সত্য নয় (যা পাইথন বাইটকোড, ডেটা স্ট্রাকচার নয়)।

কম শব্দবাচক

কোন নেই super(MyClass, self).__init__(...) , কোন def call(self, ...): ইত্যাদি

তুলনা করা:

inputs = keras.Input(shape=(32,))
x = layers.Dense(64, activation='relu')(inputs)
outputs = layers.Dense(10)(x)
mlp = keras.Model(inputs, outputs)

উপশ্রেণীর সংস্করণ সহ:

class MLP(keras.Model):

  def __init__(self, **kwargs):
    super(MLP, self).__init__(**kwargs)
    self.dense_1 = layers.Dense(64, activation='relu')
    self.dense_2 = layers.Dense(10)

  def call(self, inputs):
    x = self.dense_1(inputs)
    return self.dense_2(x)

# Instantiate the model.
mlp = MLP()
# Necessary to create the model's state.
# The model doesn't have a state until it's called at least once.
_ = mlp(tf.zeros((1, 32)))

এর সংযোগ গ্রাফ সংজ্ঞায়িত করার সময় মডেলের বৈধতা

ক্রিয়ামূলক API এ, ইনপুট স্পেসিফিকেসন (আকৃতি এবং dtype) আগাম তৈরি করা হয় (ব্যবহার Input )। আপনি যখনই একটি স্তরকে কল করেন, স্তরটি পরীক্ষা করে যে এটিতে পাস করা স্পেসিফিকেশনটি তার অনুমানের সাথে মেলে এবং এটি না হলে এটি একটি সহায়ক ত্রুটি বার্তা উত্থাপন করবে।

এটি গ্যারান্টি দেয় যে আপনি কার্যকরী API দিয়ে তৈরি করতে পারেন এমন যেকোনো মডেল চলবে। সমস্ত ডিবাগিং -- কনভারজেন্স-সম্পর্কিত ডিবাগিং ব্যতীত -- মডেল নির্মাণের সময় স্থিরভাবে ঘটে এবং কার্যকর করার সময় নয়। এটি একটি কম্পাইলার টাইপ চেকিং অনুরূপ.

একটি কার্যকরী মডেল প্লটযোগ্য এবং পরিদর্শনযোগ্য

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

features_list = [layer.output for layer in vgg19.layers]
feat_extraction_model = keras.Model(inputs=vgg19.input, outputs=features_list)

একটি কার্যকরী মডেল ক্রমিক বা ক্লোন করা যেতে পারে

যেহেতু একটি কার্যকরী মডেল কোডের একটি অংশের পরিবর্তে একটি ডেটা স্ট্রাকচার, এটি নিরাপদে সিরিয়ালাইজযোগ্য এবং একটি একক ফাইল হিসাবে সংরক্ষণ করা যেতে পারে যা আপনাকে মূল কোডের কোনোটিতে অ্যাক্সেস না করেই একই মডেলটি পুনরায় তৈরি করতে দেয়। দেখুন ধারাবাহিকতাতে & সংরক্ষণ নির্দেশিকা

একটি subclassed মডেল ধারাবাহিকভাবে করার জন্য, এটা implementer একটি নির্দিষ্ট করার জন্য প্রয়োজনীয় get_config() এবং from_config() মডেল পর্যায়ে পদ্ধতি।

কার্যকরী API দুর্বলতা:

এটি গতিশীল আর্কিটেকচার সমর্থন করে না

কার্যকরী API মডেলগুলিকে স্তরগুলির DAG হিসাবে বিবেচনা করে। এটি বেশিরভাগ ডিপ লার্নিং আর্কিটেকচারের জন্য সত্য, কিন্তু সবকটি নয় -- উদাহরণস্বরূপ, রিকার্সিভ নেটওয়ার্ক বা ট্রি আরএনএন এই ধারণাটি অনুসরণ করে না এবং কার্যকরী API-তে প্রয়োগ করা যায় না।

এপিআই শৈলী মিক্স এবং ম্যাচ করুন

কার্যকরী API বা মডেল সাবক্লাসিং এর মধ্যে নির্বাচন করা একটি বাইনারি সিদ্ধান্ত নয় যা আপনাকে মডেলের একটি বিভাগে সীমাবদ্ধ করে। সকল মডেল tf.keras এপিআই একে অপরের সাথে যোগাযোগ করতে পারেন কিনা তারা Sequential মডেল, ক্রিয়ামূলক মডেল, বা subclassed মডেলের যে গোড়া থেকে লেখা হয়।

আপনি সর্বদা একটি কার্মিক মডেল বা ব্যবহার করতে পারেন Sequential একটি subclassed মডেল বা স্তর অংশ হিসেবে মডেল:

units = 32
timesteps = 10
input_dim = 5

# Define a Functional model
inputs = keras.Input((None, units))
x = layers.GlobalAveragePooling1D()(inputs)
outputs = layers.Dense(1)(x)
model = keras.Model(inputs, outputs)


class CustomRNN(layers.Layer):
    def __init__(self):
        super(CustomRNN, self).__init__()
        self.units = units
        self.projection_1 = layers.Dense(units=units, activation="tanh")
        self.projection_2 = layers.Dense(units=units, activation="tanh")
        # Our previously-defined Functional model
        self.classifier = model

    def call(self, inputs):
        outputs = []
        state = tf.zeros(shape=(inputs.shape[0], self.units))
        for t in range(inputs.shape[1]):
            x = inputs[:, t, :]
            h = self.projection_1(x)
            y = h + self.projection_2(state)
            state = y
            outputs.append(y)
        features = tf.stack(outputs, axis=1)
        print(features.shape)
        return self.classifier(features)


rnn_model = CustomRNN()
_ = rnn_model(tf.zeros((1, timesteps, input_dim)))
(1, 10, 32)

তোমরা সেখানে বেশী দিন একটি প্রয়োগ হিসাবে হিসাবে কোনো subclassed স্তর বা কার্মিক API এ মডেল ব্যবহার করতে পারেন call পদ্ধতি নিম্নলিখিত প্যাটার্নের এক অনুসরণ করে:

  • call(self, inputs, **kwargs) - কোথায় inputs একটি টেন্সর বা tensors একটি নেস্টেড গঠন (tensors এর যেমন একটি তালিকা), এবং যেখানে **kwargs অ টেন্সর আর্গুমেন্ট (অ-ইনপুট) হয়।
  • call(self, inputs, training=None, **kwargs) - কোথায় training একটি বুলিয়ান কিনা তা নির্দেশ স্তর প্রশিক্ষণ মোড এবং অনুমান মোডে আচরণ হবে।
  • call(self, inputs, mask=None, **kwargs) - কোথায় mask একটি বুলিয়ান মাস্ক টেন্সর হয় (RNNs জন্য দরকারী উদাহরণস্বরূপ)।
  • call(self, inputs, training=None, mask=None, **kwargs) - অবশ্যই, আপনি একই সময়ে উভয় মাস্কিং ও প্রশিক্ষণ-নির্দিষ্ট আচরণ থাকতে পারে।

উপরন্তু, যদি আপনি বাস্তবায়ন get_config আপনার কাস্টম লেয়ার বা মডেল পদ্ধতি, ক্রিয়ামূলক মডেল আপনার তৈরি এখনও serializable এবং cloneable হবে।

এখানে একটি কাস্টম RNN এর একটি দ্রুত উদাহরণ, স্ক্র্যাচ থেকে লেখা, একটি কার্যকরী মডেলে ব্যবহৃত হচ্ছে:

units = 32
timesteps = 10
input_dim = 5
batch_size = 16


class CustomRNN(layers.Layer):
    def __init__(self):
        super(CustomRNN, self).__init__()
        self.units = units
        self.projection_1 = layers.Dense(units=units, activation="tanh")
        self.projection_2 = layers.Dense(units=units, activation="tanh")
        self.classifier = layers.Dense(1)

    def call(self, inputs):
        outputs = []
        state = tf.zeros(shape=(inputs.shape[0], self.units))
        for t in range(inputs.shape[1]):
            x = inputs[:, t, :]
            h = self.projection_1(x)
            y = h + self.projection_2(state)
            state = y
            outputs.append(y)
        features = tf.stack(outputs, axis=1)
        return self.classifier(features)


# Note that you specify a static batch size for the inputs with the `batch_shape`
# arg, because the inner computation of `CustomRNN` requires a static batch size
# (when you create the `state` zeros tensor).
inputs = keras.Input(batch_shape=(batch_size, timesteps, input_dim))
x = layers.Conv1D(32, 3)(inputs)
outputs = CustomRNN()(x)

model = keras.Model(inputs, outputs)

rnn_model = CustomRNN()
_ = rnn_model(tf.zeros((1, 10, 5)))