5

Tôi đã cố gắng sử dụng bình thường hóa hàng loạt để đào tạo mạng Neural của tôi bằng cách sử dụng TensorFlow nhưng nó không rõ ràng với tôi làm thế nào để sử dụng the official layer implementation of Batch Normalization (lưu ý điều này là khác với một từ API).Làm cách nào để sử dụng lớp Chuẩn hóa lô chính thức trong TensorFlow?

Sau khi đào một số khó khăn trên github issues, có vẻ như cần một tf.cond để sử dụng đúng cách và cũng là cờ 'resue = True' để thay đổi BN và biến tỷ lệ được sử dụng lại đúng cách. Sau khi hiểu rằng tôi đã cung cấp một mô tả nhỏ về cách tôi tin là đúng cách để sử dụng nó here.

Bây giờ tôi đã viết một kịch bản ngắn để kiểm tra nó (chỉ một lớp duy nhất và một ReLu, khó để làm cho nó nhỏ hơn này). Tuy nhiên, tôi không chắc chắn 100% làm thế nào để kiểm tra nó. Ngay bây giờ mã của tôi chạy không có thông báo lỗi nhưng trả về NaNs bất ngờ. Điều này làm giảm sự tự tin của tôi rằng mã tôi đã cung cấp trong bài đăng khác có thể đúng. Hoặc có lẽ mạng tôi có là lạ. Dù bằng cách nào, ai đó biết sai? Đây là mã:

import tensorflow as tf 
# download and install the MNIST data automatically 
from tensorflow.examples.tutorials.mnist import input_data 
from tensorflow.contrib.layers.python.layers import batch_norm as batch_norm 

def batch_norm_layer(x,train_phase,scope_bn): 
    bn_train = batch_norm(x, decay=0.999, center=True, scale=True, 
    is_training=True, 
    reuse=None, # is this right? 
    trainable=True, 
    scope=scope_bn) 

    bn_inference = batch_norm(x, decay=0.999, center=True, scale=True, 
    is_training=False, 
    reuse=True, # is this right? 
    trainable=True, 
    scope=scope_bn) 

    z = tf.cond(train_phase, lambda: bn_train, lambda: bn_inference) 
    return z 

def get_NN_layer(x, input_dim, output_dim, scope, train_phase): 
    with tf.name_scope(scope+'vars'): 
     W = tf.Variable(tf.truncated_normal(shape=[input_dim, output_dim], mean=0.0, stddev=0.1)) 
     b = tf.Variable(tf.constant(0.1, shape=[output_dim])) 
    with tf.name_scope(scope+'Z'): 
     z = tf.matmul(x,W) + b 
    with tf.name_scope(scope+'BN'): 
     if train_phase is not None: 
      z = batch_norm_layer(z,train_phase,scope+'BN_unit') 
    with tf.name_scope(scope+'A'): 
     a = tf.nn.relu(z) # (M x D1) = (M x D) * (D x D1) 
    return a 

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) 
# placeholder for data 
x = tf.placeholder(tf.float32, [None, 784]) 
# placeholder that turns BN during training or off during inference 
train_phase = tf.placeholder(tf.bool, name='phase_train') 
# variables for parameters 
hiden_units = 25 
layer1 = get_NN_layer(x, input_dim=784, output_dim=hiden_units, scope='layer1', train_phase=train_phase) 
# create model 
W_final = tf.Variable(tf.truncated_normal(shape=[hiden_units, 10], mean=0.0, stddev=0.1)) 
b_final = tf.Variable(tf.constant(0.1, shape=[10])) 
y = tf.nn.softmax(tf.matmul(layer1, W_final) + b_final) 

### training 
y_ = tf.placeholder(tf.float32, [None, 10]) 
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1])) 
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) 
with tf.Session() as sess: 
    sess.run(tf.initialize_all_variables()) 
    steps = 3000 
    for iter_step in xrange(steps): 
     #feed_dict_batch = get_batch_feed(X_train, Y_train, M, phase_train) 
     batch_xs, batch_ys = mnist.train.next_batch(100) 
     # Collect model statistics 
     if iter_step%1000 == 0: 
      batch_xstrain, batch_xstrain = batch_xs, batch_ys #simualtes train data 
      batch_xcv, batch_ycv = mnist.test.next_batch(5000) #simualtes CV data 
      batch_xtest, batch_ytest = mnist.test.next_batch(5000) #simualtes test data 
      # do inference 
      train_error = sess.run(fetches=cross_entropy, feed_dict={x: batch_xs, y_:batch_ys, train_phase: False}) 
      cv_error = sess.run(fetches=cross_entropy, feed_dict={x: batch_xcv, y_:batch_ycv, train_phase: False}) 
      test_error = sess.run(fetches=cross_entropy, feed_dict={x: batch_xtest, y_:batch_ytest, train_phase: False}) 

      def do_stuff_with_errors(*args): 
       print args 
      do_stuff_with_errors(train_error, cv_error, test_error) 
     # Run Train Step 
     sess.run(fetches=train_step, feed_dict={x: batch_xs, y_:batch_ys, train_phase: True}) 
    # list of booleans indicating correct predictions 
    correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) 
    # accuracy 
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 
    print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels, train_phase: False})) 

khi tôi chạy nó tôi nhận được:

Extracting MNIST_data/train-images-idx3-ubyte.gz 
Extracting MNIST_data/train-labels-idx1-ubyte.gz 
Extracting MNIST_data/t10k-images-idx3-ubyte.gz 
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz 
(2.3474066, 2.3498712, 2.3461707) 
(0.49414295, 0.88536006, 0.91152304) 
(0.51632041, 0.393666, nan) 
0.9296 

nó đã từng là tất cả những người cuối cùng là nan và bây giờ chỉ là một vài trong số họ. Tất cả mọi thứ tốt hay tôi là hoang tưởng?

+0

Kiểm tra câu trả lời của tôi trong https://stackoverflow.com/questions/33949786/how-could-i -use-batch-normalization-in-tensorflow/38325288 # 38325288. Tôi cũng đã có một NaN trong chức năng mất mát lẻ tẻ khi tôi bước đầu thử nó và có 2 vấn đề mà tôi đã giải quyết: 1) Giảm tốc độ học tập 2) Đảm bảo chuẩn hóa lô được thực hiện cho lớp MACHI. Có nghĩa là tôi chuẩn hóa hàng loạt đầu vào cho lớp ẩn và đầu ra của lớp ẩn. –

+0

Nếu tôi sử dụng một cái gì đó như: với tf.name_scope ('batch_norm'), là nó vẫn còn cần thiết để vượt qua biến phạm vi chức năng batch_norm? – resistancefm

Trả lời

6

Tôi không chắc chắn nếu điều này sẽ giải quyết vấn đề của bạn, tài liệu cho BatchNorm không phải là khá dễ sử dụng/thông tin, vì vậy đây là một bản tóm tắt ngắn về cách sử dụng BatchNorm đơn giản:

Trước hết , bạn xác định lớp BatchNorm của bạn. Nếu bạn muốn sử dụng nó sau một affine/lớp đầy đủ kết nối, bạn làm điều này (chỉ là ví dụ, trật tự có thể khác nhau/như bạn mong muốn):

... 
inputs = tf.matmul(inputs, W) + b 
inputs = tf.layers.batch_normalization(inputs, training=is_training) 
inputs = tf.nn.relu(inputs) 
... 

Chức năng tf.layers.batch_normalization gọi biến initializers. Đây là những biến nội bộ và cần có một phạm vi đặc biệt được gọi, nằm trong số tf.GraphKeys.UPDATE_OPS. Như vậy, bạn phải gọi hàm tối ưu của bạn như sau (sau khi tất cả các lớp đã được xác định!):

... 
extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) 
with tf.control_dependencies(extra_update_ops): 
    trainer = tf.train.AdamOptimizer() 
    updateModel = trainer.minimize(loss, global_step=global_step) 
... 

Bạn có thể đọc thêm về nó here. Tôi biết có hơi muộn để trả lời câu hỏi của bạn, nhưng nó có thể giúp những người khác gặp vấn đề về BatchNorm trong lưu lượng! :)

0
training =tf.placeholder(tf.bool, name = 'training') 

lr_holder = tf.placeholder(tf.float32, [], name='learning_rate') 
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) 
with tf.control_dependencies(update_ops): 
     optimizer = tf.train.AdamOptimizer(learning_rate = lr).minimize(cost) 

khi xác định các lớp, bạn cần phải sử dụng địa vị 'huấn luyện'

batchNormal_layer = tf.layers.batch_normalization(pre_batchNormal_layer, training=training) 
Các vấn đề liên quan