2016-02-19 12 views
5

Nel codice sottostante l2 restituisce in modo sorprendente lo stesso valore di l1, ma poiché l'ottimizzatore viene richiesto nell'elenco prima di l2, mi aspettavo che la perdita fosse la nuova perdita dopo l'allenamento. Posso non richiedere più valori contemporaneamente dal grafico e prevedere un risultato coerente?Richiesta di più valori dal grafico allo stesso tempo

import tensorflow as tf 
import numpy as np 

x = tf.placeholder(tf.float32, shape=[None, 10]) 
y = tf.placeholder(tf.float32, shape=[None, 2]) 

weight = tf.Variable(tf.random_uniform((10, 2), dtype=tf.float32)) 

loss = tf.nn.sigmoid_cross_entropy_with_logits(tf.matmul(x, weight), y) 

optimizer = tf.train.AdamOptimizer(0.1).minimize(loss) 

with tf.Session() as sess: 
    tf.initialize_all_variables().run() 

    X = np.random.rand(1, 10) 
    Y = np.array([[0, 1]]) 

    # Evaluate loss before running training step 
    l1 = sess.run([loss], feed_dict={x: X, y: Y})[0][0][0] 
    print(l1) # 3.32393 

    # Running the training step 
    _, l2 = sess.run([optimizer, loss], feed_dict={x: X, y: Y}) 
    print(l2[0][0]) # 3.32393 -- didn't change? 

    # Evaluate loss again after training step as sanity check 
    l3 = sess.run([loss], feed_dict={x: X, y: Y})[0][0][0] 
    print(l3) # 2.71041 

risposta

7

No - l'ordine in cui vengono richiesti nell'elenco non ha alcun effetto sull'ordine di valutazione. Per le operazioni con effetti collaterali come l'ottimizzatore, se si desidera garantire un ordine specifico, è necessario applicarlo utilizzando with_dependencies o costrutti di flusso di controllo simili. In generale, ignorando gli effetti collaterali, TensorFlow restituirà risultati acquisendo il nodo dal grafico non appena viene calcolato e, ovviamente, la perdita viene calcolata prima dello ottimizzatore, poiché l'ottimizzatore richiede la perdita come il suo contributo. (Ricordate che 'perdita' non è una variabile, è un tensore, quindi non è in realtà influenzata dalla fase di ottimizzazione.)

sess.run([loss, optimizer], ...) 

e

sess.run([optimizer, loss], ...) 

sono equivalenti.

3

Come Dave points out, l'ordine degli argomenti per Session.run() non ha alcun effetto sul l'ordine di valutazione, e la loss tensore nel tuo esempio non hanno una dipendenza sul optimizer op. Per aggiungere una dipendenza, è possibile utilizzare tf.control_dependencies() per aggiungere una dipendenza esplicita sul ottimizzatore esecuzione prima che il recupero della perdita:

with tf.control_dependencies([optimizer]): 
    loss_after_optimizer = tf.identity(loss) 

_, l2 = sess.run([optimizer, loss_after_optimizer], feed_dict={x: X, y: Y}) 
2

Ho testato la regressione logistica implementata in tensorflow con tre modi di session.run:

  1. tutti insieme

    res1, res2, res3 = sess.run ([OP1, OP2, OP3])

  2. separatamente

    res1 = sess.run (OP1)

    res2 = sess.run (OP2)

    res3 = sess.run (OP3)

  3. con dipendenze

    arguzia h tf.control_dependencies ([OP1]):

    op2_after = tf.identity (op1)

    op3_after = tf.identity (op1)

    res1, res2, res3 = sessione.run ([OP1, op2_after, op3_after])

set dimensioni del lotto come 10000, il risultato è:

1: 0.05+ secs < 2: 0.11+ secs < 3: 0.25+ secs 

La differenza principale tra 1 e 3 è solo un mini-batch. Potrebbe non valere la pena di usare 3 invece di 1.

Ecco il codice di test (è un esempio LR scritto da qualcun altro ...).

Ecco la data

#!/usr/bin/env python2 
# -*- coding: utf-8 -*- 
""" 
Created on Fri Jun 2 13:38:14 2017 

@author: inse7en 
""" 

from __future__ import print_function 
import numpy as np 
import tensorflow as tf 
from six.moves import cPickle as pickle 
import time 

pickle_file = '/Users/inse7en/Downloads/notMNIST.pickle' 
with open(pickle_file, 'rb') as f: 
    save = pickle.load(f) 
    train_dataset = save['train_dataset'] 
    train_labels = save['train_labels'] 
    valid_dataset = save['valid_dataset'] 
    valid_labels = save['valid_labels'] 
    test_dataset = save['test_dataset'] 
    test_labels = save['test_labels'] 
    del save # hint to help gc free up memory 
    print('Training set', train_dataset.shape, train_labels.shape) 
    print('Validation set', valid_dataset.shape, valid_labels.shape) 
    print('Test set', test_dataset.shape, test_labels.shape) 


image_size = 28 
num_labels = 10 

def reformat(dataset, labels): 
    dataset = dataset.reshape((-1, image_size * image_size)).astype(np.float32) 
    # Map 2 to [0.0, 1.0, 0.0 ...], 3 to [0.0, 0.0, 1.0 ...] 
    labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32) 
    return dataset, labels 
train_dataset, train_labels = reformat(train_dataset, train_labels) 
valid_dataset, valid_labels = reformat(valid_dataset, valid_labels) 
test_dataset, test_labels = reformat(test_dataset, test_labels) 
print('Training set', train_dataset.shape, train_labels.shape) 
print('Validation set', valid_dataset.shape, valid_labels.shape) 
print('Test set', test_dataset.shape, test_labels.shape) 

# This is to expedite the process 
train_subset = 10000 
# This is a good beta value to start with 
beta = 0.01 

graph = tf.Graph() 
with graph.as_default(): 
    # Input data. 
    # They're all constants. 
    tf_train_dataset = tf.constant(train_dataset[:train_subset, :]) 
    tf_train_labels = tf.constant(train_labels[:train_subset]) 
    tf_valid_dataset = tf.constant(valid_dataset) 
    tf_test_dataset = tf.constant(test_dataset) 

    # Variables 
    # They are variables we want to update and optimize. 
    weights = tf.Variable(tf.truncated_normal([image_size * image_size, num_labels])) 
    biases = tf.Variable(tf.zeros([num_labels])) 

    # Training computation. 
    logits = tf.matmul(tf_train_dataset, weights) + biases 
    # Original loss function 
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits, tf_train_labels)) 
    # Loss function using L2 Regularization 
    regularizer = tf.nn.l2_loss(weights) 
    loss = tf.reduce_mean(loss + beta * regularizer) 

    # Optimizer. 
    optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss) 

    # Predictions for the training, validation, and test data. 
    train_prediction = tf.nn.softmax(logits) 
    valid_prediction = tf.nn.softmax(tf.matmul(tf_valid_dataset, weights) + biases) 
    test_prediction = tf.nn.softmax(tf.matmul(tf_test_dataset, weights) + biases) 

    num_steps = 50 


    def accuracy(predictions, labels): 
     return (100.0 * np.sum(np.argmax(predictions, 1) == np.argmax(labels, 1)) 
       /predictions.shape[0]) 


    with tf.Session(graph=graph) as session: 
     # This is a one-time operation which ensures the parameters get initialized as 
     # we described in the graph: random weights for the matrix, zeros for the 
     # biases. 
     tf.initialize_all_variables().run() 
     print('Initialized') 
     for step in range(num_steps): 
      # Run the computations. We tell .run() that we want to run the optimizer, 
      # and get the loss value and the training predictions returned as numpy 
      # arrays. 
      #_, l, predictions = session.run([optimizer, loss, train_prediction]) 

      start_time = time.time() 
      with tf.control_dependencies([optimizer]): 
       loss_after_optimizer = tf.identity(loss) 
       predictions_after = tf.identity(train_prediction) 
       regularizers_after = tf.identity(regularizer) 


      _, l, predictions,regularizers = session.run([optimizer, loss_after_optimizer, predictions_after, regularizers_after]) 

      print("--- with dependencies: %s seconds ---" % (time.time() - start_time)) 
      #start_time = time.time() 
      #opt = session.run(optimizer) 
      #l = session.run(loss) 
      #predictions = session.run(train_prediction) 
      #regularizers = session.run(regularizer) 

      #print("--- run separately: %s seconds ---" % (time.time() - start_time)) 

      #start_time = time.time() 
      #_, l, predictions,regularizers = session.run([optimizer, loss, train_prediction, regularizer]) 

      #print("--- all together: %s seconds ---" % (time.time() - start_time)) 

      #if (step % 100 == 0): 
       #print('Loss at step {}: {}'.format(step, l)) 
       #print('Training accuracy: {:.1f}'.format(accuracy(predictions, 
                    #train_labels[:train_subset, :]))) 
       # Calling .eval() on valid_prediction is basically like calling run(), but 
       # just to get that one numpy array. Note that it recomputes all its graph 
       # dependencies. 

       # You don't have to do .eval above because we already ran the session for the 
       # train_prediction 
       #print('Validation accuracy: {:.1f}'.format(accuracy(valid_prediction.eval(), 
                    #valid_labels))) 
     #print('Test accuracy: {:.1f}'.format(accuracy(test_prediction.eval(), test_labels))) 
     #print(regularizer) 
Problemi correlati