为什么与Matlab相比,CNN在python中的运行速度非常慢



我在Matlab 2019b中训练了一个CNN,它可以在三个类之间对图像进行分类。当这个CNN在Matlab中测试时,它运行良好,只需要10-15秒就可以对图像进行分类。我在Maltab中使用了exportONNXNetwork函数,这样我就可以在Tensorflow中实现我的CNN。这是我在python中使用ONNX文件时使用的代码:

import onnx
from onnx_tf.backend import prepare 
import numpy as np
from PIL import Image 
onnx_model = onnx.load('trainednet.onnx')
tf_rep = prepare(onnx_model)
filepath = 'filepath.png' 
img = Image.open(filepath).resize((224,224)).convert("RGB") 
img = array(img).transpose((2,0,1))
img = np.expand_dims(img, 0) 
img = img.astype(np.uint8) 
probabilities = tf_rep.run(img) 
print(probabilities) 

当试图使用此代码对同一测试集进行分类时,它似乎对图像进行了正确的分类,但速度非常慢,并且冻结了我的计算机,因为它在某些时候达到了高达95%以上的内存使用率。

我还注意到,在对其进行分类时,在命令提示符中打印了以下内容:

2020-04-18 18:26:39.214286: W tensorflow/core/grappler/optimizers/meta_optimizer.cc:530] constant_folding failed: Deadline exceeded: constant_folding exceeded deadline., time = 486776.938ms.

有什么方法可以让这个python代码更快地分类吗?

也许你可以试着用这种方式理解代码的哪一部分需要很长时间:

import onnx
from onnx_tf.backend import prepare 
import numpy as np
from PIL import Image 
import datetime
now = datetime.datetime.now()
onnx_model = onnx.load('trainednet.onnx')
tf_rep = prepare(onnx_model)
filepath = 'filepath.png' 
later = datetime.datetime.now()
difference = later - now
print("Loading time : %f ms" % (difference.microseconds / 1000))
img = Image.open(filepath).resize((224,224)).convert("RGB") 
img = array(img).transpose((2,0,1))
img = np.expand_dims(img, 0) 
img = img.astype(np.uint8) 
now = datetime.datetime.now()
probabilities = tf_rep.run(img) 
later = datetime.datetime.now()
difference = later - now
print("Prediction time : %f ms" % (difference.microseconds / 1000))
print(probabilities) 

让我知道输出是什么样子的:(

在这种情况下,Grapper优化套件似乎遇到了某种无限循环或内存泄漏。我建议针对Github回购申请一个问题。

调试为什么持续折叠需要这么长时间很有挑战性,但与TensorFlow后端相比,使用ONNX TensorRT后端可能会有更好的性能。与Nvidia GPU上的TensorFlow后端相比,它实现了更好的性能,同时可以更快地编译典型的图形。对于优化良好的模型,恒定折叠通常不会提供大的加速。

import onnx
import onnx_tensorrt.backend as backend
import numpy as np
model = onnx.load("trainednet.onnx'")
engine = backend.prepare(model, device='CUDA:1')
filepath = 'filepath.png' 
img = Image.open(filepath).resize((224,224)).convert("RGB") 
img = array(img).transpose((2,0,1))
img = np.expand_dims(img, 0) 
img = img.astype(np.uint8) 
output_data = engine.run(img)[0]
print(output_data)

在使用Python处理TensorFlow时,应该考虑一些要点。GPU会更好地工作,因为它可以加快整个处理过程。为此,您必须安装CUDA支持。除此之外,编译器有时也很重要。根据我的经验,我可以告诉VSCode比Spyder更好。

我希望它能有所帮助。

由于命令提示符表示您的程序需要很长时间才能执行常量折叠,因此关闭它可能是值得的。根据此文档,您可以尝试运行:

import numpy as np
import timeit
import traceback
import contextlib
import onnx
from onnx_tf.backend import prepare 
from PIL import Image 
import tensorflow as tf
@contextlib.contextmanager
def options(options):
old_opts = tf.config.optimizer.get_experimental_options()
tf.config.optimizer.set_experimental_options(options)
try:
yield
finally:
tf.config.optimizer.set_experimental_options(old_opts)

with options({'constant_folding': False}):
onnx_model = onnx.load('trainednet.onnx')
tf_rep - prepare(onnx_model)
filepath = 'filepath.png' 
img = Image.open(filepath).resize((224,224)).convert("RGB") 
img = array(img).transpose((2,0,1))
img = np.expand_dims(img, 0) 
img = img.astype(np.uint8) 
probabilities = tf_rep.run(img)
print(probabilities)

这将禁用TensorFlow图优化中执行的常量折叠。这可以双向工作:一方面,它不会达到恒定折叠的截止日期,但另一方面,禁用恒定折叠可能会导致运行时间显著增加。不管怎样,它值得一试,祝你好运!

相关内容

  • 没有找到相关文章