LiteRT 中繼資料提供了模型說明的標準, 中繼資料是瞭解模型用途和模型的重要知識來源 輸入 / 輸出資訊中繼資料包含
- 是人類可讀性,用來傳達最佳做法 和
- 這類可由程式碼產生器使用的可讀部分,例如 LiteRT Android 程式碼 產生器 以及 Android Studio 機器學習繫結 功能
所有在 Kaggle 發布的圖片模型 模型已填入 中繼資料。
中繼資料格式的模型
![model_with_metadata](https://ai.google.dev/edge/litert/images/convert/model_with_metadata.png?hl=zh-tw)
模型中繼資料的定義位置:
metadata_schema.fbs
換
FlatBuffer
檔案。如圖 1 所示,資料會儲存在
中繼資料
TFLite 模型的] 欄位
結構定義
並在名稱下方指定 "TFLITE_METADATA"
部分模型可能含有相關聯的檔案
例如分類標籤
檔案。
這些檔案會以 ZIP 格式串連至原始模型檔案的結尾
使用 ZipFile "append"
模式 ('a'
模式)。TFLite
翻譯模式能夠以和先前相同的方式使用新檔案格式。請參閱 Pack
關聯檔案。
請參閱下方操作說明,瞭解如何填入、視覺化及讀取中繼資料。
設定中繼資料工具
在將中繼資料新增至模型之前,需要有 Python 程式設計 執行 TensorFlow 的環境設定作業查閱詳盡的指南 請前往這裡進行設定。
設定 Python 程式設計環境後,您需要安裝 其他工具:
pip install tflite-support
LiteRT 中繼資料工具支援 Python 3。
使用 Flatbuffers Python API 新增中繼資料
模型中繼資料包含三個部分 結構定義:
- 模型資訊:模型與項目的整體說明
例如授權條款詳情請見
ModelMetadata。
- 輸入資訊:輸入內容和預先處理的說明
例如正規化等詳情請見
SubGraphMetadata.input_tensor_metadata。
- 輸出資訊:輸出內容的說明和 需要進行後續處理,例如對應至標籤詳情請見 SubGraphMetadata.output_tensor_metadata。
- 輸入資訊:輸入內容和預先處理的說明
例如正規化等詳情請見
SubGraphMetadata.input_tensor_metadata。
由於 LiteRT 目前僅支援單一子圖表,因此
LiteRT 程式碼產生器
以及 Android Studio 機器學習繫結
功能
將使用 ModelMetadata.name
和 ModelMetadata.description
,而不是
SubGraphMetadata.name
和 SubGraphMetadata.description
(用於顯示裝置)
中繼資料和產生程式碼
支援的輸入 / 輸出類型
輸入和輸出的 LiteRT 中繼資料並未針對特定 具體來說是輸入和輸出類型其實並不重要 模型仍會運作,前提是輸入和輸出類型 下列項目或下列項目的組合,可以使用 TensorFlow 支援 Lite 中繼資料:
- 特徵 - 不是帶正負號整數或 float32 的數字。
- 圖片 - 中繼資料目前支援 RGB 和灰階圖片。
- 定界框 - 矩形定界框。結構定義支援 a 各種編號 配置。
封裝相關聯的檔案
LiteRT 模型可能會有不同的相關檔案。例如: 自然語言模型通常會有詞彙檔案,將字詞對應至 編號;分類模型可能有標籤檔案 指明物件類別 如果沒有關聯檔案 (如果有的話),模型將無法正常運作。
您現在可以透過中繼資料,將相關聯的檔案與模型一起封裝
Python 程式庫。新的 LiteRT 模型會成為 ZIP 檔案,當中包含
模型和相關檔案的資訊可以與一般郵遞區號解壓縮
工具。這個新模型格式會繼續使用相同的副檔名 .tflite
。這項服務
與現有的 TFLite 架構和解譯器相容。請參閱「封裝中繼資料」
複製到
模型。
相關的檔案資訊可以記錄在中繼資料中。視乎
檔案類型和附加檔案的位置 (例如 ModelMetadata
、
SubGraphMetadata
和 TensorMetadata
),也就是 LiteRT Android 程式碼
產生器可能會套用相關的前後對照
自動處理到物件請參閱<Codegen 用法>的第 節
每個關聯檔案
類型
建立 Deployment 資訊清單
正規化和量化參數
正規化是機器學習的常見資料預先處理技術。 正規化的目標是將值變更為共通的量表 用來表示值範圍的差異
模型量化是一種技巧 可降低權重的精確度表示法 儲存和運算作業的啟動功能。
在預先處理和後續處理、正規化和量化方面 兩個獨立步驟以下是問題的詳細說明:
正規化 | 量化 | |
---|---|---|
「 參數值 輸入圖片 MobileNet 可用於浮動和 量化模型 。 |
浮點模型: - 平均值:127.5 - std:127.5 數量模型: - 平均值:127.5 - 標準:127.5 |
浮點模型: - 零點:0 - 比例:1.0 數量模型: - 零點:128.0 - scale:0.0078125f |
何時應叫用? |
輸入內容:如果輸入內容 資料經過正規化處理的 訓練、輸入內容 推論需求 正規化 。 輸出:輸出 一般情況會經過正規化處理 |
浮點模型能
也不必量化 量化模型 或者可能不需要 前後測中的量化 和資料處理之間視情況而定 儲存資料類型 輸入/輸出張量 - 浮點張量:否 前後測中的量化 來處理所需資料Quant 運算和量級運算 並放入模型中 圖表。 - int8/uint8 張量: 需要量化 事前/事後處理 |
公式 |
正規化輸入 = (輸入 - 平均值) / std |
量化輸入值:
q = f / 尺 + zeroPoint 去量化 輸出: f = (q - 零點) * 縮放 |
哪裡可以查看 參數 |
由模型建立者填入
並儲存在模型中
中繼資料
NormalizationOptions |
自動填入依據: TFLite 轉換工具 儲存在 tflite 模型中 檔案。 |
如何取得 參數呢? | 透過
MetadataExtractor API
[2]。
|
穿越時空
Tensor API [1] 或
透過
MetadataExtractor API
[2]。 |
浮點值和量化 共用相同的 值呢? | 是,浮點值和量化值 都具有相同的 正規化 參數 | 否,浮點模型會 也不必量化 |
有 TFLite 程式碼 產生器或 Android Studio 機器學習繫結 自動產生 該怎麼辦? | 是 |
是 |
[1] LiteRT Java
API
和 LiteRT C++
API。
[2] 中繼資料擷取器資料庫
處理 uint8 模型的圖片資料時,正規化和量化 有時會略過。即使像素值介於 [0, 255]。但一般而言,在您處理資料時,應一律根據 常態化和量化參數
範例
我們提供多種範例,說明應如何填入不同格式的中繼資料 這裡有幾種模型
圖片分類
下載指令碼 這裡 ,會將中繼資料填入 mobilenet_v1_0.75_160_quantized.tflite. 按照以下方式執行指令碼:
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
如要填入其他圖片分類模型的中繼資料,請新增模型規格 人喜歡 本 。本指南的其餘部分將特別介紹 加入一些圖片分類範例來說明關鍵元素
深入瞭解圖片分類範例
款式資訊
中繼資料的第一步是建立新的模型資訊:
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.")
輸入 / 輸出資訊
本節說明如何說明模型的輸入和輸出簽章。 自動程式碼產生器可能會根據這些中繼資料,在 來處理程式碼如何建立張量的相關輸入或輸出資訊:
# Creates input info.
input_meta = _metadata_fb.TensorMetadataT()
# Creates output info.
output_meta = _metadata_fb.TensorMetadataT()
圖片輸入
圖片是機器學習的常見輸入類型。LiteRT 中繼資料 支援色域和預先處理資訊,如 以便處理正規化的情況不需要手動規格圖片尺寸 因為已經由輸入張量的形狀提供 由系統自動推測出來
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
標籤輸出
您可以使用以下程式碼,透過關聯檔案將標籤對應至輸出張量
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]
建立中繼資料 Flatbuffers
下列程式碼會合併模型資訊與輸入和輸出內容 每個 ACL 都由一或多個項目組成 而這些項目包含兩項資訊
# 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()
將中繼資料和相關聯的檔案封裝至模型
建立中繼資料 Flatbuffers 後,中繼資料和標籤檔案就會
已透過 populate
方法寫入 TFLite 檔案:
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()
透過這個 API,您可以將任意數量的相關檔案封裝至模型
load_associated_files
。不過,您至少要封裝這些檔案
中繼資料並列示在中繼資料內在這個範例中,如果將標籤檔案封裝為
強制規定。
以視覺化方式呈現中繼資料
您可以使用 Netron 查看
也能將 LiteRT 模型的中繼資料
使用 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 也支援透過 Android Studio ML 顯示中繼資料。 繫結 功能。
中繼資料版本管理
中繼資料 結構定義 都有版本編號的語意化編號 結構定義檔案以及 Flatbuffers 檔案識別, 與實際版本相容性
語意版本編號
中繼資料結構定義是由 Semantic 版本管理
編號,
例如 MAJOR.MINOR.PATCH可根據規則追蹤結構定義異動
請按這裡。
查看歷史沿革
欄位
已加至版本 1.0.0
。
Flatbuffers 檔案識別
語意版本管理可以在遵循規則的情況下保證相容性,但前提是 不代表實際不相容。提高 MAJOR 的數值時 但不一定代表回溯相容性故障。因此,我們 使用 Flatbuffers 檔案 身分、 file_identifier, 代表中繼資料結構定義的真正相容性。檔案 ID 為 長度為 4 個字元此政策固定為特定中繼資料結構定義,而非 隨時可能變動如果中繼資料結構定義的回溯相容性 「file_identifier」會因為某些原因而損壞,舉例來說, 從「M001」變為「M002」File_identifier 預期變更幅度會大幅減少 更新的頻率比 metadata_version 更高
中繼資料剖析器的最低版本需求
必要的中繼資料剖析器最少
版本
是中繼資料剖析器 (Flatbuffers 產生的程式碼) 的最低版本,
可以完整讀取中繼資料 Flatbuffers。版本實際上是
而所有已填入欄位的版本編號,以及
最小相容的版本 (以檔案 ID 表示)。最低
而 Deployment 將自動填入必要的中繼資料剖析器版本
MetadataPopulator
(當中繼資料填入 TFLite 模型時)。詳情請參閱
中繼資料擷取器,進一步瞭解如何
且使用的是最低必要中繼資料剖析器版本。
讀取模型的中繼資料
中繼資料擷取器程式庫可讓您輕鬆讀取中繼資料 來自不同平台模型的關聯檔案 (請參閱 Java 版本 和 C++ version)。 您可以使用其他語言的 Flatbuffers 程式庫。
以 Java 讀取中繼資料
如要在 Android 應用程式中使用中繼資料擷取器程式庫,建議您使用
LiteRT 中繼資料 AAR,
MavenCentral.
其中包含 MetadataExtractor
類別和 FlatBuffers Java
中繼資料的繫結
結構定義
和模型
結構定義。
您可以在 build.gradle
依附元件中指定此屬性,如下所示:
dependencies {
implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0'
}
如要使用夜間快照,請確定已加入 Sonatype 快照 存放區
您可以使用指向該 ByteBuffer
點的 ByteBuffer
來初始化 MetadataExtractor
物件
對應至模型:
public MetadataExtractor(ByteBuffer buffer);
ByteBuffer
在整個生命週期內必須保持不變
MetadataExtractor
物件。如果 Flatbuffers 檔案,初始化作業可能會失敗
模型中繼資料的 ID 與中繼資料剖析器的 ID 不相符。詳情請見
中繼資料版本管理。
比對檔案 ID 後,中繼資料擷取工具就能順利讀取 由 Flatbuffers 開發 具前瞻性和回溯相容性機制不過,未來的欄位 舊的中繼資料擷取器無法擷取結構定義。規定的最低 剖析器版本的中繼資料 表示可讀取中繼資料的中繼資料剖析器最低版本 完整的扁平緩衝區。您可以使用下列方法確認 符合必要的剖析器版本條件:
public final boolean isMinimumParserVersionSatisfied();
可以在沒有中繼資料的情況下傳入模型。不過,叫用方法
讀取中繼資料會導致執行階段錯誤。您可以使用
叫用 hasMetadata
方法,如下所示:
public boolean hasMetadata();
MetadataExtractor
提供便利的功能,可讓您
輸入/輸出張量中繼資料。例如:
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);
雖然 LiteRT 模型
結構定義
支援多個子圖表,TFLite 解譯器目前僅支援
單一子圖表。因此,MetadataExtractor
會在輸入內容中省略子圖表索引
引數。
讀取模型中的關聯檔案
包含中繼資料和相關檔案的 LiteRT 模型基本上是 ZIP 檔案,使用常見的壓縮工具進行解壓縮,以取得關聯檔案。 例如,您可以將檔案解壓縮 mobilenet_v1_0.75_160_quantized 然後擷取模型中的標籤檔案,如下所示:
$ 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
您也可以透過中繼資料擷取器程式庫讀取相關聯的檔案。
在 Java 中,將檔案名稱傳遞至 MetadataExtractor.getAssociatedFile
方法:
public InputStream getAssociatedFile(String fileName);
同樣地,在 C++ 中,您也可以使用 方法完成這項操作
ModelMetadataExtractor::GetAssociatedFile
:
tflite::support::StatusOr<absl::string_view> GetAssociatedFile(
const std::string& filename) const;