ช่วยปกป้อง Great Barrier Reef กับ TensorFlow บน Kaggle เข้าร่วมท้าทาย

ใช้โมเดล TF1.x ในเวิร์กโฟลว์ TF2

ดูบน TensorFlow.org ทำงานใน Google Colab ดูบน GitHub ดาวน์โหลดโน๊ตบุ๊ค

คู่มือนี้จะให้ภาพรวมและตัวอย่างของ ชิมรหัสการสร้างแบบจำลอง ที่คุณสามารถใช้เพื่อใช้รูปแบบที่มีอยู่ใน TF1.x TF2 เวิร์กโฟลว์เช่นการดำเนินการกระตือรือร้น tf.function และการกระจายกลยุทธ์ที่มีการเปลี่ยนแปลงน้อยที่สุดเพื่อรหัสการสร้างแบบจำลองของคุณ

ขอบเขตการใช้งาน

แผ่นชิมที่อธิบายในคู่มือนี้ออกแบบมาสำหรับรุ่น TF1.x ที่ต้องพึ่งพา:

  1. tf.compat.v1.get_variable และ tf.compat.v1.variable_scope ไปสู่การสร้างตัวแปรควบคุมและนำมาใช้และ
  2. APIs ตามกราฟคอลเลกชันเช่น tf.compat.v1.global_variables() , tf.compat.v1.trainable_variables , tf.compat.v1.losses.get_regularization_losses() และ tf.compat.v1.get_collection() ในการติดตาม ของน้ำหนักและการสูญเสียการทำให้เป็นมาตรฐาน

ซึ่งรวมถึงรูปแบบที่สุดสร้างขึ้นบน tf.compat.v1.layer , tf.contrib.layers APIs และ TensorFlow-สลิม

ชิมไม่จำเป็นสำหรับรุ่น TF1.x ต่อไปนี้:

  1. รูปแบบสแตนด์อะโลน Keras ที่มีอยู่แล้วติดตามทั้งหมดของน้ำหนักสุวินัยของพวกเขาและการสูญเสีย regularization ผ่าน model.trainable_weights และ model.losses ตามลำดับ
  2. tf.Module s ที่มีอยู่แล้วติดตามทั้งหมดของน้ำหนักสุวินัยของพวกเขาผ่าน module.trainable_variables และมีเพียงสร้างน้ำหนักถ้าพวกเขาไม่ได้รับการสร้างขึ้นแล้ว

รูปแบบเหล่านี้มีแนวโน้มที่จะทำงานใน TF2 กับการดำเนินความกระตือรือร้นและ tf.function s ออกจากกล่อง

ติดตั้ง

นำเข้า TensorFlow และการพึ่งพาอื่น ๆ

pip uninstall -y tensorflow_estimator tensorflow keras
pip install -U tf-nightly
# Note that the model mapping shim is available only in TF 2.7.
import tensorflow as tf
import tensorflow.compat.v1 as v1
import sys
import numpy as np

from unittest import mock
from contextlib import contextmanager

track_tf1_style_variables มัณฑนากร

ชิมสำคัญที่อธิบายไว้ในคู่มือนี้เป็น tf.compat.v1.keras.utils.track_tf1_style_variables , มัณฑนากรที่คุณสามารถใช้วิธีการภายในที่อยู่ใน tf.keras.layers.Layer และ tf.Module เพื่อติดตามน้ำหนัก TF1.x สไตล์ จับการสูญเสียการทำให้เป็นมาตรฐาน

ตกแต่ง tf.keras.layers.Layer 's หรือ tf.Module ' s วิธีการโทรกับ tf.compat.v1.keras.utils.track_tf1_style_variables ช่วยให้การสร้างตัวแปรและนำมาใช้ผ่านทาง tf.compat.v1.get_variable (และโดยการขยาย tf.compat.v1.layers ) ในการทำงานได้อย่างถูกต้องภายในของวิธีการตกแต่งมากกว่าเสมอสร้างตัวแปรใหม่ในแต่ละสาย นอกจากนี้ยังจะทำให้เกิดชั้นหรือโมดูลไปโดยปริยายติดตามน้ำหนักใด ๆ ที่สร้างหรือเข้าถึงได้ผ่านทาง get_variable ภายในวิธีการตกแต่ง

นอกจากการติดตามน้ำหนักของตัวเองภายใต้มาตรฐาน layer.variable / module.variable / ฯลฯ คุณสมบัติถ้าวิธีการที่เป็นของ tf.keras.layers.Layer แล้วการสูญเสียใด ๆ ที่ระบุ regularization ผ่าน get_variable หรือ tf.compat.v1.layers regularizer ข้อโต้แย้งจะได้รับการติดตามโดยชั้นที่อยู่ภายใต้มาตรฐาน layer.losses คุณสมบัติ

กลไกการติดตามนี้จะช่วยให้การใช้ชั้นเรียนขนาดใหญ่ของ TF1.x สไตล์ภายในรหัสรูปแบบไปข้างหน้าผ่านชั้น Keras หรือ tf.Module ใน TF2 แม้จะมี TF2 พฤติกรรมการเปิดใช้งาน

ตัวอย่างการใช้งาน

ตัวอย่างการใช้งานด้านล่างแสดงให้เห็นถึง shims การสร้างแบบจำลองที่ใช้ในการตกแต่ง tf.keras.layers.Layer วิธี แต่ยกเว้นในกรณีที่พวกเขากำลังโดยเฉพาะการมีปฏิสัมพันธ์กับ Keras มีพวกเขามีผลบังคับใช้เมื่อตกแต่ง tf.Module วิธีการเช่นกัน

เลเยอร์ที่สร้างด้วย tf.compat.v1.get_variable

ลองนึกภาพคุณมีชั้นดำเนินการตรงด้านบนของ tf.compat.v1.get_variable ดังนี้

def dense(self, inputs, units):
  out = inputs
  with tf.compat.v1.variable_scope("dense"):
    # The weights are created with a `regularizer`,
    kernel = tf.compat.v1.get_variable(
        shape=[out.shape[-1], units],
        regularizer=tf.keras.regularizers.L2(),
        initializer=tf.compat.v1.initializers.glorot_normal,
        name="kernel")
    bias = tf.compat.v1.get_variable(
        shape=[units,],
        initializer=tf.compat.v1.initializers.zeros,
        name="bias")
    out = tf.linalg.matmul(out, kernel)
    out = tf.compat.v1.nn.bias_add(out, bias)
  return out

ใช้แผ่นชิมเพื่อเปลี่ยนเป็นเลเยอร์และเรียกใช้อินพุต

class DenseLayer(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    out = inputs
    with tf.compat.v1.variable_scope("dense"):
      # The weights are created with a `regularizer`,
      # so the layer should track their regularization losses
      kernel = tf.compat.v1.get_variable(
          shape=[out.shape[-1], self.units],
          regularizer=tf.keras.regularizers.L2(),
          initializer=tf.compat.v1.initializers.glorot_normal,
          name="kernel")
      bias = tf.compat.v1.get_variable(
          shape=[self.units,],
          initializer=tf.compat.v1.initializers.zeros,
          name="bias")
      out = tf.linalg.matmul(out, kernel)
      out = tf.compat.v1.nn.bias_add(out, bias)
    return out

layer = DenseLayer(10)
x = tf.random.normal(shape=(8, 20))
layer(x)
WARNING:tensorflow:From /tmp/ipykernel_11242/795621215.py:7: The name tf.keras.utils.track_tf1_style_variables is deprecated. Please use tf.compat.v1.keras.utils.track_tf1_style_variables instead.
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[ 2.1375508 , -1.7944846 ,  0.565429  ,  2.217993  ,  1.0197983 ,
         1.1995478 ,  0.76082695,  1.2525213 , -1.1448774 , -1.5099244 ],
       [-1.8368615 ,  0.929764  , -0.68088764, -3.7934241 , -0.873991  ,
         1.1868672 ,  1.5348943 , -2.8576217 , -1.8646189 , -1.4464494 ],
       [ 1.4563093 ,  1.9133099 ,  0.2668215 , -0.47504902,  1.3939316 ,
        -2.4648583 ,  0.67149144,  0.8774765 ,  1.9594793 , -0.9630938 ],
       [ 0.63517594,  1.2447351 ,  0.57714343, -1.8551574 ,  1.2194395 ,
        -1.3226352 , -1.534353  , -1.571831  , -1.3915701 , -0.4385677 ],
       [-1.1224217 , -1.8950897 ,  1.9080337 ,  1.5483713 ,  0.3007682 ,
        -0.11733571,  1.4215202 ,  1.0951209 , -0.40666753,  1.3011668 ],
       [-1.6115788 , -0.36258316,  0.279747  , -3.3505366 ,  0.9046302 ,
        -0.0449394 , -0.25892067, -3.1661186 , -1.825649  ,  0.34308952],
       [ 0.57928437, -0.41061705, -0.18791246,  0.43806618, -1.1424513 ,
        -0.8472259 , -0.18853194,  1.1114476 , -1.1165383 , -2.1490216 ],
       [-1.425385  , -0.64927876, -0.28559908, -0.95958436, -0.5622783 ,
        -0.223617  , -1.5422437 ,  1.429243  ,  0.19077098, -0.97339046]],
      dtype=float32)>

เข้าถึงตัวแปรที่ติดตามและการสูญเสียการทำให้เป็นมาตรฐานที่บันทึกไว้เช่นเลเยอร์ Keras มาตรฐาน

layer.trainable_variables
layer.losses
2021-11-23 02:29:53.768499: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
[<tf.Tensor: shape=(), dtype=float32, numpy=0.15060465>]

หากต้องการดูว่าน้ำหนักถูกนำมาใช้ซ้ำทุกครั้งที่คุณเรียกใช้เลเยอร์ ให้ตั้งค่าน้ำหนักทั้งหมดเป็นศูนย์และเรียกเลเยอร์นั้นอีกครั้ง

print("Resetting variables to zero:", [var.name for var in layer.trainable_variables])

for var in layer.trainable_variables:
  var.assign(var * 0.0)

# Note: layer.losses is not a live view and
# will get reset only at each layer call
print("layer.losses:", layer.losses)
print("calling layer again.")
out = layer(x)
print("layer.losses: ", layer.losses)
out
Resetting variables to zero: ['dense/bias:0', 'dense/kernel:0']
layer.losses: [<tf.Tensor: shape=(), dtype=float32, numpy=0.0>]
calling layer again.
layer.losses:  [<tf.Tensor: shape=(), dtype=float32, numpy=0.0>]
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>

คุณสามารถใช้เลเยอร์ที่แปลงแล้วโดยตรงในการสร้างแบบจำลองการทำงานของ Keras เช่นกัน

inputs = tf.keras.Input(shape=(20))
outputs = DenseLayer(10)(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)

x = tf.random.normal(shape=(8, 20))
model(x)

# Access the model variables and regularization losses
model.weights
model.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.12031876>]

รูปแบบที่สร้างขึ้นด้วย tf.compat.v1.layers

ลองนึกภาพคุณมีชั้นหรือรุ่นดำเนินการตรงด้านบนของ tf.compat.v1.layers ดังนี้

def model(self, inputs, units):
  with tf.compat.v1.variable_scope('model'):
    out = tf.compat.v1.layers.conv2d(
        inputs, 3, 3,
        kernel_regularizer="l2")
    out = tf.compat.v1.layers.flatten(out)
    out = tf.compat.v1.layers.dense(
        out, units,
        kernel_regularizer="l2")
    return out

ใช้แผ่นชิมเพื่อเปลี่ยนเป็นเลเยอร์และเรียกใช้อินพุต

class CompatV1LayerModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    with tf.compat.v1.variable_scope('model'):
      out = tf.compat.v1.layers.conv2d(
          inputs, 3, 3,
          kernel_regularizer="l2")
      out = tf.compat.v1.layers.flatten(out)
      out = tf.compat.v1.layers.dense(
          out, self.units,
          kernel_regularizer="l2")
      return out

layer = CompatV1LayerModel(10)
x = tf.random.normal(shape=(8, 5, 5, 5))
layer(x)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:12: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  if sys.path[0] == '':
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/convolutional.py:575: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:13: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  del sys.path[0]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/core.py:541: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:16: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
  app.launch_new_instance()
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/core.py:261: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs)
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[ 0.37805164,  1.8133228 ,  0.86462975, -1.4787364 ,  0.02895362,
         0.8421986 ,  0.15317512,  1.1292509 , -0.2179926 ,  1.4042507 ],
       [-1.0554819 , -0.14058013, -1.3772738 ,  2.1067414 , -0.887224  ,
         0.20268968,  0.05371363,  2.3933268 ,  0.47980696,  0.07456923],
       [-0.05067754,  0.04003759, -1.1708652 ,  0.50643575,  0.43419954,
         0.49038708,  1.4956386 ,  0.52199614, -0.98080426,  0.22641146],
       [-1.4830599 ,  1.5334661 , -0.24063748, -1.5365379 , -1.323379  ,
         2.311288  ,  0.50101113,  1.661559  , -0.24971324, -0.42585582],
       [ 0.31571257, -0.5366141 , -0.38673356,  1.3282443 , -1.3107554 ,
         0.63491017, -0.9445646 ,  0.44513133,  0.8641659 ,  0.4294421 ],
       [ 0.30027592,  0.188151  ,  0.39278126,  0.9219465 ,  1.8363616 ,
        -0.18119514,  0.17797446, -0.2636444 , -1.6716032 , -1.0964239 ],
       [-0.557606  , -2.302523  , -0.82658786, -0.6043796 ,  0.4406705 ,
         0.25789356,  2.9949172 , -0.76322764,  1.8916178 , -2.500245  ],
       [-0.8927715 , -1.5578954 , -0.05657649, -1.8374336 , -0.8938144 ,
         0.8692418 , -1.4616051 ,  0.9205449 ,  2.6908588 , -2.20056   ]],
      dtype=float32)>

เข้าถึงตัวแปรที่ติดตามและการสูญเสียการทำให้เป็นมาตรฐานที่บันทึกไว้เช่นเลเยอร์ Keras มาตรฐาน

layer.trainable_variables
layer.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.03943673>,
 <tf.Tensor: shape=(), dtype=float32, numpy=0.13957524>]

หากต้องการดูว่าน้ำหนักถูกนำมาใช้ซ้ำทุกครั้งที่คุณเรียกใช้เลเยอร์ ให้ตั้งค่าน้ำหนักทั้งหมดเป็นศูนย์และเรียกเลเยอร์นั้นอีกครั้ง

print("Resetting variables to zero:", [var.name for var in layer.trainable_variables])

for var in layer.trainable_variables:
  var.assign(var * 0.0)

out = layer(x)
print("layer.losses: ", layer.losses)
out
Resetting variables to zero: ['model/conv2d/bias:0', 'model/conv2d/kernel:0', 'model/dense/bias:0', 'model/dense/kernel:0']
layer.losses:  [<tf.Tensor: shape=(), dtype=float32, numpy=0.0>, <tf.Tensor: shape=(), dtype=float32, numpy=0.0>]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:12: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  if sys.path[0] == '':
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:13: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  del sys.path[0]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:16: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
  app.launch_new_instance()
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>

คุณสามารถใช้เลเยอร์ที่แปลงแล้วโดยตรงในการสร้างแบบจำลองการทำงานของ Keras เช่นกัน

inputs = tf.keras.Input(shape=(5, 5, 5))
outputs = CompatV1LayerModel(10)(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)

x = tf.random.normal(shape=(8, 5, 5, 5))
model(x)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:12: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  if sys.path[0] == '':
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/base.py:573: UserWarning: `layer.updates` will be removed in a future version. This property should not be used in TensorFlow 2.0, as `updates` are applied automatically.
  _add_elements_to_collection(self.updates, tf.compat.v1.GraphKeys.UPDATE_OPS)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:13: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  del sys.path[0]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:16: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
  app.launch_new_instance()
<tf.Tensor: shape=(8, 10), dtype=float32, numpy=
array([[ 1.4855937e+00, -2.7656064e+00,  1.3545771e+00,  1.8412153e+00,
         2.6830747e+00,  1.5520985e+00,  1.6604857e+00, -1.5574534e+00,
         4.8879254e-01, -9.3593240e-01],
       [-3.5260645e-01, -8.5253775e-01,  2.9307604e-03,  2.5392106e+00,
        -1.0028646e+00, -1.3632554e+00,  1.3462807e+00, -9.8628730e-01,
         8.0417931e-01, -5.2788424e-01],
       [-1.1495411e+00,  3.4236248e+00,  1.4656919e+00,  8.5768580e-01,
         1.3331357e+00, -8.4157258e-01,  9.8651722e-02,  1.0235069e+00,
         1.2864964e+00,  1.7336640e-01],
       [ 1.3583817e+00, -1.2720991e+00,  2.7617774e+00, -1.6359773e+00,
        -9.3302876e-03,  2.1517355e+00,  1.4786386e-01, -2.2064322e-01,
        -7.9553246e-01,  1.3321551e+00],
       [-6.7520809e-01, -2.7840310e-01, -5.4193705e-01,  8.4345484e-01,
         4.9731803e-01, -6.1475182e-01,  1.9032955e+00, -1.2340800e+00,
        -1.0945371e-01, -1.4558470e-01],
       [-1.4447448e+00, -2.1551886e+00, -1.6724775e+00,  2.7837777e+00,
         7.7755189e-01, -4.4531783e-01,  2.2827234e+00, -1.1688620e-02,
         3.0173159e-01, -2.1856803e-01],
       [ 1.3978167e+00, -7.4688423e-01,  3.1681514e-01, -1.1488553e+00,
        -2.5831108e+00,  1.5824573e-01, -1.3887520e+00,  8.8456994e-01,
         6.5672320e-01, -5.1850575e-01],
       [-2.9664264e+00, -6.5011466e-01, -1.6712356e+00, -7.9054677e-01,
        -4.6599650e+00, -2.5024600e+00,  1.4304999e+00,  2.7220290e+00,
         7.2737026e-01,  5.9418190e-01]], dtype=float32)>
# Access the model variables and regularization losses
model.weights
model.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.042700935>,
 <tf.Tensor: shape=(), dtype=float32, numpy=0.13701487>]

จับภาพการปรับปรุงชุดฟื้นฟูและรูปแบบ training args

ใน TF1.x คุณทำการแบทช์เป็นมาตรฐานดังนี้:

  x_norm = tf.compat.v1.layers.batch_normalization(x, training=training)

  # ...

  update_ops = tf.compat.v1.get_collection(tf.GraphKeys.UPDATE_OPS)
  train_op = optimizer.minimize(loss)
  train_op = tf.group([train_op, update_ops])

โปรดทราบว่า:

  1. ฟื้นฟูชุดเคลื่อนย้ายการปรับปรุงเฉลี่ยมีการติดตามโดย get_collection ซึ่งถูกเรียกว่าแยกต่างหากจากชั้น
  2. tf.compat.v1.layers.batch_normalization ต้องมี training การโต้เถียง (เรียกโดยทั่วไป is_training เมื่อใช้ TF-สลิมชั้นชุดฟื้นฟู)

ใน TF2 เนื่องจาก การดำเนินการความกระตือรือร้น และการอ้างอิงการควบคุมอัตโนมัติฟื้นฟูชุดเคลื่อนย้ายการปรับปรุงเฉลี่ยจะถูกดำเนินการทันที ไม่จำเป็นต้องรวบรวมแยกจากคอลเลกชันอัพเดต และเพิ่มเป็นการพึ่งพาการควบคุมอย่างชัดเจน

นอกจากนี้ถ้าคุณให้คุณ tf.keras.layers.Layer วิธีผ่าน 's ไปข้างหน้า training อาร์กิวเมนต์ Keras จะสามารถที่จะผ่านขั้นตอนการฝึกอบรมในปัจจุบันและชั้นที่ซ้อนกันใด ๆ กับมันเช่นเดียวกับมันไม่สำหรับชั้นอื่น ๆ ดูเอกสาร API สำหรับ tf.keras.Model สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธี Keras จัดการ training การโต้แย้ง

หากคุณกำลังตกแต่ง tf.Module วิธีการที่คุณต้องให้แน่ใจว่าจะผ่านทั้งหมดด้วยตนเอง training การขัดแย้งตามความจำเป็น อย่างไรก็ตาม การอัปเดตค่าเฉลี่ยเคลื่อนที่ของการทำให้เป็นมาตรฐานของแบตช์จะยังคงใช้โดยอัตโนมัติโดยไม่จำเป็นต้องพึ่งพาการควบคุมอย่างชัดเจน

ข้อมูลโค้ดต่อไปนี้แสดงให้เห็นถึงวิธีการฝังชั้นชุดบรรทัดฐานในการชิมและวิธีการใช้มันในรูปแบบ Keras งาน (ที่ใช้บังคับกับ tf.keras.layers.Layer )

class CompatV1BatchNorm(tf.keras.layers.Layer):

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    print("Forward pass called with `training` =", training)
    with v1.variable_scope('batch_norm_layer'):
      return v1.layers.batch_normalization(x, training=training)
print("Constructing model")
inputs = tf.keras.Input(shape=(5, 5, 5))
outputs = CompatV1BatchNorm()(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)

print("Calling model in inference mode")
x = tf.random.normal(shape=(8, 5, 5, 5))
model(x, training=False)

print("Moving average variables before training: ",
      {var.name: var.read_value() for var in model.non_trainable_variables})

# Notice that when running TF2 and eager execution, the batchnorm layer directly
# updates the moving averages while training without needing any extra control
# dependencies
print("calling model in training mode")
model(x, training=True)

print("Moving average variables after training: ",
      {var.name: var.read_value() for var in model.non_trainable_variables})
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:7: UserWarning: `tf.layers.batch_normalization` is deprecated and will be removed in a future version. Please use `tf.keras.layers.BatchNormalization` instead. In particular, `tf.control_dependencies(tf.GraphKeys.UPDATE_OPS)` should not be used (consult the `tf.keras.layers.BatchNormalization` documentation).
  import sys
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/normalization.py:463: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs, training=training)
Constructing model
Forward pass called with `training` = None
Calling model in inference mode
Forward pass called with `training` = False
Moving average variables before training:  {'batch_norm_layer/batch_normalization/moving_mean:0': <tf.Tensor: shape=(5,), dtype=float32, numpy=array([0., 0., 0., 0., 0.], dtype=float32)>, 'batch_norm_layer/batch_normalization/moving_variance:0': <tf.Tensor: shape=(5,), dtype=float32, numpy=array([1., 1., 1., 1., 1.], dtype=float32)>}
calling model in training mode
Forward pass called with `training` = True
Moving average variables after training:  {'batch_norm_layer/batch_normalization/moving_mean:0': <tf.Tensor: shape=(5,), dtype=float32, numpy=
array([ 1.1385456e-03, -2.3051118e-04, -2.1241283e-05,  1.3993075e-03,
       -4.8623187e-04], dtype=float32)>, 'batch_norm_layer/batch_normalization/moving_variance:0': <tf.Tensor: shape=(5,), dtype=float32, numpy=
array([0.9989541, 0.9992638, 0.9984195, 0.9991469, 1.000844 ],
      dtype=float32)>}

การใช้ซ้ำตัวแปรตามขอบเขตตัวแปร

สร้างสรรค์ตัวแปรใด ๆ ในการส่งผ่านไปข้างหน้าขึ้นอยู่กับ get_variable จะรักษาเดียวกันตัวแปรการตั้งชื่อและนำมาใช้ในความหมายว่าขอบเขตตัวแปรมีใน TF1.x. นี่คือความจริงตราบใดที่คุณมีอย่างน้อยหนึ่งที่ไม่ว่างเปล่าขอบเขตด้านนอกสำหรับการใด ๆ tf.compat.v1.layers ที่มีชื่อสร้างขึ้นโดยอัตโนมัติดังกล่าวข้างต้น

การดำเนินการและความกระตือรือร้นที่ tf.function

เท่าที่เห็นข้างต้นวิธีการสำหรับการตกแต่ง tf.keras.layers.Layer และ tf.Module วิ่งภายในของการดำเนินการกระตือรือร้นและยังเข้ากันได้กับ tf.function ซึ่งหมายความว่าคุณสามารถใช้ PDB และเครื่องมืออื่น ๆ ที่จะโต้ตอบขั้นตอนผ่านไปข้างหน้าผ่านของคุณเป็นที่ทำงาน

กลยุทธ์การจัดจำหน่าย

โทรไป get_variable ภายในของ @track_tf1_style_variables -decorated ชั้นหรือโมดูลวิธีการใช้มาตรฐาน tf.Variable สร้างสรรค์ตัวแปรภายใต้ประทุน ซึ่งหมายความว่าคุณสามารถใช้พวกเขาด้วยกลยุทธ์การจัดจำหน่ายต่างๆที่มีอยู่กับ tf.distribute เช่น MirroredStrategy และ TPUStrategy

รัง tf.Variable s, tf.Module s, tf.keras.layers & tf.keras.models ในสายการตกแต่ง

ตกแต่งโทรชั้นใน tf.compat.v1.keras.utils.track_tf1_style_variables จะเพิ่มการติดตามนัยอัตโนมัติของตัวแปรที่สร้างขึ้น (และกลับมาใช้ใหม่) ผ่าน tf.compat.v1.get_variable มันจะไม่จับน้ำหนักสร้างขึ้นโดยตรงโดย tf.Variable สายเช่นที่ใช้โดยทั่วไปชั้น Keras และส่วนใหญ่ tf.Module s ส่วนนี้อธิบายวิธีจัดการกับกรณีและปัญหาที่ซ้อนกันเหล่านี้

(Pre-ประเพณีที่มีอยู่) tf.keras.layers และ tf.keras.models

สำหรับประเพณีที่มีอยู่ก่อนชั้น Keras ซ้อนกันและรูปแบบการใช้งาน tf.compat.v1.keras.utils.get_or_create_layer แนะนำเฉพาะสำหรับการทำให้การย้ายข้อมูลของ Keras ที่ซ้อนกัน TF1.x ที่มีอยู่ง่ายขึ้นเท่านั้น รหัสใหม่ควรใช้การตั้งค่าแอตทริบิวต์ที่ชัดเจนตามที่อธิบายไว้ด้านล่างสำหรับ tf.Variables และ tf.Modules

หากต้องการใช้ tf.compat.v1.keras.utils.get_or_create_layer ห่อรหัสที่สร้างรูปแบบการซ้อนกันของคุณลงในวิธีการและผ่านมันในวิธีการ ตัวอย่าง:

class NestedModel(tf.keras.Model):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  def build_model(self):
    inp = tf.keras.Input(shape=(5, 5))
    dense_layer = tf.keras.layers.Dense(
        10, name="dense", kernel_regularizer="l2",
        kernel_initializer=tf.compat.v1.ones_initializer())
    model = tf.keras.Model(inputs=inp, outputs=dense_layer(inp))
    return model

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    # Get or create a nested model without assigning it as an explicit property
    model = tf.compat.v1.keras.utils.get_or_create_layer(
        "dense_model", self.build_model)
    return model(inputs)

layer = NestedModel(10)
layer(tf.ones(shape=(5,5)))
<tf.Tensor: shape=(5, 10), dtype=float32, numpy=
array([[5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.]], dtype=float32)>

วิธีนี้ช่วยให้แน่ใจว่าเลเยอร์ที่ซ้อนกันเหล่านี้ถูกนำมาใช้ซ้ำอย่างถูกต้องและติดตามโดยเทนเซอร์โฟลว์ โปรดทราบว่า @track_tf1_style_variables มัณฑนากรยังคงต้องมีวิธีการที่เหมาะสม วิธีการสร้างแบบจำลองการผ่านเข้าสู่ get_or_create_layer (ในกรณีนี้ self.build_model ) ควรจะไม่มีข้อโต้แย้ง

มีการติดตามน้ำหนัก:

assert len(layer.weights) == 2
weights = {x.name: x for x in layer.variables}

assert set(weights.keys()) == {"dense/bias:0", "dense/kernel:0"}

layer.weights
[<tf.Variable 'dense/kernel:0' shape=(5, 10) dtype=float32, numpy=
 array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]], dtype=float32)>,
 <tf.Variable 'dense/bias:0' shape=(10,) dtype=float32, numpy=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)>]

และการสูญเสียการทำให้เป็นมาตรฐานเช่นกัน:

tf.add_n(layer.losses)
<tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.5], dtype=float32)>

การโยกย้ายที่เพิ่มขึ้น: tf.Variables และ tf.Modules

หากคุณจำเป็นต้องฝัง tf.Variable โทรออกหรือ tf.Module ในวิธีการตกแต่งของคุณ (ตัวอย่างเช่นถ้าคุณกำลังติดตามการโยกย้ายที่เพิ่มขึ้นไม่ใช่มรดก APIs TF2 อธิบายไว้ในคู่มือนี้) คุณยังคงต้องติดตามอย่างชัดเจนเหล่านี้ โดยมีข้อกำหนดดังต่อไปนี้

  • ตรวจสอบให้แน่ใจอย่างชัดเจนว่าตัวแปร/โมดูล/เลเยอร์ถูกสร้างขึ้นเพียงครั้งเดียว
  • อย่างชัดเจนแนบพวกเขาเป็นเช่นคุณลักษณะเช่นเดียวกับที่คุณจะเมื่อกำหนด โมดูลทั่วไปหรือชั้น
  • นำออบเจ็กต์ที่สร้างไว้แล้วมาใช้ใหม่อย่างชัดเจนในการเรียกที่ตามมา

เพื่อให้แน่ใจว่าไม่มีการสร้างน้ำหนักขึ้นใหม่ในการโทรแต่ละครั้งและนำกลับมาใช้ใหม่อย่างถูกต้อง นอกจากนี้ สิ่งนี้ยังช่วยให้แน่ใจว่าน้ำหนักที่มีอยู่และการสูญเสียการทำให้เป็นมาตรฐานได้รับการติดตาม

นี่คือตัวอย่างลักษณะของสิ่งนี้:

class NestedLayer(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def __call__(self, inputs):
    out = inputs
    with tf.compat.v1.variable_scope("inner_dense"):
      # The weights are created with a `regularizer`,
      # so the layer should track their regularization losses
      kernel = tf.compat.v1.get_variable(
          shape=[out.shape[-1], self.units],
          regularizer=tf.keras.regularizers.L2(),
          initializer=tf.compat.v1.initializers.glorot_normal,
          name="kernel")
      bias = tf.compat.v1.get_variable(
          shape=[self.units,],
          initializer=tf.compat.v1.initializers.zeros,
          name="bias")
      out = tf.linalg.matmul(out, kernel)
      out = tf.compat.v1.nn.bias_add(out, bias)
    return out

class WrappedDenseLayer(tf.keras.layers.Layer):

  def __init__(self, units, **kwargs):
    super().__init__(**kwargs)
    self.units = units
    # Only create the nested tf.variable/module/layer/model
    # once, and then reuse it each time!
    self._dense_layer = NestedLayer(self.units)

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    with tf.compat.v1.variable_scope('outer'):
      outputs = tf.compat.v1.layers.dense(inputs, 3)
      outputs = tf.compat.v1.layers.dense(inputs, 4)
      return self._dense_layer(outputs)

layer = WrappedDenseLayer(10)

layer(tf.ones(shape=(5, 5)))
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:38: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:39: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
<tf.Tensor: shape=(5, 10), dtype=float32, numpy=
array([[ 0.87398976,  1.2405497 ,  0.6845182 ,  0.4866921 , -0.6569822 ,
         1.0673944 , -1.3701987 ,  0.4779834 , -0.18968081,  1.5541892 ],
       [ 0.87398976,  1.2405497 ,  0.6845182 ,  0.4866921 , -0.6569822 ,
         1.0673944 , -1.3701987 ,  0.4779834 , -0.18968081,  1.5541892 ],
       [ 0.87398976,  1.2405497 ,  0.6845182 ,  0.4866921 , -0.6569822 ,
         1.0673944 , -1.3701987 ,  0.4779834 , -0.18968081,  1.5541892 ],
       [ 0.87398976,  1.2405497 ,  0.6845182 ,  0.4866921 , -0.6569822 ,
         1.0673944 , -1.3701987 ,  0.4779834 , -0.18968081,  1.5541892 ],
       [ 0.87398976,  1.2405497 ,  0.6845182 ,  0.4866921 , -0.6569822 ,
         1.0673944 , -1.3701987 ,  0.4779834 , -0.18968081,  1.5541892 ]],
      dtype=float32)>

โปรดทราบว่าการติดตามอย่างชัดเจนของโมดูลที่ซ้อนกันเป็นสิ่งจำเป็นแม้ว่าจะตกแต่งด้วย track_tf1_style_variables มัณฑนากร เนื่องจากแต่ละโมดูล/เลเยอร์ที่มีเมธอดที่ตกแต่งแล้วจะมีที่เก็บตัวแปรที่เกี่ยวข้องกัน

มีการติดตามน้ำหนักอย่างถูกต้อง:

assert len(layer.weights) == 6
weights = {x.name: x for x in layer.variables}

assert set(weights.keys()) == {"outer/inner_dense/bias:0",
                               "outer/inner_dense/kernel:0",
                               "outer/dense/bias:0",
                               "outer/dense/kernel:0",
                               "outer/dense_1/bias:0",
                               "outer/dense_1/kernel:0"}

layer.trainable_weights
[<tf.Variable 'outer/inner_dense/bias:0' shape=(10,) dtype=float32, numpy=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)>,
 <tf.Variable 'outer/inner_dense/kernel:0' shape=(4, 10) dtype=float32, numpy=
 array([[-0.7106493 ,  0.03652234, -0.5641838 ,  0.44038984,  0.26725787,
         -0.8249933 ,  0.79204524, -0.38647223, -0.68761927, -0.10278723],
        [-0.19713117, -0.61713815,  0.00494798, -0.8592477 ,  0.03517161,
         -0.41172737,  0.34112948,  0.08910135,  0.5520702 , -0.7381817 ],
        [ 0.07412005, -0.29660687, -0.23315382,  0.5994434 ,  0.40819865,
          0.35701373,  0.14988966, -0.3089575 , -0.11347155, -0.2857559 ],
        [ 0.13573293,  0.11401974, -0.24189845,  0.26831126, -0.13960141,
          0.03242165,  0.2838935 ,  0.53873944,  0.5168897 ,  0.36707175]],
       dtype=float32)>,
 <tf.Variable 'outer/dense/bias:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>,
 <tf.Variable 'outer/dense/kernel:0' shape=(5, 3) dtype=float32, numpy=
 array([[ 0.865285  , -0.5579717 , -0.22214234],
        [ 0.10053962, -0.10505754,  0.49894482],
        [ 0.16439968,  0.08750641,  0.35952443],
        [-0.6860548 , -0.76112765,  0.38850957],
        [ 0.19568652,  0.5770381 , -0.505653  ]], dtype=float32)>,
 <tf.Variable 'outer/dense_1/bias:0' shape=(4,) dtype=float32, numpy=array([0., 0., 0., 0.], dtype=float32)>,
 <tf.Variable 'outer/dense_1/kernel:0' shape=(5, 4) dtype=float32, numpy=
 array([[-0.47451308, -0.29268932, -0.31780362,  0.679634  ],
        [-0.7615033 , -0.7985905 , -0.54569066,  0.2096864 ],
        [-0.37253472, -0.70463765,  0.22033823, -0.7091312 ],
        [ 0.45600712, -0.34825963,  0.08295816, -0.01225257],
        [ 0.28514922,  0.5162982 , -0.33372337, -0.14636421]],
       dtype=float32)>]

เช่นเดียวกับการสูญเสียการทำให้เป็นมาตรฐาน:

layer.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.073024586>]

โปรดทราบว่าถ้า NestedLayer เป็นไม่ใช่ Keras tf.Module แทนตัวแปรจะยังคงติดตามการสูญเสีย แต่กูจะไม่ได้รับการติดตามโดยอัตโนมัติเพื่อให้คุณจะต้องชัดเจนติดตามพวกเขาต่างหาก

คำแนะนำเกี่ยวกับชื่อตัวแปร

อย่างชัดเจน tf.Variable โทรและชั้น Keras ใช้ชื่อชั้นที่แตกต่างกัน / กลไกการสร้างอัตโนมัติชื่อตัวแปรกว่าที่คุณอาจจะใช้จากการรวมกันของ get_variable และ variable_scopes แม้ว่าชิมจะทำให้ชื่อตัวแปรของคุณตรงสำหรับตัวแปรที่สร้างขึ้นโดย get_variable แม้ในขณะที่ไปจากกราฟ TF1.x เพื่อดำเนินการ TF2 กระตือรือร้นและ tf.function ก็ไม่สามารถรับประกันได้เหมือนกันสำหรับชื่อตัวแปรที่สร้างขึ้นสำหรับ tf.Variable โทรและชั้น Keras ว่า คุณฝังตัวมัณฑนากรวิธีการของคุณ มันเป็นไปได้สำหรับตัวแปรหลายแบ่งปันชื่อเดียวกันในการดำเนินการ TF2 กระตือรือร้นและ tf.function

คุณควรใช้ความระมัดระวังเป็นพิเศษกับสิ่งนี้เมื่อปฏิบัติตามหัวข้อเกี่ยวกับการตรวจสอบความถูกต้องและการทำแผนที่จุดตรวจ TF1.x ในภายหลังในคู่มือนี้

ใช้ tf.compat.v1.make_template ในวิธีการตกแต่ง

ก็ขอแนะนำคุณโดยตรงใช้ tf.compat.v1.keras.utils.track_tf1_style_variables แทนการใช้ tf.compat.v1.make_template มันเป็นชั้นทินเนอร์ด้านบนของ TF2

ทำตามคำแนะนำในส่วนนี้สำหรับรหัส TF1.x ก่อนที่แล้วอาศัย tf.compat.v1.make_template

เพราะ tf.compat.v1.make_template wraps รหัสที่ใช้ get_variable ที่ track_tf1_style_variables มัณฑนากรช่วยให้คุณใช้แม่แบบเหล่านี้ในการเรียกชั้นและประสบความสำเร็จติดตามน้ำหนักและการสูญเสียกู

แต่ไม่แน่ใจว่าจะโทร make_template เพียงครั้งเดียวแล้วนำมาใช้แม่แบบเดียวกันในการโทรแต่ละชั้น มิฉะนั้น เทมเพลตใหม่จะถูกสร้างขึ้นทุกครั้งที่คุณเรียกเลเยอร์พร้อมกับตัวแปรชุดใหม่

ตัวอย่างเช่น,

class CompatV1TemplateScaleByY(tf.keras.layers.Layer):

  def __init__(self, **kwargs):
    super().__init__(**kwargs)
    def my_op(x, scalar_name):
      var1 = tf.compat.v1.get_variable(scalar_name,
                            shape=[],
                            regularizer=tf.compat.v1.keras.regularizers.L2(),
                            initializer=tf.compat.v1.constant_initializer(1.5))
      return x * var1
    self.scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op, scalar_name='y')

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    with tf.compat.v1.variable_scope('layer'):
      # Using a scope ensures the `scale_by_y` name will not be incremented
      # for each instantiation of the layer.
      return self.scale_by_y(inputs)

layer = CompatV1TemplateScaleByY()

out = layer(tf.ones(shape=(2, 3)))
print("weights:", layer.weights)
print("regularization loss:", layer.losses)
print("output:", out)
weights: [<tf.Variable 'layer/scale_by_y/y:0' shape=() dtype=float32, numpy=1.5>]
regularization loss: [<tf.Tensor: shape=(), dtype=float32, numpy=0.022499999>]
output: tf.Tensor(
[[1.5 1.5 1.5]
 [1.5 1.5 1.5]], shape=(2, 3), dtype=float32)

การย้ายข้อมูลส่วนเพิ่มไปยัง Native TF2

ดังกล่าวก่อนหน้า track_tf1_style_variables ช่วยให้คุณสามารถผสม TF2 สไตล์เชิงวัตถุ tf.Variable / tf.keras.layers.Layer / tf.Module การใช้งานกับมรดก tf.compat.v1.get_variable / tf.compat.v1.layers สไตล์ การใช้งานภายในโมดูล/เลเยอร์ที่ตกแต่งเดียวกัน

ซึ่งหมายความว่าหลังจากที่คุณได้ทำในรูปแบบ TF1.x ของคุณอย่างเต็มที่ TF2 ได้คุณสามารถเขียนส่วนประกอบรูปแบบใหม่ทั้งหมดที่มีพื้นเมือง (ไม่ใช่ tf.compat.v1 ) TF2 APIs และมีพวกเขาทำงานร่วมกับรหัสเก่าของคุณ

แต่ถ้าคุณยังคงปรับเปลี่ยนส่วนประกอบรุ่นเก่าของคุณคุณอาจเลือกที่จะเพิ่มขึ้นสลับมรดกสไตล์ของคุณ tf.compat.v1 การใช้งานไปยัง APIs เชิงวัตถุอย่างหมดจดพื้นเมืองที่มีการแนะนำสำหรับรหัส TF2 เขียนขึ้นใหม่

tf.compat.v1.get_variable ใช้งานสามารถแทนที่ด้วยทั้ง self.add_weight โทรถ้าคุณกำลังตกแต่ง Keras ชั้น / รุ่นหรือ tf.Variable โทรถ้าคุณกำลังตกแต่ง Keras วัตถุหรือ tf.Module s

ทั้งรูปแบบการทำงานและเชิงวัตถุ tf.compat.v1.layers โดยทั่วไปจะสามารถแทนที่ด้วยเทียบเท่า tf.keras.layers ชั้นโดยไม่มีการเปลี่ยนแปลงอาร์กิวเมนต์ที่จำเป็น

นอกจากนี้คุณยังอาจพิจารณาชิ้นส่วนของรูปแบบของคุณหรือรูปแบบที่พบบ่อยเข้าไปในแต่ละชั้น / โมดูลในระหว่างการย้ายที่เพิ่มขึ้นของคุณเพื่อ APIs หมดจดพื้นเมืองซึ่งตัวเองอาจจะใช้ track_tf1_style_variables

หมายเหตุเกี่ยวกับ Slim และ contrib.layers

เป็นจำนวนมากรหัส TF 1.x เก่าใช้ สลิม ห้องสมุดซึ่งเป็นชุดที่มี 1.x TF เป็น tf.contrib.layers แปลงใช้รหัสผอม TF พื้นเมือง 2 เป็นส่วนร่วมมากขึ้นกว่าการแปลง v1.layers ในความเป็นจริงมันอาจจะทำให้ความรู้สึกในการแปลงรหัสสลิมของคุณเพื่อ v1.layers แรกแล้วแปลง Keras ด้านล่างนี้คือคำแนะนำทั่วไปสำหรับการแปลงโค้ด Slim

  • ตรวจสอบให้แน่ใจว่าอาร์กิวเมนต์ทั้งหมดมีความชัดเจน ลบ arg_scopes ถ้าเป็นไปได้ หากคุณยังคงต้องใช้พวกเขาแยก normalizer_fn และ activation_fn เป็นชั้นของตัวเอง
  • เลเยอร์ Conv. แบบแยกได้จะจับคู่กับเลเยอร์ Keras ที่แตกต่างกันอย่างน้อยหนึ่งเลเยอร์ (เลเยอร์ Keras ในเชิงลึก เชิงลึก และแบบแยกได้)
  • ที่บางเฉียบและ v1.layers มีชื่อแตกต่างกันและการโต้แย้งค่าเริ่มต้น
  • โปรดทราบว่าอาร์กิวเมนต์บางข้อมีมาตราส่วนต่างกัน

การโยกย้ายไปยัง Native TF2 โดยไม่สนใจความเข้ากันได้ของจุดตรวจ

ตัวอย่างโค้ดต่อไปนี้แสดงให้เห็นถึงการย้ายโมเดลที่เพิ่มขึ้นไปยัง API ดั้งเดิมโดยไม่พิจารณาความเข้ากันได้ของจุดตรวจสอบ

class CompatModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = tf.compat.v1.layers.conv2d(
          inputs, 3, 3,
          kernel_regularizer="l2")
      out = tf.compat.v1.layers.flatten(out)
      out = tf.compat.v1.layers.dropout(out, training=training)
      out = tf.compat.v1.layers.dense(
          out, self.units,
          kernel_regularizer="l2")
      return out

ถัดไปแทนที่ compat.v1 APIs เทียบเท่ากับเชิงวัตถุพื้นเมืองของพวกเขาในลักษณะค่ เริ่มต้นด้วยการเปลี่ยนเลเยอร์ Convolution เป็นวัตถุ Keras ที่สร้างขึ้นในตัวสร้างเลเยอร์

class PartiallyMigratedModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units
    self.conv_layer = tf.keras.layers.Conv2D(
      3, 3,
      kernel_regularizer="l2")

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_layer(inputs)
      out = tf.compat.v1.layers.flatten(out)
      out = tf.compat.v1.layers.dropout(out, training=training)
      out = tf.compat.v1.layers.dense(
          out, self.units,
          kernel_regularizer="l2")
      return out

ใช้เครื่องมือทดสอบการสร้างตัวเลขที่กำหนดขึ้นเพื่อตรวจสอบว่าการเปลี่ยนแปลงที่เพิ่มขึ้นนี้ทำให้โมเดลมีลักษณะการทำงานเหมือนเดิมหรือไม่

# import tensorflow.python.framework.random_seed as random_seed
seed_implementation = sys.modules[tf.compat.v1.get_seed.__module__]

class DeterministicTestTool(object):
  def __init__(self, seed: int = 42, mode='constant'):
    """Set mode to 'constant' or 'num_random_ops'. Defaults to 'constant'."""
    if mode not in {'constant', 'num_random_ops'}:
      raise ValueError("Mode arg must be 'constant' or 'num_random_ops'. " +
                       "Got: {}".format(mode))

    self._mode = mode
    self._seed = seed
    self.operation_seed = 0
    self._observed_seeds = set()

  def scope(self):
    tf.random.set_seed(self._seed)

    def _get_seed(_):
      """Wraps TF get_seed to make deterministic random generation easier.

      This makes a variable's initialization (and calls that involve random
      number generation) depend only on how many random number generations
      were used in the scope so far, rather than on how many unrelated
      operations the graph contains.

      Returns:
        Random seed tuple.
      """
      op_seed = self.operation_seed
      if self._mode == "constant":
        tf.random.set_seed(op_seed)
      else:
        if op_seed in self._observed_seeds:
          raise ValueError(
              'This `DeterministicTestTool` object is trying to re-use the ' +
              'already-used operation seed {}. '.format(op_seed) +
              'It cannot guarantee random numbers will match between eager ' +
              'and sessions when an operation seed is reused. ' +
              'You most likely set ' +
              '`operation_seed` explicitly but used a value that caused the ' +
              'naturally-incrementing operation seed sequences to overlap ' +
              'with an already-used seed.')

        self._observed_seeds.add(op_seed)
        self.operation_seed += 1

      return (self._seed, op_seed)

    # mock.patch internal symbols to modify the behavior of TF APIs relying on them

    return mock.patch.object(seed_implementation, 'get_seed', wraps=_get_seed)
random_tool = DeterministicTestTool(mode='num_random_ops')
with random_tool.scope():
  layer = CompatModel(10)

  inputs = tf.random.normal(shape=(10, 5, 5, 5))
  original_output = layer(inputs)

  # Grab the regularization loss as well
  original_regularization_loss = tf.math.add_n(layer.losses)

print(original_regularization_loss)
tf.Tensor(0.17953834, shape=(), dtype=float32)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:12: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  if sys.path[0] == '':
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:13: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  del sys.path[0]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:14: UserWarning: `tf.layers.dropout` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dropout` instead.
  
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/core.py:413: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  return layer.apply(inputs, training=training)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:17: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
random_tool = DeterministicTestTool(mode='num_random_ops')
with random_tool.scope():
  layer = PartiallyMigratedModel(10)

  inputs = tf.random.normal(shape=(10, 5, 5, 5))
  migrated_output = layer(inputs)

  # Grab the regularization loss as well
  migrated_regularization_loss = tf.math.add_n(layer.losses)

print(migrated_regularization_loss)
tf.Tensor(0.17953834, shape=(), dtype=float32)
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:14: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:15: UserWarning: `tf.layers.dropout` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dropout` instead.
  from ipykernel import kernelapp as app
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:18: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
# Verify that the regularization loss and output both match
np.testing.assert_allclose(original_regularization_loss.numpy(), migrated_regularization_loss.numpy())
np.testing.assert_allclose(original_output.numpy(), migrated_output.numpy())

ขณะนี้คุณได้เข้ามาแทนที่ทั้งหมดของแต่ละ compat.v1.layers กับชั้น Keras พื้นเมือง

class NearlyFullyNativeModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units
    self.conv_layer = tf.keras.layers.Conv2D(
      3, 3,
      kernel_regularizer="l2")
    self.flatten_layer = tf.keras.layers.Flatten()
    self.dense_layer = tf.keras.layers.Dense(
      self.units,
      kernel_regularizer="l2")

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_layer(inputs)
      out = self.flatten_layer(out)
      out = self.dense_layer(out)
      return out
random_tool = DeterministicTestTool(mode='num_random_ops')
with random_tool.scope():
  layer = NearlyFullyNativeModel(10)

  inputs = tf.random.normal(shape=(10, 5, 5, 5))
  migrated_output = layer(inputs)

  # Grab the regularization loss as well
  migrated_regularization_loss = tf.math.add_n(layer.losses)

print(migrated_regularization_loss)
tf.Tensor(0.17953834, shape=(), dtype=float32)
# Verify that the regularization loss and output both match
np.testing.assert_allclose(original_regularization_loss.numpy(), migrated_regularization_loss.numpy())
np.testing.assert_allclose(original_output.numpy(), migrated_output.numpy())

สุดท้ายเอาทั้งที่ยังเหลืออยู่ (ไม่มีอีกต่อไปจำเป็น) ใด ๆ variable_scope การใช้งานและ track_tf1_style_variables มัณฑนาตัวเอง

ตอนนี้คุณเหลือรุ่นของโมเดลที่ใช้ API ดั้งเดิมทั้งหมด

class FullyNativeModel(tf.keras.layers.Layer):

  def __init__(self, units, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.units = units
    self.conv_layer = tf.keras.layers.Conv2D(
      3, 3,
      kernel_regularizer="l2")
    self.flatten_layer = tf.keras.layers.Flatten()
    self.dense_layer = tf.keras.layers.Dense(
      self.units,
      kernel_regularizer="l2")

  def call(self, inputs):
    out = self.conv_layer(inputs)
    out = self.flatten_layer(out)
    out = self.dense_layer(out)
    return out
random_tool = DeterministicTestTool(mode='num_random_ops')
with random_tool.scope():
  layer = FullyNativeModel(10)

  inputs = tf.random.normal(shape=(10, 5, 5, 5))
  migrated_output = layer(inputs)

  # Grab the regularization loss as well
  migrated_regularization_loss = tf.math.add_n(layer.losses)

print(migrated_regularization_loss)
tf.Tensor(0.17953834, shape=(), dtype=float32)
# Verify that the regularization loss and output both match
np.testing.assert_allclose(original_regularization_loss.numpy(), migrated_regularization_loss.numpy())
np.testing.assert_allclose(original_output.numpy(), migrated_output.numpy())

การรักษาความเข้ากันได้ของจุดตรวจระหว่างการโยกย้ายไปยัง Native TF2

กระบวนการย้ายด้านบนไปเป็น TF2 API ดั้งเดิมได้เปลี่ยนทั้งชื่อตัวแปร (เนื่องจาก Keras APIs สร้างชื่อน้ำหนักที่แตกต่างกันมาก) และเส้นทางเชิงวัตถุที่ชี้ไปที่น้ำหนักที่แตกต่างกันในโมเดล ผลกระทบของการเปลี่ยนแปลงเหล่านี้คือ การเปลี่ยนแปลงเหล่านี้จะทำลายจุดตรวจตามชื่อสไตล์ TF1 ที่มีอยู่หรือจุดตรวจสอบเชิงวัตถุสไตล์ TF2

อย่างไรก็ตามในบางกรณีคุณอาจจะสามารถใช้จุดตรวจสอบชื่อตามเดิมของคุณและพบว่าการทำแผนที่ของตัวแปรให้ชื่อใหม่ของพวกเขาด้วยวิธีการเช่นเดียวกับรายละเอียดใน คู่มือด่าน Reusing TF1.x

เคล็ดลับบางประการในการทำให้สิ่งนี้เป็นไปได้มีดังนี้:

  • ตัวแปรที่ยังคงทุกคนมี name อาร์กิวเมนต์คุณสามารถตั้งค่า
  • รุ่น Keras ยังใช้ name อาร์กิวเมนต์เป็นที่พวกเขาตั้งเป็นคำนำหน้าสำหรับตัวแปรของพวกเขา
  • v1.name_scope ฟังก์ชั่นที่สามารถใช้ในการตั้งคำนำหน้าชื่อตัวแปร นี่คือความแตกต่างจาก tf.variable_scope มีผลกับชื่อเท่านั้น ไม่ติดตามตัวแปรและการนำกลับมาใช้ใหม่

เมื่อคำนึงถึงตัวชี้ด้านบนแล้ว ตัวอย่างโค้ดต่อไปนี้จะสาธิตเวิร์กโฟลว์ที่คุณสามารถปรับให้เข้ากับโค้ดของคุณเพื่ออัปเดตส่วนต่างๆ ของโมเดลในขณะที่อัปเดตจุดตรวจพร้อมกัน

  1. เริ่มต้นด้วยการเปลี่ยนการทำงานสไตล์ tf.compat.v1.layers รุ่นเชิงวัตถุของพวกเขา
class FunctionalStyleCompatModel(tf.keras.layers.Layer):

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = tf.compat.v1.layers.conv2d(
          inputs, 3, 3,
          kernel_regularizer="l2")
      out = tf.compat.v1.layers.conv2d(
          out, 4, 4,
          kernel_regularizer="l2")
      out = tf.compat.v1.layers.conv2d(
          out, 5, 5,
          kernel_regularizer="l2")
      return out

layer = FunctionalStyleCompatModel()
layer(tf.ones(shape=(10, 10, 10, 10)))
[v.name for v in layer.weights]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:8: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:11: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  # This is added back by InteractiveShellApp.init_path()
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:14: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
['model/conv2d/bias:0',
 'model/conv2d/kernel:0',
 'model/conv2d_1/bias:0',
 'model/conv2d_1/kernel:0',
 'model/conv2d_2/bias:0',
 'model/conv2d_2/kernel:0']
  1. ถัดไปกำหนดวัตถุ compat.v1.layer และตัวแปรใด ๆ ที่สร้างขึ้นโดย compat.v1.get_variable เป็นคุณสมบัติของ tf.keras.layers.Layer / tf.Module วัตถุที่มีวิธีการตกแต่งด้วย track_tf1_style_variables (หมายเหตุว่า TF2 เชิงวัตถุ จุดตรวจสอบลักษณะจะบันทึกทั้งเส้นทางตามชื่อตัวแปรและเส้นทางเชิงวัตถุใหม่)
class OOStyleCompatModel(tf.keras.layers.Layer):

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.conv_1 = tf.compat.v1.layers.Conv2D(
          3, 3,
          kernel_regularizer="l2")
    self.conv_2 = tf.compat.v1.layers.Conv2D(
          4, 4,
          kernel_regularizer="l2")

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_1(inputs)
      out = self.conv_2(out)
      out = tf.compat.v1.layers.conv2d(
          out, 5, 5,
          kernel_regularizer="l2")
      return out

layer = OOStyleCompatModel()
layer(tf.ones(shape=(10, 10, 10, 10)))
[v.name for v in layer.weights]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:19: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
['model/conv2d/kernel:0',
 'model/conv2d/bias:0',
 'model/conv2d_1/kernel:0',
 'model/conv2d_1/bias:0',
 'model/conv2d_2/bias:0',
 'model/conv2d_2/kernel:0']
  1. บันทึกจุดตรวจสอบที่โหลดใหม่ ณ จุดนี้เพื่อบันทึกเส้นทางทั้งโดยชื่อตัวแปร (สำหรับ compat.v1.layers) หรือโดยกราฟวัตถุเชิงวัตถุ
weights = {v.name: v for v in layer.weights}
assert weights['model/conv2d/kernel:0'] is layer.conv_1.kernel
assert weights['model/conv2d_1/bias:0'] is layer.conv_2.bias
  1. ขณะนี้คุณสามารถสลับออกเชิงวัตถุ compat.v1.layers สำหรับชั้น Keras พื้นเมืองในขณะที่ยังคงความสามารถในการโหลดด่านเมื่อเร็ว ๆ นี้ที่บันทึกไว้ ตรวจสอบให้แน่ใจว่าคุณรักษาชื่อตัวแปรที่เหลือ compat.v1.layers โดยยังคงบันทึกสร้างขึ้นโดยอัตโนมัติ variable_scopes ชั้นแทนที่ เลเยอร์/ตัวแปรที่สับเปลี่ยนเหล่านี้จะใช้เฉพาะเส้นทางแอตทริบิวต์ของวัตถุไปยังตัวแปรในจุดตรวจสอบแทนเส้นทางชื่อตัวแปร

โดยทั่วไปแล้วคุณสามารถแทนที่การใช้งานของ compat.v1.get_variable ในตัวแปรที่แนบมากับคุณสมบัติโดย:

  • การเปลี่ยนพวกเขากับการใช้ tf.Variable หรือ
  • การอัปเดตได้โดยใช้ tf.keras.layers.Layer.add_weight โปรดทราบว่าถ้าคุณไม่ได้เปลี่ยนชั้นทั้งหมดในหนึ่งไปนี้อาจมีการเปลี่ยนแปลงสร้างขึ้นโดยอัตโนมัติชั้น / การตั้งชื่อตัวแปรที่เหลือ compat.v1.layers ที่หายไป name อาร์กิวเมนต์ หากเป็นกรณีที่คุณต้องเก็บชื่อตัวแปรเหลือ compat.v1.layers เดียวกันโดยเปิดด้วยตนเองและปิด variable_scope สอดคล้องกับที่ถูกนำออก compat.v1.layer 's สร้างชื่อขอบเขต มิฉะนั้น เส้นทางจากจุดตรวจที่มีอยู่อาจขัดแย้งกัน และการโหลดจุดตรวจจะทำงานไม่ถูกต้อง
def record_scope(scope_name):
  """Record a variable_scope to make sure future ones get incremented."""
  with tf.compat.v1.variable_scope(scope_name):
    pass

class PartiallyNativeKerasLayersModel(tf.keras.layers.Layer):

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.conv_1 = tf.keras.layers.Conv2D(
          3, 3,
          kernel_regularizer="l2")
    self.conv_2 = tf.keras.layers.Conv2D(
          4, 4,
          kernel_regularizer="l2")

  @tf.compat.v1.keras.utils.track_tf1_style_variables
  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_1(inputs)
      record_scope('conv2d') # Only needed if follow-on compat.v1.layers do not pass a `name` arg
      out = self.conv_2(out)
      record_scope('conv2d_1') # Only needed if follow-on compat.v1.layers do not pass a `name` arg
      out = tf.compat.v1.layers.conv2d(
          out, 5, 5,
          kernel_regularizer="l2")
      return out

layer = PartiallyNativeKerasLayersModel()
layer(tf.ones(shape=(10, 10, 10, 10)))
[v.name for v in layer.weights]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:26: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
['partially_native_keras_layers_model/model/conv2d_13/kernel:0',
 'partially_native_keras_layers_model/model/conv2d_13/bias:0',
 'partially_native_keras_layers_model/model/conv2d_14/kernel:0',
 'partially_native_keras_layers_model/model/conv2d_14/bias:0',
 'model/conv2d_2/bias:0',
 'model/conv2d_2/kernel:0']

ประหยัดด่านออกในขั้นตอนนี้หลังจากที่สร้างตัวแปรที่จะทำให้มันมีเพียงเส้นทางวัตถุในปัจจุบันที่มีอยู่

ให้แน่ใจว่าคุณบันทึกขอบเขตของที่นำออก compat.v1.layers เพื่อรักษาสร้างขึ้นโดยอัตโนมัติชื่อน้ำหนักสำหรับส่วนที่เหลืออีก compat.v1.layers

weights = set(v.name for v in layer.weights)
assert 'model/conv2d_2/kernel:0' in weights
assert 'model/conv2d_2/bias:0' in weights
  1. ทำซ้ำขั้นตอนข้างต้นจนกว่าคุณจะได้แทนที่ทั้งหมด compat.v1.layers และ compat.v1.get_variable ในรูปแบบของคุณอย่างเต็มที่เทียบเท่ากับเจ้าของภาษา
class FullyNativeKerasLayersModel(tf.keras.layers.Layer):

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.conv_1 = tf.keras.layers.Conv2D(
          3, 3,
          kernel_regularizer="l2")
    self.conv_2 = tf.keras.layers.Conv2D(
          4, 4,
          kernel_regularizer="l2")
    self.conv_3 = tf.keras.layers.Conv2D(
          5, 5,
          kernel_regularizer="l2")


  def call(self, inputs, training=None):
    with tf.compat.v1.variable_scope('model'):
      out = self.conv_1(inputs)
      out = self.conv_2(out)
      out = self.conv_3(out)
      return out

layer = FullyNativeKerasLayersModel()
layer(tf.ones(shape=(10, 10, 10, 10)))
[v.name for v in layer.weights]
['fully_native_keras_layers_model/model/conv2d_16/kernel:0',
 'fully_native_keras_layers_model/model/conv2d_16/bias:0',
 'fully_native_keras_layers_model/model/conv2d_17/kernel:0',
 'fully_native_keras_layers_model/model/conv2d_17/bias:0',
 'fully_native_keras_layers_model/model/conv2d_18/kernel:0',
 'fully_native_keras_layers_model/model/conv2d_18/bias:0']

อย่าลืมทดสอบเพื่อให้แน่ใจว่าจุดตรวจที่อัปเดตใหม่ยังคงทำงานตามที่คุณคาดหวัง ใช้เทคนิคที่อธิบายไว้ใน การตรวจสอบความถูกต้องคู่มือตัวเลข ในทุกขั้นตอนที่เพิ่มขึ้นของกระบวนการนี้เพื่อให้แน่ใจว่ารหัสวิ่งโอนย้ายอย่างถูกต้อง

การจัดการการเปลี่ยนแปลงพฤติกรรมของ TF1.x เป็น TF2 ที่ไม่ครอบคลุมโดยการจำลองแบบจำลอง shims

shims การสร้างแบบจำลองที่อธิบายไว้ในคู่มือนี้จะตรวจสอบให้แน่ใจว่าตัวแปรเลเยอร์และการสูญเสียที่สร้างขึ้นด้วยกู get_variable , tf.compat.v1.layers และ variable_scope ความหมายยังคงทำงานเป็นมาก่อนเมื่อใช้การดำเนินการและความกระตือรือร้นที่ tf.function โดยไม่ต้อง พึ่งพาคอลเลกชัน

นี้ไม่ได้ครอบคลุมทุกความหมาย TF1.x เฉพาะที่รูปแบบของคุณไปข้างหน้าผ่านไปอาจจะอาศัย ในบางกรณี แผ่นชิมอาจไม่เพียงพอที่จะทำให้โมเดลของคุณส่งต่อการส่งผ่านใน TF2 ได้ด้วยตัวเอง อ่าน TF1.x VS TF2 พฤติกรรมเป็นแนวทางในการ ที่จะเรียนรู้เพิ่มเติมเกี่ยวกับความแตกต่างระหว่างพฤติกรรม TF1.x และ TF2