Lưu ngày! Google I / O hoạt động trở lại từ ngày 18 đến 20 tháng 5 Đăng ký ngay
Trang này được dịch bởi Cloud Translation API.
Switch to English

Thêm siêu dữ liệu vào các mô hình TensorFlow Lite

Siêu dữ liệu TensorFlow Lite cung cấp một tiêu chuẩn cho các mô tả mô hình. Siêu dữ liệu là một nguồn kiến ​​thức quan trọng về những gì mô hình thực hiện và thông tin đầu vào / đầu ra của nó. Siêu dữ liệu bao gồm cả hai

  • các bộ phận con người có thể đọc được để truyền đạt phương pháp hay nhất khi sử dụng mô hình và
  • các bộ phận có thể đọc được của máy có thể được sử dụng bởi trình tạo mã, chẳng hạn như trình tạo mã TensorFlow Lite Android và tính năng Android Studio ML Binding .

Tất cả các mô hình hình ảnh được xuất bản trên các mô hình được lưu trữ trên TensorFlow LiteTensorFlow Hub đã được điền siêu dữ liệu.

Mô hình có định dạng siêu dữ liệu

model_with_metadata
Hình 1. Mô hình TFLite với siêu dữ liệu và các tệp liên kết.

Siêu dữ liệu mô hình được xác định trong metadata_schema.fbs , một tệp FlatBuffer . Như trong Hình 1, nó được lưu trữ trong trường siêu dữ liệu của lược đồ mô hình TFLite , dưới tên, "TFLITE_METADATA" . Một số kiểu máy có thể đi kèm với các tệp liên quan, chẳng hạn như tệp nhãn phân loại . Các tệp này được nối với phần cuối của tệp mô hình gốc dưới dạng ZIP bằng cách sử dụng chế độ "nối thêm" của ZipFile ( chế độ 'a' ). Trình thông dịch TFLite có thể sử dụng định dạng tệp mới theo cách giống như trước đây. Xem Đóng gói các tệp được liên kết để biết thêm thông tin.

Xem hướng dẫn bên dưới về cách điền, hình ảnh hóa và đọc siêu dữ liệu.

Thiết lập các công cụ siêu dữ liệu

Trước khi thêm siêu dữ liệu vào mô hình của mình, bạn sẽ cần thiết lập môi trường lập trình Python để chạy TensorFlow. Có một hướng dẫn chi tiết về cách thiết lập điều này ở đây .

Sau khi thiết lập môi trường lập trình Python, bạn sẽ cần cài đặt thêm công cụ:

pip install tflite-support

Công cụ siêu dữ liệu TensorFlow Lite hỗ trợ cả Python 2 và Python 3.

Thêm siêu dữ liệu

Có ba phần đối với siêu dữ liệu của mô hình trong lược đồ :

  1. Thông tin mô hình - Mô tả tổng thể về mô hình cũng như các mục như điều khoản cấp phép. Xem ModelMetadata .
  2. Thông tin đầu vào - Mô tả các đầu vào và yêu cầu xử lý trước như chuẩn hóa. Xem SubGraphMetadata.input_tensor_metadata .
  3. Thông tin đầu ra - Mô tả yêu cầu đầu ra và xử lý hậu kỳ như ánh xạ tới nhãn. Xem SubGraphMetadata.output_tensor_metadata .

Vì TensorFlow Lite chỉ hỗ trợ một đồ thị con tại thời điểm này, trình tạo mã TensorFlow Lite và tính năng Android Studio ML Binding sẽ sử dụng ModelMetadata.nameModelMetadata.description , thay vì SubGraphMetadata.nameSubGraphMetadata.description , khi hiển thị siêu dữ liệu và tạo mã.

Các loại đầu vào / đầu ra được hỗ trợ

Siêu dữ liệu TensorFlow Lite cho đầu vào và đầu ra không được thiết kế với các loại mô hình cụ thể mà là các loại đầu vào và đầu ra. Mô hình hoạt động theo chức năng gì không quan trọng, miễn là các loại đầu vào và đầu ra bao gồm các loại sau hoặc kết hợp các loại sau, nó được siêu dữ liệu TensorFlow Lite hỗ trợ:

  • Tính năng - Các số là số nguyên không dấu hoặc float32.
  • Hình ảnh - Siêu dữ liệu hiện hỗ trợ hình ảnh RGB và thang độ xám.
  • Bound box - Hộp viền hình chữ nhật. Lược đồ hỗ trợ nhiều loại lược đồ đánh số .

Đóng gói các tệp được liên kết

Các mô hình TensorFlow Lite có thể đi kèm với các tệp liên kết khác nhau. Ví dụ, các mô hình ngôn ngữ tự nhiên thường có các tệp vocab ánh xạ các mảnh từ thành ID từ; các mô hình phân loại có thể có các tệp nhãn chỉ ra các loại đối tượng. Nếu không có các tệp được liên kết (nếu có), một mô hình sẽ không hoạt động tốt.

Các tệp được liên kết hiện có thể được đóng gói với mô hình thông qua thư viện Python siêu dữ liệu. Mô hình TensorFlow Lite mới sẽ trở thành một tệp zip chứa cả mô hình và các tệp được liên kết. Nó có thể được giải nén bằng các công cụ zip thông thường. Định dạng mô hình mới này tiếp tục sử dụng cùng một phần mở rộng tệp, .tflite . Nó tương thích với khung TFLite và Trình thông dịch hiện có. Xem Gói mtadata và các tệp liên quan vào mô hình để biết thêm chi tiết.

Thông tin tệp được liên kết có thể được ghi lại trong siêu dữ liệu. Tùy thuộc vào loại tệp và nơi tệp được đính kèm (tức là ModelMetadata , SubGraphMetadataTensorMetadata ), trình tạo mã TensorFlow Lite Android có thể tự động áp dụng xử lý trước / sau tương ứng cho đối tượng. Xem phần <Cách sử dụng Codegen> của từng loại tệp liên kết trong lược đồ để biết thêm chi tiết.

Các thông số chuẩn hóa và lượng tử hóa

Chuẩn hóa là một kỹ thuật tiền xử lý dữ liệu phổ biến trong học máy. Mục tiêu của chuẩn hóa là thay đổi các giá trị thành một thang đo chung, mà không làm sai lệch sự khác biệt trong các phạm vi giá trị.

Lượng tử hóa mô hình là một kỹ thuật cho phép giảm các biểu diễn chính xác của trọng lượng và tùy chọn, kích hoạt cho cả lưu trữ và tính toán.

Về tiền xử lý và hậu xử lý, chuẩn hóa và lượng tử hóa là hai bước độc lập. Đây là những thông tin chi tiết.

Bình thường hóa Lượng tử hóa

Ví dụ về các giá trị tham số của hình ảnh đầu vào trong MobileNet cho các mô hình float và quant tương ứng.
Mô hình phao :
- trung bình: 127,5
- std: 127,5
Mô hình số lượng :
- trung bình: 127,5
- std: 127,5
Mô hình phao :
- zeroĐiểm: 0
- thang điểm: 1.0
Mô hình số lượng :
- zeroĐiểm: 128.0
- quy mô: 0,0078125f




Khi nào thì gọi?


Đầu vào : Nếu dữ liệu đầu vào được chuẩn hóa trong đào tạo, thì dữ liệu đầu vào của suy luận cần được chuẩn hóa tương ứng.
Đầu ra : dữ liệu đầu ra nói chung sẽ không được chuẩn hóa.
Mô hình nổi không cần lượng tử hóa.
Mô hình lượng tử hóa có thể cần hoặc không cần lượng tử hóa trong xử lý trước / sau. Nó phụ thuộc vào kiểu dữ liệu của tensors đầu vào / đầu ra.
- float tensors: không cần lượng tử hóa trong xử lý trước / sau. Op lượng tử và op dequant được đưa vào đồ thị mô hình.
- tensors int8 / uint8: cần lượng tử hóa trong xử lý trước / sau.


Công thức


normalized_input = (input - mean) / std
Định lượng cho đầu vào :
q = f / scale + zeroPoint
Dequantize cho kết quả đầu ra :
f = (q - zeroPoint) * thang điểm

Các thông số ở đâu
Được điền bởi người tạo mô hình và được lưu trữ trong siêu dữ liệu mô hình, dưới dạng NormalizationOptions Tự động điền bởi trình chuyển đổi TFLite và được lưu trữ trong tệp mô hình tflite.
Làm thế nào để lấy các tham số? Thông qua API MetadataExtractor [2] Thông qua TFLite Tensor API [1] hoặc thông qua MetadataExtractor API [2]
Các mô hình float và quant có cùng giá trị không? Có, mô hình float và mô hình lượng tử có cùng thông số Chuẩn hóa Không, mô hình float không cần lượng tử hóa.
Trình tạo mã TFLite hoặc liên kết Android Studio ML có tự động tạo mã này trong quá trình xử lý dữ liệu không?
Đúng

Đúng

[1] API TensorFlow Lite JavaAPI TensorFlow Lite C ++ .
[2] Thư viện trình trích xuất siêu dữ liệu

Khi xử lý dữ liệu hình ảnh cho các mô hình uint8, đôi khi bỏ qua quá trình chuẩn hóa và lượng tử hóa. Bạn có thể làm như vậy khi giá trị pixel nằm trong phạm vi [0, 255]. Nhưng nói chung, bạn phải luôn xử lý dữ liệu theo các tham số chuẩn hóa và lượng tử hóa khi có thể áp dụng.

Các ví dụ

Bạn có thể tìm thấy các ví dụ về cách siêu dữ liệu nên được điền cho các loại mô hình khác nhau tại đây:

Phân loại hình ảnh

Tải xuống tập lệnh tại đây , tập lệnh này điền siêu dữ liệu vào mobilenet_v1_0.75_160_quantized.tflite . Chạy tập lệnh như sau:

python ./metadata_writer_for_image_classifier.py \
    --model_file=./model_without_metadata/mobilenet_v1_0.75_160_quantized.tflite \
    --label_file=./model_without_metadata/labels.txt \
    --export_directory=model_with_metadata

Để điền siêu dữ liệu cho các mô hình phân loại hình ảnh khác, hãy thêm các thông số kỹ thuật của mô hình như thế này vào tập lệnh. Phần còn lại của hướng dẫn này sẽ nêu bật một số phần chính trong ví dụ phân loại hình ảnh để minh họa các yếu tố chính.

Đi sâu vào ví dụ phân loại hình ảnh

Thông tin mô hình

Siêu dữ liệu bắt đầu bằng cách tạo thông tin mô hình mới:

from tflite_support import flatbuffers
from tflite_support import metadata as _metadata
from tflite_support import metadata_schema_py_generated as _metadata_fb

""" ... """
"""Creates the metadata for an image classifier."""

# Creates model info.
model_meta = _metadata_fb.ModelMetadataT()
model_meta.name = "MobileNetV1 image classifier"
model_meta.description = ("Identify the most prominent object in the "
                          "image from a set of 1,001 categories such as "
                          "trees, animals, food, vehicles, person etc.")
model_meta.version = "v1"
model_meta.author = "TensorFlow"
model_meta.license = ("Apache License. Version 2.0 "
                      "http://www.apache.org/licenses/LICENSE-2.0.")

Thông tin đầu vào / đầu ra

Phần này chỉ cho bạn cách mô tả chữ ký đầu vào và đầu ra của mô hình của bạn. Siêu dữ liệu này có thể được sử dụng bởi trình tạo mã tự động để tạo mã trước và sau xử lý. Để tạo thông tin đầu vào hoặc đầu ra về tensor:

# Creates input info.
input_meta = _metadata_fb.TensorMetadataT()

# Creates output info.
output_meta = _metadata_fb.TensorMetadataT()

Đầu vào hình ảnh

Hình ảnh là loại đầu vào phổ biến cho máy học. Siêu dữ liệu TensorFlow Lite hỗ trợ thông tin như không gian màu và thông tin tiền xử lý như chuẩn hóa. Kích thước của hình ảnh không yêu cầu đặc điểm kỹ thuật thủ công vì nó đã được cung cấp bởi hình dạng của bộ căng đầu vào và có thể được suy ra tự động.

input_meta.name = "image"
input_meta.description = (
    "Input image to be classified. The expected image is {0} x {1}, with "
    "three channels (red, blue, and green) per pixel. Each value in the "
    "tensor is a single byte between 0 and 255.".format(160, 160))
input_meta.content = _metadata_fb.ContentT()
input_meta.content.contentProperties = _metadata_fb.ImagePropertiesT()
input_meta.content.contentProperties.colorSpace = (
    _metadata_fb.ColorSpaceType.RGB)
input_meta.content.contentPropertiesType = (
    _metadata_fb.ContentProperties.ImageProperties)
input_normalization = _metadata_fb.ProcessUnitT()
input_normalization.optionsType = (
    _metadata_fb.ProcessUnitOptions.NormalizationOptions)
input_normalization.options = _metadata_fb.NormalizationOptionsT()
input_normalization.options.mean = [127.5]
input_normalization.options.std = [127.5]
input_meta.processUnits = [input_normalization]
input_stats = _metadata_fb.StatsT()
input_stats.max = [255]
input_stats.min = [0]
input_meta.stats = input_stats

Đầu ra nhãn

Nhãn có thể được ánh xạ tới một tensor đầu ra thông qua một tệp được liên kết bằng cách sử dụng TENSOR_AXIS_LABELS .

# Creates output info.
output_meta = _metadata_fb.TensorMetadataT()
output_meta.name = "probability"
output_meta.description = "Probabilities of the 1001 labels respectively."
output_meta.content = _metadata_fb.ContentT()
output_meta.content.content_properties = _metadata_fb.FeaturePropertiesT()
output_meta.content.contentPropertiesType = (
    _metadata_fb.ContentProperties.FeatureProperties)
output_stats = _metadata_fb.StatsT()
output_stats.max = [1.0]
output_stats.min = [0.0]
output_meta.stats = output_stats
label_file = _metadata_fb.AssociatedFileT()
label_file.name = os.path.basename("your_path_to_label_file")
label_file.description = "Labels for objects that the model can recognize."
label_file.type = _metadata_fb.AssociatedFileType.TENSOR_AXIS_LABELS
output_meta.associatedFiles = [label_file]

Tạo Flatbuffers siêu dữ liệu

Đoạn mã sau kết hợp thông tin mô hình với thông tin đầu vào và đầu ra:

# Creates subgraph info.
subgraph = _metadata_fb.SubGraphMetadataT()
subgraph.inputTensorMetadata = [input_meta]
subgraph.outputTensorMetadata = [output_meta]
model_meta.subgraphMetadata = [subgraph]

b = flatbuffers.Builder(0)
b.Finish(
    model_meta.Pack(b),
    _metadata.MetadataPopulator.METADATA_FILE_IDENTIFIER)
metadata_buf = b.Output()

Đóng gói siêu dữ liệu và các tệp được liên kết vào mô hình

Sau khi tạo bộ đệm phẳng siêu dữ liệu, siêu dữ liệu và tệp nhãn được ghi vào tệp TFLite thông qua phương thức populate :

populator = _metadata.MetadataPopulator.with_model_file(model_file)
populator.load_metadata_buffer(metadata_buf)
populator.load_associated_files(["your_path_to_label_file"])
populator.populate()

Bạn có thể đóng gói bao nhiêu tệp liên kết tùy thích vào mô hình thông qua load_associated_files . Tuy nhiên, ít nhất phải đóng gói các tệp đó được ghi lại trong siêu dữ liệu. Trong ví dụ này, việc đóng gói tệp nhãn là bắt buộc.

Hình dung siêu dữ liệu

Bạn có thể sử dụng Netron để trực quan hóa siêu dữ liệu của mình hoặc bạn có thể đọc siêu dữ liệu từ mô hình TensorFlow Lite sang định dạng json bằng MetadataDisplayer :

displayer = _metadata.MetadataDisplayer.with_model_file(export_model_path)
export_json_file = os.path.join(FLAGS.export_directory,
                    os.path.splitext(model_basename)[0] + ".json")
json_file = displayer.get_metadata_json()
# Optional: write out the metadata as a json file
with open(export_json_file, "w") as f:
  f.write(json_file)

Android Studio cũng hỗ trợ hiển thị siêu dữ liệu thông qua tính năng Android Studio ML Binding .

Lập phiên bản siêu dữ liệu

Lược đồ siêu dữ liệu được tạo phiên bản bằng cả số phiên bản Ngữ nghĩa, số này theo dõi các thay đổi của tệp giản đồ và bằng nhận dạng tệp Flatbuffers, cho biết khả năng tương thích phiên bản thực sự.

Số phiên bản ngữ nghĩa

Lược đồ siêu dữ liệu được tạo phiên bản bằng số phiên bản Ngữ nghĩa , chẳng hạn như MAJOR.MINOR.PATCH. Nó theo dõi các thay đổi lược đồ theo các quy tắc ở đây . Xem lịch sử của các trường được thêm vào sau phiên bản 1.0.0 .

Nhận dạng tệp Flatbuffers

Phiên bản ngữ nghĩa đảm bảo tính tương thích nếu tuân theo các quy tắc, nhưng nó không ngụ ý sự không tương thích thực sự. Khi tăng lên số CHÍNH, điều đó không nhất thiết có nghĩa là khả năng tương thích ngược bị hỏng. Do đó, chúng tôi sử dụng nhận dạng tệp Flatbuffers , file_identifier , để biểu thị tính tương thích thực sự của giản đồ siêu dữ liệu. Mã định danh tệp dài chính xác 4 ký tự. Nó được cố định cho một lược đồ siêu dữ liệu nhất định và không thể thay đổi bởi người dùng. Nếu khả năng tương thích ngược của giản đồ siêu dữ liệu phải bị hỏng vì một lý do nào đó, thì file_identifier sẽ tăng lên, chẳng hạn như từ “M001” thành “M002”. File_identifier dự kiến ​​sẽ được thay đổi ít thường xuyên hơn metadata_version.

Phiên bản phân tích cú pháp siêu dữ liệu cần thiết tối thiểu

Phiên bản phân tích cú pháp siêu dữ liệu cần thiết tối thiểuphiên bản tối thiểu của trình phân tích cú pháp siêu dữ liệu (mã do Flatbuffers tạo) có thể đọc đầy đủ các Flatbuffers siêu dữ liệu. Phiên bản thực sự là số phiên bản lớn nhất trong số các phiên bản của tất cả các trường được điền và phiên bản tương thích nhỏ nhất được chỉ ra bởi mã định danh tệp. Cần thiết phiên bản siêu dữ liệu phân tích cú pháp tối thiểu được tự động bởi MetadataPopulator khi các siêu dữ liệu được phổ biến vào một mô hình TFLite. Xem trình trích xuất siêu dữ liệu để biết thêm thông tin về cách sử dụng phiên bản phân tích cú pháp siêu dữ liệu cần thiết tối thiểu.

Đọc siêu dữ liệu từ các mô hình

Thư viện Metadata Extractor là công cụ thuận tiện để đọc siêu dữ liệu và các tệp liên quan từ các mô hình trên các nền tảng khác nhau (xem phiên bản Javaphiên bản C ++ ). Bạn có thể xây dựng công cụ trích xuất siêu dữ liệu của riêng mình bằng các ngôn ngữ khác bằng cách sử dụng thư viện Flatbuffers.

Đọc siêu dữ liệu trong Java

Để sử dụng thư viện Metadata Extractor trong ứng dụng Android của bạn, chúng tôi khuyên bạn nên sử dụng TensorFlow Lite Metadata AAR được lưu trữ tại JCenter . Nó chứa lớp MetadataExtractor , cũng như các liên kết Java FlatBuffers cho lược đồ siêu dữ liệulược đồ mô hình .

Bạn có thể chỉ định điều này trong build.gradle phụ thuộc build.gradle của mình như sau:

dependencies {
    implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0'
}

Bạn có thể khởi tạo đối tượng MetadataExtractor bằng ByteBuffer trỏ đến mô hình:

public MetadataExtractor(ByteBuffer buffer);

ByteBuffer phải không thay đổi trong toàn bộ thời gian tồn tại của đối tượng MetadataExtractor . Quá trình khởi tạo có thể không thành công nếu mã định danh tệp Flatbuffers của siêu dữ liệu mô hình không khớp với mã phân tích cú pháp siêu dữ liệu. Xem lập phiên bản siêu dữ liệu để biết thêm thông tin.

Với số nhận dạng tệp phù hợp, trình trích xuất siêu dữ liệu sẽ đọc thành công siêu dữ liệu được tạo từ tất cả các lược đồ trong quá khứ và tương lai do cơ chế tương thích chuyển tiếp và ngược của Flatbuffers. Tuy nhiên, các trường từ các lược đồ trong tương lai không thể được trích xuất bằng trình trích xuất siêu dữ liệu cũ hơn. Phiên bản phân tích cú pháp tối thiểu cần thiết của siêu dữ liệu cho biết phiên bản phân tích cú pháp siêu dữ liệu tối thiểu có thể đọc đầy đủ Bộ đệm siêu dữ liệu. Bạn có thể sử dụng phương pháp sau để xác minh xem điều kiện phiên bản phân tích cú pháp cần thiết tối thiểu có được đáp ứng hay không:

public final boolean isMinimumParserVersionSatisfied();

Được phép chuyển vào một mô hình không có siêu dữ liệu. Tuy nhiên, việc gọi các phương thức đọc từ siêu dữ liệu sẽ gây ra lỗi thời gian chạy. Bạn có thể kiểm tra xem một mô hình có siêu dữ liệu hay không bằng cách gọi phương thức hasMetadata :

public boolean hasMetadata();

MetadataExtractor cung cấp các chức năng thuận tiện để bạn lấy siêu dữ liệu đầu vào / đầu ra của tensors. Ví dụ,

public int getInputTensorCount();
public TensorMetadata getInputTensorMetadata(int inputIndex);
public QuantizationParams getInputTensorQuantizationParams(int inputIndex);
public int[] getInputTensorShape(int inputIndex);
public int getoutputTensorCount();
public TensorMetadata getoutputTensorMetadata(int inputIndex);
public QuantizationParams getoutputTensorQuantizationParams(int inputIndex);
public int[] getoutputTensorShape(int inputIndex);

Mặc dù lược đồ mô hình TensorFlow Lite hỗ trợ nhiều đồ thị con, Trình thông dịch TFLite hiện chỉ hỗ trợ một đồ thị con duy nhất. Do đó, MetadataExtractor bỏ qua chỉ mục đồ thị con làm đối số đầu vào trong các phương thức của nó.

Đọc các tệp được liên kết từ các mô hình

Mô hình TensorFlow Lite với siêu dữ liệu và các tệp được liên kết về cơ bản là một tệp zip có thể được giải nén bằng các công cụ zip phổ biến để lấy các tệp được liên kết. Ví dụ: bạn có thể giải nén mobilenet_v1_0.75_160_quantized và trích xuất tệp nhãn trong mô hình như sau:

$ unzip mobilenet_v1_0.75_160_quantized_1_metadata_1.tflite
Archive:  mobilenet_v1_0.75_160_quantized_1_metadata_1.tflite
 extracting: labels.txt

Bạn cũng có thể đọc các tệp được liên kết thông qua thư viện Metadata Extractor.

Trong Java, chuyển tên tệp vào phương thức MetadataExtractor.getAssociatedFile :

public InputStream getAssociatedFile(String fileName);

Tương tự, trong C ++, điều này có thể được thực hiện với phương thức, ModelMetadataExtractor::GetAssociatedFile :

tflite::support::StatusOr<absl::string_view> GetAssociatedFile(
      const std::string& filename) const;