概要
- 背景
- 问题
- 尝试解决问题
- 问题
- 相关问题
背景
我在Firebase服务器上保存了一个自定义的.tflite
模型(https://firebase.google.com/docs/ml-kit/android/use-custom-models)。这是我的自定义超分辨率图像生成对抗网络(GAN)生成器:我输入一张32×32的图像,它会生成一张128×128的超分辨率图像。我正尝试在我的Android应用中使用它。
我按照上面链接中提供的文档进行了操作。
问题
抛出了以下异常:
I/System.out: com.google.firebase.ml.common.FirebaseMLException: 执行Firebase ML任务时发生内部错误
尝试解决问题
分析预期的输入和输出形状
根据Google Colab Python解释器,我的预期输入和输出如下:
[ 1 32 32 3]
class ‘numpy.float32’>
[ 1 128 128 3]
class ‘numpy.float32’>
所以我必须给我的生成器模型一个32x32x3的图像,它必须输出一个128x128x3的图像,一切正常:)。这是一个正常工作的SRGAN生成器。
分析Android应用源码
这是Android应用的源代码…它包括了我的生成器模型的配置和推理运行。还显示了要发送的数据。
配置ML Kit客户端
FirebaseModelDownloadConditions.Builder conditionsBuilder = new FirebaseModelDownloadConditions.Builder().requireWifi();if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 在Android Nougat及更新版本上启用高级条件。 conditionsBuilder = conditionsBuilder .requireCharging();}FirebaseModelDownloadConditions conditions = conditionsBuilder.build();cloudSource = new FirebaseRemoteModel.Builder("srgan") .enableModelUpdates(true) .setInitialDownloadConditions(conditions) .setUpdatesDownloadConditions(conditions) .build();FirebaseModelManager.getInstance().registerRemoteModel(cloudSource);FirebaseModelOptions options = new FirebaseModelOptions.Builder() .setRemoteModelName("srgan") .build();FirebaseModelInterpreter firebaseInterpreter = FirebaseModelInterpreter.getInstance(options);FirebaseModelInputOutputOptions inputOutputOptions = new FirebaseModelInputOutputOptions.Builder() .setInputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{32, 32, 3}) .setOutputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{128, 128, 3}) .build();
定义作为输入发送的数据,一个32x32x3的像素张量(定义byte[][][] pixels
)
Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse("file://" + selected_image_uri));Bitmap bitmapResized = Bitmap.createScaledBitmap(bitmap, 32, 32, false);ByteArrayOutputStream stream = new ByteArrayOutputStream();bitmapResized.compress(Bitmap.CompressFormat.PNG, 100, stream);float[][][] pixels = new float[bitmapResized.getWidth()][bitmapResized.getHeight()][3];for(int i = 0; i < bitmapResized.getWidth(); i++) { for(int j = 0; j < bitmapResized.getHeight(); j++) { pixels[i][j][0] = Color.red(bitmapResized.getPixel(i,j)); pixels[i][j][1] = Color.green(bitmapResized.getPixel(i,j)); pixels[i][j][2] = Color.blue(bitmapResized.getPixel(i,j)); }}
生成器模型的推理(使用之前定义的byte[][][] pixels
)
FirebaseModelInputs inputs = new FirebaseModelInputs.Builder() .add(pixels) .build();firebaseInterpreter.run(inputs, inputOutputOptions) .addOnSuccessListener( new OnSuccessListener<FirebaseModelOutputs>() { @Override public void onSuccess(FirebaseModelOutputs result) { SweetAlertDialog pDialog2 = new SweetAlertDialog(context, SweetAlertDialog.SUCCESS_TYPE); pDialog2.setTitleText("GG!"); pDialog2.setContentText("图像已处理!"); pDialog2.show(); } }) .addOnFailureListener( new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { System.out.println(e); SweetAlertDialog pDialog2 = new SweetAlertDialog(context, SweetAlertDialog.ERROR_TYPE); pDialog2.setTitleText(context.getResources().getString(R.string.error_firebase_model_interpreter_running)); pDialog2.setContentText(context.getResources().getString(R.string.error_firebase_model_interpreter_running_contents)); pDialog2.show(); } });
问题
抛出的异常非常广泛。输入看起来不错。我的客户端配置也是如此。可能出了什么问题?我完全没有头绪。
相关问题
-
Android MLKit – 执行Firebase ML任务时发生内部错误 : 但我的类型是FLOAT32,我已经配置了:这种配置错误与我无关
-
另一个Stack Overflow问题,其中答案建议检查输入形状,但我的确实是32x32x3。
回答:
问题通过更改几行代码解决…真是愚蠢的错误!关键在于要考虑到第一个维度,它只包含一个值(第一个“1”)。只有一个值,因为我只发送(和接收)一张图像。
1.
.setInputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 32, 32, 3}).setOutputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 128, 128, 3})
-
float[][][][] pixels = new float[1][bitmapResized.getWidth()][bitmapResized.getHeight()][3];
-
pixels[0][i][j][0] = Color.red(bitmapResized.getPixel(i,j)); pixels[0][i][j][1] = Color.green(bitmapResized.getPixel(i,j)); pixels[0][i][j][2] = Color.blue(bitmapResized.getPixel(i,j));