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

时间:2020-04-18 21:54:31

标签: python matlab tensorflow cnn onnx

我已经在Matlab 2019b中训练了CNN,该CNN将图像分为三个类别。当在Matlab中测试此CNN时,它运行良好,仅用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%以上的高内存使用率而冻结了我的计算机。 / p>

我在分类时在命令提示符中也注意到了打印此内容

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代码更快地分类?

4 个答案:

答案 0 :(得分:2)

也许您可以尝试通过这种方式来理解代码的哪一部分需要很长时间:

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) 

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

答案 1 :(得分:2)

在这种情况下,看来Grapper optimization suite遇到了某种无限循环或内存泄漏。我建议针对Github repo提出问题。

要调试为什么恒定折叠要花这么长时间是一个挑战,但是与TensorFlow后端相比,使用ONNX TensorRT backend可能会具有更好的性能。与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)

答案 2 :(得分:0)

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

我希望这会有所帮助。

答案 3 :(得分:0)

由于命令提示符指出您的程序需要花费很长时间来执行恒定折叠,因此值得将其关闭。 Based on this documentation,您可以尝试运行:

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 Graph优化中执行的恒定折叠。这可以通过两种方式起作用:一方面,它不会达到恒定的折叠期限,但另一方面,禁用恒定的折叠会导致运行时间显着增加。无论如何都值得尝试,祝您好运!