مشاهده در TensorFlow.org | در Google Colab اجرا شود | در GitHub مشاهده کنید | دانلود دفترچه یادداشت |
بررسی اجمالی
این راهنما فرض میکند که شما مدلی دارید که نقاط بازرسی را با tf.compat.v1.Saver
ذخیره و بارگیری میکند، و میخواهید کد را با استفاده از TF2 tf.train.Checkpoint
API منتقل کنید، یا از نقاط بازرسی از قبل موجود در مدل TF2 خود استفاده کنید.
در زیر چند سناریو رایج وجود دارد که ممکن است با آنها روبرو شوید:
سناریو 1
نقاط بازرسی TF1 موجود از دوره های آموزشی قبلی وجود دارد که باید بارگذاری شوند یا به TF2 تبدیل شوند.
- برای بارگیری نقطه بازرسی TF1 در TF2، به قطعه Load a TF1 checkpoint در TF2 مراجعه کنید.
- برای تبدیل نقطه بازرسی به TF2، به تبدیل نقطه بازرسی مراجعه کنید.
سناریو 2
شما مدل خود را به گونهای تنظیم میکنید که خطر تغییر نام و مسیر متغیرها را به دنبال داشته باشد (مانند زمانی که به طور تدریجی از get_variable
به ایجاد tf.Variable
صریح مهاجرت میکنید)، و میخواهید ذخیره/بارگیری نقاط بازرسی موجود را در طول مسیر حفظ کنید.
به بخش نحوه حفظ سازگاری ایست بازرسی در طول مهاجرت مدل مراجعه کنید
سناریو 3
شما در حال انتقال کد آموزشی و نقاط بازرسی خود به TF2 هستید، اما خط لوله استنتاج شما در حال حاضر به نقاط بازرسی TF1 (برای ثبات تولید) نیاز دارد.
انتخاب 1
هنگام آموزش هر دو ایست بازرسی TF1 و TF2 را ذخیره کنید.
- ذخیره یک ایست بازرسی TF1 در TF2 را ببینید
گزینه 2
ایست بازرسی TF2 را به TF1 تبدیل کنید.
- تبدیل ایست بازرسی را ببینید
مثالهای زیر تمام ترکیبهای ذخیره و بارگیری نقاط بازرسی را در TF1/TF2 نشان میدهند، بنابراین شما در تعیین نحوه انتقال مدل خود انعطافپذیری دارید.
برپایی
import tensorflow as tf
import tensorflow.compat.v1 as tf1
def print_checkpoint(save_path):
reader = tf.train.load_checkpoint(save_path)
shapes = reader.get_variable_to_shape_map()
dtypes = reader.get_variable_to_dtype_map()
print(f"Checkpoint at '{save_path}':")
for key in shapes:
print(f" (key='{key}', shape={shapes[key]}, dtype={dtypes[key].name}, "
f"value={reader.get_tensor(key)})")
از TF1 به TF2 تغییر می کند
اگر کنجکاو هستید که بین TF1 و TF2 چه تغییری کرده است و منظور ما از "مبتنی بر نام" (TF1) در مقابل "بر اساس شی" (TF2) چیست، این بخش گنجانده شده است.
دو نوع چک پوینت در واقع در قالب یکسانی ذخیره میشوند که اساساً یک جدول کلید-مقدار است. تفاوت در نحوه تولید کلیدها نهفته است.
کلیدهای چک پوینتهای مبتنی بر نام، نام متغیرها هستند . کلیدهای چک پوینتهای مبتنی بر شی به مسیر شی ریشه تا متغیر اشاره میکنند (مثالهای زیر به درک بهتر معنی این موضوع کمک میکنند).
ابتدا برخی از نقاط بازرسی را ذخیره کنید:
with tf.Graph().as_default() as g:
a = tf1.get_variable('a', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
b = tf1.get_variable('b', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
c = tf1.get_variable('scoped/c', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
with tf1.Session() as sess:
saver = tf1.train.Saver()
sess.run(a.assign(1))
sess.run(b.assign(2))
sess.run(c.assign(3))
saver.save(sess, 'tf1-ckpt')
print_checkpoint('tf1-ckpt')
Checkpoint at 'tf1-ckpt': (key='scoped/c', shape=[], dtype=float32, value=3.0) (key='a', shape=[], dtype=float32, value=1.0) (key='b', shape=[], dtype=float32, value=2.0)
a = tf.Variable(5.0, name='a')
b = tf.Variable(6.0, name='b')
with tf.name_scope('scoped'):
c = tf.Variable(7.0, name='c')
ckpt = tf.train.Checkpoint(variables=[a, b, c])
save_path_v2 = ckpt.save('tf2-ckpt')
print_checkpoint(save_path_v2)
Checkpoint at 'tf2-ckpt-1': (key='variables/2/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=7.0) (key='variables/0/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=5.0) (key='_CHECKPOINTABLE_OBJECT_GRAPH', shape=[], dtype=string, value=b"\n!\n\r\x08\x01\x12\tvariables\n\x10\x08\x02\x12\x0csave_counter\n\x15\n\x05\x08\x03\x12\x010\n\x05\x08\x04\x12\x011\n\x05\x08\x05\x12\x012\nI\x12G\n\x0eVARIABLE_VALUE\x12\x0csave_counter\x1a'save_counter/.ATTRIBUTES/VARIABLE_VALUE\n=\x12;\n\x0eVARIABLE_VALUE\x12\x01a\x1a&variables/0/.ATTRIBUTES/VARIABLE_VALUE\n=\x12;\n\x0eVARIABLE_VALUE\x12\x01b\x1a&variables/1/.ATTRIBUTES/VARIABLE_VALUE\nD\x12B\n\x0eVARIABLE_VALUE\x12\x08scoped/c\x1a&variables/2/.ATTRIBUTES/VARIABLE_VALUE") (key='variables/1/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=6.0) (key='save_counter/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=int64, value=1)
اگر به کلیدهای tf2-ckpt
نگاه کنید، همه آنها به مسیرهای شی هر متغیر اشاره دارند. به عنوان مثال، متغیر a
اولین عنصر در لیست variables
است، بنابراین کلید آن به variables/0/...
تبدیل میشود (به راحتی میتوانید ثابت .ATTRIBUTES/VARIABLE_VALUE را نادیده بگیرید).
یک بازرسی دقیق تر از شیء Checkpoint
در زیر:
a = tf.Variable(0.)
b = tf.Variable(0.)
c = tf.Variable(0.)
root = ckpt = tf.train.Checkpoint(variables=[a, b, c])
print("root type =", type(root).__name__)
print("root.variables =", root.variables)
print("root.variables[0] =", root.variables[0])
root type = Checkpoint root.variables = ListWrapper([<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>, <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>, <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>]) root.variables[0] = <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>
سعی کنید با قطعه زیر آزمایش کنید و ببینید که چگونه کلیدهای چک پوینت با ساختار شی تغییر می کنند:
module = tf.Module()
module.d = tf.Variable(0.)
test_ckpt = tf.train.Checkpoint(v={'a': a, 'b': b},
c=c,
module=module)
test_ckpt_path = test_ckpt.save('root-tf2-ckpt')
print_checkpoint(test_ckpt_path)
Checkpoint at 'root-tf2-ckpt-1': (key='v/a/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=0.0) (key='save_counter/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=int64, value=1) (key='v/b/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=0.0) (key='module/d/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=0.0) (key='_CHECKPOINTABLE_OBJECT_GRAPH', shape=[], dtype=string, value=b"\n,\n\x05\x08\x01\x12\x01c\n\n\x08\x02\x12\x06module\n\x05\x08\x03\x12\x01v\n\x10\x08\x04\x12\x0csave_counter\n:\x128\n\x0eVARIABLE_VALUE\x12\x08Variable\x1a\x1cc/.ATTRIBUTES/VARIABLE_VALUE\n\x07\n\x05\x08\x05\x12\x01d\n\x0e\n\x05\x08\x06\x12\x01a\n\x05\x08\x07\x12\x01b\nI\x12G\n\x0eVARIABLE_VALUE\x12\x0csave_counter\x1a'save_counter/.ATTRIBUTES/VARIABLE_VALUE\nA\x12?\n\x0eVARIABLE_VALUE\x12\x08Variable\x1a#module/d/.ATTRIBUTES/VARIABLE_VALUE\n<\x12:\n\x0eVARIABLE_VALUE\x12\x08Variable\x1a\x1ev/a/.ATTRIBUTES/VARIABLE_VALUE\n<\x12:\n\x0eVARIABLE_VALUE\x12\x08Variable\x1a\x1ev/b/.ATTRIBUTES/VARIABLE_VALUE") (key='c/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=0.0)
چرا TF2 از این مکانیسم استفاده می کند؟
از آنجایی که در TF2 گراف جهانی دیگری وجود ندارد، نام متغیرها قابل اعتماد نیستند و می توانند بین برنامه ها ناسازگار باشند. TF2 رویکرد مدلسازی شیگرا را تشویق میکند که در آن متغیرها متعلق به لایهها هستند و لایهها متعلق به یک مدل هستند:
variable = tf.Variable(...)
layer.variable_name = variable
model.layer_name = layer
نحوه حفظ سازگاری ایست بازرسی در طول مهاجرت مدل
یکی از گامهای مهم در فرآیند مهاجرت، اطمینان از اینکه همه متغیرها به مقادیر صحیح مقداردهی اولیه میشوند ، به شما اجازه میدهد تا تأیید کنید که عملیات/توابع محاسبات صحیح را انجام میدهند. برای انجام این کار، باید سازگاری ایست بازرسی بین مدل ها را در مراحل مختلف مهاجرت در نظر بگیرید. اساساً، این بخش به این سؤال پاسخ می دهد که چگونه می توانم هنگام تغییر مدل از همان نقطه بازرسی استفاده کنم .
در زیر سه راه برای حفظ سازگاری ایست بازرسی به منظور افزایش انعطاف پذیری آورده شده است:
- مدل دارای نام متغیرهای قبلی است.
- مدل دارای نام متغیرهای مختلفی است و یک نقشه تخصیصی را حفظ می کند که نام متغیرها را در نقطه بازرسی به نام های جدید نگاشت می کند.
- مدل نام متغیرهای مختلفی دارد و یک شیء TF2 Checkpoint دارد که همه متغیرها را ذخیره میکند.
زمانی که نام متغیرها مطابقت دارند
عنوان طولانی: نحوه استفاده مجدد از نقاط بازرسی زمانی که نام متغیرها مطابقت دارند.
پاسخ کوتاه: می توانید مستقیماً نقطه بازرسی از قبل موجود را با tf1.train.Saver
یا tf.train.Checkpoint
کنید.
اگر از tf.compat.v1.keras.utils.track_tf1_style_variables
استفاده می کنید، مطمئن می شود که نام متغیرهای مدل شما مانند قبل است. همچنین می توانید به صورت دستی اطمینان حاصل کنید که نام متغیرها مطابقت دارند.
هنگامی که نام متغیرها در مدلهای انتقالیافته مطابقت دارند، میتوانید مستقیماً از tf.train.Checkpoint
یا tf.compat.v1.train.Saver
برای بارگیری نقطه بازرسی استفاده کنید. هر دو API با حالت اشتیاق و گراف سازگار هستند، بنابراین می توانید در هر مرحله از مهاجرت از آنها استفاده کنید.
در زیر نمونه هایی از استفاده از یک ایست بازرسی با مدل های مختلف آورده شده است. ابتدا، یک ایست بازرسی TF1 را با tf1.train.Saver
کنید:
with tf.Graph().as_default() as g:
a = tf1.get_variable('a', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
b = tf1.get_variable('b', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
c = tf1.get_variable('scoped/c', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
with tf1.Session() as sess:
saver = tf1.train.Saver()
sess.run(a.assign(1))
sess.run(b.assign(2))
sess.run(c.assign(3))
save_path = saver.save(sess, 'tf1-ckpt')
print_checkpoint(save_path)
Checkpoint at 'tf1-ckpt': (key='scoped/c', shape=[], dtype=float32, value=3.0) (key='a', shape=[], dtype=float32, value=1.0) (key='b', shape=[], dtype=float32, value=2.0)
مثال زیر از tf.compat.v1.Saver
برای بارگیری نقطه بازرسی در حالت مشتاق استفاده می کند:
a = tf.Variable(0.0, name='a')
b = tf.Variable(0.0, name='b')
with tf.name_scope('scoped'):
c = tf.Variable(0.0, name='c')
# With the removal of collections in TF2, you must pass in the list of variables
# to the Saver object:
saver = tf1.train.Saver(var_list=[a, b, c])
saver.restore(sess=None, save_path=save_path)
print(f"loaded values of [a, b, c]: [{a.numpy()}, {b.numpy()}, {c.numpy()}]")
# Saving also works in eager (sess must be None).
path = saver.save(sess=None, save_path='tf1-ckpt-saved-in-eager')
print_checkpoint(path)
WARNING:tensorflow:Saver is deprecated, please switch to tf.train.Checkpoint or tf.keras.Model.save_weights for training checkpoints. When executing eagerly variables do not necessarily have unique names, and so the variable.name-based lookups Saver performs are error-prone. INFO:tensorflow:Restoring parameters from tf1-ckpt loaded values of [a, b, c]: [1.0, 2.0, 3.0] Checkpoint at 'tf1-ckpt-saved-in-eager': (key='scoped/c', shape=[], dtype=float32, value=3.0) (key='a', shape=[], dtype=float32, value=1.0) (key='b', shape=[], dtype=float32, value=2.0)
قطعه بعدی با استفاده از TF2 API tf.train.Checkpoint
را بارگیری می کند:
a = tf.Variable(0.0, name='a')
b = tf.Variable(0.0, name='b')
with tf.name_scope('scoped'):
c = tf.Variable(0.0, name='c')
# Without the name_scope, name="scoped/c" works too:
c_2 = tf.Variable(0.0, name='scoped/c')
print("Variable names: ")
print(f" a.name = {a.name}")
print(f" b.name = {b.name}")
print(f" c.name = {c.name}")
print(f" c_2.name = {c_2.name}")
# Restore the values with tf.train.Checkpoint
ckpt = tf.train.Checkpoint(variables=[a, b, c, c_2])
ckpt.restore(save_path)
print(f"loaded values of [a, b, c, c_2]: [{a.numpy()}, {b.numpy()}, {c.numpy()}, {c_2.numpy()}]")
Variable names: a.name = a:0 b.name = b:0 c.name = scoped/c:0 c_2.name = scoped/c:0 WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/training/tracking/util.py:1345: NameBasedSaverStatus.__init__ (from tensorflow.python.training.tracking.util) is deprecated and will be removed in a future version. Instructions for updating: Restoring a name-based tf.train.Saver checkpoint using the object-based restore API. This mode uses global names to match variables, and so is somewhat fragile. It also adds new restore ops to the graph each time it is called when graph building. Prefer re-encoding training checkpoints in the object-based format: run save() on the object-based saver (the same one this message is coming from) and use that checkpoint in the future. loaded values of [a, b, c, c_2]: [1.0, 2.0, 3.0, 3.0]
نام متغیرها در TF2
- همه متغیرها هنوز هم یک آرگومان
name
دارند که می توانید تنظیم کنید. - مدلهای Keras نیز آرگومان
name
را به عنوان پیشوند برای متغیرهای خود تنظیم میکنند. - تابع
v1.name_scope
می تواند برای تنظیم پیشوندهای نام متغیر استفاده شود. این باtf.variable_scope
بسیار متفاوت است. این فقط بر نام ها تأثیر می گذارد و متغیرها و استفاده مجدد را ردیابی نمی کند.
دکوراتور tf.compat.v1.keras.utils.track_tf1_style_variables
است که به شما کمک می کند تا نام متغیرها و سازگاری ایست بازرسی TF1 را حفظ کنید، با حفظ نامگذاری و استفاده مجدد از معنای tf.variable_scope
و tf.compat.v1.get_variable
. برای اطلاعات بیشتر به راهنمای نقشه برداری مدل مراجعه کنید.
نکته 1: اگر از شیم استفاده می کنید، از API های TF2 برای بارگذاری پست های بازرسی خود استفاده کنید (حتی زمانی که از نقاط بازرسی TF1 از قبل آموزش دیده استفاده می کنید).
بخش ایست بازرسی Keras را ببینید.
نکته 2: هنگام مهاجرت به tf.Variable
از get_variable
:
اگر لایه یا ماژول تزئین شده شما متشکل از چند متغیر (یا لایهها/مدلهای Keras) است که از tf.Variable
به جای tf.compat.v1.get_variable
استفاده میکنند و بهعنوان ویژگیها/پیشگیری به روش شیگرا متصل میشوند، ممکن است متفاوت باشند. معنای نامگذاری متغیر در نمودارها/جلسات TF1.x در مقابل اجرای مشتاقانه.
به طور خلاصه، نام ها ممکن است آن چیزی که شما انتظار دارید هنگام اجرا در TF2 نباشند.
حفظ نقشه های تکالیف
نقشههای انتساب معمولاً برای انتقال وزن بین مدلهای TF1 استفاده میشوند و همچنین در صورت تغییر نام متغیرها، میتوانند در طول مهاجرت مدل شما استفاده شوند.
میتوانید از این نقشهها با tf.compat.v1.train.init_from_checkpoint
، tf.compat.v1.train.Saver
، و tf.train.load_checkpoint
برای بارگذاری وزنها در مدلهایی استفاده کنید که نام متغیر یا محدوده ممکن است تغییر کرده باشد.
نمونه های این بخش از یک چک پوینت ذخیره شده قبلی استفاده می کنند:
print_checkpoint('tf1-ckpt')
Checkpoint at 'tf1-ckpt': (key='scoped/c', shape=[], dtype=float32, value=3.0) (key='a', shape=[], dtype=float32, value=1.0) (key='b', shape=[], dtype=float32, value=2.0)
در حال بارگیری با init_from_checkpoint
tf1.train.init_from_checkpoint
باید در حین حضور در Graph/Session فراخوانی شود، زیرا به جای ایجاد یک عملیات اختصاصی، مقادیر را در مقداردهی اولیه متغیر قرار می دهد.
می توانید از آرگومان assignment_map
برای پیکربندی نحوه بارگذاری متغیرها استفاده کنید. از مستندات:
نقشه تخصیص از نحو زیر پشتیبانی می کند:
-
'checkpoint_scope_name/': 'scope_name/'
- همه متغیرهای موجود درscope_name
فعلی را ازcheckpoint_scope_name
با نامهای تانسور منطبق بارگیری میکند. -
'checkpoint_scope_name/some_other_variable': 'scope_name/variable_name'
-scope_name/variable_name
را ازcheckpoint_scope_name/some_other_variable
می کند. -
'scope_variable_name': variable
- شیtf.Variable
داده شده را با تانسور 'scope_variable_name' از نقطه بازرسی مقداردهی اولیه می کند. -
'scope_variable_name': list(variable)
- لیستی از متغیرهای پارتیشن بندی شده را با تانسور 'scope_variable_name' از نقطه بازرسی مقداردهی اولیه می کند. -
'/': 'scope_name/'
- همه متغیرهای موجود درscope_name
فعلی را از ریشه چک پوینت بارگیری می کند (مثلاً بدون محدوده).
# Restoring with tf1.train.init_from_checkpoint:
# A new model with a different scope for the variables.
with tf.Graph().as_default() as g:
with tf1.variable_scope('new_scope'):
a = tf1.get_variable('a', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
b = tf1.get_variable('b', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
c = tf1.get_variable('scoped/c', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
with tf1.Session() as sess:
# The assignment map will remap all variables in the checkpoint to the
# new scope:
tf1.train.init_from_checkpoint(
'tf1-ckpt',
assignment_map={'/': 'new_scope/'})
# `init_from_checkpoint` adds the initializers to these variables.
# Use `sess.run` to run these initializers.
sess.run(tf1.global_variables_initializer())
print("Restored [a, b, c]: ", sess.run([a, b, c]))
Restored [a, b, c]: [1.0, 2.0, 3.0]
بارگیری با tf1.train.Saver
برخلاف init_from_checkpoint
، tf.compat.v1.train.Saver
هم در حالت گراف و هم در حالت مشتاق اجرا می شود. آرگومان var_list
به صورت اختیاری یک فرهنگ لغت را می پذیرد، به جز اینکه باید نام متغیرها را به شی tf.Variable
کند.
# Restoring with tf1.train.Saver (works in both graph and eager):
# A new model with a different scope for the variables.
with tf1.variable_scope('new_scope'):
a = tf1.get_variable('a', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
b = tf1.get_variable('b', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
c = tf1.get_variable('scoped/c', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
# Initialize the saver with a dictionary with the original variable names:
saver = tf1.train.Saver({'a': a, 'b': b, 'scoped/c': c})
saver.restore(sess=None, save_path='tf1-ckpt')
print("Restored [a, b, c]: ", [a.numpy(), b.numpy(), c.numpy()])
WARNING:tensorflow:Saver is deprecated, please switch to tf.train.Checkpoint or tf.keras.Model.save_weights for training checkpoints. When executing eagerly variables do not necessarily have unique names, and so the variable.name-based lookups Saver performs are error-prone. INFO:tensorflow:Restoring parameters from tf1-ckpt Restored [a, b, c]: [1.0, 2.0, 3.0]
بارگیری با tf.train.load_checkpoint
اگر به کنترل دقیق مقادیر متغیر نیاز دارید، این گزینه برای شما مناسب است. باز هم، این در هر دو حالت گراف و مشتاق کار می کند.
# Restoring with tf.train.load_checkpoint (works in both graph and eager):
# A new model with a different scope for the variables.
with tf.Graph().as_default() as g:
with tf1.variable_scope('new_scope'):
a = tf1.get_variable('a', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
b = tf1.get_variable('b', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
c = tf1.get_variable('scoped/c', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
with tf1.Session() as sess:
# It may be easier writing a loop if your model has a lot of variables.
reader = tf.train.load_checkpoint('tf1-ckpt')
sess.run(a.assign(reader.get_tensor('a')))
sess.run(b.assign(reader.get_tensor('b')))
sess.run(c.assign(reader.get_tensor('scoped/c')))
print("Restored [a, b, c]: ", sess.run([a, b, c]))
Restored [a, b, c]: [1.0, 2.0, 3.0]
نگهداری یک شیء TF2 Checkpoint
اگر نام متغیر و محدوده ممکن است در طول مهاجرت تغییر زیادی کند، از tf.train.Checkpoint
و TF2 استفاده کنید. TF2 از ساختار شی به جای نام متغیرها استفاده می کند (جزئیات بیشتر در تغییرات از TF1 به TF2 ).
به طور خلاصه، هنگام ایجاد یک tf.train.Checkpoint
برای ذخیره یا بازیابی نقاط بازرسی، مطمئن شوید که از همان ترتیب (برای لیستها) و کلیدها (برای فرهنگ لغتها و آرگومانهای کلیدواژه اولیه Checkpoint
) استفاده میکند. چند نمونه از سازگاری ایست بازرسی:
ckpt = tf.train.Checkpoint(foo=[var_a, var_b])
# compatible with ckpt
tf.train.Checkpoint(foo=[var_a, var_b])
# not compatible with ckpt
tf.train.Checkpoint(foo=[var_b, var_a])
tf.train.Checkpoint(bar=[var_a, var_b])
نمونه کد زیر نحوه استفاده از tf.train.Checkpoint
را برای بارگیری متغیرها با نام های مختلف نشان می دهد. ابتدا یک ایست بازرسی TF2 را ذخیره کنید:
with tf.Graph().as_default() as g:
a = tf1.get_variable('a', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(1))
b = tf1.get_variable('b', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(2))
with tf1.variable_scope('scoped'):
c = tf1.get_variable('c', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(3))
with tf1.Session() as sess:
sess.run(tf1.global_variables_initializer())
print("[a, b, c]: ", sess.run([a, b, c]))
# Save a TF2 checkpoint
ckpt = tf.train.Checkpoint(unscoped=[a, b], scoped=[c])
tf2_ckpt_path = ckpt.save('tf2-ckpt')
print_checkpoint(tf2_ckpt_path)
[a, b, c]: [1.0, 2.0, 3.0] Checkpoint at 'tf2-ckpt-1': (key='unscoped/1/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=2.0) (key='unscoped/0/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=1.0) (key='_CHECKPOINTABLE_OBJECT_GRAPH', shape=[], dtype=string, value=b"\n,\n\n\x08\x01\x12\x06scoped\n\x0c\x08\x02\x12\x08unscoped\n\x10\x08\x03\x12\x0csave_counter\n\x07\n\x05\x08\x04\x12\x010\n\x0e\n\x05\x08\x05\x12\x010\n\x05\x08\x06\x12\x011\nI\x12G\n\x0eVARIABLE_VALUE\x12\x0csave_counter\x1a'save_counter/.ATTRIBUTES/VARIABLE_VALUE\nA\x12?\n\x0eVARIABLE_VALUE\x12\x08scoped/c\x1a#scoped/0/.ATTRIBUTES/VARIABLE_VALUE\n<\x12:\n\x0eVARIABLE_VALUE\x12\x01a\x1a%unscoped/0/.ATTRIBUTES/VARIABLE_VALUE\n<\x12:\n\x0eVARIABLE_VALUE\x12\x01b\x1a%unscoped/1/.ATTRIBUTES/VARIABLE_VALUE") (key='scoped/0/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=3.0) (key='save_counter/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=int64, value=1)
حتی اگر نام متغیر/حوزه تغییر کند، میتوانید از tf.train.Checkpoint
استفاده کنید:
with tf.Graph().as_default() as g:
a = tf1.get_variable('a_different_name', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
b = tf1.get_variable('b_different_name', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
with tf1.variable_scope('different_scope'):
c = tf1.get_variable('c', shape=[], dtype=tf.float32,
initializer=tf1.zeros_initializer())
with tf1.Session() as sess:
sess.run(tf1.global_variables_initializer())
print("Initialized [a, b, c]: ", sess.run([a, b, c]))
ckpt = tf.train.Checkpoint(unscoped=[a, b], scoped=[c])
# `assert_consumed` validates that all checkpoint objects are restored from
# the checkpoint. `run_restore_ops` is required when running in a TF1
# session.
ckpt.restore(tf2_ckpt_path).assert_consumed().run_restore_ops()
# Removing `assert_consumed` is fine if you want to skip the validation.
# ckpt.restore(tf2_ckpt_path).run_restore_ops()
print("Restored [a, b, c]: ", sess.run([a, b, c]))
Initialized [a, b, c]: [0.0, 0.0, 0.0] Restored [a, b, c]: [1.0, 2.0, 3.0]
و در حالت مشتاق:
a = tf.Variable(0.)
b = tf.Variable(0.)
c = tf.Variable(0.)
print("Initialized [a, b, c]: ", [a.numpy(), b.numpy(), c.numpy()])
# The keys "scoped" and "unscoped" are no longer relevant, but are used to
# maintain compatibility with the saved checkpoints.
ckpt = tf.train.Checkpoint(unscoped=[a, b], scoped=[c])
ckpt.restore(tf2_ckpt_path).assert_consumed().run_restore_ops()
print("Restored [a, b, c]: ", [a.numpy(), b.numpy(), c.numpy()])
Initialized [a, b, c]: [0.0, 0.0, 0.0] Restored [a, b, c]: [1.0, 2.0, 3.0]
پست های بازرسی TF2 در برآوردگر
بخش های بالا نحوه حفظ سازگاری ایست بازرسی را در حین مهاجرت مدل خود توضیح می دهند. این مفاهیم برای مدلهای برآوردگر نیز اعمال میشود، اگرچه نحوه ذخیره/بارگیری نقطه بازرسی کمی متفاوت است. همانطور که مدل برآوردگر خود را برای استفاده از APIهای TF2 منتقل میکنید، ممکن است بخواهید در حالی که مدل هنوز از تخمینگر استفاده میکند، از نقاط بازرسی TF1 به TF2 جابجا شوید. این بخش نحوه انجام این کار را نشان می دهد.
tf.estimator.Estimator
و MonitoredSession
دارای یک مکانیسم ذخیره به نام scaffold
، یک شی tf.compat.v1.train.Scaffold
هستند. Scaffold
میتواند حاوی یک tf1.train.Saver
یا tf.train.Checkpoint
باشد که به Estimator
و MonitoredSession
اجازه میدهد تا پستهای بازرسی به سبک TF1 یا TF2 را ذخیره کنند.
# A model_fn that saves a TF1 checkpoint
def model_fn_tf1_ckpt(features, labels, mode):
# This model adds 2 to the variable `v` in every train step.
train_step = tf1.train.get_or_create_global_step()
v = tf1.get_variable('var', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(0))
return tf.estimator.EstimatorSpec(
mode,
predictions=v,
train_op=tf.group(v.assign_add(2), train_step.assign_add(1)),
loss=tf.constant(1.),
scaffold=None
)
!rm -rf est-tf1
est = tf.estimator.Estimator(model_fn_tf1_ckpt, 'est-tf1')
def train_fn():
return tf.data.Dataset.from_tensor_slices(([1,2,3], [4,5,6]))
est.train(train_fn, steps=1)
latest_checkpoint = tf.train.latest_checkpoint('est-tf1')
print_checkpoint(latest_checkpoint)
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'est-tf1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true graph_options { rewrite_options { meta_optimizer_iterations: ONE } } , '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1} WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/training/training_util.py:401: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version. Instructions for updating: Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts. INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0... INFO:tensorflow:Saving checkpoints for 0 into est-tf1/model.ckpt. INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0... INFO:tensorflow:loss = 1.0, step = 0 INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 1... INFO:tensorflow:Saving checkpoints for 1 into est-tf1/model.ckpt. INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 1... INFO:tensorflow:Loss for final step: 1.0. Checkpoint at 'est-tf1/model.ckpt-1': (key='var', shape=[], dtype=float32, value=2.0) (key='global_step', shape=[], dtype=int64, value=1)
# A model_fn that saves a TF2 checkpoint
def model_fn_tf2_ckpt(features, labels, mode):
# This model adds 2 to the variable `v` in every train step.
train_step = tf1.train.get_or_create_global_step()
v = tf1.get_variable('var', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(0))
ckpt = tf.train.Checkpoint(var_list={'var': v}, step=train_step)
return tf.estimator.EstimatorSpec(
mode,
predictions=v,
train_op=tf.group(v.assign_add(2), train_step.assign_add(1)),
loss=tf.constant(1.),
scaffold=tf1.train.Scaffold(saver=ckpt)
)
!rm -rf est-tf2
est = tf.estimator.Estimator(model_fn_tf2_ckpt, 'est-tf2',
warm_start_from='est-tf1')
def train_fn():
return tf.data.Dataset.from_tensor_slices(([1,2,3], [4,5,6]))
est.train(train_fn, steps=1)
latest_checkpoint = tf.train.latest_checkpoint('est-tf2')
print_checkpoint(latest_checkpoint)
assert est.get_variable_value('var_list/var/.ATTRIBUTES/VARIABLE_VALUE') == 4
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'est-tf2', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true graph_options { rewrite_options { meta_optimizer_iterations: ONE } } , '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1} INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Warm-starting with WarmStartSettings: WarmStartSettings(ckpt_to_initialize_from='est-tf1', vars_to_warm_start='.*', var_name_to_vocab_info={}, var_name_to_prev_var_name={}) INFO:tensorflow:Warm-starting from: est-tf1 INFO:tensorflow:Warm-starting variables only in TRAINABLE_VARIABLES. INFO:tensorflow:Warm-started 1 variables. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0... INFO:tensorflow:Saving checkpoints for 0 into est-tf2/model.ckpt. INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0... INFO:tensorflow:loss = 1.0, step = 0 INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 1... INFO:tensorflow:Saving checkpoints for 1 into est-tf2/model.ckpt. INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 1... INFO:tensorflow:Loss for final step: 1.0. Checkpoint at 'est-tf2/model.ckpt-1': (key='var_list/var/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=4.0) (key='_CHECKPOINTABLE_OBJECT_GRAPH', shape=[], dtype=string, value=b"\n\x18\n\x08\x08\x01\x12\x04step\n\x0c\x08\x02\x12\x08var_list\n@\x12>\n\x0eVARIABLE_VALUE\x12\x0bglobal_step\x1a\x1fstep/.ATTRIBUTES/VARIABLE_VALUE\n\t\n\x07\x08\x03\x12\x03var\n@\x12>\n\x0eVARIABLE_VALUE\x12\x03var\x1a'var_list/var/.ATTRIBUTES/VARIABLE_VALUE") (key='step/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=int64, value=1)
مقدار نهایی v
باید 16
باشد، پس از شروع گرم از est-tf1
، سپس برای 5 مرحله دیگر آموزش داده شود. مقدار پله قطار از ایست بازرسی warm_start
شود.
ایست بازرسی کراس
مدلهای ساخته شده با Keras هنوز از tf1.train.Saver
و tf.train.Checkpoint
برای بارگیری وزنهای از قبل موجود استفاده میکنند. هنگامی که مدل شما به طور کامل منتقل شد، به استفاده از model.save_weights
و model.load_weights
، به خصوص اگر هنگام آموزش از حالت برگشت به تماس ModelCheckpoint
استفاده می کنید.
نکاتی که باید در مورد پست های بازرسی و کراس بدانید:
مقداردهی اولیه در مقابل ساختمان
مدلها و لایههای Keras قبل از ایجاد کامل باید دو مرحله را طی کنند. ابتدا مقداردهی اولیه شی پایتون است: layer = tf.keras.layers.Dense(x)
. مرحله دوم مرحله ساخت است که در آن بیشتر وزن ها در واقع ایجاد می شوند: layer.build(input_shape)
. همچنین میتوانید یک مدل را با فراخوانی آن یا اجرای یک train
، eval
یا predict
مرحله بسازید (فقط برای اولین بار).
اگر متوجه شدید که model.load_weights(path).assert_consumed()
یک خطا ایجاد می کند، احتمالا مدل/لایه ها ساخته نشده اند.
کراس از نقاط بازرسی TF2 استفاده می کند
tf.train.Checkpoint(model).write
.write معادل model.save_weights
است. با tf.train.Checkpoint(model).read
و model.load_weights
. توجه داشته باشید که Checkpoint(model) != Checkpoint(model=model)
.
چک پوینت های TF2 با مرحله build()
Keras کار می کنند
tf.train.Checkpoint.restore
مکانیزمی به نام بازیابی معوق دارد که به اشیاء tf.Module
و Keras اجازه می دهد مقادیر متغیر را در صورتی که متغیر هنوز ایجاد نشده است ذخیره کنند. این به مدلهای اولیه اجازه میدهد وزنها را بارگذاری کنند و بعد از آن بسازند .
m = YourKerasModel()
status = m.load_weights(path)
# This call builds the model. The variables are created with the restored
# values.
m.predict(inputs)
status.assert_consumed()
به دلیل این مکانیسم، ما به شدت توصیه می کنیم که از API های بارگیری نقطه بازرسی TF2 با مدل های Keras استفاده کنید (حتی در هنگام بازیابی نقاط بازرسی TF1 از قبل موجود در شیم های نقشه برداری مدل ). در راهنمای ایست بازرسی بیشتر ببینید.
قطعه کد
قطعههای زیر سازگاری نسخه TF1/TF2 را در APIهای ذخیرهسازی نقطه بازرسی نشان میدهند.
یک ایست بازرسی TF1 را در TF2 ذخیره کنید
a = tf.Variable(1.0, name='a')
b = tf.Variable(2.0, name='b')
with tf.name_scope('scoped'):
c = tf.Variable(3.0, name='c')
saver = tf1.train.Saver(var_list=[a, b, c])
path = saver.save(sess=None, save_path='tf1-ckpt-saved-in-eager')
print_checkpoint(path)
WARNING:tensorflow:Saver is deprecated, please switch to tf.train.Checkpoint or tf.keras.Model.save_weights for training checkpoints. When executing eagerly variables do not necessarily have unique names, and so the variable.name-based lookups Saver performs are error-prone. Checkpoint at 'tf1-ckpt-saved-in-eager': (key='scoped/c', shape=[], dtype=float32, value=3.0) (key='a', shape=[], dtype=float32, value=1.0) (key='b', shape=[], dtype=float32, value=2.0)
یک ایست بازرسی TF1 را در TF2 بارگیری کنید
a = tf.Variable(0., name='a')
b = tf.Variable(0., name='b')
with tf.name_scope('scoped'):
c = tf.Variable(0., name='c')
print("Initialized [a, b, c]: ", [a.numpy(), b.numpy(), c.numpy()])
saver = tf1.train.Saver(var_list=[a, b, c])
saver.restore(sess=None, save_path='tf1-ckpt-saved-in-eager')
print("Restored [a, b, c]: ", [a.numpy(), b.numpy(), c.numpy()])
Initialized [a, b, c]: [0.0, 0.0, 0.0] WARNING:tensorflow:Saver is deprecated, please switch to tf.train.Checkpoint or tf.keras.Model.save_weights for training checkpoints. When executing eagerly variables do not necessarily have unique names, and so the variable.name-based lookups Saver performs are error-prone. INFO:tensorflow:Restoring parameters from tf1-ckpt-saved-in-eager Restored [a, b, c]: [1.0, 2.0, 3.0]
یک ایست بازرسی TF2 را در TF1 ذخیره کنید
with tf.Graph().as_default() as g:
a = tf1.get_variable('a', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(1))
b = tf1.get_variable('b', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(2))
with tf1.variable_scope('scoped'):
c = tf1.get_variable('c', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(3))
with tf1.Session() as sess:
sess.run(tf1.global_variables_initializer())
ckpt = tf.train.Checkpoint(
var_list={v.name.split(':')[0]: v for v in tf1.global_variables()})
tf2_in_tf1_path = ckpt.save('tf2-ckpt-saved-in-session')
print_checkpoint(tf2_in_tf1_path)
Checkpoint at 'tf2-ckpt-saved-in-session-1': (key='var_list/scoped.Sc/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=3.0) (key='var_list/b/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=2.0) (key='var_list/a/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=1.0) (key='_CHECKPOINTABLE_OBJECT_GRAPH', shape=[], dtype=string, value=b"\n \n\x0c\x08\x01\x12\x08var_list\n\x10\x08\x02\x12\x0csave_counter\n\x1c\n\x05\x08\x03\x12\x01a\n\x05\x08\x04\x12\x01b\n\x0c\x08\x05\x12\x08scoped/c\nI\x12G\n\x0eVARIABLE_VALUE\x12\x0csave_counter\x1a'save_counter/.ATTRIBUTES/VARIABLE_VALUE\n<\x12:\n\x0eVARIABLE_VALUE\x12\x01a\x1a%var_list/a/.ATTRIBUTES/VARIABLE_VALUE\n<\x12:\n\x0eVARIABLE_VALUE\x12\x01b\x1a%var_list/b/.ATTRIBUTES/VARIABLE_VALUE\nK\x12I\n\x0eVARIABLE_VALUE\x12\x08scoped/c\x1a-var_list/scoped.Sc/.ATTRIBUTES/VARIABLE_VALUE") (key='save_counter/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=int64, value=1)
یک ایست بازرسی TF2 را در TF1 بارگیری کنید
with tf.Graph().as_default() as g:
a = tf1.get_variable('a', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(0))
b = tf1.get_variable('b', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(0))
with tf1.variable_scope('scoped'):
c = tf1.get_variable('c', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(0))
with tf1.Session() as sess:
sess.run(tf1.global_variables_initializer())
print("Initialized [a, b, c]: ", sess.run([a, b, c]))
ckpt = tf.train.Checkpoint(
var_list={v.name.split(':')[0]: v for v in tf1.global_variables()})
ckpt.restore('tf2-ckpt-saved-in-session-1').run_restore_ops()
print("Restored [a, b, c]: ", sess.run([a, b, c]))
Initialized [a, b, c]: [0.0, 0.0, 0.0] Restored [a, b, c]: [1.0, 2.0, 3.0]
تبدیل ایست بازرسی
می توانید با بارگیری و ذخیره مجدد نقاط بازرسی، نقاط بازرسی را بین TF1 و TF2 تبدیل کنید. یک جایگزین tf.train.load_checkpoint
است که در کد زیر نشان داده شده است.
ایست بازرسی TF1 را به TF2 تبدیل کنید
def convert_tf1_to_tf2(checkpoint_path, output_prefix):
"""Converts a TF1 checkpoint to TF2.
To load the converted checkpoint, you must build a dictionary that maps
variable names to variable objects.
```
ckpt = tf.train.Checkpoint(vars={name: variable})
ckpt.restore(converted_ckpt_path)
```
Args:
checkpoint_path: Path to the TF1 checkpoint.
output_prefix: Path prefix to the converted checkpoint.
Returns:
Path to the converted checkpoint.
"""
vars = {}
reader = tf.train.load_checkpoint(checkpoint_path)
dtypes = reader.get_variable_to_dtype_map()
for key in dtypes.keys():
vars[key] = tf.Variable(reader.get_tensor(key))
return tf.train.Checkpoint(vars=vars).save(output_prefix)
```
Convert the checkpoint saved in the snippet `Save a TF1 checkpoint in TF2`:
```python
# Make sure to run the snippet in `Save a TF1 checkpoint in TF2`.
print_checkpoint('tf1-ckpt-saved-in-eager')
converted_path = convert_tf1_to_tf2('tf1-ckpt-saved-in-eager',
'converted-tf1-to-tf2')
print("\n[Converted]")
print_checkpoint(converted_path)
# Try loading the converted checkpoint.
a = tf.Variable(0.)
b = tf.Variable(0.)
c = tf.Variable(0.)
ckpt = tf.train.Checkpoint(vars={'a': a, 'b': b, 'scoped/c': c})
ckpt.restore(converted_path).assert_consumed()
print("\nRestored [a, b, c]: ", [a.numpy(), b.numpy(), c.numpy()])
Checkpoint at 'tf1-ckpt-saved-in-eager': (key='scoped/c', shape=[], dtype=float32, value=3.0) (key='a', shape=[], dtype=float32, value=1.0) (key='b', shape=[], dtype=float32, value=2.0) [Converted] Checkpoint at 'converted-tf1-to-tf2-1': (key='vars/scoped.Sc/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=3.0) (key='vars/b/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=2.0) (key='vars/a/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=1.0) (key='_CHECKPOINTABLE_OBJECT_GRAPH', shape=[], dtype=string, value=b"\n\x1c\n\x08\x08\x01\x12\x04vars\n\x10\x08\x02\x12\x0csave_counter\n\x1c\n\x0c\x08\x03\x12\x08scoped/c\n\x05\x08\x04\x12\x01a\n\x05\x08\x05\x12\x01b\nI\x12G\n\x0eVARIABLE_VALUE\x12\x0csave_counter\x1a'save_counter/.ATTRIBUTES/VARIABLE_VALUE\nG\x12E\n\x0eVARIABLE_VALUE\x12\x08Variable\x1a)vars/scoped.Sc/.ATTRIBUTES/VARIABLE_VALUE\n?\x12=\n\x0eVARIABLE_VALUE\x12\x08Variable\x1a!vars/a/.ATTRIBUTES/VARIABLE_VALUE\n?\x12=\n\x0eVARIABLE_VALUE\x12\x08Variable\x1a!vars/b/.ATTRIBUTES/VARIABLE_VALUE") (key='save_counter/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=int64, value=1) Restored [a, b, c]: [1.0, 2.0, 3.0]
ایست بازرسی TF2 را به TF1 تبدیل کنید
def convert_tf2_to_tf1(checkpoint_path, output_prefix):
"""Converts a TF2 checkpoint to TF1.
The checkpoint must be saved using a
`tf.train.Checkpoint(var_list={name: variable})`
To load the converted checkpoint with `tf.compat.v1.Saver`:
```
saver = tf.compat.v1.train.Saver(var_list={name: variable})
# An alternative, if the variable names match the keys:
saver = tf.compat.v1.train.Saver(var_list=[variables])
saver.restore(sess, output_path)
```
"""
vars = {}
reader = tf.train.load_checkpoint(checkpoint_path)
dtypes = reader.get_variable_to_dtype_map()
for key in dtypes.keys():
# Get the "name" from the
if key.startswith('var_list/'):
var_name = key.split('/')[1]
# TF2 checkpoint keys use '/', so if they appear in the user-defined name,
# they are escaped to '.S'.
var_name = var_name.replace('.S', '/')
vars[var_name] = tf.Variable(reader.get_tensor(key))
return tf1.train.Saver(var_list=vars).save(sess=None, save_path=output_prefix)
```
Convert the checkpoint saved in the snippet `Save a TF2 checkpoint in TF1`:
```python
# Make sure to run the snippet in `Save a TF2 checkpoint in TF1`.
print_checkpoint('tf2-ckpt-saved-in-session-1')
converted_path = convert_tf2_to_tf1('tf2-ckpt-saved-in-session-1',
'converted-tf2-to-tf1')
print("\n[Converted]")
print_checkpoint(converted_path)
# Try loading the converted checkpoint.
with tf.Graph().as_default() as g:
a = tf1.get_variable('a', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(0))
b = tf1.get_variable('b', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(0))
with tf1.variable_scope('scoped'):
c = tf1.get_variable('c', shape=[], dtype=tf.float32,
initializer=tf1.constant_initializer(0))
with tf1.Session() as sess:
saver = tf1.train.Saver([a, b, c])
saver.restore(sess, converted_path)
print("\nRestored [a, b, c]: ", sess.run([a, b, c]))
Checkpoint at 'tf2-ckpt-saved-in-session-1': (key='var_list/scoped.Sc/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=3.0) (key='var_list/b/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=2.0) (key='var_list/a/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=float32, value=1.0) (key='_CHECKPOINTABLE_OBJECT_GRAPH', shape=[], dtype=string, value=b"\n \n\x0c\x08\x01\x12\x08var_list\n\x10\x08\x02\x12\x0csave_counter\n\x1c\n\x05\x08\x03\x12\x01a\n\x05\x08\x04\x12\x01b\n\x0c\x08\x05\x12\x08scoped/c\nI\x12G\n\x0eVARIABLE_VALUE\x12\x0csave_counter\x1a'save_counter/.ATTRIBUTES/VARIABLE_VALUE\n<\x12:\n\x0eVARIABLE_VALUE\x12\x01a\x1a%var_list/a/.ATTRIBUTES/VARIABLE_VALUE\n<\x12:\n\x0eVARIABLE_VALUE\x12\x01b\x1a%var_list/b/.ATTRIBUTES/VARIABLE_VALUE\nK\x12I\n\x0eVARIABLE_VALUE\x12\x08scoped/c\x1a-var_list/scoped.Sc/.ATTRIBUTES/VARIABLE_VALUE") (key='save_counter/.ATTRIBUTES/VARIABLE_VALUE', shape=[], dtype=int64, value=1) WARNING:tensorflow:Saver is deprecated, please switch to tf.train.Checkpoint or tf.keras.Model.save_weights for training checkpoints. When executing eagerly variables do not necessarily have unique names, and so the variable.name-based lookups Saver performs are error-prone. [Converted] Checkpoint at 'converted-tf2-to-tf1': (key='scoped/c', shape=[], dtype=float32, value=3.0) (key='a', shape=[], dtype=float32, value=1.0) (key='b', shape=[], dtype=float32, value=2.0) INFO:tensorflow:Restoring parameters from converted-tf2-to-tf1 Restored [a, b, c]: [1.0, 2.0, 3.0]