Ngày Cộng đồng ML là ngày 9 tháng 11! Tham gia với chúng tôi để cập nhật từ TensorFlow, JAX, và nhiều hơn nữa Tìm hiểu thêm

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à
  • máy có thể đọc được các bộ phận mà có thể được thừa hưởng bởi máy phát điện mã, chẳng hạn như tạo mã TensorFlow Lite Android và các tính năng Binding Android Studio ML .

Tất cả các model hình ảnh được công bố trên TensorFlow Lite tổ chức mô hìnhTensorFlow Hub đã được dân cư với 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 định nghĩa trong metadata_schema.fbs , một FlatBuffer tập tin. Như thể hiện trong hình 1, nó được lưu trữ trong các siêu dữ liệu lĩnh vực các giản đồ mô hình TFLite , dưới danh nghĩa, "TFLITE_METADATA" . Một số mô hình có thể đến với các tập tin có liên quan, chẳng hạn như các file nhãn phân loại . Những tập tin này được nối vào cuối của tập tin mô hình ban đầu như một bưu điện bằng cách sử dụng ZipFile "append" chế độ ( 'a' mode). 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 Gói các tập tin liên quan để 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 này lên đâ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ợ Python 3.

Thêm siêu dữ liệu bằng API Flatbuffers Python

Có ba phần để các siêu dữ liệu mô hình trong sơ đồ :

  1. Thông tin mô hình - Mô tả chung về mô hình cũng như các hạng 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à sơ chế cần thiết như bình thường. Xem SubGraphMetadata.input_tensor_metadata .
  3. Thông tin đầu ra - Mô tả các đầu ra và sau xử lý cần thiết như bản đồ để nhãn. Xem SubGraphMetadata.output_tensor_metadata .

Kể từ TensorFlow Lite chỉ hỗ trợ đồ thị con duy nhất tại thời điểm này, các mã máy phát điện TensorFlow Litetính năng Binding Android Studio ML 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 hỗ trợ bởi siêu dữ liệu TensorFlow Lite:

  • 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. Giản đồ hỗ trợ một loạt các sơ đồ sắp xếp .

Đó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 phần mở rộng tập tin tương tự, .tflite . Nó tương thích với khung TFLite và Trình thông dịch hiện có. Xem Gói siêu dữ liệu và các tập tin 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 file và nơi các tập tin được gắn vào (tức là ModelMetadata , SubGraphMetadata , và TensorMetadata ), mã máy phát điện TensorFlow Lite Android có thể áp dụng tự động tương ứng trước / sau xử lý đến đối tượng. Xem các <sử dụng codegen> của từng loại tập tin kết hợp 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ị.

Mô hình lượng tử hóa là một kỹ thuật cho phép để giảm cơ quan đại 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 float:
- trung bình: 127,5
- std: 127,5
Mô hình Quant:
- trung bình: 127,5
- std: 127,5
Mô hình float:
- zeroĐiểm: 0
- thang điểm: 1.0
Mô hình Quant:
- 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, các dữ liệu đầu vào của nhu cầu suy luận được chuẩn hóa cho phù hợp.
Đầu ra: Dữ liệu đầu ra sẽ không được bình thường hóa nói chung.
Mô hình phao không cần lượng tử.
Mô hình lượng tử có thể hoặc có thể không cần lượng tử ở trước / sau chế biến. Nó phụ thuộc vào kiểu dữ liệu của bộ căng đầ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
Quantize 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
Lấp đầy bởi người sáng tạo mô hình và được lưu trữ trong siêu dữ liệu mô hình, như 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ố? Qua MetadataExtractor API [2] 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 ML của Android Studio có tự động tạo mã này trong quá trình xử lý dữ liệu không?
đúng

đúng

[1] TensorFlow Lite Java APITensorFlow Lite C ++ API .
[2] Các thư viện vắ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 nên 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.

TensorFlow Lite công tác thư viện có thể xử lý bình thường dành cho bạn nếu bạn thiết lập NormalizationOptions trong siêu dữ liệu. Quá trình lượng tử hóa và dequantization luôn được liệt kê.

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 về kịch bản ở đây , mà populates siêu dữ liệu để 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

Để metadata điền để mô hình phân loại hình ảnh khác, thêm các thông số kỹ thuật mô hình như này vào kịch bản. 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à một loại đầu vào phổ biến cho học máy. 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 tin có liên quan 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

Khi Flatbuffers siêu dữ liệu được tạo ra, các siêu dữ liệu và các tập tin nhãn được viết vào tập tin TFLite qua populate phương pháp:

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 như nhiều tác phẩm liên quan như bạn muốn 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 để hình dung siêu dữ liệu của bạn, hoặc bạn có thể đọc các siêu dữ liệu từ một mô hình TensorFlow Lite sang một định dạng json sử dụ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 các tính năng Binding Android Studio ML .

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

Các sơ đồ siêu dữ liệu được phiên bản cả bằng của số phiên bản Semantic, theo dõi những thay đổi của tập tin lược đồ, và bởi việc xác định tập tin Flatbuffers, mà chỉ ra khả năng tương thích phiên bản đúng.

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

Giản đồ siêu dữ liệu được phiên bản bằng các số phiên bản Semantic , chẳng hạn như MAJOR.MINOR.PATCH. Nó theo dõi thay đổi sơ đồ theo các quy tắc ở đây . Xem lịch sử của lĩnh vực thêm vào sau khi 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 chạm vào 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ị phá vỡ. Do đó, chúng tôi sử dụng xác định tập tin Flatbuffers , file_identifier , để biểu thị khả năng tương thích thực sự của giản đồ siêu dữ liệu. Đị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

Các cần thiết phiên bản siêu dữ liệu phân tích cú pháp tối thiểu là phiên bản tối thiểu của phân tích cú pháp siêu dữ liệu (các Flatbuffers tạo code) mà có thể đọc các Flatbuffers siêu dữ liệu đầy đủ. 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 vắt siêu dữ liệu để biết thêm thông tin về cách phiên bản siêu dữ liệu phân tích cú pháp tối thiểu cần thiết được sử dụng.

Đọ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 các siêu dữ liệu và các tập tin liên quan đến từ một mô hình trên nhiều nền tảng khác nhau (xem phiên bản JavaC ++ phiên bản ). 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 sử dụng các TensorFlow Lite Metadata AAR lưu trữ tại MavenCentral . Nó chứa các MetadataExtractor lớp, cũng như các ràng buộc FlatBuffers Java cho các giản đồ siêu dữ liệusơ đồ mô hình .

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

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

Để sử dụng các bức ảnh chụp đêm, hãy chắc chắn rằng bạn đã thêm kho Sonatype ảnh chụp .

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

public MetadataExtractor(ByteBuffer buffer);

Các ByteBuffer phải vẫn không thay đổi cho toàn bộ vòng đời của MetadataExtractor đối tượng. 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 siêu dữ liệu versioning để 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. Các phiên bản phân tích cú pháp cần thiết tối thiểu của các siêu dữ liệu cho thấy phiên bản tối thiểu của phân tích cú pháp siêu dữ liệu có thể đọc các Flatbuffers siêu dữ liệu đầy đủ. 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 bằng cách gọi các hasMetadata phương pháp:

public boolean hasMetadata();

MetadataExtractor cung cấp các chức năng thuận tiện cho bạn để có được siêu dữ liệu tensors đầu vào / đầu ra. 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ù các giản đồ mô hình TensorFlow Lite hỗ trợ nhiều đồ thị con, các TFLite Interpreter hiện chỉ hỗ trợ một đồ thị con duy nhất. Do đó, MetadataExtractor bỏ qua chỉ số đồ thị con như một tham số đầu vào trong 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 các tập tin 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, vượt qua các tên tập tin vào MetadataExtractor.getAssociatedFile phương pháp:

public InputStream getAssociatedFile(String fileName);

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

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