Định dạng SavingModel của TensorFlow 2 là cách được khuyên dùng để chia sẻ các mô hình và phần mô hình được đào tạo trước trên TensorFlow Hub. Nó thay thế định dạng TF1 Hub cũ hơn và đi kèm với một bộ API mới.
Trang này giải thích cách sử dụng lại TF2 SavingModels trong chương trình TensorFlow 2 với API hub.load()
cấp thấp và trình bao bọc hub.KerasLayer
của nó. (Thông thường, hub.KerasLayer
được kết hợp với tf.keras.layers
khác để xây dựng mô hình Keras hoặc model_fn
của Công cụ ước tính TF2.) Các API này cũng có thể tải các mô hình cũ ở định dạng TF1 Hub, trong giới hạn, hãy xem hướng dẫn tương thích .
Người dùng TensorFlow 1 có thể cập nhật lên TF 1.15 và sau đó sử dụng cùng các API. Các phiên bản cũ hơn của TF1 không hoạt động.
Sử dụng SavingModels từ TF Hub
Sử dụng SavingModel trong Keras
Keras là API cấp cao của TensorFlow để xây dựng các mô hình học sâu bằng cách kết hợp các đối tượng Lớp Keras. Thư viện tensorflow_hub
cung cấp lớp hub.KerasLayer
được khởi tạo bằng URL (hoặc đường dẫn hệ thống tệp) của SavingModel, sau đó cung cấp tính toán từ SavingModel, bao gồm cả các trọng số được đào tạo trước của nó.
Dưới đây là ví dụ về cách sử dụng tính năng nhúng văn bản được đào tạo trước:
import tensorflow as tf
import tensorflow_hub as hub
hub_url = "https://tfhub.dev/google/nnlm-en-dim128/2"
embed = hub.KerasLayer(hub_url)
embeddings = embed(["A long sentence.", "single-word", "http://example.com"])
print(embeddings.shape, embeddings.dtype)
Từ đó, một trình phân loại văn bản có thể được xây dựng theo cách Keras thông thường:
model = tf.keras.Sequential([
embed,
tf.keras.layers.Dense(16, activation="relu"),
tf.keras.layers.Dense(1, activation="sigmoid"),
])
Colab phân loại văn bản là một ví dụ hoàn chỉnh về cách đào tạo và đánh giá một trình phân loại như vậy.
Trọng lượng mô hình trong hub.KerasLayer
được đặt thành không thể đào tạo theo mặc định. Xem phần tinh chỉnh bên dưới để biết cách thay đổi điều đó. Trọng lượng được chia sẻ giữa tất cả các ứng dụng của cùng một đối tượng lớp, như thường lệ trong Keras.
Sử dụng SavingModel trong Công cụ ước tính
Người dùng API Ước tính của TensorFlow cho đào tạo phân tán có thể sử dụng SavingModels từ TF Hub bằng cách viết model_fn
của họ theo hub.KerasLayer
trong số tf.keras.layers
khác.
Hậu trường: Tải xuống và lưu vào bộ đệm của SavingModel
Sử dụng SavingModel từ TensorFlow Hub (hoặc các máy chủ HTTPS khác triển khai giao thức lưu trữ của nó) sẽ tải xuống và giải nén nó vào hệ thống tệp cục bộ nếu chưa có. Biến môi trường TFHUB_CACHE_DIR
có thể được đặt để ghi đè vị trí tạm thời mặc định để lưu vào bộ nhớ đệm của SavingModels đã tải xuống và không nén. Để biết chi tiết, hãy xem Bộ nhớ đệm .
Sử dụng SavingModel trong TensorFlow cấp thấp
Tay cầm mẫu
SavingModels có thể được tải từ một handle
được chỉ định, trong đó bộ handle
là đường dẫn hệ thống tệp, URL mô hình TFhub.dev hợp lệ (ví dụ: "https://tfhub.dev/..."). Các URL của Mô hình Kaggle phản ánh TFhub.dev xử lý theo Điều khoản của chúng tôi và giấy phép được liên kết với nội dung mô hình, ví dụ: "https://www.kaggle.com/...". Các bộ điều khiển từ Mô hình Kaggle tương đương với bộ điều khiển TFhub.dev tương ứng của chúng.
Hàm hub.load(handle)
tải xuống và giải nén một SavingModel (trừ khi handle
đã là đường dẫn hệ thống tệp) rồi trả về kết quả tải nó bằng hàm tf.saved_model.load()
được tích hợp sẵn của TensorFlow. Do đó, hub.load()
có thể xử lý bất kỳ SavingModel hợp lệ nào (không giống như hub.Module
tiền nhiệm của nó cho TF1).
Chủ đề nâng cao: những gì mong đợi từ SavingModel sau khi tải
Tùy thuộc vào nội dung của SavingModel, kết quả của obj = hub.load(...)
có thể được gọi theo nhiều cách khác nhau (như được giải thích chi tiết hơn nhiều trong Hướng dẫn SavingModel của TensorFlow :
Chữ ký phục vụ của SavingModel (nếu có) được biểu diễn dưới dạng từ điển của các hàm cụ thể và có thể được gọi như
tensors_out = obj.signatures["serving_default"](**tensors_in)
, với từ điển của tensor được khóa theo đầu vào và đầu ra tương ứng tên và tuân theo các ràng buộc về hình dạng và dtype của chữ ký.Các phương thức trang trí
@tf.function
- của đối tượng đã lưu (nếu có) được khôi phục dưới dạng các đối tượng tf.function có thể được gọi bằng tất cả các kết hợp các đối số Tensor và không Tensor mà tf.function đã được theo dõi trước khi lưu. Đặc biệt, nếu có một phương thứcobj.__call__
với dấu vết phù hợp thì bản thânobj
có thể được gọi giống như một hàm Python. Một ví dụ đơn giản có thể trông như thế nàyoutput_tensor = obj(input_tensor, training=False)
.
Điều này mang lại sự tự do rất lớn trong các giao diện mà SavingModels có thể triển khai. Giao diện SavingModels có thể tái sử dụng cho obj
thiết lập các quy ước sao cho mã máy khách, bao gồm các bộ điều hợp như hub.KerasLayer
, biết cách sử dụng SavingModel.
Một số SavingModels có thể không tuân theo quy ước đó, đặc biệt là toàn bộ mô hình không được sử dụng lại trong các mô hình lớn hơn và chỉ cung cấp chữ ký phục vụ.
Các biến có thể huấn luyện trong SavingModel được tải lại dưới dạng có thể huấn luyện và tf.GradientTape
sẽ xem chúng theo mặc định. Xem phần tinh chỉnh bên dưới để biết một số lưu ý và cân nhắc tránh điều này khi mới bắt đầu. Ngay cả khi bạn muốn tinh chỉnh, bạn có thể muốn xem liệu obj.trainable_variables
có khuyên chỉ đào tạo lại một tập hợp con của các biến có thể huấn luyện ban đầu hay không.
Tạo các mô hình đã lưu cho TF Hub
Tổng quan
SavingModel là định dạng tuần tự hóa tiêu chuẩn của TensorFlow dành cho các mô hình hoặc phần mô hình được đào tạo. Nó lưu trữ các trọng số đã được huấn luyện của mô hình cùng với các thao tác TensorFlow chính xác để thực hiện tính toán của nó. Nó có thể được sử dụng độc lập với mã đã tạo ra nó. Đặc biệt, nó có thể được sử dụng lại trên các API xây dựng mô hình cấp cao khác nhau như Keras, vì các hoạt động TensorFlow là ngôn ngữ cơ bản chung của chúng.
Tiết kiệm từ Keras
Bắt đầu với TensorFlow 2, tf.keras.Model.save()
và tf.keras.models.save_model()
mặc định ở định dạng SavingModel (không phải HDF5). Các SavingModel thu được có thể được sử dụng với hub.load()
, hub.KerasLayer
và các bộ điều hợp tương tự cho các API cấp cao khác khi chúng có sẵn.
Để chia sẻ Mô hình Keras hoàn chỉnh, chỉ cần lưu nó với include_optimizer=False
.
Để chia sẻ một phần của Mô hình Keras, hãy biến phần đó thành Mô hình và sau đó lưu phần đó. Bạn có thể bố trí mã như thế ngay từ đầu ....
piece_to_share = tf.keras.Model(...)
full_model = tf.keras.Sequential([piece_to_share, ...])
full_model.fit(...)
piece_to_share.save(...)
...hoặc cắt ra phần để chia sẻ sau khi thực tế (nếu nó phù hợp với lớp của mô hình đầy đủ của bạn):
full_model = tf.keras.Model(...)
sharing_input = full_model.get_layer(...).get_output_at(0)
sharing_output = full_model.get_layer(...).get_output_at(0)
piece_to_share = tf.keras.Model(sharing_input, sharing_output)
piece_to_share.save(..., include_optimizer=False)
Mô hình TensorFlow trên GitHub sử dụng cách tiếp cận trước đây cho BERT (xem nlp/tools/export_tfhub_lib.py , lưu ý sự phân chia giữa core_model
để xuất và pretrainer
để khôi phục điểm kiểm tra) và cách tiếp cận sau cho ResNet (xem Legacy/image_classification/tfhub_export.py ).
Lưu từ TensorFlow cấp thấp
Điều này đòi hỏi sự hiểu biết tốt về SavingModel Guide của TensorFlow.
Nếu bạn muốn cung cấp nhiều hơn chỉ là chữ ký phục vụ, bạn nên triển khai giao diện SavingModel có thể tái sử dụng . Về mặt khái niệm, điều này trông giống như
class MyMulModel(tf.train.Checkpoint):
def __init__(self, v_init):
super().__init__()
self.v = tf.Variable(v_init)
self.variables = [self.v]
self.trainable_variables = [self.v]
self.regularization_losses = [
tf.function(input_signature=[])(lambda: 0.001 * self.v**2),
]
@tf.function(input_signature=[tf.TensorSpec(shape=None, dtype=tf.float32)])
def __call__(self, inputs):
return tf.multiply(inputs, self.v)
tf.saved_model.save(MyMulModel(2.0), "/tmp/my_mul")
layer = hub.KerasLayer("/tmp/my_mul")
print(layer([10., 20.])) # [20., 40.]
layer.trainable = True
print(layer.trainable_weights) # [2.]
print(layer.losses) # 0.004
Tinh chỉnh
Việc huấn luyện các biến đã được huấn luyện của một SavingModel đã nhập cùng với các biến của mô hình xung quanh nó được gọi là tinh chỉnh SavingModel. Điều này có thể mang lại chất lượng tốt hơn nhưng thường khiến quá trình đào tạo trở nên khắt khe hơn (có thể mất nhiều thời gian hơn, phụ thuộc nhiều hơn vào trình tối ưu hóa và siêu tham số của nó, làm tăng nguy cơ trang bị quá mức và yêu cầu tăng cường tập dữ liệu, đặc biệt là đối với CNN). Chúng tôi khuyên người tiêu dùng SavingModel chỉ nên xem xét tinh chỉnh sau khi đã thiết lập chế độ đào tạo tốt và chỉ khi nhà xuất bản SavingModel đề xuất chế độ đó.
Tinh chỉnh thay đổi các tham số mô hình "liên tục" đã được huấn luyện. Nó không thay đổi các phép biến đổi được mã hóa cứng, chẳng hạn như mã hóa thông tin nhập văn bản và ánh xạ mã thông báo tới các mục nhập tương ứng của chúng trong ma trận nhúng.
Dành cho người tiêu dùng SavingModel
Tạo một hub.KerasLayer
thích
layer = hub.KerasLayer(..., trainable=True)
cho phép tinh chỉnh SavingModel được lớp tải. Nó bổ sung các trọng số có thể huấn luyện và các bộ điều chỉnh trọng số được khai báo trong SavingModel vào mô hình Keras và chạy tính toán của SavingModel trong chế độ huấn luyện (hãy nghĩ đến việc bỏ học, v.v.).
Colab phân loại hình ảnh chứa một ví dụ toàn diện với tính năng tinh chỉnh tùy chọn.
Xuất lại kết quả tinh chỉnh
Người dùng nâng cao có thể muốn lưu lại kết quả tinh chỉnh vào SavingModel để có thể sử dụng thay vì kết quả được tải ban đầu. Điều này có thể được thực hiện với mã như
loaded_obj = hub.load("https://tfhub.dev/...")
hub_layer = hub.KerasLayer(loaded_obj, trainable=True, ...)
model = keras.Sequential([..., hub_layer, ...])
model.compile(...)
model.fit(...)
export_module_dir = os.path.join(os.getcwd(), "finetuned_model_export")
tf.saved_model.save(loaded_obj, export_module_dir)
Dành cho người tạo SavingModel
Khi tạo SavingModel để chia sẻ trên TensorFlow Hub, hãy suy nghĩ trước xem liệu người tiêu dùng có nên tinh chỉnh nó hay không và bằng cách nào, đồng thời cung cấp hướng dẫn trong tài liệu.
Việc lưu từ Mô hình Keras sẽ làm cho tất cả các cơ chế tinh chỉnh hoạt động (tiết kiệm tổn thất chính quy hóa trọng lượng, khai báo các biến có thể huấn luyện, truy tìm __call__
cho cả training=True
và training=False
, v.v.)
Chọn giao diện mô hình hoạt động tốt với luồng gradient, ví dụ: nhật ký đầu ra thay vì xác suất softmax hoặc dự đoán top-k.
Nếu mô hình sử dụng phương pháp bỏ học, chuẩn hóa hàng loạt hoặc các kỹ thuật đào tạo tương tự có liên quan đến siêu tham số, hãy đặt chúng thành các giá trị có ý nghĩa đối với nhiều vấn đề mục tiêu dự kiến và quy mô lô. (Tại thời điểm viết bài này, việc tiết kiệm từ Keras không giúp người tiêu dùng dễ dàng điều chỉnh chúng.)
Bộ điều chỉnh trọng số trên các lớp riêng lẻ được lưu (với hệ số cường độ chính quy của chúng), nhưng việc điều chỉnh trọng số từ bên trong trình tối ưu hóa (như tf.keras.optimizers.Ftrl.l1_regularization_strength=...)
) sẽ bị mất. Tư vấn cho người tiêu dùng về SavingModel của bạn một cách phù hợp.