当前位置: 首页 > 知识库问答 >
问题:

与python模型相比,tensorflow lite模型给出了非常不同的精度值

颛孙博易
2023-03-14

我使用的是tensorflow 1.10 Python 3.6

我的代码基于TensorFlow提供的预制虹膜分类模型。这意味着,我使用的是一个Tensorflow DNN预制的分类器,区别如下:

  • 10个功能改为4个。
  • 5个类改为3个。

我做了一个代码将这个分类器导出为tflite格式,但是python模型中的准确率高于75%,但是当导出时,准确率大约下降到45%,这意味着大约30%的准确率丢失了(这太多了)。我尝试了不同的数据集的代码,在所有的输出后的准确性下降了很多!这使我认为TocoConverter函数出了问题,或者我可能不正确地导出到tflite,丢失了一个参数或类似的东西。

这是我生成模型的方式:

classifier = tf.estimator.DNNClassifier(
        feature_columns=my_feature_columns,
        hidden_units=[100, 500],
        optimizer=tf.train.AdagradOptimizer(learning_rate=0.003),
        n_classes=num_labels,
        model_dir="myModel")

这是我用来转换为TFLITE的函数:

converter = tf.contrib.lite.TocoConverter.from_frozen_graph(final_model_path, input_arrays, output_arrays, input_shapes={"dnn/input_from_feature_columns/input_layer/concat": [1, 10]})
        tflite_model = converter.convert()

我分享了完整的代码,在这些代码中,我还计算得到的.tflite文件的准确性。

import argparse
import tensorflow as tf

import pandas as pd
import csv

from tensorflow.python.tools import freeze_graph
from tensorflow.python.tools import optimize_for_inference_lib
import numpy as np


parser = argparse.ArgumentParser()
parser.add_argument('--batch_size', default=100, type=int, help='batch size')
parser.add_argument('--train_steps', default=1000, type=int,
                    help='number of training steps')

features_global = None
feature_spec = None

MODEL_NAME = 'myModel'

def load_data(train_path, test_path):
    """Returns the iris dataset as (train_x, train_y), (test_x, test_y)."""

    with open(train_path, newline='') as f:
        reader = csv.reader(f)
        column_names = next(reader)

    y_name = column_names[-1]

    train = pd.read_csv(train_path, names=column_names, header=0)
    train_x, train_y = train, train.pop(y_name)

    test = pd.read_csv(test_path, names=column_names, header=0)
    test_x, test_y = test, test.pop(y_name)

    return (train_x, train_y), (test_x, test_y)


def train_input_fn(features, labels, batch_size):
    """An input function for training"""
    # Convert the inputs to a Dataset.
    dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))

    # Shuffle, repeat, and batch the examples.
    dataset = dataset.shuffle(1000).repeat().batch(batch_size)

    # Return the dataset.
    return dataset


def eval_input_fn(features, labels, batch_size):
    """An input function for evaluation or prediction"""
    features=dict(features)
    if labels is None:
        # No labels, use only features.
        inputs = features
    else:
        inputs = (features, labels)

    # Convert the inputs to a Dataset.
    dataset = tf.data.Dataset.from_tensor_slices(inputs)

    # Batch the examples
    assert batch_size is not None, "batch_size must not be None"
    dataset = dataset.batch(batch_size)

    # Return the dataset.
    return dataset


def main(argv):
    args = parser.parse_args(argv[1:])

    train_path = "trainData.csv"
    test_path = "testData.csv"

    # Fetch the data
    (train_x, train_y), (test_x, test_y) = load_data(train_path, test_path)

    # Load labels
    num_labels = 5

    # Feature columns describe how to use the input.
    my_feature_columns = []
    for key in train_x.keys():
        my_feature_columns.append(tf.feature_column.numeric_column(key=key))

    # Build 2 hidden layer DNN
    classifier = tf.estimator.DNNClassifier(
        feature_columns=my_feature_columns,
        hidden_units=[100, 500],
        optimizer=tf.train.AdagradOptimizer(learning_rate=0.003),
        # The model must choose between 'num_labels' classes.
        n_classes=num_labels,
        model_dir="myModel")

    # Train the Model
    classifier.train(
        input_fn=lambda:train_input_fn(train_x, train_y,
                                                args.batch_size),
        steps=args.train_steps)

    # Evaluate the model.
    eval_result = classifier.evaluate(
        input_fn=lambda:eval_input_fn(test_x, test_y,
                                                args.batch_size))

    print('\nTest set accuracy: {accuracy:0.3f}\n'.format(**eval_result))

    # Export model
    feature_spec = tf.feature_column.make_parse_example_spec(my_feature_columns)
    serve_input_fun = tf.estimator.export.build_parsing_serving_input_receiver_fn(feature_spec)
    saved_model_path = classifier.export_savedmodel(
            export_dir_base="out",
            serving_input_receiver_fn=serve_input_fun,
            as_text=True,
            checkpoint_path=classifier.latest_checkpoint(),
        )
    tf.reset_default_graph()
    var = tf.Variable(0)
    with tf.Session() as sess:
        # First let's load meta graph and restore weights
        sess.run(tf.global_variables_initializer())
        latest_checkpoint_path = classifier.latest_checkpoint()
        saver = tf.train.import_meta_graph(latest_checkpoint_path + '.meta')
        saver.restore(sess, latest_checkpoint_path)

        input_arrays = ["dnn/input_from_feature_columns/input_layer/concat"]
        output_arrays = ["dnn/logits/BiasAdd"]

        frozen_graph_def = tf.graph_util.convert_variables_to_constants(
            sess, sess.graph_def,
            output_node_names=["dnn/logits/BiasAdd"])

        frozen_graph = "out/frozen_graph.pb"

        with tf.gfile.FastGFile(frozen_graph, "wb") as f:
                f.write(frozen_graph_def.SerializeToString())

        # save original graphdef to text file
        with open("estimator_graph.pbtxt", "w") as fp:
            fp.write(str(sess.graph_def))
        # save frozen graph def to text file
        with open("estimator_frozen_graph.pbtxt", "w") as fp:
            fp.write(str(frozen_graph_def))

        input_node_names = input_arrays
        output_node_name = output_arrays
        output_graph_def = optimize_for_inference_lib.optimize_for_inference(
                frozen_graph_def, input_node_names, output_node_name,
                tf.float32.as_datatype_enum)

        final_model_path = 'out/opt_' + MODEL_NAME + '.pb'
        with tf.gfile.FastGFile(final_model_path, "wb") as f:
            f.write(output_graph_def.SerializeToString())

        tflite_file = "out/iris.tflite"

        converter = tf.contrib.lite.TocoConverter.from_frozen_graph(final_model_path, input_arrays, output_arrays, input_shapes={"dnn/input_from_feature_columns/input_layer/concat": [1, 10]})
        tflite_model = converter.convert()
        open(tflite_file, "wb").write(tflite_model)

        interpreter = tf.contrib.lite.Interpreter(model_path=tflite_file)
        interpreter.allocate_tensors()

        # Get input and output tensors.
        input_details = interpreter.get_input_details()
        output_details = interpreter.get_output_details()

        # Test model on random input data.
        input_shape = input_details[0]['shape']
        # change the following line to feed into your own data.
        input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)
        resultlist = list()
        df = pd.read_csv(test_path)
        expected = df.iloc[:, -1].values.tolist()
        with open(test_path, newline='') as f:
            reader = csv.reader(f)
            column_names = next(reader)
            for x in range(0, len(expected)):
                linea = next(reader)
                linea = linea[:len(linea) - 1]
                input_data2 = np.array(linea, dtype=np.float32)
                interpreter.set_tensor(input_details[0]['index'], [input_data2])
                interpreter.invoke()
                output_data = interpreter.get_tensor(output_details[0]['index'])
                #print(output_data)
                max = 0;
                longitud = len(output_data[0])

                for k in range(0, longitud):
                    if (output_data[0][k] > output_data[0][max]):
                        max = k
                resultlist.append(max)
            print(resultlist)

        coincidences = 0
        for pred_dict, expec in zip(resultlist, expected):
            if pred_dict == expec:
                coincidences = coincidences + 1

        print("tflite Accuracy: " + str(coincidences / len(expected)))


if __name__ == '__main__':
    tf.logging.set_verbosity(tf.logging.INFO)
    tf.app.run(main)

我希望你们中的一些人能找出这个错误,或者给出一个可能的解决方案

共有1个答案

雷方伟
2023-03-14

这个问题的答案在这里可能会有所帮助。

正如答案分享中提到的,做一些

预处理

interpreter.invoke()

数字=NP.argmax(output()[0])

#打印(数字)

预测=结果[数字]

如您所见,在使用“imread()”读取图像后,有两个关键的命令/预处理:

i)应该将图像大小调整为训练期间使用的输入图像/张量的“input_height”和“input_width”值的大小。在我的例子(inception-v3)中,“input_height”和“input_width”的值都是299。(阅读该值的模型文档,或者在用于训练或重新训练模型的文件中查找该变量)

ii)上述代码中的下一个命令是:

test_image=np.expand_dims((test_image)/255,axis=0).astype(np.float32)

我从“公式”/模型代码中得到了这个:

 类似资料:
  • 我想创建一个预测年龄和性别的模型,并将其集成到Android应用程序中。 我在Ubuntu 16上使用Python 3.6,Tensorflow 1.13.1和Keras 2.2.4。 首先,我用IMDB数据集训练不同的模型:keras的Mobilenet V1和V2,以及我自己编写的VGG。对于这两个MobileNet,我使用imagenet权重来初始化模型。 准确率相当高,性别的准确率超过90

  • 我正在开发一个端到端训练和量化感知的训练示例。使用CIFAR10数据集,我加载了一个预训练的MobilenetV2模型,然后使用TensorFlow指南中的代码来量化我的模型。整个过程适当结束后,我得到以下结果: 注意,我并没有更改我从TensorFlow指南中附带的代码,我只是使用了一个不同的数据集和模型。

  • 我正在培训一个Keras模型,我想在量化的8位环境(微控制器)中使用TFLite部署它。为了提高量化性能,我进行量化感知训练。然后,我使用验证集作为代表性数据集创建量化的TFLite模型。使用验证集评估性能,如图所示: 不同条件下20次运行的不同批次的错误率 如果我不是简单地从QA训练模型(图中红色)生成TFLite模型(图中青色),而是将权重从QA训练模型复制到原始模型,然后生成TFLite模型

  • 我正在使用ML Vision api从FaceNet模型创建嵌入,然后比较两个嵌入之间的余弦距离。Android版本和Python的输出有很大不同。Python版本的性能比android版本好得多。可能是什么问题?我在两者中都使用FaceNet模型。 我正在使用ML工具包进行推理 https://firebase.google.com/docs/ml-kit/android/use-custom-

  • 我在Tensorflow中训练了一个模型,因此可以产生的最大产出值为1.0。然后我将其转换为Tensorflow Lite以安装在android上,现在Tensorflow Lite模型产生的值远大于1.0。我可以做些什么来解决这个问题? 我用的是Tensorflow 2.5 tf模型-

  • 我做了一个模型,预测一个字符在一个图像,做车牌识别。它在我的电脑上运行得非常好,但我需要把这项工作放在一个Android应用程序中。所以我开发了一个小应用程序,将我的keras模型转换为TFLITE。现在它总是预测同一个角色。 有没有更好的方法转换模型,还是我遗漏了什么? 编辑:这是我管理位图的操作