Ich habe mich schon eine Weile damit beschäftigt. Ich habe eine Menge Artikel gefunden; aber keine zeigt nur Tensorfluss-Inferenz als eine einfache Schlussfolgerung. Es verwendet immer die Serving-Engine oder eine Grafik, die vor-codiert/definiert ist.TensorFlow Inference
Hier ist das Problem: Ich habe ein Gerät, das gelegentlich nach aktualisierten Modellen sucht. Es muss dann dieses Modell laden und Eingabevorhersagen durch das Modell ausführen.
In Keras war das einfach: ein Modell bauen; Trainiere das Modell und den Aufruf model.predict(). In scikit - lerne dasselbe.
Ich bin in der Lage, ein neues Modell zu greifen und es zu laden; Ich kann alle Gewichte ausdrucken; aber wie um alles in der Welt laufe ich dagegen?
-Code-Modell und Druck Gewichte zu laden:
with tf.Session() as sess:
new_saver = tf.train.import_meta_graph(MODEL_PATH + '.meta', clear_devices=True)
new_saver.restore(sess, MODEL_PATH)
for var in tf.trainable_variables():
print(sess.run(var))
ich alle meine Sammlungen ausgedruckt und ich habe: [ 'queue_runners', 'Variablen', 'Verluste', 'Zusammenfassungen', ‚train_op ',' cond_context ',' trainable_variables ']
Ich habe versucht mit sess.run (train_op); Jedoch begann gerade eine volle Trainingseinheit zu beginnen; was ich nicht machen möchte. Ich möchte nur Inferenz gegen eine andere Reihe von Eingaben ausführen, die ich zur Verfügung stelle und die nicht TF Records sind.
Nur ein wenig ausführlicher:
Das Gerät kann C++ verwenden oder Python; solange ich eine .exe erzeugen kann. Ich kann ein Feed-Diktat einrichten, wenn ich das System füttern möchte. Ich habe mit TFRecords trainiert; aber in der Produktion werde ich keine TFRecords verwenden; es ist ein Real/Near-Real-Time-System.
Danke für jede Eingabe. Ich poste Beispielcode zu diesem Repo: https://github.com/drcrook1/CIFAR10/TensorFlow, das das ganze Training und die Beispielschlußfolgerung tut.
Alle Hinweise werden sehr geschätzt!
------------ EDITS ----------------- ich das Modell wieder aufgebaut, wie unten zu sein:
def inference(images):
'''
Portion of the compute graph that takes an input and converts it into a Y output
'''
with tf.variable_scope('Conv1') as scope:
C_1_1 = ld.cnn_layer(images, (5, 5, 3, 32), (1, 1, 1, 1), scope, name_postfix='1')
C_1_2 = ld.cnn_layer(C_1_1, (5, 5, 32, 32), (1, 1, 1, 1), scope, name_postfix='2')
P_1 = ld.pool_layer(C_1_2, (1, 2, 2, 1), (1, 2, 2, 1), scope)
with tf.variable_scope('Dense1') as scope:
P_1 = tf.reshape(C_1_2, (CONSTANTS.BATCH_SIZE, -1))
dim = P_1.get_shape()[1].value
D_1 = ld.mlp_layer(P_1, dim, NUM_DENSE_NEURONS, scope, act_func=tf.nn.relu)
with tf.variable_scope('Dense2') as scope:
D_2 = ld.mlp_layer(D_1, NUM_DENSE_NEURONS, CONSTANTS.NUM_CLASSES, scope)
H = tf.nn.softmax(D_2, name='prediction')
return H
Hinweis Ich füge der TF-Operation den Namen "Vorhersage" hinzu, damit ich sie später abrufen kann.
Beim Training habe ich die Eingabe-Pipeline für tfrecords und Eingabewarteschlangen verwendet.
GRAPH = tf.Graph()
with GRAPH.as_default():
examples, labels = Inputs.read_inputs(CONSTANTS.RecordPaths,
batch_size=CONSTANTS.BATCH_SIZE,
img_shape=CONSTANTS.IMAGE_SHAPE,
num_threads=CONSTANTS.INPUT_PIPELINE_THREADS)
examples = tf.reshape(examples, [CONSTANTS.BATCH_SIZE, CONSTANTS.IMAGE_SHAPE[0],
CONSTANTS.IMAGE_SHAPE[1], CONSTANTS.IMAGE_SHAPE[2]])
logits = Vgg3CIFAR10.inference(examples)
loss = Vgg3CIFAR10.loss(logits, labels)
OPTIMIZER = tf.train.AdamOptimizer(CONSTANTS.LEARNING_RATE)
Ich versuche feed_dict für die geladene Operation in der Grafik zu verwenden; aber jetzt ist es einfach nur hängen ....
MODEL_PATH = 'models/' + CONSTANTS.MODEL_NAME + '.model'
images = tf.placeholder(tf.float32, shape=(1, 32, 32, 3))
def run_inference():
'''Runs inference against a loaded model'''
with tf.Session() as sess:
#sess.run(tf.global_variables_initializer())
new_saver = tf.train.import_meta_graph(MODEL_PATH + '.meta', clear_devices=True)
new_saver.restore(sess, MODEL_PATH)
pred = tf.get_default_graph().get_operation_by_name('prediction')
rand = np.random.rand(1, 32, 32, 3)
print(rand)
print(pred)
print(sess.run(pred, feed_dict={images: rand}))
print('done')
run_inference()
Ich glaube, dies nicht funktioniert, weil das ursprüngliche Netzwerk trainiert wurde TFRecords verwenden. Im Beispiel-CIFAR-Datensatz sind die Daten klein; Unser realer Datensatz ist riesig und es ist mein Verständnis, dass TFRecords die Standard-Best Practice für das Training eines Netzwerks ist. Das feed_dict ist aus produktionstechnischer Sicht sehr sinnvoll. Wir können einige Threads aufdrehen und dieses Ding aus unseren Eingabesystemen bestücken.
Also ich denke, ich habe ein Netzwerk, das trainiert ist, kann ich die Vorhersage Operation erhalten; aber wie sage ich es, um die Eingangswarteschlangen zu stoppen und das feed_dict zu benutzen?Denken Sie daran, dass ich aus Sicht der Produktion keinen Zugang zu dem habe, was die Wissenschaftler getan haben, um es zu machen. Sie machen ihr Ding; und wir halten es in der Produktion mit dem vereinbarten Standard.
------- INPUT OPS --------
tf.Operation 'input/input_producer/Konst' type = Konst, tf.Operation 'input/input_producer/Size' Art = Const, tf.Operation 'Input/Input_Producer/Greater/y' Typ = Const, tf.Operation 'Input/Input_Producer/Greater' Typ = Greater, tf.Operation 'Input/Input_Producer/Assert/Const' Typ = Const, tf .Operation 'Input/Input_Producer/Assert/Assert/data_0' Typ = Const, tf.Operation 'Input/Input_Producer/Assert/Assert' Typ = Assert, tf.Operation 'Input/Input_Producer/Identity' Typ = Identität, tf.Operation 'input/input_producer/RandomShuffle' type = RandomShuffle, tf.Operation 'input/input_producer' type = FIFOQueueV2, tf.Operation 'input/input_producer/input_producer_EnqueueMany' type = QueueEnqueueManyV2, tf.Operation 'input/input_producer/input_pr oducer_Close 'type = QueueCloseV2, tf.Operation' input/input_producer/input_producer_Close_1 'type = QueueCloseV2, tf.Operation' input/input_producer/input_producer_Size 'type = QueueSizeV2, tf.Operation' input/input_producer/Cast 'type = Cast, tf. Operation 'Input/Input_producer/mul/y' Typ = Const, tf.Operation 'Input/Input_producer/mul' Typ = Mul, tf.Operation 'Input/Input_Producer/Bruch_von_32_Full/Tags' Typ = Const, tf.Operation 'Eingabe/input_producer/fraction_of_32_full‘type = ScalarSummary, tf.Operation 'input/TFRecordReaderV2' type = TFRecordReaderV2, tf.Operation 'input/ReaderReadV2' type = ReaderReadV2,
------ END INPUT OPS -----
---- UPDATE 3 ----
Ich glaube, was ich tun muss, ist, den Eingabeabschnitt des Graphen, der mit TF Records trainiert wurde, zu beenden und den Eingang der ersten Schicht auf einen neuen Eingang umzuverdrahten. Es ist wie eine Operation; aber das ist der einzige Weg, die ich finden kann Inferenz tun, wenn ich mit TFRecords wie verrückt trainiert, wie es klingt ...
Voll Graph:
Abschnitt zu töten:
Also ich denke, die Frage wird: Wie tötet man den Eingabeabschnitt des Graphen und ersetzt es durch ein feed_dict?
Ein Follow-up zu diesem wäre: Ist das wirklich der richtige Weg, es zu tun? Das scheint verrückt zu sein.
---- END UPDATE 3 ----
--- Link-Dateien Checkpoint ---
--end Link-Dateien Checkpoint ---
----- UPDATE 4 -----
Ich gab nach und gab nur einen Schuß auf die 'normale' Art der Inferenz, vorausgesetzt, ich könnte die Wissenschaftler einfach nur ihre beizen lassen Modelle und wir könnten die Modellbeize greifen; entpacke es und führe dann Rückschlüsse darauf. Also zum Testen habe ich den normalen Weg ausprobiert, vorausgesetzt, wir haben es schon ausgepackt ... Es funktioniert auch keine Bohnen wert ...
Tensorflow endet mit dem Erstellen eines neuen Graphen mit der Inferenzfunktion aus dem geladenen Modell; dann hängt es alle anderen Sachen von der anderen Grafik an das Ende davon an. Also dann, wenn ich ein feed_dict bevölkere, in der Erwartung, Inferenzen zurück zu bekommen; Bekomme ich nur ein paar zufälligen Müll, als wäre es der erste Durchgang durch das Netzwerk war ...
wieder; das scheint verrückt zu sein; Muss ich wirklich ein eigenes Framework zum Serialisieren und Deserialisieren von Zufallsnetzwerken schreiben? Dieser hatte zuvor getan worden sein ...
----- UPDATE 4 -----
wieder; Vielen Dank!
Für die Interessierten war das zu viel Gesang und Tanz. Wir verwenden CNTK jetzt stattdessen ... Es war einfacher, alles für alle Teams zu standardisieren und etwas in die Produktion konsistent zu bekommen. –