Giới thiệu về mô-đun, lớp và mô hình

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải xuống sổ ghi chép

Để thực hiện học máy trong TensorFlow, bạn có thể cần phải xác định, lưu và khôi phục một mô hình.

Một mô hình, một cách trừu tượng là:

  • Một hàm tính toán một cái gì đó trên tensors (một chuyển tiếp )
  • Một số biến có thể được cập nhật để đáp ứng với quá trình đào tạo

Trong hướng dẫn này, bạn sẽ đi xuống bên dưới bề mặt của Keras để xem các mô hình TensorFlow được xác định như thế nào. Điều này xem xét cách TensorFlow thu thập các biến và mô hình, cũng như cách chúng được lưu và khôi phục.

Thành lập

import tensorflow as tf
from datetime import datetime

%load_ext tensorboard

Xác định mô hình và lớp trong TensorFlow

Hầu hết các mô hình được làm bằng nhiều lớp. Lớp là các hàm có cấu trúc toán học đã biết có thể được sử dụng lại và có các biến có thể kiểm tra. Trong TensorFlow, hầu hết các triển khai cấp cao của các lớp và mô hình, chẳng hạn như Keras hoặc Sonnet , được xây dựng trên cùng một lớp nền tảng: tf.Module .

Đây là một ví dụ về một tf.Module rất đơn giản hoạt động trên một tensor vô hướng:

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

simple_module = SimpleModule(name="simple")

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

Các mô-đun và, nói cách khác, các lớp là thuật ngữ học sâu cho "các đối tượng": chúng có trạng thái bên trong và các phương thức sử dụng trạng thái đó.

Không có gì đặc biệt về __call__ ngoại trừ hoạt động như một Python có thể gọi được; bạn có thể gọi các mô hình của mình với bất kỳ chức năng nào bạn muốn.

Bạn có thể bật và tắt khả năng đào tạo của các biến vì bất kỳ lý do gì, bao gồm cả các lớp đóng băng và các biến trong quá trình tinh chỉnh.

Bằng cách phân lớp con tf.Module , mọi cá thể tf.Variable hoặc tf.Module được gán cho các thuộc tính của đối tượng này sẽ được tự động thu thập. Điều này cho phép bạn lưu và tải các biến, đồng thời tạo bộ sưu tập các tf.Module s.

# All trainable variables
print("trainable variables:", simple_module.trainable_variables)
# Every variable
print("all variables:", simple_module.variables)
trainable variables: (<tf.Variable 'train_me:0' shape=() dtype=float32, numpy=5.0>,)
all variables: (<tf.Variable 'train_me:0' shape=() dtype=float32, numpy=5.0>, <tf.Variable 'do_not_train_me:0' shape=() dtype=float32, numpy=5.0>)
2021-10-26 01:29:45.284549: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.

Đây là một ví dụ về mô hình lớp tuyến tính hai lớp được tạo ra từ các mô-đun.

Đầu tiên một lớp dày đặc (tuyến tính):

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

Và sau đó là mô hình hoàn chỉnh, tạo ra hai phiên bản lớp và áp dụng chúng:

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

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

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

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

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

Các cá thể tf.Module sẽ tự động thu thập, đệ quy, bất kỳ cá thể tf.Variable hoặc tf.Module được gán cho nó. Điều này cho phép bạn quản lý tập hợp các tf.Module với một phiên bản mô hình duy nhất, đồng thời lưu và tải toàn bộ mô hình.

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

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

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

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

Đang chờ tạo biến

Bạn có thể nhận thấy ở đây rằng bạn phải xác định cả kích thước đầu vào và đầu ra cho lớp. Vì vậy, biến w có hình dạng đã biết và có thể được cấp phát.

Bằng cách trì hoãn việc tạo biến cho lần đầu tiên mô-đun được gọi với một hình dạng đầu vào cụ thể, bạn không cần chỉ định kích thước đầu vào lên trước.

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

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

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

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

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

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

Tính linh hoạt này là lý do tại sao các lớp TensorFlow thường chỉ cần xác định hình dạng của đầu ra của chúng, chẳng hạn như trong tf.keras.layers.Dense , thay vì cả kích thước đầu vào và đầu ra.

Tiết kiệm trọng lượng

Bạn có thể lưu tf.Module dưới dạng cả một trạm kiểm soátSavedModel .

Các điểm kiểm tra chỉ là trọng số (nghĩa là giá trị của tập hợp các biến bên trong mô-đun và các mô-đun con của nó):

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

Điểm kiểm tra bao gồm hai loại tệp: bản thân dữ liệu và tệp chỉ mục cho siêu dữ liệu. Tệp chỉ mục theo dõi những gì thực sự được lưu và đánh số các điểm kiểm tra, trong khi dữ liệu điểm kiểm tra chứa các giá trị biến và đường dẫn tra cứu thuộc tính của chúng.

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

Bạn có thể nhìn vào bên trong một điểm kiểm tra để đảm bảo rằng toàn bộ tập hợp các biến đã được lưu, được sắp xếp theo đối tượng Python chứa chúng.

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

Trong quá trình đào tạo phân tán (nhiều máy), chúng có thể được chia nhỏ, đó là lý do tại sao chúng được đánh số (ví dụ: '00000-of-00001'). Tuy nhiên, trong trường hợp này, chỉ có một phân đoạn.

Khi bạn tải lại các mô hình, bạn sẽ ghi đè các giá trị trong đối tượng Python của mình.

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

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

Tiết kiệm các chức năng

TensorFlow có thể chạy các mô hình mà không có các đối tượng Python ban đầu, như được chứng minh bởi TensorFlow ServingTensorFlow Lite , ngay cả khi bạn tải xuống mô hình được đào tạo từ TensorFlow Hub .

TensorFlow cần biết cách thực hiện các phép tính được mô tả bằng Python, nhưng không có mã gốc . Để làm điều này, bạn có thể tạo một biểu đồ , được mô tả trong Hướng dẫn Giới thiệu về đồ thị và hàm .

Biểu đồ này chứa các hoạt động, hoặc hoạt động, triển khai chức năng.

Bạn có thể xác định một đồ thị trong mô hình trên bằng cách thêm trình trang trí @tf.function để chỉ ra rằng mã này sẽ chạy dưới dạng một đồ thị.

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

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

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

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

Mô-đun bạn đã thực hiện hoạt động giống hệt như trước đây. Mỗi chữ ký duy nhất được truyền vào hàm sẽ tạo ra một đồ thị riêng biệt. Kiểm tra hướng dẫn Giới thiệu về đồ thị và hàm để biết chi tiết.

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

Bạn có thể hình dung biểu đồ bằng cách truy tìm nó trong bản tóm tắt TensorBoard.

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

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

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

Khởi chạy TensorBoard để xem dấu vết kết quả:

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

Ảnh chụp màn hình của biểu đồ trong TensorBoard

Tạo SavedModel

Cách được khuyến nghị để chia sẻ các mô hình đã được đào tạo hoàn toàn là sử dụng SavedModel . SavedModel chứa cả một tập hợp các hàm và một tập hợp các trọng số.

Bạn có thể lưu mô hình bạn vừa được đào tạo như sau:

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

Tệp saved_model.pb là một bộ đệm giao thức mô tả chức năng tf.Graph .

Các mô hình và lớp có thể được tải từ biểu diễn này mà không thực sự tạo ra một thể hiện của lớp đã tạo ra nó. Điều này được mong muốn trong các tình huống mà bạn không có (hoặc muốn) trình thông dịch Python, chẳng hạn như phân phát trên quy mô lớn hoặc trên thiết bị cạnh hoặc trong các tình huống mà mã Python gốc không có sẵn hoặc thực tế để sử dụng.

Bạn có thể tải mô hình dưới dạng đối tượng mới:

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

new_model , được tạo từ việc tải một mô hình đã lưu, là một đối tượng người dùng TensorFlow nội bộ mà không có bất kỳ kiến ​​thức nào về lớp. Nó không thuộc loại SequentialModule .

isinstance(new_model, SequentialModule)
False

Mô hình mới này hoạt động trên các chữ ký đầu vào đã được xác định. Bạn không thể thêm nhiều chữ ký vào một mô hình được khôi phục như thế này.

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

Do đó, bằng cách sử dụng SavedModel , bạn có thể lưu các trọng số và đồ thị TensorFlow bằng tf.Module , sau đó tải lại chúng.

Các mô hình và lớp Keras

Lưu ý rằng cho đến thời điểm này, không có đề cập đến Keras. Bạn có thể xây dựng API cấp cao của riêng mình trên tf.Module và mọi người có.

Trong phần này, bạn sẽ kiểm tra cách Keras sử dụng tf.Module . Có thể tìm thấy hướng dẫn sử dụng đầy đủ về các kiểu máy Keras trong hướng dẫn Keras .

Keras các lớp

tf.keras.layers.Layer là lớp cơ sở của tất cả các lớp Keras và nó kế thừa từ tf.Module .

Bạn có thể chuyển đổi một mô-đun thành một lớp Keras chỉ bằng cách hoán đổi lớp cha và sau đó thay đổi __call__ để call :

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

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

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

Các lớp Keras có __call__ riêng của chúng thực hiện một số công việc ghi sổ được mô tả trong phần tiếp theo và sau đó gọi hàm call() . Bạn sẽ nhận thấy không có thay đổi về chức năng.

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

Bước build

Như đã lưu ý, trong nhiều trường hợp, thật tiện lợi khi đợi tạo các biến cho đến khi bạn chắc chắn về hình dạng đầu vào.

Các lớp Keras đi kèm với một bước vòng đời bổ sung cho phép bạn linh hoạt hơn trong cách xác định các lớp của mình. Điều này được xác định trong hàm build .

bản build được gọi chính xác một lần và nó được gọi với hình dạng của đầu vào. Nó thường được sử dụng để tạo các biến (trọng số).

Bạn có thể viết lại lớp MyDense ở trên để linh hoạt với kích thước đầu vào của nó:

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

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

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

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

Tại thời điểm này, mô hình chưa được xây dựng nên không có biến:

flexible_dense.variables
[]

Gọi hàm phân bổ các biến có kích thước thích hợp:

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

Vì bản build chỉ được gọi một lần, các đầu vào sẽ bị từ chối nếu hình dạng đầu vào không tương thích với các biến của lớp:

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

Các lớp Keras có nhiều tính năng bổ sung hơn bao gồm:

  • Các khoản lỗ tùy chọn
  • Hỗ trợ các chỉ số
  • Hỗ trợ tích hợp cho một đối số training tùy chọn để phân biệt giữa đào tạo và sử dụng suy luận
  • Các phương thức get_configfrom_config cho phép bạn lưu trữ chính xác các cấu hình để cho phép sao chép mô hình trong Python

Đọc về chúng trong hướng dẫn đầy đủ về các lớp và mô hình tùy chỉnh.

Mô hình Keras

Bạn có thể xác định mô hình của mình dưới dạng các lớp Keras lồng nhau.

Tuy nhiên, Keras cũng cung cấp một lớp mô hình đầy đủ tính năng được gọi là tf.keras.Model . Nó kế thừa từ tf.keras.layers.Layer , do đó, một mô hình Keras có thể được sử dụng, lồng vào nhau và lưu theo cách giống như các lớp Keras. Các mô hình Keras có thêm chức năng giúp chúng dễ dàng đào tạo, đánh giá, tải, lưu và thậm chí đào tạo trên nhiều máy.

Bạn có thể xác định SequentialModule từ trên với mã gần giống hệt nhau, một lần nữa chuyển đổi __call__ thành call() và thay đổi cha mẹ:

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

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

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

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

Tất cả các tính năng tương tự đều có sẵn, bao gồm các biến theo dõi và mô-đun con.

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

Ghi đè tf.keras.Model là một cách tiếp cận rất Pythonic để xây dựng mô hình TensorFlow. Nếu bạn đang di chuyển mô hình từ các khuôn khổ khác, điều này có thể rất đơn giản.

Nếu bạn đang xây dựng các mô hình là các tập hợp đơn giản của các lớp và đầu vào hiện có, bạn có thể tiết kiệm thời gian và không gian bằng cách sử dụng API chức năng , đi kèm với các tính năng bổ sung xung quanh việc xây dựng lại mô hình và kiến ​​trúc.

Đây là mô hình tương tự với API chức năng:

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

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

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

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

Sự khác biệt chính ở đây là hình dạng đầu vào được chỉ định trước như một phần của quá trình xây dựng chức năng. Đối số input_shape trong trường hợp này không cần phải được chỉ định hoàn toàn; bạn có thể để một số thứ nguyên là None .

Tiết kiệm mô hình Keras

Các mô hình Keras có thể được kiểm tra và trông giống như tf.Module .

Các mô hình Keras cũng có thể được lưu bằng tf.saved_model.save() , vì chúng là các mô-đun. Tuy nhiên, các mô hình Keras có các phương pháp tiện lợi và chức năng khác:

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

Cũng dễ dàng như vậy, chúng có thể được tải lại vào:

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

Keras SavedModels cũng lưu các trạng thái số liệu, mất mát và trình tối ưu hóa.

Mô hình được tái tạo này có thể được sử dụng và sẽ tạo ra cùng một kết quả khi được gọi trên cùng một dữ liệu:

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

Có nhiều điều cần biết về cách lưu và tuần tự hóa các mô hình Keras, bao gồm việc cung cấp các phương pháp cấu hình cho các lớp tùy chỉnh để hỗ trợ tính năng. Xem hướng dẫn lưu và tuần tự hóa .

Cái gì tiếp theo

Nếu bạn muốn biết thêm chi tiết về Keras, bạn có thể làm theo các hướng dẫn Keras hiện có tại đây .

Một ví dụ khác về API cấp cao được xây dựng trên tf.module là Sonnet từ DeepMind, được đề cập trên trang web của họ .