مؤتمر Google I / O هو التفاف! تابع جلسات TensorFlow اعرض الجلسات

مقدمة للوحدات والطبقات والنماذج

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

للقيام بالتعلم الآلي في TensorFlow ، من المحتمل أن تحتاج إلى تعريف نموذج وحفظه واستعادته.

النموذج ، بشكل تجريدي:

  • دالة تحسب شيئًا ما على موترات ( تمريرة أمامية )
  • بعض المتغيرات التي يمكن تحديثها استجابة للتدريب

في هذا الدليل ، ستنتقل إلى أسفل سطح Keras لترى كيف يتم تعريف نماذج TensorFlow. يبحث هذا في كيفية جمع TensorFlow للمتغيرات والنماذج ، وكذلك كيفية حفظها واستعادتها.

يثبت

import tensorflow as tf
from datetime import datetime

%load_ext tensorboard

تحديد النماذج والطبقات في TensorFlow

معظم النماذج مصنوعة من طبقات. الطبقات هي وظائف ذات بنية رياضية معروفة يمكن إعادة استخدامها ولها متغيرات قابلة للتدريب. في TensorFlow ، تم بناء معظم تطبيقات الطبقات والنماذج عالية المستوى ، مثل Keras أو Sonnet ، على نفس الفئة التأسيسية: tf.Module .

فيما يلي مثال على وحدة 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__ باستثناء التصرف مثل Python القابل للاستدعاء ؛ يمكنك استدعاء النماذج الخاصة بك بأي وظائف ترغب فيها.

يمكنك ضبط إمكانية تدريب المتغيرات وإيقاف تشغيلها لأي سبب ، بما في ذلك طبقات التجميد والمتغيرات أثناء الضبط الدقيق.

من خلال التصنيف الفرعي 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 مع مثيل نموذج واحد ، وحفظ النماذج وتحميلها بالكامل.

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 كنقطة تفتيش ونموذج SavedModel .

نقاط التحقق هي مجرد أوزان (أي قيم مجموعة المتغيرات داخل الوحدة النمطية ووحداتها الفرعية):

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

يمكنك النظر داخل نقطة تفتيش للتأكد من حفظ المجموعة الكاملة للمتغيرات ، مرتبة حسب كائن Python الذي يحتوي عليها.

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"). في هذه الحالة ، على الرغم من ذلك ، لا يوجد سوى جزء واحد.

عند إعادة تحميل النماذج ، تقوم بالكتابة فوق القيم الموجودة في كائن Python الخاص بك.

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 تشغيل النماذج بدون كائنات Python الأصلية ، كما هو موضح في TensorFlow Serving و TensorFlow Lite ، حتى عند تنزيل نموذج مدرب من TensorFlow Hub .

يحتاج TensorFlow إلى معرفة كيفية إجراء الحسابات الموضحة في Python ، ولكن بدون الكود الأصلي . للقيام بذلك ، يمكنك عمل رسم بياني موصوف في مقدمة إلى الرسوم البيانية ودليل الوظائف .

يحتوي هذا الرسم البياني على العمليات ، أو العمليات ، التي تنفذ الوظيفة.

يمكنك تحديد رسم بياني في النموذج أعلاه عن طريق إضافة @tf.function decorator للإشارة إلى أن هذا الرمز يجب أن يعمل كرسم بياني.

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)

قم بتشغيل TensorBoard لعرض التتبع الناتج:

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

لقطة شاشة للرسم البياني في TensorBoard

إنشاء 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 الوظيفي.

يمكن تحميل النماذج والطبقات من هذا التمثيل دون عمل مثيل للفئة التي أنشأتها. هذا مطلوب في المواقف التي لا يتوفر فيها (أو تريد) مترجم بايثون ، مثل العمل على نطاق واسع أو على جهاز حافة ، أو في المواقف التي لا يتوفر فيها كود Python الأصلي أو يكون عمليًا للاستخدام.

يمكنك تحميل النموذج ككائن جديد:

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 ، يمكنك حفظ أوزان TensorFlow والرسوم البيانية باستخدام tf.Module ، ثم تحميلها مرة أخرى.

نماذج وطبقات Keras

لاحظ أنه حتى هذه النقطة ، لا يوجد ذكر لـ Keras. يمكنك إنشاء واجهة برمجة تطبيقات عالية المستوى خاصة بك فوق tf.Module ، كما يمتلكها الأشخاص.

في هذا القسم ، سوف تدرس كيفية استخدام tf.Module . يمكن العثور على دليل مستخدم كامل لنماذج Keras في دليل Keras .

طبقات كيراس

tf.keras.layers.Layer هي الفئة الأساسية لجميع طبقات Keras ، وهي ترث من tf.Module .

يمكنك تحويل وحدة نمطية إلى طبقة Keras فقط عن طريق تبديل الأصل ثم تغيير __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)

طبقات Keras لها __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

كما لوحظ ، من الملائم في كثير من الحالات الانتظار لإنشاء متغيرات حتى تتأكد من شكل الإدخال.

تأتي طبقات Keras بخطوة دورة حياة إضافية تتيح لك مزيدًا من المرونة في كيفية تحديد طبقاتك. يتم تعريف هذا في وظيفة 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]

تتمتع طبقات Keras بالعديد من الميزات الإضافية بما في ذلك:

  • خسائر اختيارية
  • دعم المقاييس
  • دعم مدمج لحجة training اختيارية للتمييز بين استخدام التدريب والاستدلال
  • أساليب get_config و from_config التي تسمح لك بتخزين التكوينات بدقة للسماح باستنساخ النماذج في Python

اقرأ عنها في الدليل الكامل للطبقات والنماذج المخصصة.

نماذج Keras

يمكنك تعريف النموذج الخاص بك على أنه طبقات Keras المتداخلة.

ومع ذلك ، توفر Keras أيضًا فئة نموذجية كاملة الميزات تسمى tf.keras.Model . يرث من tf.keras.layers.Layer ، لذلك يمكن استخدام نموذج Keras وتداخله وحفظه بنفس طريقة طبقات Keras. تأتي طرازات Keras بوظائف إضافية تسهل تدريبها وتقييمها وتحميلها وحفظها وحتى تدريبها على أجهزة متعددة.

يمكنك تحديد 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 هو نهج بيثوني للغاية لبناء نماذج TensorFlow. إذا كنت تقوم بترحيل نماذج من أطر أخرى ، فقد يكون ذلك واضحًا جدًا.

إذا كنت تقوم بإنشاء نماذج عبارة عن تجميعات بسيطة للطبقات والمدخلات الموجودة ، فيمكنك توفير الوقت والمساحة باستخدام واجهة برمجة التطبيقات الوظيفية ، والتي تأتي مع ميزات إضافية حول إعادة بناء النموذج وبنيته.

هنا نفس النموذج مع 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 .

يمكن أيضًا حفظ نماذج Keras باستخدام tf.saved_model.save() ، لأنها وحدات نمطية. ومع ذلك ، فإن نماذج Keras لها طرق ملائمة ووظائف أخرى:

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.

تقوم Keras 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)>

هناك المزيد لمعرفته حول حفظ نماذج Keras وتسلسلها ، بما في ذلك توفير طرق التكوين للطبقات المخصصة لدعم الميزات. راجع دليل الحفظ والتسلسل .

ماذا بعد

إذا كنت تريد معرفة المزيد من التفاصيل حول Keras ، فيمكنك اتباع أدلة Keras الحالية هنا .

مثال آخر لواجهة برمجة تطبيقات عالية المستوى مبنية على tf.module هو Sonnet من DeepMind ، والتي يتم تغطيتها على موقعهم .