도움말 Kaggle에 TensorFlow과 그레이트 배리어 리프 (Great Barrier Reef)를 보호하기 도전에 참여

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

TensorFlow Lite 메타데이터는 모델 설명에 대한 표준을 제공합니다. 메타데이터는 모델이 하는 일과 해당 입력/출력 정보에 대한 중요한 지식 소스입니다. 메타데이터는 두 가지 모두로 구성됩니다.

에 게시 된 모든 이미지 모델 TensorFlow Lite는 모델을 호스팅 하고 TensorFlow 허브는 메타 데이터로 채워되었다.

메타데이터 형식의 모델

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

모델 메타 데이터에 정의되어 metadata_schema.fbs 하는 FlatBuffer의 파일을. 도 1에 도시 된 바와 같이,이 저장되는 메타 데이터 의 필드 TFLite 모델 스키마 이름 아래 "TFLITE_METADATA" . 일부 모델은 다음과 같은 관련 파일을 함께 제공 할 수 분류 라벨 파일 . 이러한 파일은 ZipFile를 사용하여 우편으로 원래 모델 파일의 끝에 연결된다 "APPEND"모드 ( 'a' 모드). TFLite Interpreter는 이전과 동일한 방식으로 새 파일 형식을 사용할 수 있습니다. 참조 팩에게 관련 파일을 자세한 내용은.

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

메타데이터 도구 설정

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

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

pip install tflite-support

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

Flatbuffers Python API를 사용하여 메타데이터 추가

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

  1. 모델 정보 - 전체 모델에 대한 설명뿐만 아니라 라이센스 조건 등의 항목. 참조 ModelMetadata를 .
  2. 입력 정보 - 입력의 설명 및 사전 처리는 정규화 등이 필요. 참조 SubGraphMetadata.input_tensor_metadata을 .
  3. 출력 정보 - 출력 및 사후 처리에 대한 설명은 라벨에 매핑 등이 필요합니다. 참조 SubGraphMetadata.output_tensor_metadata을 .

TensorFlow 라이트는이 시점에서 하나의 서브 그래프를 지원하기 때문에, TensorFlow 라이트 코드 생성기안드로이드 스튜디오 ML 바인딩 기능을 사용 ModelMetadata.nameModelMetadata.description 대신 SubGraphMetadata.nameSubGraphMetadata.description , 메타 데이터를 표시하고 생성하는 코드입니다.

지원되는 입력/출력 유형

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

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

관련 파일 압축

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

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

관련 파일 정보는 메타데이터에 기록될 수 있습니다. 파일 유형 및 파일 (즉, 부착 위치에 따라 ModelMetadata , SubGraphMetadataTensorMetadata ) TensorFlow 라이트 안드로이드 코드 생성기는 객체 자동 전 / 후 처리를 대응 적용 할 수있다. 참조 각 연관 파일 형식의 <CODEGEN 사용> 섹션 자세한 내용은 스키마를.

정규화 및 양자화 매개변수

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

양자화 모델은 저장 및 계산 모두에 대한 무게와 선택적 활성화의 감소 된 정밀도 표현을 가능하게하는 기술이다.

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

표준화 양자화

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




언제 호출합니까?


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


공식


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

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

[1] TensorFlow 라이트 자바 APITensorFlow 라이트 C ++ API .
[2] 메타 데이터 추출기 라이브러리

uint8 모델의 이미지 데이터를 처리할 때 정규화 및 양자화를 건너뛰는 경우가 있습니다. 픽셀 값이 [0, 255] 범위에 있을 때 그렇게 하는 것이 좋습니다. 그러나 일반적으로 적용 가능한 경우 항상 정규화 및 양자화 매개변수에 따라 데이터를 처리해야 합니다.

TensorFlow 라이트 태스크 라이브러리는 사용자가 설정하는 경우에 대한 정상화를 처리 할 수 NormalizationOptions 메타 데이터에. 양자화 및 역양자화 처리는 항상 캡슐화됩니다.

여기에서 다양한 유형의 모델에 대해 메타데이터를 채우는 방법에 대한 예를 찾을 수 있습니다.

이미지 분류

스크립트를 다운로드 여기에 메타 데이터가있는 웁니다 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()

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

메타 데이터 Flatbuffers가 생성되면, 메타 데이터 및 레이블 파일을 통해 TFLite 파일에 기록된다 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()

당신은을 통해 모델에 원하는 수 많은 관련 파일로 포장 할 수 load_associated_files . 그러나 최소한 메타데이터에 문서화된 파일을 압축해야 합니다. 이 예에서는 레이블 파일을 반드시 패킹해야 합니다.

메타데이터 시각화

당신은 사용할 수 있습니다 Netron를 메타 데이터를 시각화하거나 사용하여 JSON 형식으로 TensorFlow 라이트 모델의 메타 데이터를 읽을 수 있습니다 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)

안드로이드 스튜디오는 또한을 통해 메타 데이터를 표시하는 지원 안드로이드 스튜디오 ML 바인딩 기능 .

메타데이터 버전 관리

메타 데이터 스키마는 스키마 파일의 변경 사항을 추적하고, 진정한 버전 호환성을 나타내는 Flatbuffers 파일 식별에 의해 시맨틱 버전 번호가 모두 버전입니다.

시맨틱 버전 번호

메타 데이터 스키마에 의해 버전입니다 시맨틱 버전 번호 등 MAJOR.MINOR.PATCH 등. 이 규칙에 따라 스키마 변경 사항을 추적 여기 . 참고 항목 필드의 역사 버전 이후에 추가 1.0.0 .

플랫 버퍼 파일 식별

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

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

필요 최소한의 메타 데이터 파서 판 전체의 메타 데이터를 읽을 수 Flatbuffers 메타 데이터 파서의 최소 버전합니다 (Flatbuffers 생성 한 코드)이다. 버전은 채워진 모든 필드의 버전 중에서 사실상 가장 큰 버전 번호이며 파일 식별자로 표시된 가장 작은 호환 버전입니다. 최소 필요한 메타 데이터 파서 버전이 자동적으로 채워 MetadataPopulator 메타 데이터가 TFLite 모델로 채워지면. 참고 항목 메타 데이터 추출을 필요한 최소한의 메타 데이터 파서 버전을 사용하는 방법에 대한 자세한 내용은.

모델에서 메타데이터 읽기

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

Java에서 메타데이터 읽기

안드로이드 응용 프로그램의 메타 데이터 추출기 라이브러리를 사용하기 위해, 우리는 사용하는 것이 좋습니다 TensorFlow 라이트 메타 데이터 AAR은 MavenCentral에서 호스팅 . 그것은 포함 MetadataExtractor 클래스뿐만 아니라에 대한 FlatBuffers 자바 바인딩 메타 데이터 스키마모델 스키마를 .

당신은 당신이 지정할 수 있습니다 build.gradle 다음과 같은 종속 관계 :

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

야간 스냅 샷을 사용하려면, 당신이 추가 한 것을 확인 Sonatype 스냅 샷 저장소를 .

당신은 초기화 할 수 있습니다 MetadataExtractor 와 객체를 ByteBuffer 그 모델로 점 :

public MetadataExtractor(ByteBuffer buffer);

ByteBuffer 의 전체 수명 동안 변경되지 않은 상태로 유지해야한다 MetadataExtractor 객체입니다. 모델 메타데이터의 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 라이트 모델 스키마가 여러 서브 그래프 지원의 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

Metadata Extractor 라이브러리를 통해 관련 파일을 읽을 수도 있습니다.

자바에서에 파일 이름을 전달 MetadataExtractor.getAssociatedFile 방법 :

public InputStream getAssociatedFile(String fileName);

이와 비슷하게, C ++에서이는 방법으로 수행 할 수 있습니다 ModelMetadataExtractor::GetAssociatedFile :

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