2015-12-04 39 views
27

Supponendo che abbia una rete neurale molto semplice, come il percettore multistrato. Per ogni livello la funzione di attivazione è sigmoid e la rete è completamente connessa.TensorFlow Training

In tensorflow questo potrebbe essere definito in questo modo:

sess = tf.InteractiveSession() 

    # Training Tensor 
    x = tf.placeholder(tf.float32, shape = [None, n_fft]) 
    # Label Tensor 
    y_ = tf.placeholder(tf.float32, shape = [None, n_fft]) 

    # Declaring variable buffer for weights W and bias b 
    # Layer structure [n_fft, n_fft, n_fft, n_fft] 
    # Input -> Layer 1 
    struct_w = [n_fft, n_fft] 
    struct_b = [n_fft] 
    W1 = weight_variable(struct_w, 'W1') 
    b1 = bias_variable(struct_b, 'b1') 
    h1 = tf.nn.sigmoid(tf.matmul(x, W1) + b1) 

    # Layer1 -> Layer 2 
    W2 = weight_variable(struct_w, 'W2') 
    b2 = bias_variable(struct_b, 'b2') 
    h2 = tf.nn.sigmoid(tf.matmul(h1, W2) + b2) 

    # Layer2 -> output 
    W3 = weight_variable(struct_w, 'W3') 
    b3 = bias_variable(struct_b, 'b3') 
    y = tf.nn.sigmoid(tf.matmul(h2, W3) + b3) 

    # Calculating difference between label and output using mean square error 
    mse = tf.reduce_mean(tf.square(y - y_)) 

    # Train the Model 
    # Gradient Descent 
    train_step = tf.train.GradientDescentOptimizer(0.3).minimize(mse) 

L'obiettivo di progettazione per questo modello è quello di mappare un n_fft punti spettrogramma FFT ad un altro spettrogramma n_fft bersaglio. Supponiamo che i dati di allenamento e di destinazione siano entrambi di dimensioni [3000, n_fft]. Sono memorizzati nelle variabili spec_train e spec_target.

Ora arriva la domanda. Per TensorFlow c'è qualche differenza tra questi due allenamenti?

Training 1:

for i in xrange(200): 
     train_step.run(feed_dict = {x: spec_train, y_: spec_target}) 

Training 2:

for i in xrange(200): 
     for j in xrange(3000): 
      train = spec_train[j, :].reshape(1, n_fft) 
      label = spec_target[j, :].reshape(1, n_fft) 
      train_step.run(feed_dict = {x: train, y_: label}) 

Grazie mille!

risposta

36

Nella prima versione di allenamento, si sta addestrando l'intero batch di dati di allenamento contemporaneamente, il che significa che il primo e il 3000esimo elemento di spec_train verranno elaborati utilizzando gli stessi parametri del modello in un unico passaggio. Questo è noto come Discesa gradiente (batch).

Nella seconda versione di allenamento, si sta formando un singolo esempio dai dati di allenamento in una volta, il che significa che il 3000 ° elemento di spec_train verrà elaborato utilizzando i parametri del modello che sono stati aggiornati 2999 volte dal momento che il primo elemento era più recente trasformati. Questo è noto come Discesa gradiente stocastico (o lo sarebbe se l'elemento fosse selezionato a caso).

In generale, TensorFlow viene utilizzato con set di dati troppo grandi per essere elaborati in un unico batch, pertanto viene preferito il mini-batch SGD (in cui un sottoinsieme degli esempi viene elaborato in un unico passaggio). L'elaborazione di un singolo elemento alla volta è teoricamente auspicabile, ma è intrinsecamente sequenziale e ha costi fissi elevati poiché le moltiplicazioni della matrice e altre operazioni non sono così densi dal punto di vista computazionale. Pertanto, elaborare un piccolo batch (ad esempio 32 o 128) di esempi contemporaneamente è l'approccio abituale, con più repliche di formazione su lotti diversi in parallelo.

Vedere questo Stats StackExchange question per una discussione più teorica su quando è necessario utilizzare un approccio rispetto all'altro.

+0

Questo è quello che ho ottenuto dal tuo post. Nella versione 1 i pesi e i bias non verranno aggiornati fino a quando il programma non trasmetterà l'intero batch di dati al modello. Ciò significa che 3000 punti dati produrranno una grande regolazione del peso.E per la versione 2 è come se io usassi quei 3000 punti dati per aggiornare i pesi per 3000 volte, 3000 regolazioni di piccolo peso. È corretto? Grazie. – yc2986

+1

Esatto, sì. E se si eseguono 3000 aggiornamenti separati, gli aggiornamenti successivi utilizzeranno versioni più aggiornate dei parametri, che tenderanno a migliorare la convergenza (per ciascun punto di dati addestrato). – mrry

+0

@mrry Puoi spiegare perché "L'elaborazione di un singolo elemento alla volta è teoricamente auspicabile"? Ho sempre pensato che una maggiore dimensione del lotto fosse migliore. –

0

Sì, c'è una differenza. Penso che la seconda funzione di perdita di senso possa essere un po 'confusa. È più simile alla formazione online. Per ogni punto di dati dell'intero batch, aggiorni tutti i tuoi parametri. Ma nel primo modo si chiama il gradiente batch in cui si prende un lotto alla volta e si prende la perdita media, quindi si aggiornano i parametri.

prega di fare riferimento questo link https://stats.stackexchange.com/questions/49528/batch-gradient-descent-versus-stochastic-gradient-descent Prima risposta è veramente buono in questo link