2016-06-29 28 views
10

TLDR: non è possibile capire come utilizzare la precisioni riqualificateV3 per le previsioni di immagini multiple.Edit tensorflow inizioV3 retraining-example.py per più classificazioni

Ciao persone gentili :) Ho trascorso alcuni giorni cercando molti post di StackOverflow e la documentazione, ma non sono riuscito a trovare una risposta a questa domanda. Apprezzerei molto qualsiasi aiuto su questo!

ho riqualificato un modello tensorflow inceptionV3 sulle nuove immagini, ed è in grado di lavorare su nuove immagini seguendo le istruzioni a https://www.tensorflow.org/versions/r0.9/how_tos/image_retraining/index.html e utilizzando i seguenti comandi:

bazel build tensorflow/examples/label_image:label_image && \ 
bazel-bin/tensorflow/examples/label_image/label_image \ 
--graph=/tmp/output_graph.pb --labels=/tmp/output_labels.txt \ 
--output_layer=final_result \ 
--image= IMAGE_DIRECTORY_TO_CLASSIFY 

Tuttavia, ho bisogno di classificare multipla immagini (come un set di dati) e sono seriamente bloccato su come farlo. Ho trovato il seguente esempio a

https://github.com/eldor4do/Tensorflow-Examples/blob/master/retraining-example.py

su come utilizzare il modello riqualificato, ma ancora una volta, è molto sparsa sui dettagli su come modificarlo per molteplici classificazioni.

Da quanto ho ricavato dal tutorial MNIST, ho bisogno di inserire feed_dict nell'oggetto sess.run(), ma sono rimasto bloccato perché non riuscivo a capire come implementarlo in questo contesto.

Qualsiasi assistenza sarà estremamente apprezzata! :)

EDIT:

Esecuzione sceneggiatura di Styrke con alcune modifiche, ho ottenuto questo

[email protected]:~/git$ python tensorflowMassPred.py I 
     tensorflow/stream_executor/dso_loader.cc:108] successfully opened 
     CUDA library libcublas.so locally I 
     tensorflow/stream_executor/dso_loader.cc:108] successfully opened 
     CUDA library libcudnn.so locally I 
     tensorflow/stream_executor/dso_loader.cc:108] successfully opened 
     CUDA library libcufft.so locally I 
     tensorflow/stream_executor/dso_loader.cc:108] successfully opened 
     CUDA library libcuda.so locally I 
     tensorflow/stream_executor/dso_loader.cc:108] successfully opened 
     CUDA library libcurand.so locally 
     /home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py:1197: 
     VisibleDeprecationWarning: converting an array with ndim > 0 to an 
     index will result in an error in the future 
     result_shape.insert(dim, 1) I 
     tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:924] successful 
     NUMA node read from SysFS had negative value (-1), but there must be 
     at least one NUMA node, so returning NUMA node zero I 
     tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 0 
     with properties: name: GeForce GTX 660 major: 3 minor: 0 
     memoryClockRate (GHz) 1.0975 pciBusID 0000:01:00.0 Total memory: 
     2.00GiB Free memory: 1.78GiB I tensorflow/core/common_runtime/gpu/gpu_init.cc:126] DMA: 0 I 
     tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 0: Y I 
     tensorflow/core/common_runtime/gpu/gpu_device.cc:806] Creating 
     TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 660, pci 
     bus id: 0000:01:00.0) W tensorflow/core/framework/op_def_util.cc:332] 
     Op BatchNormWithGlobalNormalization is deprecated. It will cease to 
     work in GraphDef version 9. Use tf.nn.batch_normalization(). E 
     tensorflow/core/common_runtime/executor.cc:334] Executor failed to 
     create kernel. Invalid argument: NodeDef mentions attr 'T' not in 
     Op<name=MaxPool; signature=input:float -> output:float; 
     attr=ksize:list(int),min=4; attr=strides:list(int),min=4; 
     attr=padding:string,allowed=["SAME", "VALID"]; 
     attr=data_format:string,default="NHWC",allowed=["NHWC", "NCHW"]>; 
     NodeDef: pool = MaxPool[T=DT_FLOAT, data_format="NHWC", ksize=[1, 3, 
     3, 1], padding="VALID", strides=[1, 2, 2, 1], 
     _device="/job:localhost/replica:0/task:0/gpu:0"](pool/control_dependency) 
     [[Node: pool = MaxPool[T=DT_FLOAT, data_format="NHWC", ksize=[1, 3, 
     3, 1], padding="VALID", strides=[1, 2, 2, 1], 
     _device="/job:localhost/replica:0/task:0/gpu:0"](pool/control_dependency)]] 
     Traceback (most recent call last): File 
     "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", 
     line 715, in _do_call 
      return fn(*args) File "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", 
     line 697, in _run_fn 
      status, run_metadata) File "/home/waffle/anaconda3/lib/python3.5/contextlib.py", line 66, in 
     __exit__ 
      next(self.gen) File "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/errors.py", 
     line 450, in raise_exception_on_not_ok_status 
      pywrap_tensorflow.TF_GetCode(status)) tensorflow.python.framework.errors.InvalidArgumentError: NodeDef 
     mentions attr 'T' not in Op<name=MaxPool; signature=input:float -> 
     output:float; attr=ksize:list(int),min=4; 
     attr=strides:list(int),min=4; attr=padding:string,allowed=["SAME", 
     "VALID"]; attr=data_format:string,default="NHWC",allowed=["NHWC", 
     "NCHW"]>; NodeDef: pool = MaxPool[T=DT_FLOAT, data_format="NHWC", 
     ksize=[1, 3, 3, 1], padding="VALID", strides=[1, 2, 2, 1], 
     _device="/job:localhost/replica:0/task:0/gpu:0"](pool/control_dependency) 
     [[Node: pool = MaxPool[T=DT_FLOAT, data_format="NHWC", ksize=[1, 3, 
     3, 1], padding="VALID", strides=[1, 2, 2, 1], 
     _device="/job:localhost/replica:0/task:0/gpu:0"](pool/control_dependency)]] 

     During handling of the above exception, another exception occurred: 

     Traceback (most recent call last): File "tensorflowMassPred.py", 
     line 116, in <module> 
      run_inference_on_image() File "tensorflowMassPred.py", line 98, in run_inference_on_image 
      {'DecodeJpeg/contents:0': image_data}) File "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", 
     line 372, in run 
      run_metadata_ptr) File "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", 
     line 636, in _run 
      feed_dict_string, options, run_metadata) File "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", 
     line 708, in _do_run 
      target_list, options, run_metadata) File "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/client/session.py", 
     line 728, in _do_call 
      raise type(e)(node_def, op, message) tensorflow.python.framework.errors.InvalidArgumentError: NodeDef 
     mentions attr 'T' not in Op<name=MaxPool; signature=input:float -> 
     output:float; attr=ksize:list(int),min=4; 
     attr=strides:list(int),min=4; attr=padding:string,allowed=["SAME", 
     "VALID"]; attr=data_format:string,default="NHWC",allowed=["NHWC", 
     "NCHW"]>; NodeDef: pool = MaxPool[T=DT_FLOAT, data_format="NHWC", 
     ksize=[1, 3, 3, 1], padding="VALID", strides=[1, 2, 2, 1], 
     _device="/job:localhost/replica:0/task:0/gpu:0"](pool/control_dependency) 
     [[Node: pool = MaxPool[T=DT_FLOAT, data_format="NHWC", ksize=[1, 3, 
     3, 1], padding="VALID", strides=[1, 2, 2, 1], 
     _device="/job:localhost/replica:0/task:0/gpu:0"](pool/control_dependency)]] 
     Caused by op 'pool', defined at: File "tensorflowMassPred.py", line 
     116, in <module> 
      run_inference_on_image() File "tensorflowMassPred.py", line 87, in run_inference_on_image 
      create_graph() File "tensorflowMassPred.py", line 68, in create_graph 
      _ = tf.import_graph_def(graph_def, name='') File "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/importer.py", 
     line 274, in import_graph_def 
      op_def=op_def) File "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", 
     line 2260, in create_op 
      original_op=self._default_original_op, op_def=op_def) File "/home/waffle/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", 
     line 1230, in __init__ 
      self._traceback = _extract_stack() 

Questo è lo script: alcune funzioni vengono rimossi.

import os 
import numpy as np 
import tensorflow as tf 
os.chdir('tensorflow/') #if need to run in the tensorflow directory 
import csv,os 
import pandas as pd 
import glob 

imagePath = '../_images_processed/test' 
modelFullPath = '/tmp/output_graph.pb' 
labelsFullPath = '/tmp/output_labels.txt' 

# FILE NAME TO SAVE TO. 
SAVE_TO_CSV = 'tensorflowPred.csv' 


def makeCSV(): 
    global SAVE_TO_CSV 
    with open(SAVE_TO_CSV,'w') as f: 
     writer = csv.writer(f) 
     writer.writerow(['id','label']) 


def makeUniqueDic(): 
    global SAVE_TO_CSV 
    df = pd.read_csv(SAVE_TO_CSV) 
    doneID = df['id'] 
    unique = doneID.unique() 
    uniqueDic = {str(key):'' for key in unique} #for faster lookup 
    return uniqueDic 


def create_graph(): 
    """Creates a graph from saved GraphDef file and returns a saver.""" 
    # Creates graph from saved graph_def.pb. 
    with tf.gfile.FastGFile(modelFullPath, 'rb') as f: 
     graph_def = tf.GraphDef() 
     graph_def.ParseFromString(f.read()) 
     _ = tf.import_graph_def(graph_def, name='') 


def run_inference_on_image(): 
    answer = [] 
    global imagePath 
    if not tf.gfile.IsDirectory(imagePath): 
     tf.logging.fatal('imagePath directory does not exist %s', imagePath) 
     return answer 

    if not os.path.exists(SAVE_TO_CSV): 
     makeCSV() 

    files = glob.glob(imagePath+'/*.jpg') 
    uniqueDic = makeUniqueDic()   
    # Get a list of all files in imagePath directory 
    #image_list = tf.gfile.ListDirectory(imagePath) 

    # Creates graph from saved GraphDef. 
    create_graph() 

    with tf.Session() as sess: 

     softmax_tensor = sess.graph.get_tensor_by_name('final_result:0') 

     for pic in files: 
      name = getNamePicture(pic) 
      if name not in uniqueDic: 
       image_data = tf.gfile.FastGFile(pic, 'rb').read() 
       predictions = sess.run(softmax_tensor, 
            {'DecodeJpeg/contents:0': image_data}) 
       predictions = np.squeeze(predictions) 

       top_k = predictions.argsort()[-5:][::-1] # Getting top 5 predictions 
       f = open(labelsFullPath, 'rb') 
       lines = f.readlines() 
       labels = [str(w).replace("\n", "") for w in lines] 
#   for node_id in top_k: 
#    human_string = labels[node_id] 
#    score = predictions[node_id] 
#    print('%s (score = %.5f)' % (human_string, score)) 
       pred = labels[top_k[0]] 
       with open(SAVE_TO_CSV,'a') as f: 
        writer = csv.writer(f) 
        writer.writerow([name,pred]) 
    return answer 

if __name__ == '__main__': 
    run_inference_on_image() 

risposta

4

Così guardando lo script collegato:

with tf.Session() as sess: 

    softmax_tensor = sess.graph.get_tensor_by_name('final_result:0') 
    predictions = sess.run(softmax_tensor, 
          {'DecodeJpeg/contents:0': image_data}) 
    predictions = np.squeeze(predictions) 

    top_k = predictions.argsort()[-5:][::-1] # Getting top 5 predictions 

All'interno di questo frammento di codice, image_data è la nuova immagine che si desidera alimentare al modello, che è caricato poche righe in precedenza:

image_data = tf.gfile.FastGFile(imagePath, 'rb').read() 

Quindi il mio istinto sarebbe quello di modificare il run_inference_on_image per accettare imagePath come parametro e utilizzare os.listdir e os.path.join per farlo su ogni immagine nel set di dati.

+0

Ciao, grazie per la tua risposta! Mi dispiace, non capisco cosa intendi. Stai dicendo di caricare tutte le foto, quindi loop sess.run()? – Wboy

+0

Questo è un ottimo modo per farlo! : D – struct

+0

Sfortunatamente, non è quello che sto cercando. È simile al montaggio delle righe una per una in un normale classificatore (come xgboost) ed è incredibilmente lento (richiede 31 ore per le immagini 8k). Sto cercando una soluzione che alimenta l'intera immagine X in feed_dict e nel classificatore e restituisce previsioni per tutte le immagini in un colpo solo. – Wboy

5

I dati raw jpeg sembrano essere inviati direttamente a un'operazione decode_jpeg, che richiede solo una singola immagine come input alla volta. Per elaborare più di una immagine alla volta, probabilmente dovrai definire più operazioni decode_jpeg. Se è possibile farlo, al momento non so come.

La prossima cosa migliore, che è facile, è probabilmente classificare tutte le immagini una per una all'interno con un ciclo della sessione TensorFlow. In questo modo eviterai almeno di ricaricare il grafico e di iniziare una nuova sessione TF per ogni immagine che vuoi classificare, entrambe le quali possono richiedere un po 'di tempo se devi farlo molto.

Qui ho modificato la definizione della funzione run_inference_on_image() in modo da classificare tutte le immagini nella directory specificata dalla variabile imagePath.Non ho testato questo codice, quindi potrebbero esserci problemi minori che devono essere risolti.

def run_inference_on_image(): 
    answer = [] 

    if not tf.gfile.IsDirectory(imagePath): 
     tf.logging.fatal('imagePath directory does not exist %s', imagePath) 
     return answer 

    # Get a list of all files in imagePath directory 
    image_list = tf.gfile.ListDirectory(imagePath) 

    # Creates graph from saved GraphDef. 
    create_graph() 

    with tf.Session() as sess: 

     softmax_tensor = sess.graph.get_tensor_by_name('final_result:0') 

     for i in image_list: 
      image_data = tf.gfile.FastGFile(i, 'rb').read() 
      predictions = sess.run(softmax_tensor, 
            {'DecodeJpeg/contents:0': image_data}) 
      predictions = np.squeeze(predictions) 

      top_k = predictions.argsort()[-5:][::-1] # Getting top 5 predictions 
      f = open(labelsFullPath, 'rb') 
      lines = f.readlines() 
      labels = [str(w).replace("\n", "") for w in lines] 
      for node_id in top_k: 
       human_string = labels[node_id] 
       score = predictions[node_id] 
       print('%s (score = %.5f)' % (human_string, score)) 

      answer.append(labels[top_k[0]]) 
    return answer 
+0

Ciao, grazie mille per la tua risposta - Ho avuto diversi problemi con questo script, ho aggiornato la mia risposta. Sarebbe bello se potessi aiutare di nuovo! :) – Wboy

+0

@Wboy C'è un [problema di TensorFlow] (https://github.com/tensorflow/tensorflow/issues/1528) che sembra correlato al tuo nuovo problema. – Styrke

+0

Non ho ancora risolto, ma ti assegnerò la taglia prima che finisca :) – Wboy

0

Ho avuto gli stessi problemi. Ho seguito tutte le possibili soluzioni e finalmente trovato quello che ha funzionato per me. Questo errore si verifica quando la versione di Tensorflow utilizzata per ri-addestrare il modello è diversa da quella in cui viene utilizzata.

La soluzione è aggiornare Tensorflow all'ultima versione. Dal momento che avevo usato pip installare tensorflow, ho avuto solo per eseguire il seguente comando:

sudo pip install tensorflow --upgrade 

e ha funzionato perfettamente.