הצג באתר TensorFlow.org | הפעל בגוגל קולאב | צפה במקור ב-GitHub | הורד מחברת |
כדי לבצע למידת מכונה ב-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
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
גם כנקודת ביקורת וגם כ-SaveModel .
מחסומים הם רק המשקולות (כלומר, הערכים של קבוצת המשתנים בתוך המודול ותתי המודולים שלו):
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-of-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, אך ללא הקוד המקורי . לשם כך, אתה יכול ליצור גרף , המתואר במדריך מבוא לגרפים ופונקציות .
גרף זה מכיל פעולות, או ops , המיישמות את הפונקציה.
אתה יכול להגדיר גרף במודל שלמעלה על ידי הוספת ה- @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
יצירת 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, כגון הגשה בקנה מידה או במכשיר קצה, או במצבים שבהם קוד 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
, ולאחר מכן לטעון אותם שוב.
דגמי קרס ושכבות
שימו לב שעד לנקודה זו, אין אזכור של קרס. אתה יכול לבנות ממשק API ברמה גבוהה משלך על גבי tf.Module
, ולאנשים יש.
בחלק זה, תבחן כיצד Keras משתמש ב- 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 מספקת גם מחלקת דגמים מלאה בשם 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 הפונקציונלי , שמגיע עם תכונות נוספות סביב שחזור וארכיטקטורה של מודל.
הנה אותו דגם עם ה-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 הקיימים כאן .
דוגמה נוספת ל-API ברמה גבוהה הבנויה על tf.module
היא Sonnet מ-DeepMind, אשר מכוסה באתר שלהם .