TensorFlow:如何在多个图像上执行图像分类

时间:2018-01-01 17:12:21

标签: python numpy tensorflow

希望有人可以帮助解决TensorFlow问题。我确定,这不是一个困难的问题。我只是缺乏与TensorFlow和NumPy相关的知识。

如果没有任何TensorFlow的经验,我已经实现了a tutorial的Python代码来进行图像分类。这有效。经过训练,它可以分辨出猫与狗的区别。

目前这是单个图像的硬连线。我希望能够对多个图像(即文件夹的内容)进行分类,并有效地执行此操作。到目前为止,我为实现这一点而做的是简单地在所有内容周围添加一个循环,因此它运行每个图像的所有代码。但是,操作的计时表明每个连续图像的分类比前一个图像的分类要长。因此存在某种增量开销。每个循环都需要花费更多时间。我不能马上看到它是什么。

有两种方法可以改善这一点。之一:

(1)保持循环不变,防止这种减速,或

(2)(优先恕我直言,如果可能的话)将图像列表传递给TensorFlow进行分类,并返回结果列表。这似乎更有效。

这是代码:

import tensorflow as tf
import numpy as np
import os,glob,cv2
import sys,argparse
import time

try:

  inputdir = [redacted - insert input dir here]

  for f in os.listdir(inputdir):

    start_time = time.time()

    filename = os.path.join(inputdir,f)

    image_size=128
    num_channels=3
    images = []
    image = cv2.imread(filename) # read image using OpenCV

    # Resize image to desired size and preprocess exactly as done during training...
    image = cv2.resize(image, (image_size, image_size),0,0, cv2.INTER_LINEAR)
    images.append(image)
    images = np.array(images, dtype=np.uint8)
    images = images.astype('float32')
    images = np.multiply(images, 1.0/255.0)

    # The input to the network is of shape [None image_size image_size num_channels]. Hence we reshape.
    x_batch = images.reshape(1, image_size,image_size,num_channels)

    sess = tf.Session() # restore the saved model
    saver = tf.train.import_meta_graph('dogs-cats-model.meta') # Step 1: Recreate the network graph. At this step only graph is created
    saver.restore(sess, tf.train.latest_checkpoint('./')) # Step 2: Load the weights saved using the restore method
    graph = tf.get_default_graph() # access the default graph which we have restored

    # Now get hold of the op that we can be processed to get the output.
    # In the original network y_pred is the tensor that is the prediction of the network
    y_pred = graph.get_tensor_by_name("y_pred:0")

    ## Feed the images to the input placeholders...
    x= graph.get_tensor_by_name("x:0") 
    y_true = graph.get_tensor_by_name("y_true:0") 
    y_test_images = np.zeros((1, 2)) 

    # Create the feed_dict that is required to be fed to calculate y_pred...
    feed_dict_testing = {x: x_batch, y_true: y_test_images}
    result=sess.run(y_pred, feed_dict=feed_dict_testing)
    # Note: result is a numpy.ndarray
    print(f + '\t' + str(result) + ' ' + '%.2f' % (time.time()-start_time) + ' seconds')

  # next image

except:
  import traceback
  tb = traceback.format_exc()
  print(tb)

finally:
  input() # keep window open until key is pressed

我尝试修改上述内容的方法是使用...

创建文件名列表
images.append(image)

...然后将剩下的代码从循环中取出。但是,这没有用。它导致以下错误:

  

ValueError:无法将大小为294912的数组重塑为形状   (1,128,128,3)

在这一行:

x_batch = images.reshape(1, image_size,image_size,num_channels)

显然,这种重塑方法在图像列表上不起作用(至少实现了)。

所以我的问题是:

  1. 什么会导致图像分类时间稳步增加,我已经看到图像被迭代了?

  2. 我可以一次性对多个图像进行分类,而不是逐个循环进行分类吗?

  3. 提前致谢。

1 个答案:

答案 0 :(得分:1)

您的问题:

1 a)它如此缓慢的主要原因是:您正在为每个图像重新创建图形。

1 b)增量开销来自每次创建新会话而不破坏旧会话。 with语法有助于此。 e.g:

with tf.Session(graph=tf.Graph()) as session:
  # do something with the session

但在解决a)之后,这不是一个值得注意的问题。

在考虑问题时,可能会发现代码的哪些部分依赖于图像而哪些部分不依赖于图像。与每个图像不同的TensorFlow相关部分是对session.run的调用,以图像形式输入。其他所有东西都可以移出循环。

2)您还可以一次分类多个图像。 x_batch的第一个维度是批量大小。你指定一个。但是你可能会耗尽内存资源来尝试为大量图像做这些事情。