【问题标题】:Unable to correctly get the output of Custom Model Tflite Model in Android application无法在 Android 应用程序中正确获取 Custom Model Tflite Model 的输出
【发布时间】:2020-01-14 15:32:08
【问题描述】:

我已经训练了一个非常简单的模型并将其转换为Tflite模型......该模型的python代码如下

# -*- coding: utf-8 -*-
"""
Created on Sat Sep 28 21:05:22 2019

@author: Aneshka Goyal
"""

import tensorflow as tf
def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
    """
    Freezes the state of a session into a pruned computation graph.

    Creates a new computation graph where variable nodes are replaced by
    constants taking their current value in the session. The new graph will be
    pruned so subgraphs that are not necessary to compute the requested
    outputs are removed.
    @param session The TensorFlow session to be frozen.
    @param keep_var_names A list of variable names that should not be frozen,
                          or None to freeze all the variables in the graph.
    @param output_names Names of the relevant graph outputs.
    @param clear_devices Remove the device directives from the graph for better portability.
    @return The frozen graph definition.
    """
    graph = session.graph
    with graph.as_default():
        freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
        output_names = output_names or []
        output_names += [v.op.name for v in tf.global_variables()]
        input_graph_def = graph.as_graph_def()
        if clear_devices:
            for node in input_graph_def.node:
                node.device = ""
        frozen_graph = tf.graph_util.convert_variables_to_constants(
            session, input_graph_def, output_names, freeze_var_names)
        return frozen_graph

inp = tf.placeholder(name="inp", dtype=tf.float32, shape=(1, 1))

w = tf.Variable(tf.zeros([1, 1], tf.float32), dtype=tf.float32, name="w")



y = tf.matmul(w, inp)



out = tf.identity(y, name="out")



init_op = tf.global_variables_initializer()



with tf.Session() as sess:

    sess.run(init_op)



    # After Init var, change the value to 2

    assignment = w.assign([[2]])

    sess.run(assignment)



    output = sess.run(out, feed_dict={inp: [[1]]})

    print (output)



    frozen_graph = freeze_session(sess, output_names=[out.op.name])



    tflite_model = tf.contrib.lite.toco_convert(frozen_graph, [inp], [out])

    open("mat_mul.tflite", "wb").write(tflite_model)

我能够获得此模型的输入和输出的正确尺寸,以将其放入以下 ​​android 代码中,以便与我的 android 应用程序集成,但我怀疑从 FirebaseInterpreter 中正确取出输出......因为由 try-catch 块上的注释指示。

    package com.example.aneshkagoyal.samplecustom;

    import android.support.annotation.NonNull;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.TextView;
    import android.widget.Toast;

    import com.google.android.gms.tasks.OnFailureListener;
    import com.google.android.gms.tasks.OnSuccessListener;
    import com.google.firebase.FirebaseApp;
    import com.google.firebase.ml.common.FirebaseMLException;
    import com.google.firebase.ml.custom.FirebaseModelDataType;
    import com.google.firebase.ml.custom.FirebaseModelInputOutputOptions;
    import com.google.firebase.ml.custom.FirebaseModelInputs;
    import com.google.firebase.ml.custom.FirebaseModelInterpreter;
    import com.google.firebase.ml.custom.FirebaseModelManager;
    import com.google.firebase.ml.custom.FirebaseModelOptions;
    import com.google.firebase.ml.custom.FirebaseModelOutputs;
    import com.google.firebase.ml.custom.model.FirebaseLocalModelSource;

    public class MainActivity extends AppCompatActivity {
        FirebaseModelInterpreter firebaseInterpreter;
        FirebaseModelInputs inputs;
        FirebaseModelInputOutputOptions inputOutputOptions;
        TextView t;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            t = findViewById(R.id.my_text);
            FirebaseLocalModelSource localSource =
                    new FirebaseLocalModelSource.Builder("mat_mul")  // Assign a name to this model
                            .setAssetFilePath("mat_mul.tflite")
                            .build();
            FirebaseModelManager.getInstance().registerLocalModelSource(localSource);
            FirebaseModelOptions options = new FirebaseModelOptions.Builder()
                    .setLocalModelName("asset")
                    .build();
            try {
                 firebaseInterpreter =
                        FirebaseModelInterpreter.getInstance(options);
            } catch (FirebaseMLException e) {
                e.printStackTrace();

            }




            // Define the Input and Output dimensions and types

            try {
                 inputOutputOptions = new FirebaseModelInputOutputOptions.Builder()

                        .setInputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1,1})//This line

                        .setOutputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1,1})//This line

                        .build();
            } catch (FirebaseMLException e) {
                e.printStackTrace();

            }
            float[][] input;
            input = new float[1][1];
            //output = new float[1][1];
            input[0][0]= 21.0f;
            try {
                 inputs = new FirebaseModelInputs.Builder()
                        .add(input)  // add() as many input arrays as your model requires
                        .build();
            } catch (FirebaseMLException e) {
                e.printStackTrace();
                Log.d("Failure","in InputBuilder");
            }
//Check if the output is being correctly taken as float[1][1]
            try {
                firebaseInterpreter.run(inputs, inputOutputOptions)
                        .addOnSuccessListener(
                                new OnSuccessListener<FirebaseModelOutputs>() {
                                    @Override
                                    public void onSuccess(FirebaseModelOutputs result) {
                                        Toast.makeText(MainActivity.this,"output"+result.<float[][]>getOutput(0).toString(),Toast.LENGTH_SHORT).show();
                                        Log.d("ANSWERIS", result.<float[][]>getOutput(0).toString());
                                        t.setText(result.<float[][]>getOutput(0).toString());
                                    }
                                })
                        .addOnFailureListener(
                                new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception e) {
                                        // Task failed with an exception
                                        // ...
                                        Log.d("Failure","ho gyaa");
                                    }
                                });
            } catch (FirebaseMLException e) {
                e.printStackTrace();
            }

        }



    }

我在应用程序中得到的输出是垃圾类型的值 [[F@6061395 并且值每次都会改变,当我运行 python 脚本(仅)时得到的输出是 [[2.]] 应该是正确的答案。 请根据我的感觉提出可能的错误来源来提供帮助,因为我不确定我是否做得对。

【问题讨论】:

  • 您是否尝试在Netron 工具中打开mat_mul.tflite?该工具将为您提供 tflite 模型的输入和输出的详细信息
  • 嗨 Afsaredrisy 我确实尝试过输入该工具给出 float32[1,1] 并输出它给出 float32[1,1]

标签: python android neural-network tensorflow-lite firebase-mlkit


【解决方案1】:

我解决了这个问题。我修复了将 sigmoid 简化配置为标签数量而不是 value=1

【讨论】:

  • 解决问题之前的上下文:我想 [[F@6061395 值是内存中保存数组的位置。在显示使用 tflite 模型(使用 FLOAT32 格式)评估图像的输出分数时,我遇到了类似的问题。在 Netron 中,我可以看到模型的输出是 float[1,1] 而不是 float[1,Number of tags]。如果你显示整个数组的 .toString(),你会得到 [F@5bb25d2,它每次都会改变。但是,获取数组的单个值的值,我得到一个常量 4.156027E-39 值。
  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
相关资源
最近更新 更多