오늘 현지 TensorFlow Everywhere 이벤트에 참석하세요!
이 페이지는 Cloud Translation API를 통해 번역되었습니다.
Switch to English

TensorFlow Lite 모델에 메타 데이터 추가

TensorFlow Lite 메타 데이터는 모델 설명에 대한 표준을 제공합니다. 메타 데이터는 모델이 수행하는 작업과 입력 / 출력 정보에 대한 중요한 지식 소스입니다. 메타 데이터는

TensorFlow Lite 호스팅 모델TensorFlow Hub 에 게시 된 모든 이미지 모델은 메타 데이터로 채워졌습니다.

메타 데이터 형식이있는 모델

model_with_metadata
그림 1. 메타 데이터 및 관련 파일이있는 TFLite 모델.

모델 메타 데이터에 정의되어 metadata_schema.fbs 하는 FlatBuffer의 파일을. 그림 1에서 볼 수 있듯이 TFLite 모델 스키마메타 데이터 필드에 "TFLITE_METADATA" 라는 이름으로 저장됩니다. 일부 모델에는 분류 레이블 파일 과 같은 관련 파일이 함께 제공 될 수 있습니다 . 이러한 파일은 ZipFile "추가"모드 ( 'a' 모드)를 사용하여 ZIP으로 원본 모델 파일의 끝에 연결됩니다. TFLite Interpreter는 이전과 동일한 방식으로 새 파일 형식을 사용할 수 있습니다. 자세한 정보 는 연관된 파일 압축 을 참조하십시오.

메타 데이터를 채우고 시각화하고 읽는 방법은 아래 지침을 참조하십시오.

메타 데이터 도구 설정

모델에 메타 데이터를 추가하기 전에 TensorFlow를 실행하기위한 Python 프로그래밍 환경 설정이 필요합니다. 이를 설정하는 방법에 대한 자세한 가이드는 여기에 있습니다 .

Python 프로그래밍 환경을 설정 한 후 추가 도구를 설치해야합니다.

pip install tflite-support

TensorFlow Lite 메타 데이터 도구는 Python 2와 Python 3을 모두 지원합니다.

메타 데이터 추가

스키마 의 모델 메타 데이터에는 세 부분이 있습니다.

  1. 모델 정보 -모델 및 라이선스 조건과 같은 항목에 대한 전체 설명입니다. ModelMetadata를 참조하십시오.
  2. 입력 정보 -정규화와 같이 필요한 입력 및 전처리에 대한 설명입니다. SubGraphMetadata.input_tensor_metadata를 참조하십시오.
  3. 출력 정보 -라벨 매핑과 같이 필요한 출력 및 사후 처리에 대한 설명입니다. SubGraphMetadata.output_tensor_metadata를 참조하십시오.

이 시점에서 TensorFlow Lite는 단일 하위 그래프 만 지원하므로 TensorFlow Lite 코드 생성기Android 스튜디오 ML 바인딩 기능 은 메타 데이터를 표시하고 코드를 생성 할 때 SubGraphMetadata.nameSubGraphMetadata.description 대신 ModelMetadata.nameModelMetadata.description 을 사용합니다.

지원되는 입력 / 출력 유형

입력 및 출력을위한 TensorFlow Lite 메타 데이터는 특정 모델 유형이 아니라 입력 및 출력 유형을 염두에두고 설계되었습니다. 입력 및 출력 유형이 다음 또는 다음 조합으로 구성되는 한 모델이 기능적으로 수행하는 작업은 중요하지 않으며 TensorFlow Lite 메타 데이터에서 지원됩니다.

  • 기능-부호없는 정수 또는 float32 인 숫자.
  • 이미지-메타 데이터는 현재 RGB 및 그레이 스케일 이미지를 지원합니다.
  • 경계 상자-직사각형 모양 경계 상자. 스키마는 다양한 번호 매기기 체계를 지원 합니다 .

관련 파일 압축

TensorFlow Lite 모델은 다른 관련 파일과 함께 제공 될 수 있습니다. 예를 들어, 자연어 모델에는 일반적으로 단어 조각을 단어 ID에 매핑하는 어휘 파일이 있습니다. 분류 모델에는 객체 범주를 나타내는 레이블 파일이있을 수 있습니다. 연관된 파일이 없으면 (있는 경우) 모델이 제대로 작동하지 않습니다.

이제 관련 파일을 메타 데이터 Python 라이브러리를 통해 모델과 함께 번들로 제공 할 수 있습니다. 새로운 TensorFlow Lite 모델은 모델과 관련 파일을 모두 포함하는 zip 파일이됩니다. 일반적인 zip 도구로 압축을 풀 수 있습니다. 이 새로운 모델 형식은 동일한 파일 확장자 인 .tflite 계속 사용합니다. 기존 TFLite 프레임 워크 및 인터프리터와 호환됩니다. 자세한 내용은 mtadata 및 관련 파일을 모델압축 을 참조하십시오.

관련 파일 정보는 메타 데이터에 기록 될 수 있습니다. 파일 유형 및 파일이 첨부 된 위치 (예 : ModelMetadata , SubGraphMetadataTensorMetadata )에 따라 TensorFlow Lite Android 코드 생성기 는 해당 사전 / 사후 처리를 객체에 자동으로 적용 할 수 있습니다. 자세한 내용 스키마에있는 각 관련 파일 유형의 <Codegen 사용> 섹션 을 참조하십시오.

정규화 및 양자화 매개 변수

정규화는 기계 학습에서 일반적인 데이터 전처리 기술입니다. 정규화의 목표는 값 범위의 차이를 왜곡하지 않고 값을 공통 척도로 변경하는 것입니다.

모델 양자화 는 가중치의 정밀도 표현을 줄이고 선택적으로 저장 및 계산을위한 활성화를 허용하는 기술입니다.

전처리 및 후 처리 측면에서 정규화와 양자화는 두 개의 독립적 인 단계입니다. 세부 사항은 다음과 같습니다.

표준화 양자화

각각 float 및 quant 모델에 대한 MobileNet의 입력 이미지 매개 변수 값의 예입니다.
플로트 모델 :
-평균 : 127.5
-표준 : 127.5
Quant 모델 :
-평균 : 127.5
-표준 : 127.5
플로트 모델 :
-zeroPoint : 0
-규모 : 1.0
Quant 모델 :
-영점 : 128.0
-규모 : 0.0078125f




언제 호출해야합니까?


입력 : 입력 데이터가 학습에서 정규화되면 추론의 입력 데이터도 이에 따라 정규화되어야합니다.
출력 : 출력 데이터는 일반적으로 정규화되지 않습니다.
부동 모델 에는 양자화가 필요하지 않습니다.
양자화 된 모델 은 사전 / 사후 처리에서 양자화가 필요할 수도 있고 필요하지 않을 수도 있습니다. 입력 / 출력 텐서의 데이터 유형에 따라 다릅니다.
-부동 텐서 : 사전 / 사후 처리에서 양자화가 필요하지 않습니다. Quant op 및 dequant op는 모델 그래프에 구워집니다.
-int8 / uint8 텐서 : 사전 / 사후 처리에서 양자화가 필요합니다.


공식


normalized_input = (입력-평균) / 표준
입력을위한 양자화 :
q = f / 스케일 + 영점
출력을 위해 역 양자화 :
f = (q-zeroPoint) * 스케일

매개 변수는 어디에 있습니까
모델 생성자가 채우고 모델 메타 데이터에 NormalizationOptions 로 저장 됨 TFLite 변환기에 의해 자동으로 채워지고 tflite 모델 파일에 저장됩니다.
매개 변수를 얻는 방법? MetadataExtractor API를 통해 [2] TFLite Tensor API [1] 또는 MetadataExtractor API [2]를 통해
float 및 quant 모델은 동일한 값을 공유합니까? 예, float 및 quant 모델은 동일한 정규화 매개 변수를 갖습니다. 아니요, float 모델에는 양자화가 필요하지 않습니다.
TFLite 코드 생성기 또는 Android Studio ML 바인딩은 데이터 처리에서 자동으로 생성합니까?

[1] TensorFlow Lite Java APITensorFlow Lite 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()

이미지 입력

이미지는 기계 학습을위한 일반적인 입력 유형입니다. TensorFlow Lite 메타 데이터는 색 공간과 같은 정보 및 정규화와 같은 전처리 정보를 지원합니다. 이미지의 치수는 이미 입력 텐서의 모양에 의해 제공되고 자동으로 추론 될 수 있으므로 수동 지정이 필요하지 않습니다.

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]

메타 데이터 플랫 버퍼 생성

다음 코드는 모델 정보를 입력 및 출력 정보와 결합합니다.

# 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()

모델에 메타 데이터 및 관련 파일 압축

메타 데이터 플랫 버퍼가 생성되면, 메타 데이터와 라벨 파일은 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()

load_associated_files 통해 원하는만큼의 관련 파일을 모델에 압축 할 수 있습니다. 그러나 메타 데이터에 문서화 된 파일은 적어도 압축해야합니다. 이 예에서는 레이블 파일 압축이 필수입니다.

메타 데이터 시각화

Netron 을 사용하여 메타 데이터를 시각화하거나 MetadataDisplayer를 사용하여 TensorFlow Lite 모델의 MetadataDisplayer json 형식으로 읽을 수 있습니다.

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 스튜디오는 Android 스튜디오 ML 바인딩 기능을 통한 메타 데이터 표시도 지원 합니다 .

메타 데이터 버전 관리

메타 데이터 스키마 는 스키마 파일의 변경 사항을 추적하는 의미 체계 버전 번호와 실제 버전 호환성을 나타내는 Flatbuffers 파일 식별에 의해 버전이 지정됩니다.

시맨틱 버전 번호

메타 데이터 스키마는 MAJOR.MINOR.PATCH와 같은 의미 체계 버전 번호로 버전 이 지정됩니다. 여기 에서 규칙에 따라 스키마 변경을 추적 합니다 . 버전 1.0.0 이후에 추가 된 필드기록을 확인하세요.

Flatbuffers 파일 식별

시맨틱 버전 관리는 규칙을 따르는 경우 호환성을 보장하지만 진정한 비 호환성을 의미하지는 않습니다. MAJOR 번호를 올릴 때 반드시 이전 버전과의 호환성이 깨지는 것은 아닙니다. 따라서 메타 데이터 스키마의 진정한 호환성을 나타 내기 위해 Flatbuffers 파일 식별file_identifier 를 사용합니다. 파일 식별자는 정확히 4 자입니다. 특정 메타 데이터 스키마에 고정되어 있으며 사용자가 변경할 수 없습니다. 어떤 이유로 메타 데이터 스키마의 이전 버전과의 호환성이 깨져야하는 경우 file_identifier가 예를 들어 "M001"에서 "M002"로 올라갑니다. File_identifier는 metadata_version보다 훨씬 덜 자주 변경 될 것으로 예상됩니다.

필요한 최소 메타 데이터 파서 버전

필요한 최소 메타 데이터 파서 버전 은 메타 데이터 플랫 버퍼를 전체적으로 읽을 수있는 메타 데이터 파서 (플랫 버퍼 생성 코드)의 최소 버전입니다. 버전은 채워진 모든 필드의 버전 중 가장 큰 버전 번호이며 파일 식별자로 표시되는 가장 작은 호환 버전입니다. 필요한 최소 메타 데이터 파서 버전은 메타 데이터가 TFLite 모델에 채워질 때 MetadataPopulator 의해 자동으로 채워집니다. 필요한 최소 메타 데이터 구문 분석기 버전이 사용되는 방법에 대한 자세한 정보는 메타 데이터 추출기 를 참조하십시오.

모델에서 메타 데이터 읽기

Metadata Extractor 라이브러리는 서로 다른 플랫폼의 모델에서 메타 데이터 및 관련 파일을 읽을 수있는 편리한 도구입니다 ( Java 버전C ++ 버전 참조 ). Flatbuffers 라이브러리를 사용하여 다른 언어로 고유 한 메타 데이터 추출 도구를 빌드 할 수 있습니다.

자바로 메타 데이터 읽기

Android 앱에서 Metadata Extractor 라이브러리를 사용하려면 JCenter에서 호스팅되는 TensorFlow Lite 메타 데이터 AAR을 사용하는 것이 좋습니다. 여기에는 MetadataExtractor 클래스와 메타 데이터 스키마모델 스키마에 대한 FlatBuffers Java 바인딩이 포함됩니다.

다음과 같이 build.gradle 종속성에서이를 지정할 수 있습니다.

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

모델을 가리키는 ByteBuffer 를 사용하여 MetadataExtractor 개체를 초기화 할 수 있습니다.

public MetadataExtractor(ByteBuffer buffer);

ByteBufferMetadataExtractor 개체의 전체 수명 동안 변경되지 않은 상태로 유지되어야합니다. 모델 메타 데이터의 Flatbuffers 파일 식별자가 메타 데이터 파서의 식별자와 일치하지 않으면 초기화가 실패 할 수 있습니다. 자세한 내용은 메타 데이터 버전 관리 를 참조하세요.

일치하는 파일 식별자를 사용하면 메타 데이터 추출기는 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);

TensorFlow Lite 모델 스키마 는 여러 하위 그래프를 지원하지만 TFLite 인터프리터는 현재 단일 하위 그래프 만 지원합니다. 따라서 MetadataExtractor 는 메서드에서 입력 인수로 하위 그래프 인덱스를 생략합니다.

모델에서 관련 파일 읽기

메타 데이터 및 관련 파일이있는 TensorFlow Lite 모델은 기본적으로 관련 파일을 가져 오기 위해 일반적인 zip 도구로 압축을 풀 수있는 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 메소드를 사용 ModelMetadataExtractor::GetAssociatedFile 작업을 수행 할 수 있습니다.

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