Создание прогнозов для каталога изображений - Conv Nets с tf.estimators - PullRequest
0 голосов
/ 03 сентября 2018

Я провел обучение сверточной нейронной сети, теперь я хочу сделать прогнозы для каталога изображений, например, у меня есть 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}

Как мне получить прогнозы для двух моих изображений? Спасибо

EDIT Так мой код будет таким?

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 голосов
/ 03 сентября 2018

Проблема в том, что вы запрашиваете только один прогноз. predict из tf.Estimator работает как генератор, то есть выдает единичные предсказания на основе входной функции. Когда вы делаете что-то вроде этого

print(next(pred_results))

Вы запрашиваете только первый элемент генератора. Чтобы получить все прогнозы, вы должны сделать что-то вроде:

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))

и все должно работать нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...