【问题标题】:Why CNN running in python is extremely slow in comparison to Matlab?为什么在 python 中运行的 CNN 与 Matlab 相比非常慢?
【发布时间】:2020-08-01 10:31:39
【问题描述】:

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

【问题讨论】:

  • 我建议您首先检查几件事: 1. 您是否将 GPU 与 python 和 Matlab 一起使用? 2.什么需要15秒(Matlab)或更多(python),是分类本身还是加载模型和图像处理? 3. 加载一张图片后,内存何时满?另外,您使用的是什么操作系统?
  • 您是否尝试过运行分析器来查看您的瓶颈在哪里?见docs.python.org/3/library/profile.html#module-cProfiletoucantoco.com/en/tech-blog/tech/…
  • “让python更快的最好方法就是少用它”
  • Matlab 是专有产品,物有所值
  • 能贴出matlab代码吗?

标签: python matlab tensorflow conv-neural-network onnx


【解决方案1】:

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

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) 

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

【讨论】:

    【解决方案2】:

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

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      由于命令提示符表明您的程序需要很长时间才能执行常量折叠,因此关闭它可能是值得的。 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 优化中执行的常量折叠。这可以双向工作:一方面它不会达到常量折叠的最后期限,但另一方面禁用常量折叠会导致运行时间显着增加。总之值得一试,祝你好运!

      【讨论】:

        【解决方案4】:

        在这种情况下,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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-02-13
          • 2017-06-05
          • 1970-01-01
          • 2012-11-25
          • 1970-01-01
          • 1970-01-01
          • 2021-02-13
          相关资源
          最近更新 更多