Попытка загрузить модель tflite завершается с java .io.FileNotFoundException - что я делаю не так? - PullRequest
0 голосов
/ 19 марта 2020

Моя проблема

Я пытаюсь запустить свою модель TensorFlow (которая управляет изображениями) на Android как tflite, но я продолжаю получать java .io.FileNotFoundException .

Не беспокойтесь о прочтении всего кода Java - он не работает даже до того, как запускается, при попытке загрузить модель:

        // Initialize model
        try{
            MappedByteBuffer tfliteModel
                    = FileUtil.loadMappedFile(this,
                    "model.tflite");
            tflite = new Interpreter(tfliteModel);
        } catch (IOException e){
            Log.e("tfliteException", "Error: couldn't load tflite model.", e);
        }

Мой код

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.example.tflite"
        minSdkVersion 27
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    // tf lite
    aaptOptions {
        noCompress "tflite"
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    // tf lite
    implementation 'org.tensorflow:tensorflow-lite:+'    
    // tf lite gpu
    implementation 'org.tensorflow:tensorflow-lite-gpu:+'
    // tf lite support library
    implementation 'org.tensorflow:tensorflow-lite-support:+'
}

AndroidManifest. xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.tflite">

    <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity. java

package com.example.tflite;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import org.tensorflow.lite.DataType;
import org.tensorflow.lite.Interpreter;

import org.tensorflow.lite.support.common.FileUtil;
import org.tensorflow.lite.support.image.ImageProcessor;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.image.ops.ResizeOp;

import org.tensorflow.lite.support.image.ops.ResizeWithCropOrPadOp;
import org.tensorflow.lite.support.image.ops.Rot90Op;
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;
import org.tensorflow.lite.support.model.Model;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class MainActivity extends AppCompatActivity {
    private static final int PIXEL_SIZE = 3;

    // constants

    private int REQUEST_IMAGE_SELECT = 101;
    private int REQUEST_START = 201;
    public static final int MEDIA_ACCESS_PERMISSION_CODE = 101;
    private int imageHeight = 0, imageWidth = 0;

    // RGB presets
    private static final int IMAGE_MEAN = 128;
    private static final float IMAGE_STD = 128.0f;

    // variables

    Button selectButton, startButton;
    ImageView imageView;
    TextView result;
    Bitmap bitmap, outputImage;

    Interpreter tflite;
    private ByteBuffer imageByteData = null;
    private float accuracy = 0;
    private int[] imageIntValues;

    ImageProcessor imageProcessor =
            new ImageProcessor.Builder()
                    .add(new ResizeOp(100, 100, ResizeOp.ResizeMethod.BILINEAR))
                    .build();

    TensorImage tImage = new TensorImage(DataType.UINT8);

    TensorBuffer probabilityBuffer =
            TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // init
        startButton = findViewById(R.id.startButton);
        selectButton = findViewById(R.id.selectButton);
        imageView = findViewById(R.id.imageView);
        result = findViewById(R.id.resultTextView);

        // Initialize model
        try{
            MappedByteBuffer tfliteModel
                    = FileUtil.loadMappedFile(this,
                    "model.tflite");
            tflite = new Interpreter(tfliteModel);
        } catch (IOException e){
            Log.e("tfliteException", "Error: couldn't load tflite model.", e);
        }

        // select button
        selectButton.setOnClickListener( new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                askMediaPermission(REQUEST_IMAGE_SELECT);
            }
        });

        // start button
        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                float[] accuracy = doTfLite();
                result.setText(Float.toString(accuracy[0]));

                // close interperter
                tflite.close();
            }
        });
    }

    private void askMediaPermission(int request) {
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_MEDIA_LOCATION) != PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_MEDIA_LOCATION}, MEDIA_ACCESS_PERMISSION_CODE);
        else {
            selectImage(request);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if(requestCode == MEDIA_ACCESS_PERMISSION_CODE){
            if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                // access granted
                Toast.makeText(this, "Granted!", Toast.LENGTH_SHORT).show();
            }
            else {
                // access denied
                Toast.makeText(this, "Media Access Permissions are required.", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void selectImage(int request) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select"), request);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // image select
        if (requestCode == REQUEST_IMAGE_SELECT && resultCode == RESULT_OK && data != null) {

            Uri uri = data.getData();

            try {
                bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);

                // int array init
                imageHeight = bitmap.getHeight();
                imageWidth = bitmap.getWidth();
                imageIntValues = new int[imageWidth * imageHeight];

                // byte array init (for loading model)
                imageByteData = ByteBuffer.allocateDirect(imageHeight * imageWidth * PIXEL_SIZE * 4);
                imageByteData.order(ByteOrder.nativeOrder());
                imageView.setImageBitmap(bitmap);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // start
        else if (requestCode == REQUEST_START && resultCode == RESULT_OK ) {

            Toast.makeText(this, "Request code of START.", Toast.LENGTH_SHORT).show();    
        }

    }

    public float[] doTfLite(){

        // Analysis code for every frame
        // Preprocess the image
        tImage.load(bitmap);
        tImage = imageProcessor.process(tImage);

        // Running inference
        if (tflite != null) {
            tflite.run(tImage.getBuffer(), probabilityBuffer.getBuffer());
        }
        return probabilityBuffer.getFloatArray();
    }

    //// loading model
    //private MappedByteBuffer loadModelFile() throws IOException {
    //    // open the model using input stream, and memory-map it to load
    //    AssetFileDescriptor fileDescriptor = this.getAssets().openFd("model.tflite");
    //    FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
    //    FileChannel fileChannel = inputStream.getChannel();
    //    long startOffset = fileDescriptor.getStartOffset();
    //    long declaredLength = fileDescriptor.getDeclaredLength();
    //    return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
    //}

}

Есть идеи?

1 Ответ

1 голос
/ 19 марта 2020

Я застрял на этом в течение 3 дней, отсканировал весь inte rnet ... и решил это через несколько часов после публикации этого сообщения ...

Я удалил свою папку ресурсов и повторно -создал его . Это решило мою проблему.

У меня нет времени исследовать это, и я понятия не имею, почему это помогло (поскольку я уже дважды пытался начать с нуля), но я публикую это для дальнейшего использования (возможно, также для разработчиков Google TFLite?).

...