- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 tensorflow 1.10 Python 3.6
我的代码基于预制的 iris classification model由 TensorFlow 提供。这意味着,我使用的是 Tensorflow DNN 预制分类器,具有以下区别:
测试和训练文件可以从以下链接下载: https://www.dropbox.com/sh/nmu8i2i8xe6hvfq/AADQEOIHH8e-kUHQf8zmmDMDa?dl=0
我编写了一个代码将这个分类器导出为 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)
我希望你们中的一些人能够找出错误,或者给出一个可能的解决方案
最佳答案
这个问题得到了回答here可能有帮助。
在回答分享中提到,做一些
pre-processing
在将图像送入“interpreter.invoke()”之前在图像上解决问题(如果这是首先出现的问题)。
为了详细说明这里是来自共享链接的 block 引用:
The below code you see is what I meant by pre-processing:
test_image = cv2.imread(file_name)
test_image = cv2.resize(test_image,(299,299),cv2.INTER_AREA)
test_image = np.expand_dims((test_image)/255,axis=0).astype(np.float32)
interpreter.set_tensor(input_tensor_index, test_image)
interpreter.invoke()
digit = np.argmax(output()[0])
#print(digit)
prediction = result[digit]
As you can see there are two crucial commands/pre-processing done on the image once it is read using "imread()":
i) The image should be resized to the size that is the "input_height" and "input_width" values of the input image/tensor that was used during the training. In my case (inception-v3) this was 299 for both "input_height" and "input_width". (Read the documentation of the model for this value or look for this variable in the file that you used to train or retrain the model)
ii) The next command in the above code is:
test_image = np.expand_dims((test_image)/255,axis=0).astype(np.float32)
I got this from the "formulae"/model code:
test_image = np.expand_dims((test_image - input_mean)/input_std, axis=0).astype(np.float32)
Reading the documentation revealed that for my architecture input_mean = 0 and input_std = 255.
希望这对您有所帮助。
关于python - 与 python 模型相比,tensorflow lite 模型给出了非常不同的精度值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52057552/
我在使用带有 vector STL 的迭代器时遇到了这个错误。 代码:- #include #include void print_vec(std::vector vec) { auto
JAVA:两个引用“p”&&“pp”之间有区别吗? PrintStream p = new PrintStream(System.out); p.println("lol");
我尝试从主分支中拉出,但收到错误消息: $ git --no-optional-locks -c color.branch=false -c color.diff=false -c color.sta
我面临着一个让我抓狂的问题! 我有一个函数,这个: void load_weapons3(t_env *e, char *name, int x, t_weapon *w) { char
我正在尝试使用 CUDA 中的最小值、最大值、总和和平均值实现并行归约。 这是我目前的主要代码片段。 int main() { const auto count = 8; const
我知道 double free 或 corruption 错误通常是对 big 3 的违规,但在这种情况下,我找不到违规发生的地方。我有一个复制构造函数、析构函数和赋值运算符,适用于任何处理指针的东西
GTK+ 中的“focus”和“focus-in(out)-event”信号有什么区别?哪个先发射?它们与键盘(TAB)和鼠标点击有什么关系。他们互相依赖吗? 我问这个是因为我想在顶层窗口中跟踪当前聚
*** glibc detected *** /home/ghoshs/workspace/Simulator/Debug/Simulator: double free or corruption (
#include #include #include #include using namespace std; #define MAX_WEIGHT 1000000 class Set {
我在服务器上有两个分支一个叫 R2 的分支和一个叫 DEV 的分支我无意中登录了错误的服务器,进入了存储库并执行了GIT pull 源开发但是存储库在 R2 上。所以我意识到我的错误然后尝试通过做一个
我有一个包含循环的大约 1000 个顶点和 3000 个边的有向图。 我试图从给定的顶点找到所有下游(出)路径。 使用以下 Gremlin 查询时 g.V(45712).repeat(out().si
使用 Delphi XE 2 我试图确定缩放方向以将缩放效果应用于图像(TImage),但没有找到执行此操作的函数,并且图像的 OnGesture 事件中的 EventInfo 属性没有此信息. 我见
我正在尝试创建一个 Zoom_image 函数,它使用离散傅里叶变换来缩放灰度图像。如果图像大小小于或等于 4*4 但大小增加,我包含的代码可以工作。它给出“双重释放或损坏(出)中止(核心转储)”错误
当我执行 popAll 函数时,出现以下错误: 双重释放或腐败(出)中止(核心转储) 我想我已经将错误来源缩小到了这个函数。 IntegerStack 是我制作的一个简单的 ADT,其中包含一个名为
我有网络开发背景,我正在尝试创建类似于 this technique 的东西适用于 iOS(使用 Cocoa/Obj C)。我在谷歌搜索资源时遇到了很多困难,因为 iOS 中的“视差”往往指的是 iO
我想实现一个 faceted search对于我的一个项目。我正在使用 PHP5、Mysql 和 Symfony 1.4。显然社区指向Apache Solr这似乎正是我想要完成的。 问题是该网站将在不
我知道有 questions floating around当您没有提供明确的分支名称时,关于来自特定分支的 git pull,但是我想知道即使用户确实指定了不同的分支,是否也可以强制 pull 分支
我正在尝试将我的更改推送到 NAS 上的存储库。它以我无法理解的方式失败。 documentation声明默认情况下 push 仅适用于快进更新。很公平。所以我做了一个 git pull(我的 Rem
我刚开始使用 Oracle 的 Coherence 缓存,我注意到这一点:如果我在缓存中放入一个 ConcurrentHashMap 对象,当我检索它时,我可以看到它被转换为一个普通的 HashMap
我尝试创建一个连接到数据库的线程,从那里获取一些数据并打印到控制台。问题是当该线程完成时抛出异常: 双重免费或腐败(出局)中止(核心转储) 我尝试使用 sqlite3 和 pthread,但这两个并不
我是一名优秀的程序员,十分优秀!