预测图像目录-使用tf.estimators的Conv Nets

时间:2018-09-03 05:02:14

标签: python tensorflow neural-network conv-neural-network tensorflow-estimator

我进行了卷积神经元网络的训练,现在我想对图像目录进行预测,例如,我的文件夹中有2张图像,我想获得这2张图像的预测,但是当进入目录时在我的代码中,我只能得到其中之一的预测,这是我的代码

import tensorflow as tf
import numpy as np
import os
import argparse
from Tkinter import Tk
from tkinter.filedialog import askopenfilename
from tensorflow.contrib.learn.python.learn.utils import (
    saved_model_export_utils)
from tensorflow.contrib.training.python.training import hparam


pred_path="/Users/David/Desktop/David/Tesis/Practica/Programas/Versiones/Sexta_Version_Combinacion/Direct/*.jpg"

tf.logging.set_verbosity(tf.logging.INFO)#Comando para impresion de datos en la ejecucion

batch_size_pred=1

sess=tf.Session()#Creacion de session

#Modelo convolucional...........................................................................................
def cnn_model(features,labels,mode):

  input_layer=tf.reshape(features["x"],[-1,224,224,3])

  conv1=tf.layers.conv2d(
    inputs=input_layer,
    filters=30,
    kernel_size=[10,10],
    padding="same",
    activation=tf.nn.relu,
    name="Convolucion_1")

  pool1=tf.layers.max_pooling2d(inputs=conv1,pool_size=[4,4],strides=4,name="Pool_1")

  conv2=tf.layers.conv2d(
    inputs=pool1,
    filters=60,
    kernel_size=[5,5],
    padding="same",
    activation=tf.nn.relu,
    name="Convolucion_2")

  pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[4, 4], strides=4,name="Pool_2")

  conv3=tf.layers.conv2d(
    inputs=pool2,
    filters=90,
    kernel_size=[5,5],
    padding="same",
    activation=tf.nn.relu,
    name="Convolucion_3")

  pool3 = tf.layers.max_pooling2d(inputs=conv3, pool_size=[2, 2], strides=2,name="Pool_3")
  pool3_flat=tf.reshape(pool3,[-1,7*7*90],name="Flat_Pool")

  dense=tf.layers.dense(inputs=pool3_flat,units=2000,activation=tf.nn.relu,name="Capa_1")
  dropout = tf.layers.dropout(inputs=dense, rate=0.5, training=mode == tf.estimator.ModeKeys.TRAIN)
  logits=tf.layers.dense(inputs=dropout,units=2,name="Capa_final")

  predictions = {"classes": tf.argmax(input=logits, axis=1)}


  if mode==tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode,predictions=predictions)


def read_file(filename_queue):

  # Make a queue of file names including all the JPEG images files in the relative
  # image directory.
  filename_queue = tf.train.string_input_producer(
  tf.train.match_filenames_once("/Users/David/Desktop/David/Tesis/Practica/Programas/Versiones/Sexta_Version_Combinacion/Direct/*.jpg"))

  # Read an entire image file which is required since they're JPEGs, if the images
  # are too large they could be split in advance to smaller files or use the Fixed
  # reader to split up the file.
  image_reader = tf.WholeFileReader()

  # Read a whole file from the queue, the first returned value in the tuple is the
  # filename which we are ignoring.
  _, image_file = image_reader.read(filename_queue)

  # Decode the image as a JPEG file, this will turn it into a Tensor which we can
  # then use in training.
  image = tf.image.decode_jpeg(image_file)

  image = tf.image.resize_images(image, [224, 224])
  image.set_shape((224, 224, 3))
  print(image)

  batch_size = 1
  num_preprocess_threads = 1
  min_queue_examples = 1
  images = tf.train.shuffle_batch([image],batch_size=batch_size,num_threads=num_preprocess_threads,capacity=min_queue_examples+3*batch_size,min_after_dequeue=min_queue_examples)

  return images


def main(hparams):

  img_pred=read_file(pred_path)

  detector=tf.estimator.Estimator(model_fn=cnn_model,model_dir='/Users/David/Desktop/David/Tesis/Practica/Programas/Versiones/Quinta_Version/Modelo_QuintaVersion')

  init_op=tf.group(tf.global_variables_initializer(),tf.local_variables_initializer())
  sess.run(init_op)

  coord = tf.train.Coordinator()
  threads=tf.train.start_queue_runners(sess=sess,coord=coord)


  img_p=sess.run(img_pred)

  pred_input_fn=tf.estimator.inputs.numpy_input_fn(
    x={"x":img_p},
    shuffle=False)
  pred_results=detector.predict(input_fn=pred_input_fn)
  print(next(pred_results))

  coord.request_stop()
  coord.join(threads)
  sess.close()

if __name__ == '__main__':
  tf.app.run()

例如,在放置的目录中,我有2张图像,但是我只能得到其中之一的预测,这就是我的结果:

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /Users/David/Desktop/David/Tesis/Practica/Programas/Versiones/Quinta_Version/Modelo_QuintaVersion/model.ckpt-9000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
{'classes': 1}

如何获得两个图像的预测?谢谢

编辑 所以我的代码会是这样吗?

def main(hparams):



  detector=tf.estimator.Estimator(model_fn=cnn_model,model_dir='/Users/David/Desktop/David/Tesis/Practica/Programas/Versiones/Quinta_Version/Modelo_QuintaVersion')

  init_op=tf.group(tf.global_variables_initializer(),tf.local_variables_initializer())
  sess.run(init_op)

  coord = tf.train.Coordinator()
  threads=tf.train.start_queue_runners(sess=sess,coord=coord)


  pred_results=detector.predict(input_fn=lambda: read_file(pred_path))


  results = []
  for prediction in pred_results:
    results.append(prediction)

但是我得到这个错误:

TypeError: cannot concatenate 'str' and 'int' objects

1 个答案:

答案 0 :(得分:1)

问题在于您只请求一个一个预测。 predict中的tf.Estimator就像生成器一样工作,即,它基于输入函数产生单个预测。当你做这样的事情

print(next(pred_results))

您仅请求生成器的 first 项目。要获得所有预测,您应该执行以下操作:

results = []
for prediction in gun_detector.predict(input_fn=pred_input_fn)
    results.append(prediction)

编辑:我刚刚注意到您也在犯另一个错误。首先,您获得一个批数据,并通过调用

将其保存在img_p
img_p=sess.run(img_pred)

然后您创建一个新的输入功能,该功能只能提供这一批

pred_input_fn=tf.estimator.inputs.numpy_input_fn(
    x={"x":img_p},
    shuffle=False
)

然后让估算器对此数据进行预测

pred_results=detector.predict(input_fn=pred_input_fn)

这没有道理。只需将这些行替换为

pred_results = detector.predict(input_fn=lambda: read_file(pred_path))

一切都应该正常工作。