모바일 애플리케이션 개발자는 일반적으로 다음과 같은 유형이 지정된 객체와 상호작용합니다. 비트맵 또는 프리미티브(예: 정수) 하지만 LiteRT 인터프리터는 온디바이스 머신러닝 모델을 실행하는 API는 다음과 같은 형식으로 텐서를 사용합니다. ByteBuffer: 디버그 및 조작하기 어려울 수 있습니다. 이 LiteRT Android 지원 라이브러리 LiteRT 모델의 입력과 출력을 처리하도록 설계되어 있습니다. LiteRT 인터프리터를 더 쉽게 사용할 수 있습니다.
시작하기
Gradle 종속 항목 및 기타 설정 가져오기
.tflite
모델 파일을 Android 모듈의 assets 디렉터리에 복사합니다.
지정할 수도 있습니다 파일을 압축하지 않도록 지정합니다.
LiteRT 라이브러리를 모듈의 build.gradle
파일에 추가합니다.
android {
// Other settings
// Specify tflite file should not be compressed for the app apk
aaptOptions {
noCompress "tflite"
}
}
dependencies {
// Other dependencies
// Import tflite dependencies
implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly-SNAPSHOT'
// The GPU delegate library is optional. Depend on it as needed.
implementation 'com.google.ai.edge.litert:litert-gpu:0.0.0-nightly-SNAPSHOT'
implementation 'com.google.ai.edge.litert:litert-support:0.0.0-nightly-SNAPSHOT'
}
이제 MavenCentral에서 호스팅되는 LiteRT 지원 라이브러리 AAR 서로 다른 버전의 지원 라이브러리에 대해 자세히 알아볼 수 있습니다.
기본적인 이미지 조작 및 변환
LiteRT 지원 라이브러리에는 기본적인 이미지 조작 묶음이 있습니다.
사용할 수 있습니다. 사용하려면 ImagePreprocessor
를 만들고
필요한 작업을 추가합니다. 이미지를 텐서 형식으로 변환하기
필요한 경우 사용할 TensorImage
를 만듭니다.
다음과 같이 입력합니다.
import org.tensorflow.lite.DataType;
import org.tensorflow.lite.support.image.ImageProcessor;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.image.ops.ResizeOp;
// Initialization code
// Create an ImageProcessor with all ops required. For more ops, please
// refer to the ImageProcessor Architecture section in this README.
ImageProcessor imageProcessor =
new ImageProcessor.Builder()
.add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR))
.build();
// Create a TensorImage object. This creates the tensor of the corresponding
// tensor type (uint8 in this case) that the LiteRT interpreter needs.
TensorImage tensorImage = new TensorImage(DataType.UINT8);
// Analysis code for every frame
// Preprocess the image
tensorImage.load(bitmap);
tensorImage = imageProcessor.process(tensorImage);
텐서의 DataType
는
메타데이터 추출기 라이브러리
다른 모델 정보를 확인할 수 있습니다
기본 오디오 데이터 처리
LiteRT 지원 라이브러리는 TensorAudio
클래스 래핑도 정의합니다.
몇 가지 기본적인 오디오 데이터 처리 방법을 다룹니다. 주로 함께 사용됩니다.
AudioRecord
링 버퍼에서 오디오 샘플을 캡처합니다.
import android.media.AudioRecord;
import org.tensorflow.lite.support.audio.TensorAudio;
// Create an `AudioRecord` instance.
AudioRecord record = AudioRecord(...)
// Create a `TensorAudio` object from Android AudioFormat.
TensorAudio tensorAudio = new TensorAudio(record.getFormat(), size)
// Load all audio samples available in the AudioRecord without blocking.
tensorAudio.load(record)
// Get the `TensorBuffer` for inference.
TensorBuffer buffer = tensorAudio.getTensorBuffer()
출력 객체 만들기 및 모델 실행
모델을 실행하기 전에 작업을 수행할 컨테이너 객체를 다음과 같이 결과를 저장합니다.
import org.tensorflow.lite.DataType;
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;
// Create a container for the result and specify that this is a quantized model.
// Hence, the 'DataType' is defined as UINT8 (8-bit unsigned integer)
TensorBuffer probabilityBuffer =
TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);
모델 로드 및 추론 실행:
import java.nio.MappedByteBuffer;
import org.tensorflow.lite.InterpreterFactory;
import org.tensorflow.lite.InterpreterApi;
// Initialise the model
try{
MappedByteBuffer tfliteModel
= FileUtil.loadMappedFile(activity,
"mobilenet_v1_1.0_224_quant.tflite");
InterpreterApi tflite = new InterpreterFactory().create(
tfliteModel, new InterpreterApi.Options());
} catch (IOException e){
Log.e("tfliteSupport", "Error reading model", e);
}
// Running inference
if(null != tflite) {
tflite.run(tImage.getBuffer(), probabilityBuffer.getBuffer());
}
결과 액세스
개발자는 Cloud Build API를 통해
probabilityBuffer.getFloatArray()
모델이 양자화된 출력을 생성하는 경우
결과를 변환해야 합니다 MobileNet 양자화 모델의 경우 개발자는
각 출력값을 255로 나누어
각 카테고리에 대해 0 (가능성이 가장 낮음)부터 1 (가장 높음) 사이로 표시합니다.
선택사항: 결과에 결과 매핑
개발자는 선택적으로 결과를 라벨에 매핑할 수도 있습니다. 먼저, 텍스트를 복사합니다 라벨이 포함된 파일을 모듈의 assets 디렉터리에 복사합니다. 다음으로 라벨을 로드합니다. 파일을 업로드할 수 있습니다.
import org.tensorflow.lite.support.common.FileUtil;
final String ASSOCIATED_AXIS_LABELS = "labels.txt";
List<String> associatedAxisLabels = null;
try {
associatedAxisLabels = FileUtil.loadLabels(this, ASSOCIATED_AXIS_LABELS);
} catch (IOException e) {
Log.e("tfliteSupport", "Error reading label file", e);
}
다음 스니펫은 확률을 카테고리 라벨:
import java.util.Map;
import org.tensorflow.lite.support.common.TensorProcessor;
import org.tensorflow.lite.support.common.ops.NormalizeOp;
import org.tensorflow.lite.support.label.TensorLabel;
// Post-processor which dequantize the result
TensorProcessor probabilityProcessor =
new TensorProcessor.Builder().add(new NormalizeOp(0, 255)).build();
if (null != associatedAxisLabels) {
// Map of labels and their corresponding probability
TensorLabel labels = new TensorLabel(associatedAxisLabels,
probabilityProcessor.process(probabilityBuffer));
// Create a map to access the result based on label
Map<String, Float> floatMap = labels.getMapWithFloatValue();
}
현재 사용 사례 범위
현재 버전의 LiteRT 지원 라이브러리는 다음을 포함합니다.
- 일반적인 데이터 유형 (float, uint8, images, 오디오 및 이러한 객체의 배열) tflite 모델의 입력 및 출력으로 사용할 수 있습니다.
- 기본 이미지 작업 (이미지 자르기, 크기 조절 및 회전)을 제공합니다.
- 정규화와 양자화
- 파일 유틸리티
향후 버전에서는 텍스트 관련 애플리케이션에 대한 지원이 개선될 예정입니다.
ImageProcessor 아키텍처
ImageProcessor
의 설계 덕분에 이미지 조작 작업은
미리 정의하고 빌드 프로세스 중에
최적화할 수 있습니다 ImageProcessor
는 현재 세 가지 기본 전처리 작업을 지원합니다.
세 개의 주석이 있습니다.
import org.tensorflow.lite.support.common.ops.NormalizeOp;
import org.tensorflow.lite.support.common.ops.QuantizeOp;
import org.tensorflow.lite.support.image.ops.ResizeOp;
import org.tensorflow.lite.support.image.ops.ResizeWithCropOrPadOp;
import org.tensorflow.lite.support.image.ops.Rot90Op;
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int size = height > width ? width : height;
ImageProcessor imageProcessor =
new ImageProcessor.Builder()
// Center crop the image to the largest square possible
.add(new ResizeWithCropOrPadOp(size, size))
// Resize using Bilinear or Nearest neighbour
.add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR));
// Rotation counter-clockwise in 90 degree increments
.add(new Rot90Op(rotateDegrees / 90))
.add(new NormalizeOp(127.5, 127.5))
.add(new QuantizeOp(128.0, 1/128.0))
.build();
세부정보 더보기 자세한 내용은 여기를 정규화와 양자화의 두 가지 개념입니다.
지원 라이브러리의 최종 목표는
tf.image
드림
사용할 수 있습니다 즉, 변환은 TensorFlow와 동일하며
구현은 운영 체제와 독립적입니다.
개발자는 커스텀 프로세서를 만들 수도 있습니다. 인코더-디코더 아키텍처를 이 사례를 교육 프로세스에 맞게 조정해야 합니다. 즉, 학습과 추론에 모두 전처리를 적용하여 복제할 수 있습니다
양자화
입력 또는 출력 객체(예: TensorImage
또는 TensorBuffer
)를 시작할 때
유형을 DataType.UINT8
또는 DataType.FLOAT32
로 지정해야 합니다.
TensorImage tensorImage = new TensorImage(DataType.UINT8);
TensorBuffer probabilityBuffer =
TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);
TensorProcessor
는 입력 텐서를 양자화하거나 출력을 비양자화하는 데 사용할 수 있음
텐서 등이 포함됩니다 예를 들어 양자화 출력 TensorBuffer
를 처리할 때
개발자는 DequantizeOp
를 사용하여 결과를 부동 소수점으로 비양자화할 수 있음
0과 1 사이의 확률입니다.
import org.tensorflow.lite.support.common.TensorProcessor;
// Post-processor which dequantize the result
TensorProcessor probabilityProcessor =
new TensorProcessor.Builder().add(new DequantizeOp(0, 1/255.0)).build();
TensorBuffer dequantizedBuffer = probabilityProcessor.process(probabilityBuffer);
텐서의 양자화 매개변수는 메타데이터 추출기 라이브러리를 사용하여 BigQuery에서 직접 데이터를 가져올 수 있습니다.