Siêu dữ liệu LiteRT cung cấp một tiêu chuẩn cho nội dung mô tả mô hình. Chiến lược phát hành đĩa đơn siêu dữ liệu là một nguồn kiến thức quan trọng về chức năng của mô hình và thông tin đầu vào / đầu ra. Siêu dữ liệu bao gồm cả hai
- phần mà con người có thể đọc được, giúp truyền tải phương pháp hay nhất khi sử dụng mô hình, và
- những phần mà máy có thể đọc được mà trình tạo mã có thể tận dụng, chẳng hạn như Mã LiteRT dành cho Android công cụ tạo và Liên kết máy học Android Studio .
Tất cả mẫu hình ảnh được xuất bản trên Kaggle Hệ thống đã điền sẵn mô hình siêu dữ liệu.
Mô hình có định dạng siêu dữ liệu
Siêu dữ liệu của mô hình được xác định trong
metadata_schema.fbs,
một
FlatBuffer
. Như được minh hoạ trong Hình 1, dữ liệu này được lưu trữ trong
siêu dữ liệu
trường của mô hình TFLite
giản đồ,
dưới tên, "TFLITE_METADATA"
. Một số mô hình có thể có tệp liên kết,
chẳng hạn như nhãn phân loại
tệp.
Các tệp này được nối vào cuối tệp mô hình ban đầu dưới dạng tệp ZIP
bằng cách sử dụng "nối" của ZipFile
chế độ (chế độ 'a'
). TFLite
Chế độ phiên dịch có thể sử dụng định dạng tệp mới này theo cách tương tự như trước đây. Xem Gói
các tệp liên quan để biết thêm thông tin.
Hãy xem hướng dẫn dưới đây về cách điền sẵn, trực quan hoá và đọc siêu dữ liệu.
Thiết lập công cụ siêu dữ liệu
Trước khi thêm siêu dữ liệu vào mô hình, bạn cần lập trình Python thiết lập môi trường để chạy TensorFlow. Có hướng dẫn chi tiết về cách hãy thiết lập điều này tại đây.
Sau khi thiết lập môi trường lập trình Python, bạn sẽ cần cài đặt công cụ bổ sung:
pip install tflite-support
Công cụ siêu dữ liệu LiteRT hỗ trợ Python 3.
Thêm siêu dữ liệu bằng API Flatbuffers Python
Có ba phần siêu dữ liệu của mô hình trong giản đồ:
- Thông tin về mẫu thiết bị – Mô tả tổng thể về mô hình cũng như các mặt hàng
chẳng hạn như các điều khoản cấp phép. Xem
ModelMetadata.
- Thông tin đầu vào – Nội dung mô tả về dữ liệu đầu vào và quá trình xử lý trước
chẳng hạn như chuẩn hoá. Xem
SubGraphMetadata.input_tensor_metadata.
- Thông tin đầu ra – Nội dung mô tả về đầu ra và hậu xử lý bắt buộc, chẳng hạn như ánh xạ đến nhãn. Xem SubGraphMetadata.output_tensor_metadata.
- Thông tin đầu vào – Nội dung mô tả về dữ liệu đầu vào và quá trình xử lý trước
chẳng hạn như chuẩn hoá. Xem
SubGraphMetadata.input_tensor_metadata.
Vì LiteRT chỉ hỗ trợ một đồ thị con tại thời điểm này, nên phương thức
Trình tạo mã LiteRT
và Liên kết máy học Android Studio
tính năng
sẽ sử dụng ModelMetadata.name
và ModelMetadata.description
, thay vì
SubGraphMetadata.name
và SubGraphMetadata.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 LiteRT cho đầu vào và đầu ra không được thiết kế với loại mô hình đầu vào và đầu ra. Không quan trọng mô hình hoạt động về chức năng, miễn là loại đầu vào và đầu ra bao gồm ký tự sau hoặc kết hợp các thuộc tính sau đây, nó được TensorFlow hỗ trợ Siêu dữ liệu phiên bản rút gọn:
- Tính năng – 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 màu xám.
- Hộp giới hạn – Hộp giới hạn hình chữ nhật. Giản đồ này hỗ trợ a nhiều cách đánh số .
Đóng gói các tệp liên quan
Các mô hình LiteRT có thể đi kèm với nhiều tệp liên kết. Ví dụ: mô hình ngôn ngữ tự nhiên thường có tệp từ vựng liên kết các phần từ với từ Giấy tờ tuỳ thân; mô hình phân loại có thể có tệp nhãn cho biết các danh mục đối tượng. Nếu không có các tệp liên kết (nếu có), mô hình sẽ không hoạt động tốt.
Giờ đây, bạn có thể nhóm các tệp đã liên kết cùng với mô hình thông qua siêu dữ liệu
Thư viện Python. Mô hình LiteRT mới sẽ trở thành tệp zip chứa
cả mô hình và các tệp được liên kết. Tệp này có thể được giải nén bằng mã zip thông thường
và các công cụ lập mô hình tuỳ chỉnh. Định dạng tệp mới này tiếp tục sử dụng cùng một đuôi tệp là .tflite
. Nó
tương thích với khung TFLite và Trình thông dịch hiện có. Xem phần Siêu dữ liệu của gói
và tệp được liên kết vào
mô hình để biết thêm chi tiết.
Thông tin về tệp liên kết có thể được ghi lại trong siêu dữ liệu. Tuỳ thuộc vào
loại tệp và nơi tệp được đính kèm (ví dụ: ModelMetadata
,
SubGraphMetadata
và TensorMetadata
), mã LiteRT Android
công cụ tạo có thể áp dụng trước/sau tương ứng
tự động xử lý cho đối tượng. Hãy xem phần <Codegen Usage> phần của
từng tệp liên kết
loại thiết bị
trong giản đồ để biết thêm chi tiết.
Tham số chuẩn hoá và lượng tử hoá
Chuẩn hoá là một kỹ thuật tiền xử lý dữ liệu phổ biến trong công nghệ học máy. Chiến lược phát hành đĩa đơn mục tiêu của quá trình chuẩn hoá là thay đổi các giá trị về một thang đo chung mà không làm biến dạng sự khác biệt trong phạm vi giá trị.
Lượng tử hoá mô hình là một kỹ thuật cho phép giảm độ chính xác của trọng số và không bắt buộc cho cả việc lưu trữ và tính toán.
Về mặt tiền xử lý và hậu xử lý, chuẩn hoá và lượng tử hoá là hai bước độc lập. Dưới đây là các chi tiết.
Chuẩn hoá | Lượng tử hoá | |
---|---|---|
Ví dụ về các giá trị thông số của thuộc tính nhập hình ảnh vào MobileNet cho độ chính xác đơn và mô hình lượng tử, tương ứng. |
Mô hình số thực: - trung bình: 127,5 - tiêu chuẩn: 127,5 Mô hình lượng: - trung bình: 127,5 - std: 127,5 |
Mô hình số thực: - zeroPoint: 0 - tỷ lệ: 1,0 Mô hình lượng: – zeroPoint: 128,0 - tỷ lệ:0.0078125f |
Khi nào nên gọi? |
Đầu vào: Nếu đầu vào được chuẩn hoá theo huấn luyện, đầu vào dữ liệu của nhu cầu suy luận để được chuẩn hoá cho phù hợp. Kết quả: đầu ra sẽ không được được chuẩn hoá nói chung. |
Mô hình nổi có thể
không cần lượng tử hoá. Mô hình lượng tử có thể hoặc có thể không cần lượng tử hoá trong giai đoạn trước và sau khi triển khai đang xử lý. Tuỳ trường hợp dựa trên loại dữ liệu của tensor đầu vào/đầu ra. – tensor số thực: không lượng tử hoá trong giai đoạn trước và sau khi triển khai cần xử lý. Quant hoạt động vận hành và gián tiếp đưa vào mô hình biểu đồ. - tensor int8/uint8: cần định lượng trong xử lý trước/sau. |
Công thức |
đầu_ vào_chuẩn = (đầu vào – trung bình) / std |
Định lượng dữ liệu đầu vào:
q = f / tỷ lệ + zeroPoint Loại bỏ lượng tử trong kết quả: f = (q - zeroPoint) * quy mô |
Vị trí tham số |
Điền bởi người tạo mô hình
và được lưu trữ trong mô hình
siêu dữ liệu, như
NormalizationOptions |
Được tự động điền bởi Công cụ chuyển đổi TFLite và được lưu trữ trong mô hình tflite . |
Cách tải tham số không? | Thông qua
API MetadataExtractor
[2]
|
Thông qua TFLite
Tensor API [1] hoặc
thông qua
API MetadataExtractor
[2] |
Độ chính xác đơn và số tử các mô hình có cùng giá trị? | Có, số thực và số lượng các mô hình có cùng Chuẩn hoá tham số | Không, mô hình số thực không cần lượng tử hoá. |
Có mã TFLite trình tạo hoặc Android Liên kết công nghệ học máy trong Studio tự động tạo trong quá trình xử lý dữ liệu? | Có |
Có |
[1] LiteRT Java
API
và LiteRT 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 mô hình uint8, việc chuẩn hoá và lượng tử hoá đôi khi bị bỏ qua. Bạn có thể làm như vậy khi giá trị pixel nằm trong khoảng [0, 255]. Nhưng nhìn chung, bạn nên luôn xử lý dữ liệu theo các tham số chuẩn hoá và lượng tử hoá khi có thể.
Ví dụ
Bạn có thể xem các ví dụ về cách điền siêu dữ liệu cho các các loại mô hình ở đây:
Phân loại hình ảnh
Tải tập lệnh xuống tại đây , giúp điền 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
Để đ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 thông số kỹ thuật của mô hình lượt thích 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 hoạ các yếu tố chính.
Tìm hiểu sâu ví dụ về cách phân loại hình ảnh
Thông tin mẫu
Siêu dữ liệu bắt đầu bằng cách tạo một 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 cho bạn biết cách mô tả chữ ký đầu vào và đầu ra của mô hình. Trình tạo mã tự động có thể sử dụng siêu dữ liệu này để tạo mã xử lý. Cách tạo thông tin đầu vào hoặc đầu ra về một tensor:
# Creates input info.
input_meta = _metadata_fb.TensorMetadataT()
# Creates output info.
output_meta = _metadata_fb.TensorMetadataT()
Nhập hình ảnh
Hình ảnh là một loại dữ liệu đầu vào phổ biến cho công nghệ học máy. Siêu dữ liệu LiteRT hỗ trợ các thông tin như hệ màu và thông tin xử lý trước như chuẩn hoá dữ liệu. Kích thước của hình ảnh không yêu cầu thông số kỹ thuật thủ công vì nó đã được cung cấp bởi hình dạng của tensor đầu vào và có thể được được tự động suy luận.
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 của nhãn
Có thể ánh xạ nhãn tới một tensor đầu ra thông qua một tệp 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 Vùng đệm phẳng siêu dữ liệu
Đoạn mã sau đây kết hợp thông tin về mô hình với dữ liệu đầu vào và đầu ra của bạn:
# 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 liên kết vào mô hình
Sau khi siêu dữ liệu Flatbuffers được tạo, siêu dữ liệu và tệp nhãn sẽ
đượ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 tuỳ thích vào mô hình thông qua
load_associated_files
. Tuy nhiên, bạn cần phải đóng gói ít nhất 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 sẽ
bắt buộc.
Trực quan hoá siêu dữ liệu
Bạn có thể sử dụng Netron để trực quan hoá
siêu dữ liệu hoặc bạn có thể đọc siêu dữ liệu từ mô hình LiteRT thành tệp json
bằng cách 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 Học máy Android Studio Ràng buộc .
Tạo phiên bản siêu dữ liệu
Siêu dữ liệu giản đồ được tạo phiên bản theo cả số phiên bản ngữ nghĩa, giúp theo dõi các thay đổi của tệp giản đồ và bằng cách nhận dạng tệp Flatbuffers, mã này cho biết khả năng tương thích thực sự với phiên bản.
Số phiên bản ngữ nghĩa
Giản đồ siêu dữ liệu được tạo phiên bản theo Phiên bản ngữ nghĩa
số,
chẳng hạn như MAJOR.MINOR.PATCH. Theo dõi các thay đổi của giản đồ theo quy tắc
tại đây.
Xem lịch sử của
trường
được thêm sau phiên bản 1.0.0
.
Nhận dạng tệp Flatbuffers
Việc tạo phiên bản ngữ nghĩa đảm bảo tính tương thích nếu bạn tuân thủ các quy tắc, nhưng không ngụ ý sự không tương thích thực sự. Khi tăng số MAJOR, 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 hãy dùng tệp Flatbuffers nhận dạng, file_identifier, để biểu thị khả năng tương thích thực sự của giản đồ siêu dữ liệu. Giá trị nhận dạng tệp là dài chính xác 4 ký tự. Nó được cố định theo một giản đồ siêu dữ liệu nhất định và không có thể thay đổi bởi người dùng. Nếu giản đồ siêu dữ liệu có khả năng tương thích ngược bị hỏng vì lý do nào đó, file_identifier sẽ tăng lên, ví dụ: từ "M001" đến "M002". File_identifier có thể sẽ ít thay đổi hơn thường xuyên hơn phiên bản siêu dữ liệu.
Phiên bản tối thiểu cần thiết của trình phân tích cú pháp siêu dữ liệu
Trình phân tích cú pháp siêu dữ liệu cần thiết tối thiểu
phiên bản
là phiên bản tối thiểu của trình phân tích cú pháp siêu dữ liệu (mã được tạo bằng Flatbuffers)
có thể đọc toàn bộ siêu dữ liệu Flatbuffers. Phiên bản này 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 sẵn và
phiên bản tương thích nhỏ nhất được biểu thị
bằng mã nhận dạng tệp. Giá trị tối thiểu
phiên bản trình phân tích cú pháp siêu dữ liệu cần thiết được điền tự động bằng
MetadataPopulator
khi siêu dữ liệu được điền vào mô hình TFLite. Xem
công cụ trích xuất siêu dữ liệu để biết thêm thông tin về cách
bạn cần sử dụng phiên bản tối thiểu cần thiết của trình phân tích cú pháp siêu dữ liệu.
Đọc siêu dữ liệu của mô hình
Thư viện Trình trích xuất siêu dữ liệu là một công cụ thuận tiện để đọc siêu dữ liệu và tệp được liên kết từ mô hình trên các nền tảng khác nhau (xem Hướng dẫn phiên bản và C++ 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 Trình trích xuất siêu dữ liệu trong ứng dụng Android, bạn nên sử dụng
AAR siêu dữ liệu LiteRT được lưu trữ tại
MavenCentral.
Tệp này chứa lớp MetadataExtractor
, cũng như Java FlatBuffers
các liên kết cho siêu dữ liệu
giản đồ
và mô hình
giản đồ.
Bạn có thể chỉ định mã này trong các phần phụ thuộc build.gradle
như sau:
dependencies {
implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0'
}
Để sử dụng ảnh chụp nhanh hàng đêm, hãy đảm bảo bạn đã thêm ảnh chụp nhanh Sonatype kho lưu trữ.
Bạn có thể khởi tạo đối tượng MetadataExtractor
bằng ByteBuffer
trỏ đến
cho mô hình:
public MetadataExtractor(ByteBuffer buffer);
ByteBuffer
không được thay đổi trong toàn bộ thời gian hoạt động của
Đối tượng MetadataExtractor
. Quá trình khởi chạy có thể không thành công nếu tệp Flatbuffers
giá trị nhận dạng của siêu dữ liệu mô hình không khớp với giá trị nhận dạng của trình phân tích cú pháp siêu dữ liệu. Xem
tạo phiên bản siêu dữ liệu để biết thêm thông tin.
Khi có giá trị nhận dạng tệp trùng khớ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ả giản đồ trước đây và trong tương lai do Flatbuffers tương thích tiến và tương thích ngược. Tuy nhiên, các trường trong tương lai các công cụ trích xuất siêu dữ liệu cũ không thể trích xuất giản đồ. Số tiền tối thiểu cần thiết phiên bản trình phân tích cú pháp của siêu dữ liệu cho biết phiên bản tối thiểu của trình phân tích cú pháp siêu dữ liệu có thể đọc siêu dữ liệu Hết vùng đệm phẳng. Bạn có thể sử dụng phương pháp sau đây để xác minh xem giá trị Điều kiện phiên bản trình phân tích cú pháp cần thiết được đáp ứng:
public final boolean isMinimumParserVersionSatisfied();
Bạn có thể truyền dữ liệu vào 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
siêu dữ liệu bằng cách gọi phương thức hasMetadata
:
public boolean hasMetadata();
MetadataExtractor
cung cấp các hàm thuận tiện để bạn có thể lấy
tensor đầu vào/đầu ra siêu dữ liệu. 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ù mô hình LiteRT
giản đồ
hỗ trợ nhiều đồ thị con, nên Trình thông dịch TFLite hiện chỉ hỗ trợ
đồ thị con đơn. Do đó, MetadataExtractor
bỏ qua chỉ mục đồ thị con làm dữ liệu đầu vào
đối số trong phương thức của nó.
Đọc các tệp được liên kết từ mô hình
Mô hình LiteRT với siêu dữ liệu và các tệp được liên kết về cơ bản là 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 liên quan. 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 liên quan thông qua thư viện Trình trích xuất siêu dữ liệu.
Trong Java, hãy chuyển tên tệp vào MetadataExtractor.getAssociatedFile
phương thức:
public InputStream getAssociatedFile(String fileName);
Tương tự, trong C++, bạn có thể thực hiện việc này bằng phương thức,
ModelMetadataExtractor::GetAssociatedFile
:
tflite::support::StatusOr<absl::string_view> GetAssociatedFile(
const std::string& filename) const;