মডিউল, স্তর এবং মডেলগুলির ভূমিকা

সেভ করা পৃষ্ঠা গুছিয়ে রাখতে 'সংগ্রহ' ব্যবহার করুন আপনার পছন্দ অনুযায়ী কন্টেন্ট সেভ করুন ও সঠিক বিভাগে রাখুন।

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

টেনসরফ্লোতে মেশিন লার্নিং করতে, আপনাকে সম্ভবত একটি মডেল সংজ্ঞায়িত, সংরক্ষণ এবং পুনরুদ্ধার করতে হবে।

একটি মডেল হল, বিমূর্তভাবে:

  • একটি ফাংশন যা টেনসরগুলিতে কিছু গণনা করে (একটি ফরোয়ার্ড পাস )
  • কিছু ভেরিয়েবল যা প্রশিক্ষণের প্রতিক্রিয়া হিসাবে আপডেট করা যেতে পারে

এই নির্দেশিকায়, টেনসরফ্লো মডেলগুলি কীভাবে সংজ্ঞায়িত করা হয়েছে তা দেখতে আপনি কেরাসের পৃষ্ঠের নীচে যাবেন। এটি TensorFlow কীভাবে ভেরিয়েবল এবং মডেল সংগ্রহ করে, সেইসাথে সেগুলি কীভাবে সংরক্ষিত এবং পুনরুদ্ধার করা হয় তা দেখায়।

সেটআপ

import tensorflow as tf
from datetime import datetime

%load_ext tensorboard

TensorFlow-এ মডেল এবং স্তর সংজ্ঞায়িত করা

বেশিরভাগ মডেলই স্তর দিয়ে তৈরি। স্তরগুলি একটি পরিচিত গাণিতিক কাঠামো সহ ফাংশন যা পুনরায় ব্যবহার করা যেতে পারে এবং প্রশিক্ষণযোগ্য ভেরিয়েবল থাকতে পারে। টেনসরফ্লোতে, কেরাস বা সনেটের মতো স্তর এবং মডেলগুলির বেশিরভাগ উচ্চ-স্তরের বাস্তবায়ন একই ফাউন্ডেশনাল ক্লাসে নির্মিত হয়: tf.Module

এখানে একটি খুব সাধারণ tf. মডিউলের একটি উদাহরণ যা একটি স্কেলার tf.Module কাজ করে:

class SimpleModule(tf.Module):
  def __init__(self, name=None):
    super().__init__(name=name)
    self.a_variable = tf.Variable(5.0, name="train_me")
    self.non_trainable_variable = tf.Variable(5.0, trainable=False, name="do_not_train_me")
  def __call__(self, x):
    return self.a_variable * x + self.non_trainable_variable

simple_module = SimpleModule(name="simple")

simple_module(tf.constant(5.0))
<tf.Tensor: shape=(), dtype=float32, numpy=30.0>

মডিউল এবং, এক্সটেনশন দ্বারা, স্তরগুলি হল "বস্তুগুলির" জন্য গভীর-শিক্ষার পরিভাষা: তাদের অভ্যন্তরীণ অবস্থা এবং পদ্ধতিগুলি সেই অবস্থা ব্যবহার করে।

পাইথন কলেবলের মত কাজ করা ছাড়া __call__ সম্পর্কে বিশেষ কিছু নেই; আপনি আপনার ইচ্ছামত ফাংশন সঙ্গে আপনার মডেল আহ্বান করতে পারেন.

আপনি সূক্ষ্ম-টিউনিংয়ের সময় জমা স্তর এবং ভেরিয়েবল সহ যে কোনও কারণে ভেরিয়েবলের প্রশিক্ষণযোগ্যতা সেট করতে পারেন।

tf.Module সাবক্লাস করার মাধ্যমে, এই বস্তুর বৈশিষ্ট্যের জন্য নির্ধারিত যেকোন tf.Variable বা tf.Module দৃষ্টান্ত স্বয়ংক্রিয়ভাবে সংগ্রহ করা হয়। এটি আপনাকে ভেরিয়েবল সংরক্ষণ এবং লোড করতে এবং tf.Module s এর সংগ্রহ তৈরি করতে দেয়।

# All trainable variables
print("trainable variables:", simple_module.trainable_variables)
# Every variable
print("all variables:", simple_module.variables)
trainable variables: (<tf.Variable 'train_me:0' shape=() dtype=float32, numpy=5.0>,)
all variables: (<tf.Variable 'train_me:0' shape=() dtype=float32, numpy=5.0>, <tf.Variable 'do_not_train_me:0' shape=() dtype=float32, numpy=5.0>)
2021-10-26 01:29:45.284549: 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.

এটি মডিউল দিয়ে তৈরি একটি দ্বি-স্তর রৈখিক স্তর মডেলের একটি উদাহরণ।

প্রথমে একটি ঘন (রৈখিক) স্তর:

class Dense(tf.Module):
  def __init__(self, in_features, out_features, name=None):
    super().__init__(name=name)
    self.w = tf.Variable(
      tf.random.normal([in_features, out_features]), name='w')
    self.b = tf.Variable(tf.zeros([out_features]), name='b')
  def __call__(self, x):
    y = tf.matmul(x, self.w) + self.b
    return tf.nn.relu(y)

এবং তারপর সম্পূর্ণ মডেল, যা দুটি স্তর উদাহরণ তৈরি করে এবং তাদের প্রয়োগ করে:

class SequentialModule(tf.Module):
  def __init__(self, name=None):
    super().__init__(name=name)

    self.dense_1 = Dense(in_features=3, out_features=3)
    self.dense_2 = Dense(in_features=3, out_features=2)

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

# You have made a model!
my_model = SequentialModule(name="the_model")

# Call it, with random results
print("Model results:", my_model(tf.constant([[2.0, 2.0, 2.0]])))
Model results: tf.Tensor([[7.706234  3.0919805]], shape=(1, 2), dtype=float32)

tf.Module দৃষ্টান্তগুলি স্বয়ংক্রিয়ভাবে সংগ্রহ করবে, পুনরাবৃত্তিমূলকভাবে, এটিতে নির্ধারিত যেকোন tf.Variable বা tf.Module দৃষ্টান্তগুলি। এটি আপনাকে একটি একক মডেল উদাহরণ সহ tf.Module s এর সংগ্রহ পরিচালনা করতে এবং পুরো মডেলগুলি সংরক্ষণ এবং লোড করতে দেয়।

print("Submodules:", my_model.submodules)
Submodules: (<__main__.Dense object at 0x7f7ab2391290>, <__main__.Dense object at 0x7f7b6869ea10>)
for var in my_model.variables:
  print(var, "\n")
<tf.Variable 'b:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)> 

<tf.Variable 'w:0' shape=(3, 3) dtype=float32, numpy=
array([[ 0.05711935,  0.22440144,  0.6370985 ],
       [ 0.3136791 , -1.7006774 ,  0.7256515 ],
       [ 0.16120772, -0.8412193 ,  0.5250952 ]], dtype=float32)> 

<tf.Variable 'b:0' shape=(2,) dtype=float32, numpy=array([0., 0.], dtype=float32)> 

<tf.Variable 'w:0' shape=(3, 2) dtype=float32, numpy=
array([[-0.5353216 ,  1.2815404 ],
       [ 0.62764466,  0.47087234],
       [ 2.19187   ,  0.45777202]], dtype=float32)>

ভেরিয়েবল তৈরি করার জন্য অপেক্ষা করা হচ্ছে

আপনি এখানে লক্ষ্য করেছেন যে আপনাকে স্তরটিতে ইনপুট এবং আউটপুট উভয় আকার নির্ধারণ করতে হবে। এটি তাই w ভেরিয়েবলের একটি পরিচিত আকৃতি রয়েছে এবং বরাদ্দ করা যেতে পারে।

একটি নির্দিষ্ট ইনপুট আকারের সাথে মডিউলটিকে প্রথমবার কল করার সময় পরিবর্তনশীল সৃষ্টিকে স্থগিত করে, আপনার সামনে ইনপুট আকার নির্দিষ্ট করার দরকার নেই।

class FlexibleDenseModule(tf.Module):
  # Note: No need for `in_features`
  def __init__(self, out_features, name=None):
    super().__init__(name=name)
    self.is_built = False
    self.out_features = out_features

  def __call__(self, x):
    # Create variables on first call.
    if not self.is_built:
      self.w = tf.Variable(
        tf.random.normal([x.shape[-1], self.out_features]), name='w')
      self.b = tf.Variable(tf.zeros([self.out_features]), name='b')
      self.is_built = True

    y = tf.matmul(x, self.w) + self.b
    return tf.nn.relu(y)
# Used in a module
class MySequentialModule(tf.Module):
  def __init__(self, name=None):
    super().__init__(name=name)

    self.dense_1 = FlexibleDenseModule(out_features=3)
    self.dense_2 = FlexibleDenseModule(out_features=2)

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

my_model = MySequentialModule(name="the_model")
print("Model results:", my_model(tf.constant([[2.0, 2.0, 2.0]])))
Model results: tf.Tensor([[4.0598335 0.       ]], shape=(1, 2), dtype=float32)

এই নমনীয়তার কারণেই TensorFlow স্তরগুলিকে প্রায়শই শুধুমাত্র তাদের আউটপুটগুলির আকৃতি নির্দিষ্ট করতে হয়, যেমন tf.keras.layers.Dense এ, ইনপুট এবং আউটপুট উভয় আকারের পরিবর্তে।

ওজন সংরক্ষণ

আপনি একটি tf.Module একটি চেকপয়েন্ট এবং একটি tf.Module উভয় হিসাবে সংরক্ষণ করতে পারেন।

চেকপয়েন্টগুলি কেবলমাত্র ওজন (অর্থাৎ, মডিউল এবং এর সাবমডিউলগুলির মধ্যে ভেরিয়েবলের সেটের মান):

chkp_path = "my_checkpoint"
checkpoint = tf.train.Checkpoint(model=my_model)
checkpoint.write(chkp_path)
'my_checkpoint'

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

ls my_checkpoint*
my_checkpoint.data-00000-of-00001  my_checkpoint.index

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

tf.train.list_variables(chkp_path)
[('_CHECKPOINTABLE_OBJECT_GRAPH', []),
 ('model/dense_1/b/.ATTRIBUTES/VARIABLE_VALUE', [3]),
 ('model/dense_1/w/.ATTRIBUTES/VARIABLE_VALUE', [3, 3]),
 ('model/dense_2/b/.ATTRIBUTES/VARIABLE_VALUE', [2]),
 ('model/dense_2/w/.ATTRIBUTES/VARIABLE_VALUE', [3, 2])]

বিতরণকৃত (মাল্টি-মেশিন) প্রশিক্ষণের সময় তাদের শার্ড করা যেতে পারে, এ কারণেই তাদের সংখ্যা করা হয় (যেমন, '00000-এর-00001')। এই ক্ষেত্রে, যদিও, শুধুমাত্র একটি শার্ড আছে.

আপনি যখন মডেলগুলি আবার লোড করেন, আপনি আপনার পাইথন অবজেক্টের মানগুলি ওভাররাইট করেন।

new_model = MySequentialModule()
new_checkpoint = tf.train.Checkpoint(model=new_model)
new_checkpoint.restore("my_checkpoint")

# Should be the same result as above
new_model(tf.constant([[2.0, 2.0, 2.0]]))
<tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[4.0598335, 0.       ]], dtype=float32)>

সংরক্ষণ ফাংশন

TensorFlow আসল পাইথন অবজেক্ট ছাড়াই মডেল চালাতে পারে, যেমন TensorFlow Serving এবং TensorFlow Lite দ্বারা দেখানো হয়েছে, এমনকি আপনি যখন TensorFlow Hub থেকে একটি প্রশিক্ষিত মডেল ডাউনলোড করেন।

TensorFlow কে পাইথনে বর্ণিত গণনাগুলি কীভাবে করতে হয় তা জানতে হবে, কিন্তু মূল কোড ছাড়াই । এটি করার জন্য, আপনি একটি গ্রাফ তৈরি করতে পারেন, যা গ্রাফ এবং ফাংশন নির্দেশিকাগুলির ভূমিকায় বর্ণিত হয়েছে।

এই গ্রাফটিতে ক্রিয়াকলাপ বা অপ্স রয়েছে যা ফাংশনটি বাস্তবায়ন করে।

আপনি @tf.function ডেকোরেটর যোগ করে উপরের মডেলটিতে একটি গ্রাফ সংজ্ঞায়িত করতে পারেন যাতে এই কোডটি একটি গ্রাফ হিসাবে চালানো উচিত।

class MySequentialModule(tf.Module):
  def __init__(self, name=None):
    super().__init__(name=name)

    self.dense_1 = Dense(in_features=3, out_features=3)
    self.dense_2 = Dense(in_features=3, out_features=2)

  @tf.function
  def __call__(self, x):
    x = self.dense_1(x)
    return self.dense_2(x)

# You have made a model with a graph!
my_model = MySequentialModule(name="the_model")

আপনার বানানো মডিউল ঠিক আগের মতই কাজ করে। ফাংশনে পাস করা প্রতিটি অনন্য স্বাক্ষর একটি পৃথক গ্রাফ তৈরি করে। বিস্তারিত জানার জন্য গ্রাফ এবং ফাংশন গাইডের ভূমিকা দেখুন।

print(my_model([[2.0, 2.0, 2.0]]))
print(my_model([[[2.0, 2.0, 2.0], [2.0, 2.0, 2.0]]]))
tf.Tensor([[0.62891716 0.        ]], shape=(1, 2), dtype=float32)
tf.Tensor(
[[[0.62891716 0.        ]
  [0.62891716 0.        ]]], shape=(1, 2, 2), dtype=float32)

আপনি একটি TensorBoard সারাংশের মধ্যে ট্রেস করে গ্রাফটিকে কল্পনা করতে পারেন।

# Set up logging.
stamp = datetime.now().strftime("%Y%m%d-%H%M%S")
logdir = "logs/func/%s" % stamp
writer = tf.summary.create_file_writer(logdir)

# Create a new model to get a fresh trace
# Otherwise the summary will not see the graph.
new_model = MySequentialModule()

# Bracket the function call with
# tf.summary.trace_on() and tf.summary.trace_export().
tf.summary.trace_on(graph=True)
tf.profiler.experimental.start(logdir)
# Call only one tf.function when tracing.
z = print(new_model(tf.constant([[2.0, 2.0, 2.0]])))
with writer.as_default():
  tf.summary.trace_export(
      name="my_func_trace",
      step=0,
      profiler_outdir=logdir)
tf.Tensor([[0.         0.01750386]], shape=(1, 2), dtype=float32)

ফলস্বরূপ ট্রেস দেখতে টেনসরবোর্ড চালু করুন:

#docs_infra: no_execute
%tensorboard --logdir logs/func

টেনসরবোর্ডে গ্রাফের একটি স্ক্রিনশট

একটি SavedModel

সম্পূর্ণ প্রশিক্ষিত মডেল শেয়ার করার প্রস্তাবিত উপায় হল SavedModel ব্যবহার করা। SavedModel এ ফাংশনের সংগ্রহ এবং ওজনের সংগ্রহ উভয়ই রয়েছে।

আপনি যে মডেলটি প্রশিক্ষিত করেছেন তা নিম্নরূপ সংরক্ষণ করতে পারেন:

tf.saved_model.save(my_model, "the_saved_model")
INFO:tensorflow:Assets written to: the_saved_model/assets
# Inspect the SavedModel in the directory
ls -l the_saved_model
total 24
drwxr-sr-x 2 kbuilder kokoro  4096 Oct 26 01:29 assets
-rw-rw-r-- 1 kbuilder kokoro 14702 Oct 26 01:29 saved_model.pb
drwxr-sr-x 2 kbuilder kokoro  4096 Oct 26 01:29 variables
# The variables/ directory contains a checkpoint of the variables
ls -l the_saved_model/variables
total 8
-rw-rw-r-- 1 kbuilder kokoro 408 Oct 26 01:29 variables.data-00000-of-00001
-rw-rw-r-- 1 kbuilder kokoro 356 Oct 26 01:29 variables.index

saved_model.pb ফাইলটি একটি প্রোটোকল বাফার যা কার্যকরী tf.Graph বর্ণনা করে।

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

আপনি মডেলটিকে নতুন অবজেক্ট হিসাবে লোড করতে পারেন:

new_model = tf.saved_model.load("the_saved_model")

new_model , একটি সংরক্ষিত মডেল লোড করার মাধ্যমে তৈরি করা হয়েছে, এটি একটি অভ্যন্তরীণ TensorFlow ব্যবহারকারী অবজেক্ট যা কোনো শ্রেণির জ্ঞান ছাড়াই। এটি SequentialModule টাইপের নয়।

isinstance(new_model, SequentialModule)
False

এই নতুন মডেলটি ইতিমধ্যে-সংজ্ঞায়িত ইনপুট স্বাক্ষরগুলিতে কাজ করে৷ আপনি এই মত পুনরুদ্ধার একটি মডেল আরো স্বাক্ষর যোগ করতে পারবেন না.

print(my_model([[2.0, 2.0, 2.0]]))
print(my_model([[[2.0, 2.0, 2.0], [2.0, 2.0, 2.0]]]))
tf.Tensor([[0.62891716 0.        ]], shape=(1, 2), dtype=float32)
tf.Tensor(
[[[0.62891716 0.        ]
  [0.62891716 0.        ]]], shape=(1, 2, 2), dtype=float32)

এইভাবে, SavedModel ব্যবহার করে, আপনি tf.Module ব্যবহার করে tf.Module ওজন এবং গ্রাফ সংরক্ষণ করতে পারবেন, এবং তারপরে আবার লোড করতে পারবেন।

কেরাস মডেল এবং স্তর

নোট করুন যে এই বিন্দু পর্যন্ত, কেরাসের কোন উল্লেখ নেই। আপনি tf.Module এর উপরে আপনার নিজস্ব উচ্চ-স্তরের API তৈরি করতে পারেন এবং লোকেদের আছে।

এই বিভাগে, আপনি কেরাস কিভাবে tf.Module ব্যবহার করে তা পরীক্ষা করবেন। কেরাস মডেলগুলির একটি সম্পূর্ণ ব্যবহারকারীর নির্দেশিকা কেরাস গাইডে পাওয়া যাবে।

কেরাস স্তর

tf.keras.layers.Layer হল কেরাস লেয়ারের বেস ক্লাস, এবং এটি tf.Module থেকে উত্তরাধিকারসূত্রে প্রাপ্ত।

আপনি একটি মডিউলকে কেরাস স্তরে রূপান্তর করতে পারেন শুধুমাত্র অভিভাবককে অদলবদল করে এবং তারপরে __call__ পরিবর্তন করে call করতে পারেন:

class MyDense(tf.keras.layers.Layer):
  # Adding **kwargs to support base Keras layer arguments
  def __init__(self, in_features, out_features, **kwargs):
    super().__init__(**kwargs)

    # This will soon move to the build step; see below
    self.w = tf.Variable(
      tf.random.normal([in_features, out_features]), name='w')
    self.b = tf.Variable(tf.zeros([out_features]), name='b')
  def call(self, x):
    y = tf.matmul(x, self.w) + self.b
    return tf.nn.relu(y)

simple_layer = MyDense(name="simple", in_features=3, out_features=3)

কেরাস স্তরগুলির নিজস্ব __call__ রয়েছে যা পরবর্তী বিভাগে বর্ণিত কিছু হিসাবরক্ষণ করে এবং তারপরে call() করে। আপনি কার্যকারিতা কোন পরিবর্তন লক্ষ্য করা উচিত নয়.

simple_layer([[2.0, 2.0, 2.0]])
<tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[0.      , 0.179402, 0.      ]], dtype=float32)>

build ধাপ

যেমন উল্লেখ করা হয়েছে, আপনি ইনপুট আকৃতি সম্পর্কে নিশ্চিত না হওয়া পর্যন্ত ভেরিয়েবল তৈরি করার জন্য অপেক্ষা করা অনেক ক্ষেত্রে সুবিধাজনক।

কেরাস স্তরগুলি একটি অতিরিক্ত জীবনচক্র পদক্ষেপের সাথে আসে যা আপনাকে আপনার স্তরগুলিকে কীভাবে সংজ্ঞায়িত করবে তাতে আরও নমনীয়তা দেয়৷ এটি build ফাংশনে সংজ্ঞায়িত করা হয়েছে।

build ঠিক একবার বলা হয়, এবং এটি ইনপুটের আকার দিয়ে বলা হয়। এটি সাধারণত ভেরিয়েবল (ওজন) তৈরি করতে ব্যবহৃত হয়।

এর ইনপুটগুলির আকারে নমনীয় হতে আপনি উপরে MyDense স্তরটি পুনরায় লিখতে পারেন:

class FlexibleDense(tf.keras.layers.Layer):
  # Note the added `**kwargs`, as Keras supports many arguments
  def __init__(self, out_features, **kwargs):
    super().__init__(**kwargs)
    self.out_features = out_features

  def build(self, input_shape):  # Create the state of the layer (weights)
    self.w = tf.Variable(
      tf.random.normal([input_shape[-1], self.out_features]), name='w')
    self.b = tf.Variable(tf.zeros([self.out_features]), name='b')

  def call(self, inputs):  # Defines the computation from inputs to outputs
    return tf.matmul(inputs, self.w) + self.b

# Create the instance of the layer
flexible_dense = FlexibleDense(out_features=3)

এই মুহুর্তে, মডেলটি তৈরি করা হয়নি, তাই কোন ভেরিয়েবল নেই:

flexible_dense.variables
[]

ফাংশন কল করা যথাযথভাবে আকারের ভেরিয়েবল বরাদ্দ করে:

# Call it, with predictably random results
print("Model results:", flexible_dense(tf.constant([[2.0, 2.0, 2.0], [3.0, 3.0, 3.0]])))
Model results: tf.Tensor(
[[-1.6998017  1.6444504 -1.3103955]
 [-2.5497022  2.4666753 -1.9655929]], shape=(2, 3), dtype=float32)
flexible_dense.variables
[<tf.Variable 'flexible_dense/w:0' shape=(3, 3) dtype=float32, numpy=
 array([[ 1.277462  ,  0.5399406 , -0.301957  ],
        [-1.6277349 ,  0.7374014 , -1.7651852 ],
        [-0.49962795, -0.45511687,  1.4119445 ]], dtype=float32)>,
 <tf.Variable 'flexible_dense/b:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>]

যেহেতু build শুধুমাত্র একবার বলা হয়, ইনপুট প্রত্যাখ্যান করা হবে যদি ইনপুট আকৃতি লেয়ারের ভেরিয়েবলের সাথে সামঞ্জস্যপূর্ণ না হয়:

try:
  print("Model results:", flexible_dense(tf.constant([[2.0, 2.0, 2.0, 2.0]])))
except tf.errors.InvalidArgumentError as e:
  print("Failed:", e)
Failed: In[0] mismatch In[1] shape: 4 vs. 3: [1,4] [3,3] 0 0 [Op:MatMul]

কেরাস স্তরগুলিতে আরও অনেক অতিরিক্ত বৈশিষ্ট্য রয়েছে যার মধ্যে রয়েছে:

  • ঐচ্ছিক লোকসান
  • মেট্রিক্স জন্য সমর্থন
  • প্রশিক্ষণ এবং অনুমান ব্যবহারের মধ্যে পার্থক্য করার জন্য একটি ঐচ্ছিক training আর্গুমেন্টের জন্য অন্তর্নির্মিত সমর্থন
  • get_config এবং from_config পদ্ধতি যা আপনাকে পাইথনে মডেল ক্লোনিংয়ের অনুমতি দেওয়ার জন্য সঠিকভাবে কনফিগারেশন সংরক্ষণ করতে দেয়

কাস্টম স্তর এবং মডেলগুলির সম্পূর্ণ গাইডে সেগুলি সম্পর্কে পড়ুন৷

কেরাস মডেল

আপনি আপনার মডেলটিকে নেস্টেড কেরাস স্তর হিসাবে সংজ্ঞায়িত করতে পারেন।

যাইহোক, কেরাস tf.keras.Model নামে একটি পূর্ণ-বৈশিষ্ট্যযুক্ত মডেল ক্লাস সরবরাহ করে। এটি tf.keras.layers.Layer থেকে উত্তরাধিকারসূত্রে প্রাপ্ত, তাই কেরাস মডেল ব্যবহার করা, নেস্ট করা এবং কেরাস স্তরগুলির মতো একইভাবে সংরক্ষণ করা যেতে পারে। কেরাস মডেলগুলি অতিরিক্ত কার্যকারিতার সাথে আসে যা তাদের প্রশিক্ষণ, মূল্যায়ন, লোড, সংরক্ষণ এবং এমনকি একাধিক মেশিনে প্রশিক্ষণ দেওয়া সহজ করে তোলে।

আপনি প্রায় অভিন্ন কোড দিয়ে উপরে থেকে SequentialModule মডিউল সংজ্ঞায়িত করতে পারেন, আবার __call__ কে call() তে রূপান্তর করতে এবং অভিভাবক পরিবর্তন করতে পারেন:

class MySequentialModel(tf.keras.Model):
  def __init__(self, name=None, **kwargs):
    super().__init__(**kwargs)

    self.dense_1 = FlexibleDense(out_features=3)
    self.dense_2 = FlexibleDense(out_features=2)
  def call(self, x):
    x = self.dense_1(x)
    return self.dense_2(x)

# You have made a Keras model!
my_sequential_model = MySequentialModel(name="the_model")

# Call it on a tensor, with random results
print("Model results:", my_sequential_model(tf.constant([[2.0, 2.0, 2.0]])))
Model results: tf.Tensor([[5.5604653 3.3511646]], shape=(1, 2), dtype=float32)

ট্র্যাকিং ভেরিয়েবল এবং সাবমডিউল সহ সমস্ত একই বৈশিষ্ট্য উপলব্ধ।

my_sequential_model.variables
[<tf.Variable 'my_sequential_model/flexible_dense_1/w:0' shape=(3, 3) dtype=float32, numpy=
 array([[ 0.05627853, -0.9386015 , -0.77410126],
        [ 0.63149   ,  1.0802224 , -0.37785745],
        [-0.24788402, -1.1076807 , -0.5956209 ]], dtype=float32)>,
 <tf.Variable 'my_sequential_model/flexible_dense_1/b:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>,
 <tf.Variable 'my_sequential_model/flexible_dense_2/w:0' shape=(3, 2) dtype=float32, numpy=
 array([[-0.93912166,  0.77979285],
        [ 1.4049559 , -1.9380962 ],
        [-2.6039495 ,  0.30885765]], dtype=float32)>,
 <tf.Variable 'my_sequential_model/flexible_dense_2/b:0' shape=(2,) dtype=float32, numpy=array([0., 0.], dtype=float32)>]
my_sequential_model.submodules
(<__main__.FlexibleDense at 0x7f7b48525550>,
 <__main__.FlexibleDense at 0x7f7b48508d10>)

tf.keras.Model টেনসরফ্লো মডেল তৈরির জন্য একটি অত্যন্ত পাইথনিক পদ্ধতি। আপনি যদি অন্য ফ্রেমওয়ার্ক থেকে মডেলগুলি স্থানান্তর করেন তবে এটি খুব সোজা হতে পারে।

আপনি যদি এমন মডেলগুলি তৈরি করেন যা বিদ্যমান স্তর এবং ইনপুটগুলির সাধারণ সমাবেশ, আপনি কার্যকরী API ব্যবহার করে সময় এবং স্থান বাঁচাতে পারেন, যা মডেল পুনর্গঠন এবং স্থাপত্যের চারপাশে অতিরিক্ত বৈশিষ্ট্য সহ আসে৷

এখানে কার্যকরী API সহ একই মডেল রয়েছে:

inputs = tf.keras.Input(shape=[3,])

x = FlexibleDense(3)(inputs)
x = FlexibleDense(2)(x)

my_functional_model = tf.keras.Model(inputs=inputs, outputs=x)

my_functional_model.summary()
Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 3)]               0         
_________________________________________________________________
flexible_dense_3 (FlexibleDe (None, 3)                 12        
_________________________________________________________________
flexible_dense_4 (FlexibleDe (None, 2)                 8         
=================================================================
Total params: 20
Trainable params: 20
Non-trainable params: 0
_________________________________________________________________
my_functional_model(tf.constant([[2.0, 2.0, 2.0]]))
<tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[8.219393, 4.511119]], dtype=float32)>

এখানে প্রধান পার্থক্য হল যে ইনপুট আকৃতিটি কার্যকরী নির্মাণ প্রক্রিয়ার অংশ হিসাবে সামনের দিকে নির্দিষ্ট করা হয়েছে। এই ক্ষেত্রে input_shape আর্গুমেন্টকে সম্পূর্ণভাবে নির্দিষ্ট করতে হবে না; আপনি None হিসাবে কিছু মাত্রা রেখে যেতে পারেন।

কেরাস মডেল সংরক্ষণ করা হচ্ছে

Keras মডেল চেকপয়েন্ট করা যেতে পারে, এবং এটি tf.Module এর মতই দেখাবে।

কেরাস মডেলগুলি tf.saved_model.save() সংরক্ষণ করা যেতে পারে, কারণ সেগুলি মডিউল। যাইহোক, কেরাস মডেলগুলির সুবিধার পদ্ধতি এবং অন্যান্য কার্যকারিতা রয়েছে:

my_sequential_model.save("exname_of_file")
INFO:tensorflow:Assets written to: exname_of_file/assets

ঠিক যেমন সহজে, তারা আবার লোড করা যেতে পারে:

reconstructed_model = tf.keras.models.load_model("exname_of_file")
WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.

SavedModels এছাড়াও মেট্রিক, ক্ষতি, এবং অপ্টিমাইজার অবস্থা সংরক্ষণ করে।

এই পুনর্গঠিত মডেলটি ব্যবহার করা যেতে পারে এবং একই ডেটাতে কল করার সময় একই ফলাফল তৈরি করবে:

reconstructed_model(tf.constant([[2.0, 2.0, 2.0]]))
<tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[5.5604653, 3.3511646]], dtype=float32)>

বৈশিষ্ট্য সমর্থনের জন্য কাস্টম স্তরগুলির জন্য কনফিগারেশন পদ্ধতি প্রদান সহ কেরাস মডেলগুলির সংরক্ষণ এবং ক্রমিককরণ সম্পর্কে আরও কিছু জানার আছে৷ সংরক্ষণ এবং ক্রমিককরণের জন্য গাইডটি দেখুন।

এরপর কি

আপনি যদি কেরাস সম্পর্কে আরও বিশদ জানতে চান তবে আপনি এখানে বিদ্যমান কেরাস গাইডগুলি অনুসরণ করতে পারেন

tf.module-এ নির্মিত একটি উচ্চ-স্তরের API-এর আরেকটি উদাহরণ হল tf.module থেকে সনেট, যা তাদের সাইটে কভার করা হয়েছে।