Tensorflow: Mudah digunakan lapisan norma batch.

Dibuat pada 16 Feb 2016  ·  127Komentar  ·  Sumber: tensorflow/tensorflow

Banyak non-ahli menggunakan kode berikut http://stackoverflow.com/questions/33949786/how-could-i-use-batch-normalization-in-tensorflow?answertab=votes#tab -top.

Akan menyenangkan memiliki lapisan norma kelompok resmi mengingat pentingnya pelatihan DNN.

contributions welcome docs-bug

Komentar yang paling membantu

Semua 127 komentar

Saya sedang mengerjakan beberapa bagian itu.

Saya pikir ada yang salah dengan lapisan ini. dalam pelatihan semuanya baik-baik saja dan penurunan kerugian sangat baik. tetapi dalam pengujian saya mendapatkan akurasi nol.
By the way dalam pengujian ketika saya menggunakan is_training = False, saya mendapatkan nol acc.
Saya tahu normalisasi batch berperilaku berbeda dalam fase pelatihan dan pengujian , seperti yang dijelaskan dalam - Quora . Saya pikir implementasi ini tidak jelas

Sama di sini, saya telah mengalami beberapa perilaku tak terduga dengan is_training = False. Bagaimana cara yang benar untuk mengubah bendera ini? Saat ini saya menggunakan tf.cond karena tidak memerlukan tf.placeholders dengan sendirinya.

@pawni Anda harus menggunakan Python boolean untuk is_training . Tidak boleh menjadi tf.cond .

@ppwwyyxx baik saya melakukan tf.cond(placeholder, batch_norm(.., is_training = True), batch_norm(.., is_training = False)) atau seseorang hanya seharusnya melakukan batch_norm(.., is_training=variable) dan mengubahnya di luar grafik bila diperlukan?

Oh, saya pikir Anda melakukan batch_norm(.., is_training=tf.cond(placeholder)) , itu tidak benar.
Cara Anda saat ini mungkin juga bermasalah. Anda harus memeriksa ulang bahwa dua batch_norm op yang Anda buat memiliki cakupan yang sama, jika tidak, keduanya tidak akan berbagi statistik mean / varians yang mendasarinya.

Untuk melakukan ini argumen reuse mungkin membantu, tapi saya tidak yakin karena saya menggunakan versi saya sendiri dari lapisan bn.

Saya menggunakan cakupan yang sama dan reuse=True . Tampaknya kadang-kadang berhasil tetapi saya tidak terlalu yakin. Akan sangat bagus jika layer dapat ditambahkan ke dokumentasi dengan penjelasan singkat bagaimana cara terbaik menangani perubahan dari pelatihan ke pengujian.

@sguada FY

Saat ini batch_norm membutuhkan python boolean, tetapi kami sedang berupaya menambahkan opsi untuk meneruskan Tensor.

@pawni Jika Anda tidak ingin khawatir tentang pemutakhiran moving_mean dan moving_variance set updates_collections = Tidak ada untuk memastikannya diperbarui, jika tidak, Anda perlu memastikan update_ops yang ditambahkan ke tf.GraphKeys.UPDATE_OPS dijalankan selama pelatihan.

Saya pikir tensorflow membutuhkan 2 metode hiper yang mengubah status model, seperti obor. ubah status model . Saya pikir ini sangat mudah.

apakah ada skrip kecil dengan NN yang sangat sederhana yang menunjukkan cara yang tepat untuk menggunakan lapisan BN "resmi" ini? Saya sangat menghargainya.

maaf jika ini sedikit berulang, tetapi tampaknya API berbicara tentang BN dalam antarmuka yang berbeda: https://www.tensorflow.org/versions/r0.9/api_docs/python/nn.html#batch_normalization

bukankah itu cara resmi menggunakan BN? Saya bingung tentang cara menggunakannya dan SO tampaknya sudah ketinggalan zaman dan kemudian ada lapisan di tautan yang berbeda dari API, bagaimana tepatnya seseorang melakukan ini? Saya tidak jelas apakah harus pergi ke SO atau bertanya di sini.

maaf untuk spammingnya, tapi apa salahnya hanya menggunakan sesuatu seperti ini:

def standard_batch_norm(l, x, n_out, phase_train, scope='BN'):
    """
    Batch normalization on feedforward maps.
    Args:
        x:           Vector
        n_out:       integer, depth of input maps
        phase_train: boolean tf.Varialbe, true indicates training phase
        scope:       string, variable scope
    Return:
        normed:      batch-normalized maps
    """
    with tf.variable_scope(scope+l):
        #beta = tf.Variable(tf.constant(0.0, shape=[n_out], dtype=tf.float64 ), name='beta', trainable=True, dtype=tf.float64 )
        #gamma = tf.Variable(tf.constant(1.0, shape=[n_out],dtype=tf.float64 ), name='gamma', trainable=True, dtype=tf.float64 )
        init_beta = tf.constant(0.0, shape=[n_out], dtype=tf.float64)
        init_gamma = tf.constant(1.0, shape=[n_out],dtype=tf.float64)
        beta = tf.get_variable(name='beta'+l, dtype=tf.float64, initializer=init_beta, regularizer=None, trainable=True)
        gamma = tf.get_variable(name='gamma'+l, dtype=tf.float64, initializer=init_gamma, regularizer=None, trainable=True)
        batch_mean, batch_var = tf.nn.moments(x, [0], name='moments')
        ema = tf.train.ExponentialMovingAverage(decay=0.5)

        def mean_var_with_update():
            ema_apply_op = ema.apply([batch_mean, batch_var])
            with tf.control_dependencies([ema_apply_op]):
                return tf.identity(batch_mean), tf.identity(batch_var)

        mean, var = tf.cond(phase_train, mean_var_with_update, lambda: (ema.average(batch_mean), ema.average(batch_var)))
        normed = tf.nn.batch_normalization(x, mean, var, beta, gamma, 1e-3)
    return normed

maka mudah untuk memberi tahu tensorflow mana yang akan digunakan dengan kamus umpan seperti di:

feed_dict = {x: Xminibatch, y_: Yminibatch, phase_train: True}
sess.run(fetches=[merged,train_step], feed_dict=feed_dict)

karena tidak jelas apakah implementasinya akan berubah, saya ingin memberikan saran (perhatikan mudahnya untuk memperluas ke konvolusi dan hal-hal yang saya tidak tempelkan kode itu).

@pawni @ppwwyyxx apakah kalian memutuskan apakah Anda harus menggunakan reuse to true untuk menyelesaikan masalah pelingkupan?

@ brando90 saat ini saya melakukan sesuatu seperti:

def BatchNorm(inputT, is_training=True, scope=None):
    return tf.cond(isTraining,
                lambda: batch_norm(inputT, is_training=True,
                                   center=False, updates_collections=None, scope=scope),
                lambda: batch_norm(inputT, is_training=False,
                                   updates_collections=None, center=False, scope=scope, reuse = True))

Namun, saya pikir # 3265 pada dasarnya ingin menerapkannya seperti ini. Referensi bisa menjadi implementasi dropout di sini: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/layers/python/layers/layers.py#L433 -L435

Ketika updates_collections = None maka pembaruan terjadi di tempat dan lebih mudah menggunakan tf.cond () untuk memungkinkan is_training menjadi Tensor sedikit lebih rumit adalah ketika pembaruan ditunda dan update_ops dijalankan kemudian.
Saya akan mencoba untuk mendapatkan bagian pertama segera.

@ brando90 @pawni dia kodenya bekerja dengan baik, tapi harus berubah seperti di bawah ini

def BatchNorm(inputT, is_training=True, scope=None):
    # Note: is_training is tf.placeholder(tf.bool) type
    return tf.cond(is_training,  
                lambda: batch_norm(inputT, is_training=True,  
                                   center=False, updates_collections=None, scope=scope),  
                lambda: batch_norm(inputT, is_training=False,  
                                   updates_collections=None, center=False, scope=scope, reuse = True))  

Dan saat dijalankan dalam waktu pelatihan atau ujian,

# when training 
sess.run([opt, loss], feed_dict={x: bx, y: by, is_training=True})  

# when test 
sess.run([opt, loss], feed_dict={x: bx, y: by, is_training=False})  

Kode ini berfungsi, tetapi seperti # 3265 mengatakan akan sangat bagus jika tf.contrib.layers.batch_norm mendapatkan is_training variabel sebagai tf.plcaeholer .

@nmhkahn @pawni terima kasih atas cuplikan kodenya. Mereka sangat berguna dalam menambahkan normalisasi batch ke jaringan konvolusi saya. Pelatihan tampaknya berhasil dengan baik. Pengujian tidak. Dalam beberapa versi akurasi pelatihan kode jauh lebih tinggi daripada akurasi pengujian, yang mungkin berarti saya tidak membagikan parameter normalisasi batch. Di versi lain dari kode saya mendapatkan "ValueError: Variabel konv1 / beta sudah ada, tidak diizinkan. Apakah Anda bermaksud menyetel reuse = True di VarScope?" yang sepertinya menunjukkan bahwa saya mencoba mempelajari kembali parameter ... ketika saya mencoba menggunakan kembali.

Adakah yang bisa memberikan contoh bagaimana memanggil fungsi "def BatchNorm" selama pelatihan dan pengujian sehingga berbagi variabel terjadi dengan benar.

Terima kasih atas bantuannya.

UPDATE 25 Juli 2016:

@nmhkahn @pawni terima kasih atas komentar Anda. Setelah melihat lebih dekat kode di kontrib saya menyadari apa masalah saya. Selama pelatihan dan pengujian, kami memperbarui atau menggunakan kembali empat variabel (beta, gamma, moving_mean, dan moving_variance). Untuk membuatnya unik, saya harus menetapkan cakupan per lapisan. Saya melakukannya seperti ini:

conv1 = tf.nn.relu (batch_norm_layer (conv2d_stride2_valid (data, W_conv1) + b_conv1, train_phase, scope = "conv1"))

di mana batch_norm_layer mirip dengan contoh dari @nmhkahn @pawni , konv2d_stride2_valid hanyalah def untuk mendefinisikan lapisan konvolusional, dan W_conv1 dan b_conv1 adalah variabel yang menahan bobot dan bias. Saya mungkin bisa menghapus istilah bias karena kami menggunakan normalisasi batch.

Sekarang internet bekerja dengan baik. Saya perhatikan setelah merencanakan akurasi dalam mode pelatihan dan pengujian bahwa akurasi pengujian mulai meningkat setelah akurasi pelatihan. Dalam retrospeksi, itu masuk akal karena kami mengumpulkan statistik set data untuk pengujian. Tetapi tampaknya saya melakukan sesuatu yang salah selama tes awal saya. Terima kasih atas komentar Anda dan membuat normalisasi batch tersedia untuk komunitas.

@nmhkahn apa bedanya dengan saran pawni?

@ brando90 Saya mengalami kesalahan kecil dalam versi saya yang telah diperbaiki oleh nmhkahn (mengubah isTraining menjadi is_training )

@diegoAtAlpine Saya menemukan masalah yang sama - meskipun tidak yakin mengapa ini terjadi. Namun, ValueError harus diselesaikan dengan potongan kode. Tidak yakin apa yang Anda ingin lihat bagaimana menyebutnya sebagai contoh nmhkahn tampaknya melakukan pekerjaan itu?

@nmhkahn @pawni @ ketika Anda melakukannya:

sess.run([opt, loss], feed_dict={x: bx, y: by, is_training=True})

bukankah itu berarti Anda menggunakan is_training sebagai placeholder? Orang-orang berkomentar bahwa mereka ingin is_training menjadi pemegang placer tetapi itulah yang saya miliki untuk versi saya:

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

benar bukan?

Saya telah memperluas tf.contrib.layers.batch_norm untuk memungkinkan penerusan Tensor atau Placeholder untuk is_training. Ini akan segera digabungkan dalam kontribus TF.

Sekarang tersedia dalam
https://github.com/tensorflow/tensorflow/commit/9da5fc8e6425cabd61fc36f0dcc1823a093d5c1d#diff -94bbcef0ec8a5cdef55f705e99c2b2ed

apakah hanya saya atau apakah menambahkan lapisan BN ini secara nyata memperlambat pelatihan satu periode?

@ Brando90 Ini memperlambat pelatihan untuk saya juga, tetapi saya pikir ini diharapkan karena perlu menghitung beberapa statistik. Dan versi Anda terlihat bagus untuk saya.

BatchNorm saat ini sangat lambat (karena semua statistik yang dihitung), tetapi mereka bekerja untuk menambahkan operasi batchnorm yang dapat dimengerti seperti yang dikatakan di sini .

@nmhkahn pertanyaan singkat. Saat Anda menulis (untuk pengujian):

sess.run([opt, loss], feed_dict={x: bx, y: by, is_training=False})

dalam teori, dapatkah bx dan menjadi kumpulan data? yaitu masih bisa menjadi set pelatihan meskipun kita tidak berlatih? (yaitu hanya untuk melacak kesalahan kereta)

@ brando90 Anda benar.

Saya juga bingung tentang flag is_training dan reuse. Saya telah membuat program mengikuti contoh CIFAR, di mana kode saya terstruktur seperti di CIFAR:

  • Kesimpulan
  • Kerugian
  • Melatih

Dan saya menjalankannya dengan mode multi-gpu (untuk pelatihan).
Jadi saya memiliki satu skrip untuk pelatihan (mirip dengan cifar10_multigpu.py) dan satu skrip untuk pengujian (mirip dengan cifar10_eval.py).
Begitu

for ii in xrange(2):  # Num of GPU
  with tf.device('/gpu:%d' % ii):
    with tf.name_scope('device_%d' % ii) as scope:

      data_batch, label_batch = factory.GetShuffleBatch(batch_size)

      unnormalized_logits = factory.MyModel(dataBatch=data_batch, numClasses=numClasses,
                                                 isTraining=True)

      More stuff happening
      tf.get_variable_scope().reuse_variables()

Inferensi terjadi dengan fungsi MyModel. (di bawah ini adalah contoh fungsinya, pada kenyataannya saya menggunakan lebih banyak lapisan dan neuron).

def MyModel(data_batch, num_classes, feature_dim):

  # Hidden Layer 1
  with tf.variable_scope('hidden1') as scope:
    weights = variable_on_cpu('weights',[feature_dim, 256], tf.truncated_normal_initializer(stddev=0.04))
    biases = variable_on_cpu('biases', [256], tf.constant_initializer(0.001))
    hidden1 = tf.nn.relu(tf.matmul(data_batch, weights) + biases, name=scope.name)

  # Hidden Layer 2
  with tf.variable_scope('hidden2') as scope:
    weights = variable_on_cpu('weights',[256, 256], tf.truncated_normal_initializer(stddev=0.04))
    biases = variable_on_cpu('biases', [256], tf.constant_initializer(0.001))
    hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases, name=scope.name)

  # output, unnormalized softmax
  with tf.variable_scope('softmax_unnorm') as scope:

    weights = variable_on_cpu('weights', [256, num_classes], tf.truncated_normal_initializer(stddev=1/num_classes))
    biases = variable_on_cpu('biases', [num_classes], tf.constant_initializer(0.0))
    softmax_un = tf.add(tf.matmul(hidden2, weights), biases, name=scope.name)

  return softmax_un

Saya ingin melakukan nomalisasi batch. Jadi ketika saya melakukannya:

def MyModel(data_batch, num_classes, feature_dim, isTraining):

  with tf.variable_scope('bnormalization') as scope:
    norm_data_batch = tcl.batch_norm(inputs=dataBatch, epsilon=0.0001, is_training=isTraining, 
                                      reuse=True, scope=scope)

  # Hidden Layer 1
  with tf.variable_scope('hidden1') as scope:
    weights = variable_on_cpu('weights',[feature_dim, 256], tf.truncated_normal_initializer(stddev=0.04))
    biases = variable_on_cpu('biases', [256], tf.constant_initializer(0.001))
    hidden1 = tf.nn.relu(tf.matmul(data_batch, weights) + biases, name=scope.name)

Saya mendapat kesalahan berikut dalam fase pelatihan:
Bnormalisasi variabel / beta tidak ada, tidak diizinkan. Apakah Anda bermaksud menyetel reuse = None di VarScope?

Dari apa yang telah saya baca di utas ini pada fase pelatihan, saya harus menggunakan reuse = None. Apakah bagian ini sudah benar? Jika ini benar, maka karena saya menggunakan dua GPUS, haruskah saya melakukan reuse = None di GPU pertama dan menggunakan kembali = True di GPU kedua? Atau karena saya melakukan tf.get_variable_scope (). Reuse_variables () itu mengurus dirinya sendiri?

Akhirnya, dalam tahap pengujian, haruskah saya memiliki is_training = False dan reuse = True?

Bantuan apa pun sangat dihargai.

Sekarang tf.contrib.layers.batch_norm menerima Tensor, Variable, atau Placeholder sebagai is_training

https://github.com/tensorflow/tensorflow/commit/9da5fc8e6425cabd61fc36f0dcc1823a093d5c1d#diff -94bbcef0ec8a5cdef55f705e99c2b2ed

Apakah normalisasi Batch memperburuk eksperimen saya? Saya mencobanya pada jaringan NN 2 lapis berdasarkan tutorial pemula MNIST dan saya secara konsisten mendapatkan hasil yang lebih buruk ketika ada BN: dengan BN (satu dengan skala dan pusat terlatih dan yang lainnya tidak) akurasi 0,8423, 0,8221 dan tanpa akurasi BN 0,9477.

Skrip saya ada di sini https://github.com/brando90/tensor_flow_experiments/blob/master/tf_tutorials/beginner_tutorial_MNIST_BN.py

ada yang pernah mengalami masalah ini atau BN hanya seperti ini dan saya perlu melakukan sesuatu yang lain untuk membuatnya bekerja?

Versi terbaru tf.contrib.layers.batch_norm sekarang menerima placeholder untuk is_training jadi tidak perlu melakukannya sendiri.

Tetapi yang penting adalah Anda meneruskan updates_collections = None sehingga moving_mean dan moving_variance diperbarui di tempat, jika tidak, Anda perlu mengumpulkan update_ops dan memastikannya dijalankan.

Saya ingin mendorong Anda untuk menggunakan tf.contrib.layers atau tf.contrib.slim untuk membangun model Anda.

slim = tf.contrib.slim

def build_NN_two_hidden_layers(x, is_training):
 batch_norm_params = {'is_training': is_training, 'decay': 0.9, 'updates_collections': None}
 with slim.arg_scope([slim.fully_connected], 
    activation_fn=tf.nn.relu,
    weigths_initializer=tf.contrib.layers.xavier_initializer(),
    biases_initializer=tf.constant_initializer(0.1),
    normalizer_fn=slim.batch_norm,
    normalizer_params=batch_norm_params):
   net = slim.fully_connected(x, 50, scope='A1')
   net = slim.fully_connected(net, 49, scope='A2')
   y = slim.fully_connected(net, 10, activation_fn=tf.nn.softmax, normalizer_fn=None, scope='A3')
 return y


@sguada Saya mengubah yang lama saya di mana saya secara manual mengatakan untuk melatih atau tidak (berdasarkan tf.cond) dan sekarang tampaknya keakuratannya hingga ~ 95 lagi. Mengapa saya perlu mengubah updates_collections menjadi None? Apakah Anda keberatan menjelaskan mengapa hal itu memberikan perbedaan akurasi yang begitu besar? Ini tampak seperti perubahan non-sepele (haruskah None menjadi nilai defaultnya jika itu sangat penting?). Terima kasih! :)

Selain itu, saya perhatikan Anda mengatakan itu adalah placeholder dan saya tidak perlu melakukannya secara manual. Namun, ketika saya melewati placeholder untuk is_training, katanya

TypeError: Using a tf. Sensor as a Python bool is not allowed. Use jika tidak Tidak ada: instead of if t: to test if a tensor is defined, and use the logical TensorFlow ops to test the value of a tensor.

dan menunjuk ke kode batch_norm. Mungkin bagus untuk menunjukkan bagaimana placeholder ini harus digunakan karena sepertinya saya tidak mengerti bagaimana seharusnya digunakan. Terima kasih! :)

@ brando
Bagian yang relevan dari kode ada di sini L227-256 .

Seperti yang akan Anda lihat, ada pernyataan with ops.control_dependencies yang memaksa pembaruan. Saya percaya bahwa untuk kode yang akan digunakan "langsung dari kotak" defaultnya harus None.

Adapun komentar saya di atas 1122 , saya menemukan bahwa tf.get_variable_scope (). Reuse_variables () menangani masalah ini, jadi dalam fase pelatihan argumen penggunaan kembali batch_norm harus Tidak Ada. Ini ada hubungannya dengan pernyataan variable_op_scope (baca dokumentasinya di tensorflow)

Penggunaan batch_norm dengan tf.placeholder

x = tf.placeholder(tf.float32, [None, 784])
is_training = tf.placeholder(tf.bool, [], name='is_training')
y = build_NN_two_hidden_layers(x, is_training)

# For training
sess.run(y, {is_training: True, x: train_data})

# For eval
sess.run(y, {is_training: False, x: eval_data})

Masalah sebelumnya adalah Anda tidak memperbarui moving_mean dan moving_variance setelah setiap langkah, ketika updates_collections adalah None, pembaruan akan dipaksa sebagai bagian dari komputasi.
Namun, jika jaringan memiliki banyak lapisan batch_norm, akan lebih efisien untuk mengumpulkan semua operasi pembaruan dan menjalankannya bersama-sama, sehingga setiap lapisan tidak perlu menunggu pembaruan selesai.

y = build_model_with_batch_norm(x, is_training)
update_ops = tf.group(tf.get_collection(tf.GraphKeys.UPDATE_OPS))

sess.run([y, update_ops])

Apakah sudah ada kemajuan yang dicapai dengan mempercepat norma batch?

Saya mencoba menggunakan norma batch dengan NN yang terhubung padat 2 lapis dengan set data (rata) MNIST (dan unit relu) untuk tugas pengkodean otomatis dan saya terus mendapatkan kesalahan NaN. Ada yang tahu mengapa ini terjadi? Apakah ini mungkin dengan BN? tampak mencurigakan, tetapi itu tidak bisa menjadi pengaturan pembelajaran saya, menilai dll. (tetapi saya akan berasumsi seharusnya tidak karena BN harus menjadi semacam rubust untuk ini)

@sguada Saya tidak memahami cara yang benar dalam menggunakan batch_norm khususnya tentang flag updates_collections . Jika saya mengerti dengan benar jika benderanya adalah None jaringan tidak efisien, jadi saya harus membiarkan updates_collections=tf.GraphKeys.UPDATE_OPS dan kemudian saya harus mengumpulkan semua pembaruan batch_norm dan menjalankannya bersama-sama.

Anda mengumpulkan pembaruan batch_norms dengan melakukan: update_ops = tf.group(tf.get_collection(tf.GraphKeys.UPDATE_OPS)) .

Saya memiliki banyak model berbeda yang menggunakan lapisan batch_norm berbeda, ini tidak akan berfungsi dengan benar ?:

#model 1
y1 = build_model_with_batch_norm(x, is_training)
update_ops1 = tf.group(tf.get_collection(tf.GraphKeys.UPDATE_OPS))
sess.run([y1, update_ops1])
#model 2
y2 = build_model_with_batch_norm(x, is_training)
update_ops2 = tf.group(tf.get_collection(tf.GraphKeys.UPDATE_OPS))
sess.run([y2, update_ops2])

Bisakah Anda menjelaskan bagian ini dengan sedikit lebih detail? Terima kasih banyak.

Taruh saja di kunci-koleksi terpisah:

# While building your 1st model...
tf.contrib.layers.batch_norm(..., updates_collection="updates-model1")

# same for 2nd model with key "updates-model2"
#model 1
y1 = build_model_with_batch_norm(x, is_training)
update_ops1 = tf.group(tf.get_collection("updates-model1"))
sess.run([y1, update_ops1])
#model 2
y2 = build_model_with_batch_norm(x, is_training)
update_ops2 = tf.group(tf.get_collection("updates-model1"))
sess.run([y2, update_ops2])

Namun demikian, dokumentasinya sepertinya sudah ketinggalan zaman. Ini memberitahu untuk melakukan hal berikut:

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
if update_ops:
    updates = tf.group(update_ops)
    total_loss = control_flow_ops.with_dependencies([updates], total_loss)

Tapi:

  • _tf.group () _ tidak menerima daftar. Saya menggantinya dengan _tf.tuple () _
  • Saya tidak tahu cara mengakses _control_flow_ops.with_dependencies () _. Saya telah melihat contoh lain hanya menggunakan tf.with_dependecies (), tetapi saya tidak dapat melakukannya dengan Tensorflow 0.10. Saya menemukannya di sini: _tf.python.control_flow_ops.with_dependencies () _

EDIT:

Dokumentasi harus diperbarui ke s.th. seperti ini:

from tensorflow.python import control_flow_ops

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
if update_ops:
    updates = tf.tuple(update_ops)
    total_loss = control_flow_ops.with_dependencies(updates, total_loss)

EDIT 2:

Setelah melakukan beberapa proses di jaringan saya, saya harus mengatakan bahwa saya tidak dapat melihat perbedaan kinerja apa pun antara menggunakan _updates_collections = None_ dibandingkan dengan mengambil _tf.GraphKeys.UPDATE_OPS_ secara manual saat membuat grafik . Bahkan dengan banyak penggunaan normalisasi batch (secara total, _tf.get_collection saya (tf.GraphKeys.UPDATE_OPS) _ mengembalikan 140 Operasi Pembaruan, semuanya hanya operasi BN)

Sunting: Sulit dikatakan, jika hasil saya benar, tetapi seluruh jaringan benar-benar menjadi 1,5x lebih cepat. Sejauh yang saya tahu, BN-statistik dihitung berdasarkan CPU, bukan GPU sejauh ini.

Adakah di antara Anda yang dapat melihat manfaat kinerja juga? Silakan bagikan hasil Anda :)

Kembali ke masalah kinerja, apakah lapisan norma batch saat ini bermanfaat sama sekali dari penggunaan GPU? Adakah yang pernah merasakan manfaat dari GPU dengan penerapan norma batch ini?

Maaf untuk spam, tapi dokumentasinya tidak benar-benar menjelaskan cara menggunakan BN ini dengan konvolusi (mungkin harus disediakan di suatu tempat?). Singkatnya, bagaimana cara mengetahui bahwa ia harus menerapkan dan mempelajari parameter yang sama per fitur (bukan per aktivasi)?

(Apakah setidaknya ada cuplikan kode untuk melakukan ini?)

Slim batch_norm wrapper dinormalisasi selama dimensi terakhir tensor input Anda. Jadi jika tensor input 2D yang berasal dari lapisan yang sepenuhnya terhubung, ia akan dinormalisasi melalui batch, dan dengan demikian melakukan normalisasi per aktivasi. Jika tensor 4D berasal dari konvolusi, ia akan dinormalisasi pada tiga dimensi pertama (batch, lebar, kedalaman), dan dengan demikian melakukan normalisasi per fitur. @sguada mungkin sedikit lebih deskriptif tentang ini.

@nmhkahn Mengenai cuplikan kode Anda, bolehkah saya bertanya mengapa reuse disetel menjadi None bila is_training=True ? Bukankah itu akan memicu parameter penskalaan gamma dan parameter offset beta diinisialisasi ulang di setiap langkah pelatihan? Saya pikir di makalah asli, beta dan gamma "dipelajari bersama dengan parameter model asli". Untuk melakukan itu, bukankah seharusnya mereka hanya diinisialisasi sekali dan kemudian digunakan kembali dalam semua langkah pelatihan?

tf.cond(is_training, lambda: batch_norm(inputT, is_training=True, updates_collections=None, scope=scope), lambda: batch_norm(inputT, is_training=False, updates_collections=None, scope=scope, reuse = True))

Saya sangat menghargai pekerjaan yang telah dilakukan oleh tim TF di sini untuk membuat batch_norm tersedia dan efektif. Dari pencarian saya, utas ini adalah sumber terbaik tentang cara menggunakannya. Ada banyak masalah dan ide berbeda yang berkeliaran di sini, dan sulit untuk menemukan saran konsensus untuk kasus standar paling sederhana tentang cara menggunakan lapisan batch_norm. Saya pikir akan ada banyak manfaat dalam memperluas dokumentasi untuk menentukan penggunaan yang disarankan secara tepat.

Upaya terbaik saya untuk mengetahuinya membawa saya ke kode berikut:

is_training_ph = tf.placeholder(tf.bool)
...
with tf.variable_scope('bn_test_layer') as vs:
    layer_output = tf.cond(is_training_ph,
        lambda: tf.contrib.layers.batch_norm(layer_input, is_training=True, center=True, scale=True, activation_fn=tf.nn.relu, updates_collections=None, scope=vs),
        lambda: tf.contrib.layers.batch_norm(layer_input, is_training=False, center=True, scale=True, activation_fn=tf.nn.relu, updates_collections=None, scope=vs, reuse=True))

Kemudian saya menetapkan is_training_ph ke True untuk pelatihan dan False untuk pengujian. Ini tidak berhasil untuk saya. Modelnya berlatih dengan baik, tetapi kinerja pengujiannya buruk. Sebaliknya, jika saya mempertahankan is_training_ph = True untuk waktu pengujian, ini berfungsi dengan baik. Jadi, saya menduga saya masih memiliki masalah ruang lingkup sehingga tidak menemukan variabel yang ada dengan tepat.

@ davek44 Saya menggunakan kerangka kode yang sama yang Anda gunakan dan saya mengamati hal yang sama: ketika mengaktifkan is_training=True selama fase pelatihan dan mematikan is_training=False untuk validasi dan / atau fase pengujian, model berlatih dengan baik seperti yang dijelaskan di makalah (model menyatu lebih cepat dan saya dapat menggunakan kecepatan pemelajaran yang lebih besar), namun kinerja pengujiannya buruk. Jika saya menyalakan is_training=True sepanjang waktu, modelnya melatih sama seperti tanpa memasukkan lapisan norma batch. Saya belum tahu apa yang saya lakukan salah, saya berencana menggunakan TensorBoard untuk memantau parameter. Bisakah Anda memperbarui jika Anda mendiagnosis penyebab perilaku ini?

tf.contrib.layers.batch_norm dapat menggunakan tensor sebagai is_training, jadi tidak perlu melakukan apa-apa.

is_training_ph = tf.placeholder(tf.bool)

outputs = tf.contrib.layers.batch_norm(layer_input, is_training=is_training_ph, center=True, scale=True, activation_fn=tf.nn.relu, updates_collections=None, scope='batch_norm'),

Saya melihat kinerja pengujian yang buruk yang sama dengan kode itu.

Tanpa detail lebih lanjut tidak mungkin untuk diketahui, tebakan saya adalah Anda hanya berlatih untuk beberapa iterasi, jadi moving_mean dan moving_average belum bertemu.

Anda dapat mengubah batch_size selama pengujian untuk melihat bagaimana performa menurun saat Anda membuat batch lebih kecil.

Saya melihat kinerja pengujian yang buruk yang sama dengan kode itu.

Saya memiliki masalah yang persis sama baik dengan tf.slim batchnorm atau dengan tf.cond dan masukan is_training sebagai placeholder.
Dalam kasus sebelumnya, ketika menyelidiki model yang dilatih, saya menemukan bahwa moving mean dan moving variance terdiri dari semua nol.
Dalam kasus terakhir, mean bergerak dan varians terlihat lebih masuk akal (dengan nilai berbeda), tetapi jika saya menggunakan is_training = False dalam waktu pengujian, kinerjanya juga sangat buruk. Menggunakan is_training = True, ini bekerja lebih baik tetapi saya pikir itu hanya menggunakan rata-rata bergerak dan varians di dalam batch pengujian.

@nmduc @ davek44 Saya menulis beberapa kode untuk melacak mean bergerak dan varian bergerak yang dihitung dalam tf.contrib.layers.batch_norm selama pelatihan dan pengujian. Saya menemukan bahwa nilai decay penting (mereka menggunakan peluruhan eksponensial untuk menghitung rata-rata bergerak dan varian bergerak), dengan pengaturan decay mendekati 1.0 (yaitu decay=.999 ), rata-rata pemindahan turun ke nilai yang mendekati 0. Saya melakukan 2 pengujian yang dijalankan dengan kode yang persis sama tetapi pengaturan decay berbeda di tf.contrib.layers.batch_norm , dan akurasi validasi / pengujian saya tampak lebih masuk akal.

Hasil uji coba dengan decay=0.9
screen shot 2016-11-16 at 1 51 51 pm

Hasil uji coba dengan decay=0.999 ( decay=0.999 adalah pengaturan default di tf.contrib.layers.batch_norm )
screen shot 2016-11-16 at 2 03 58 pm

(sepertinya juga nilai peluruhan yang lebih besar akan membutuhkan model untuk berlatih lebih lama untuk melihat perubahan akurasi validasi)

Yup itu sudah diperbaiki. Terima kasih telah membagikan analisis Anda @zhongyuk!

Saya mendorong para pengembang untuk mempertimbangkan membuat pembusukan = 0,9 sebagai default. Bahkan 0,99 tidak bekerja dengan baik untuk saya. Itu juga merupakan nilai default dalam implementasi Torch; lihat parameter momentum di https://github.com/torch/nn/blob/master/BatchNormalization.lua

@zhongyuk Terima kasih banyak telah berbagi. Ini bekerja untuk saya sekarang.

Ini sepertinya penting. @sguada kita harus mempertimbangkan tindakan yang benar di sini sebelum 1.0. Dalam jangka pendek, dapatkah salah satu pihak yang berkepentingan mengirimi saya PR yang mendokumentasikan fakta bahwa decay mungkin harus diturunkan secara signifikan ketika mengalami kinerja evaluasi yang buruk? Saya cukup yakin saya tidak pernah harus mengubah parameter itu, tetapi ini mungkin merupakan efek samping dari pengaturan terdistribusi.

Kami dapat mengubah default ke 0.9 atau mendokumentasikan dengan lebih baik dampaknya dalam kumpulan data yang lebih kecil atau beberapa pembaruan.
@vincentvanhoucke dalam pengaturan terdistribusi kami biasanya melakukan jutaan pembaruan jadi tidak apa-apa, namun dalam kasus lain seperti di sini yang hanya melakukan beberapa ratus pembaruan, itu membuat perbedaan besar:
Misalnya menggunakan decay = 0,999 memiliki bias 0,36 setelah 1000 pembaruan, tetapi bias itu turun menjadi 0,000045 setelah 10.000 pembaruan dan menjadi 0,0 setelah 50000 pembaruan.

Hanya ingin mencatat bahwa saya juga memiliki masalah kinerja pengujian yang buruk, khususnya menggunakan ukuran batch kecil (lebih kecil dari 10 daripada 200 yang saya gunakan untuk pelatihan mengurangi akurasi pengujian). Saya telah menggunakan tf.placeholder untuk beralih di antara mode pengujian / pelatihan.

Sangat bagus bahwa lapisan normalisasi batch ini berfungsi untuk konvergensi pelatihan yang lebih baik, tetapi jika Anda tidak dapat menerapkan model dalam produksi, tidak ada gunanya menggunakannya. Adakah yang bisa memastikan kinerja pengujian yang baik dengan sampel data kecil atau tunggal menggunakan lapisan norma batch ini?

Saya dapat mengonfirmasi bahwa kinerja pengujian baik saat menggunakan is_training = False dengan batch kecil dan bahkan dengan batch_size = 1, karena tidak menggunakan statistik dari batch, tetapi statistik yang dipelajari selama pelatihan. Hanya perlu memastikan bahwa statistik telah bertemu dengan peluruhan default = 0,999 yang menyiratkan setidaknya 50 ribu pembaruan.

Untuk menindaklanjuti dengan konfirmasi pengembang TF, saya melacak konvergensi statistik dengan dua pengaturan decay berbeda (dan pelatihan batch_size = 1). Dengan decay=0.99 , statistik bertemu (bias <0,001) setelah 550 ~ 600 langkah pembelajaran / pembaruan. Dengan decay=0.9 , statistik bertemu (bias <0,001) dalam 100 langkah pembelajaran / pembaruan.

@ syuada terima kasih, apakah itu juga berarti output sebenarnya tidak bergantung pada ukuran batch? karena saya memperhatikan perubahan yang sangat kecil dengan pengaruh besar pada akurasi saya (mungkin definisi kinerja saya lebih mudah terpengaruh oleh perubahan kecil ini). Tepatnya, semua nilai dalam tensor keluaran 128 dimensi saya meningkat sedemikian rupa sehingga total panjang vektor berskala hampir linier dengan ukuran batch. Per nilai ini tidak terlalu berbeda, tetapi memiliki dampak besar saat menghitung jarak vektor di ruang laten.

@zhongyuk terima kasih, saya telah menjalankan sekitar 5k pembaruan dengan decay=0.9 , jadi seharusnya sudah terkonvergensi dan pengujian kinerja menggunakan ukuran batch besar tidak masalah. Tetapi bahkan jika tidak, apakah itu akan menghasilkan perbedaan antara melatih dan menguji? Saya akan melihat kinerja buruk selama pelatihan dan pengujian jika tidak menyatu, bukan?

Saya akan menyelidiki lebih lanjut dan melihat apakah saya dapat mereproduksi masalah tersebut pada tugas lain. Terima kasih atas umpan balik cepatnya sejauh ini!

@dominikandreas Jika kinerja pengujian Anda yang buruk disebabkan oleh statistik yang tidak konvergen, Anda akan melihat kinerja pelatihan yang cukup baik tetapi kinerja pengujian yang buruk. Karena selama pelatihan, normalisasi batch dilakukan hanya dengan menggunakan statistik batch pelatihan. Namun, selama waktu pengujian, statistik rata-rata bergerak dari semua batch pelatihan digunakan untuk menormalkan tensor masukan.

Saya menemukan dan kesalahan dalam kode saya, normalisasi batch berfungsi dengan baik sekarang :-) terima kasih atas dukungan Anda

Hai @zhongyuk , bagaimana Anda melacak mean dan varians yang bergerak?
Terima kasih!

@rogertrullo Umumnya saya menyiapkan TensorBoard untuk melacak mean dan varians yang bergerak. Selain itu, saya juga mencoba mengambil statistik melalui tf.get_variable("moving_mean") dalam ruang lingkup selama pelatihan dan referensi untuk memantau bias.

Hai,
Saya memiliki masalah yang sama seperti yang dijelaskan lainnya bahwa saya memiliki hasil pelatihan yang baik tetapi validasi / pengujian buruk setelah menggunakan batch_norm.
Saya menggunakan fungsi seperti ini:
conv_normed1 = tf.contrib.layers.batch_norm (conv1 + block1_layer3_1_biases, update_collections = Tidak ada, scale = True, decay = batch_norm_decay, center = True, is_training = is_training)
nilai peluruhan 0,9
apakah saya perlu menyetel flag reuse?
Saya akan senang untuk bantuan apapun.

Saya telah menggunakan batch_norm seperti yang dijelaskan di utas ini (dengan tf.bool untuk pelatihan; dan ops.GraphKeys.UPDATE_OPS) dan semuanya berfungsi.

Saat menyimpan dan memulihkan menggunakan:
saver = tf.train.Saver ()
berhasil,

tetapi saat menyimpan menggunakan:
saver = tf.train.Saver (tf.trainable_variables () + [global_step])
sehingga saya dapat menghemat ruang penyimpanan (dengan tidak menyimpan gradien dll)
saat memulihkan ada kesalahan:
"nilai yang tidak diinisialisasi unpool4 / convc / bn / moving_mean"

Jelas ini karena moving_mean (dan saya kira moving_variance) belum disimpan untuk lapisan mana pun. Karena saya memiliki banyak nilai (bersarang di banyak lapisan) - apa cara paling efisien untuk menambahkannya ke daftar nilai yang akan disimpan? Selain itu, mengingat ini adalah variabel yang dapat dilatih, mengapa variabel tersebut tidak ditambahkan ke koleksi trainable_variables?

Rata -rata bergerak
Untuk menyimpan / memulihkannya, Anda dapat menggunakan tf.global_variables ()

bagi saya hal-hal mulai berfungsi ketika saya menggunakan pembungkus ini:
def batch_norm_wrapper(x, phase, decay, scope, reuse): with tf.variable_scope(scope, reuse=reuse): normed = tf.contrib.layers.batch_norm(x, center=True, scale=True, decay=decay, is_training=phase, scope='bn',updates_collections=None, reuse=reuse) return normed
seluruh penggunaan cakupan dan penggunaan kembali tidak jelas di utas ini menurut pendapat saya.

Terimakasih banyak. Dengan tf.global_variables () file penyimpanan jauh lebih besar karena saya pikir itu termasuk gradien; pada akhirnya saya menggunakan:

saver = tf.train.Saver ([x untuk x di tf.global_variables () jika 'Adam' tidak ada di x.name])

dan karena manajer sesi init tidak menginisialisasi mereka dengan benar:

sess.run (tf.variables_initializer ([x untuk x di tf.global_variables () jika 'Adam' di x.name]))

(Menggunakan tf.train.AdamOptimizer)

Anda juga bisa menggunakan tf.model_variables () yang berisi variabel model, yaitu moving_mean

@sguada Maaf merepotkan Anda, tetapi apakah mungkin untuk membuat contoh tentang cara menggunakan slim.batch_norm jika digabungkan dengan slim.conv2d / slim.fully_connect di readme.md?

Saya menggunakan slim.batch_norm, tetapi mendapatkan performa pelatihan yang baik dan performa validasi / pengujian yang buruk. Saya pikir itu pasti karena penggunaan yang tidak benar dari reuse atau scope atau beberapa parameter lainnya. Meskipun ada banyak masalah pada normalisasi batch, sulit untuk menemukan potongan kode lengkap tentang cara menggunakannya, khususnya. untuk mengetahui cara melewatkan parameter yang berbeda dalam fase yang berbeda.

Katakanlah, dalam kode mnist_bn saya, saya mengontrol dependensi menggunakan tf.GraphKeys.UPDATE_OPS dan menyiapkan is_training sebagai placeholder. Tetapi kinerja validasi masih buruk jika saya memberi makan {is_training: False}.

Saya akan sangat menghargai jika ada contoh normalisasi batch yang resmi dan lengkap (yang berarti pelatihan, validasi, pengujian, semuanya disertakan).

Terima kasih sebelumnya!

Hai,
Anda perlu menetapkan cakupan yang berbeda untuk setiap kali Anda menggunakan norma batch dan memberikan input penggunaan kembali sesuai dengan fase pelatihan / pengujian (BENAR saat menguji SALAH saat melatih) yang sesuai untuk saya.

@ishaybee Terima kasih atas bantuan Anda. Saya telah menemukan masalah saya = = Ini karena awal yang dingin dari moving_mean / moving_variance.

Karena saya belum melatih langkah-langkah yang cukup, perkiraan rata-rata / varians bergerak tidak stabil. Hasilnya ternyata: model berkinerja cukup baik pada pelatihan mini-batch (Anda tahu di awal kerugian turun dengan cepat), tetapi kinerja validasi tidak menentu (karena perkiraan rata-rata / varians populasi tidak cukup stabil).

Saat saya melatih model lebih lama, akurasi validasi juga menjadi lebih cantik.

Hal penting lainnya adalah, pastikan untuk menggunakan slim.learning.create_train_op untuk membuat operasi kereta . Jangan gunakan tf native tf.train.GradientDescentOptimizer(0.1).minimize(loss) .

Jadi jawabannya adalah, saya menggunakan normalisasi batch dengan benar, tetapi saya belum sepenuhnya memahami dinamikanya selama pelatihan.

================
Apalagi:

  1. Berikut adalah contoh lengkap bagaimana menggunakan layer BN pada dataset MNIST.
  2. Penggunaan nilai peluruhan yang lebih kecil akan mempercepat fase pemanasan. Peluruhan default adalah 0,999, untuk kumpulan data kecil seperti MNIST, Anda dapat memilih 0,99 atau 0,95, dan memanas dalam waktu singkat.

@soloice , perhatikan, bagaimana di about comment , parameter berikut diteruskan ke dalam lapisan untuk memanggil batch_norm:

batch_norm_params = {'is_training': is_training, 'decay': 0.9, 'updates_collections': Tidak Ada}

Tanpa updates_collections disetel ke Tidak ada (jadi pembaruan berarti dilakukan di tempat di dalam BatchNorm), saya tidak akan mengharapkan lapisan sekitarnya (misalnya konv2d) untuk entah bagaimana mengeksekusi tf.GraphKeys.UPDATE_OPS diperlukan lapisan BatchNorm untuk memperbarui oleh karena itu dapat dijalankan pada data pengujian nanti.

Atau Anda dapat mencoba menjalankan UPDATE_OPS sendiri secara eksplisit sebagai salah satunya di sini

    update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
    if update_ops:
        updates = tf.group(*update_ops)
        cross_entropy = control_flow_ops.with_dependencies([updates], cross_entropy)

Perbarui - Saya menemukan bahwa saya mengutip kode Anda dengan tepat dan Anda menggunakan UPDATE_OPS.

Adapun "start dingin", seperti yang Anda lihat di atas dalam diskusi, mengurangi BatchNorm yang menjalankan peluruhan rata-rata (parameter input) dari default 0,999 menjadi 0,95 dapat mempercepat start-up

@pavelbulanov Anda baik sekali membantu saya dalam hal ini! Saya akan mencoba nilai yang lebih kecil dari decay untuk melihat bagaimana ini membantu.

================
Pembaruan: gunakan kerusakan kecil (katakanlah, 0,9 atau 0,95) sangat membantu. Kerugian validasi turun dengan sangat cepat ketika saya menetapkan decay menjadi 0,9. Namun kekurangan dari small decay adalah range efektifnya yang kecil: Hasilnya didominasi oleh beberapa sample baru sehingga tidak bisa menjadi estimasi yang baik untuk mean / varians populasi. Seseorang perlu menyeimbangkan antara mulai cepat (kerusakan kecil) dan rentang efektif yang lebih panjang (kerusakan besar).

Hai,
Saya mencoba menerapkan lapisan normalisasi batch dengan bantuan saran dalam masalah ini, tetapi saya masih memiliki kesalahan> 70% dalam validasi dan pengujian ... Saya memiliki peluruhan yang lebih rendah untuk panggilan non-pelatihan ...

Ini kode saya:

def BatchNorm(inputT, is_training=False, scope=None):
  return tf.cond(
    is_training,
    lambda: tf.contrib.layers.batch_norm(inputT, is_training=True,  reuse=None, decay=0.999, epsilon=1e-5, center=True, scale=True, updates_collections=None, scope=scope),
    lambda: tf.contrib.layers.batch_norm(inputT, is_training=False, reuse=True, decay=0.900, epsilon=1e-5, center=True, scale=True, updates_collections=None, scope=scope)
    )

Terima kasih sebelumnya.

@ Alexivia Tampaknya Anda menggunakan dua lapisan normalisasi batch yang berbeda? Anda harus menggunakan hanya satu lapisan BN (tentu saja, dengan parameter is_training ).

Terima kasih atas saran Anda @soloice.
Saya mencoba sekarang hanya dengan parameter is_training dan reuse :

lambda: tf.contrib.layers.batch_norm(inputT, is_training=True,  reuse=None, decay=0.9, epsilon=1e-5, center=True, scale=True, updates_collections=None, scope=scope),
lambda: tf.contrib.layers.batch_norm(inputT, is_training=False, reuse=True, decay=0.9, epsilon=1e-5, center=True, scale=True, updates_collections=None, scope=scope)

masih belum mendapatkan validasi dan hasil pengujian yang baik ...> 70% ...

Hai,
silakan lihat pembungkus saya di atas.
Anda harus menggunakan "dengan tf.variable_scope (scope, reuse = reuse):" Saya rasa.

Hai @ishaybee ,
Saya mengikuti saran Anda, sekarang kode saya adalah:

def BatchNorm(inputT, is_training=False, reuse=True, scope=None):
  with tf.variable_scope(scope, reuse=reuse):
    return tf.contrib.layers.batch_norm(inputT, is_training=is_training, reuse=reuse, scope=scope, updates_collections=None, decay=0.9, center=True, scale=True)

dan saya memberi makan is_training dan reuse melalui feed_dict, tetapi sekarang saya mendapatkan kesalahan ValueError("The reuse parameter must be True or False or None.")

coba beri makan digunakan kembali sebagai variabel python (masukan model) dan sebagai placeholder.

Saya mencobanya, dan sekarang berhenti mengeluh tentang nilainya ... tetapi saya pikir nilai placeholder tidak digunakan, karena saya tidak melihat perubahan jika saya memaksakan nilai ke fungsi batch_norm , dan di TensorBoard tidak terhubung ke grafik ... (lihat gambar terlampir)
screen shot 2017-04-03 at 19 54 54

Kode saya seperti ini sekarang:
Batch Normalization wrapper

def BatchNorm(inputT, is_training=False, reuse=None, scope=None):
  with tf.variable_scope(scope):
    return tf.contrib.layers.batch_norm(inputT, is_training=is_training, reuse=reuse, scope=scope, updates_collections=None, decay=0.9, center=True, scale=True)

Definisi model

def model(data, train=False, is_training=False, reuse=None):
  # 1st conv layer
  with tf.name_scope('conv1') as scope:
    conv = tf.nn.conv2d(
    <...>
    norm = BatchNorm(pool, is_training=is_training, reuse=reuse, scope=scope)

Latihan

feed_dict = {train_data_node: batch_data,
      train_labels_node: batch_labels,
      is_training: True,
      reuse: None}
  # Run the optimizer to update weights.
  sess.run(optimizer, feed_dict=feed_dict)

Validasi

batch_predictions = sess.run(eval_prediction, feed_dict={eval_data: data[-EVAL_BATCH_SIZE:, ...], is_training: False, reuse: True})

Meskipun is_traning dapat digunakan kembali placeholder harus berupa bool, dan tidak dapat berupa tensor atau placeholder.

Saya tidak yakin apa yang Anda coba lakukan, dalam banyak kasus menggunakan nilai statis menyelesaikan masalah. Misalnya pola ini bekerja dengan baik:

def model(data, is_training=False, reuse=None, scope='my_model'):
  # Define a variable scope to contain all the variables of your model
  with tf.variable_scope(scope, 'model', data, reuse=reuse):
    # 1 layer
    net = tf.contrib.layers.conv2d(data, ....)
    ....
    net = tf.contrib.layers.batch_norm(net, is_training)
   return net

train_outputs = model(train_data, is_training=True)
eval_outputs = model(eval_data, is_training=False, reuse=True)

eval_predictions = sess.run(eval_outputs, feed_dict={eval_data: data[-EVAL_BATCH_SIZE:, ...]})

Kecuali Anda perlu mengubah perilaku model secara dinamis, Anda tidak perlu menggunakan placeholder untuk is_training. Triknya adalah dengan membuat model dua kali, tetapi membagikan variabel untuk kedua kalinya.

Terima kasih @sguada ! Setelah menerapkan saran Anda, saya akhirnya berhasil!

Akan sangat membantu jika dokumentasi API 1.0 menunjukkan bahwa Anda perlu menambahkan operasi pembaruan secara manual ke grafik. Menjadi pengguna tf yang lebih baru, saya menemukan bahwa kesalahan pengujian saya gila dan kemudian harus menghabiskan cukup banyak waktu untuk men-debug grafik saya sampai saya menyadari bahwa normalisasi batch adalah masalahnya. Kemudian saya harus menghabiskan lebih banyak waktu untuk mencari tahu bahwa secara default variabel pelacakan momen tidak diperbarui kecuali Anda menggunakan fungsi kontribusi untuk pengoptimalan. Karena di 1.0 tidak ada opsi untuk menyetel update_collections ke None, tidak ada indikator dari dokumentasi bahwa ini bahkan mungkin menjadi masalah. Selain itu, tampaknya masuk akal untuk memiliki parameter untuk menambahkan dependensi aliran kontrol ke operasi yang berjalan dalam kasus pelatihan.

@rsc Tepat. Penggunaan lapisan BN cukup membingungkan. Saya menyarankan untuk menambahkan dokumen atau tutorial resmi lengkap tentang normalisasi batch, tetapi sayangnya tidak mendapat respon = =

Sangat setuju. Saya pikir penggunaan BN sangat rumit dan dokumentasinya saat ini sangat tidak memadai. Ini harus diperbaiki untuk lapisan yang umum digunakan.

Membuka kembali untuk visibilitas masalah dokumentasi.

@sguada menugaskan kepada Anda untuk triaging. Mungkin layak mendapatkan penulis teknologi dalam kasus ini.

Baru saja bingung dengan masalah ini minggu lalu dan menyia-nyiakan 3 hari pelatihan ... Semoga dokumen dapat segera diperbaiki, dan contoh normalisasi batch resmi dapat ditambahkan di dokumen API.

@sguada Saya perhatikan Anda mengatakan "tf.contrib.layers.batch_norm dapat menggunakan tensor sebagai is_training, jadi tidak perlu melakukan apa pun".
Namun, komentar dalam kode tersebut adalah
Jika is_training tidak memiliki nilai konstan, karena itu adalah Tensor ,
# a Variable atau Placeholder maka is_training_value akan menjadi None dan
# needs_moments akan menjadi true.
Apakah ini berarti bahwa nees_moments akan menjadi true bahkan dalam tahap pengujian jika saya menetapkan is_training sebagai placeholder?
Sejauh yang saya tahu, momen tidak diperlukan saat menguji.

Jadi jika is_training adalah Variable atau Placeholder , itu berarti dapat berubah, sehingga grafik untuk menghitung momen diperlukan, sehingga layer membangunnya.
Kemudian dalam waktu berjalan tergantung pada nilainya menjadi True atau False akan menggunakan kumpulan moments atau moving_mean dan moving_variance .

Jadi selama pengujian Anda akan menetapkan nilai menjadi False dan moments tidak akan digunakan.

@sguada @ brando90

def batch_norm_layer(self, x,train_phase, scope_bn):
        bn_train = batch_norm(x, decay=0.9, center=False, scale=True,
        updates_collections=None,
        is_training=True,
        reuse=None,
        variables_collections= [UPDATE_OPS_COLLECTION],
        trainable=True,
        scope=scope_bn)
        bn_inference = batch_norm(x, decay=0.9, center=False, scale=True,
        updates_collections=None,
        is_training=False,
        reuse=True,
        variables_collections= [UPDATE_OPS_COLLECTION],
        trainable=True,
        scope=scope_bn)
        z = tf.cond(train_phase, lambda: bn_train, lambda: bn_inference)
        return z

Saya membangun batchnorm seperti ini, namun, mean bergerak dan variabel bergerak diperbarui selama pengujian, saya tidak dapat menemukan alasannya.

Saya mencoba membuat dua model seperti @sguada berkata, namun, model saya di mana is_training = False hanya macet.

W tensorflow/core/framework/op_kernel.cc:993] Not found: Key fully_connected_5/weights not found in checkpoint
W tensorflow/core/framework/op_kernel.cc:993] Not found: Key fully_connected_6/weights not found in checkpoint
W tensorflow/core/framework/op_kernel.cc:993] Not found: Key fully_connected_7/biases not found in checkpoint
W tensorflow/core/framework/op_kernel.cc:993] Not found: Key fully_connected_6/biases not found in checkpoint
W tensorflow/core/framework/op_kernel.cc:993] Not found: Key fully_connected_7/weights not found in checkpoint
W tensorflow/core/framework/op_kernel.cc:993] Not found: Key history_embeddings_1 not found in checkpoint
W tensorflow/core/framework/op_kernel.cc:993] Not found: Key global_step_1 not found in checkpoint

Saya merasa mungkin harus ada contoh konkret tentang bagaimana melakukan norma batch dengan jaringan yang terhubung sepenuhnya, serta dengan CNN. Menyebalkan bahwa saya telah melatih model selama berhari-hari mengharapkan semuanya bekerja sebelum melihat bahwa semua orang yang mencoba menggunakan fitur ini menjadi gila.

Yang cukup menarik, dibutuhkan waktu miliaran tahun untuk memulihkan model setelah pelatihan dengan batch_norm juga. Kemungkinan besar akan menunggu sampai TF 2.0 untuk mencoba sesuatu seperti ini lagi.

@MisayaZ Anda tidak perlu membuat dua lapisan batch_norm Anda cukup meneruskan train_phase (dengan asumsi ini adalah tf.bool) ke batch_norm. Anda juga meneruskan UPDATE_OPS_COLLECTION variable_collections, yang mengubah koleksi mana yang ditambahkan variabel.

Berikut ini seharusnya bekerja:

z = batch_norm(x, decay=0.9, center=False, scale=True, updates_collections=None, 
                             is_training=train_phase, scope=scope_bn)

@OktayGardener tidak yakin model apa yang Anda coba buat, tampaknya variabel tidak disimpan di pos pemeriksaan Anda.

batch_norm juga bekerja dengan lapisan yang terhubung sepenuhnya.

slim = tf.contrib.slim
def model(data, is_training=False, reuse=None, scope='my_model'):
  # Define a variable scope to contain all the variables of your model
  with tf.variable_scope(scope, 'model', data, reuse=reuse):
    # Configure arguments of fully_connected layers
    with slim.arg_scope([slim.fully_connected],
                        activation_fn=tf.nn.relu,
                        normalizer_fn=slim.batch_nom):
      # Configure arguments of batch_norm layers
      with slim.arg_scope([slim.batch_norm],
                          decay=0.9,  # Adjust decay to the number of iterations
                          update_collections=None, # Make sure updates happen automatically
                          is_training=is_training, # Switch behavior from training to non-training):
        net = slim.fully_connected(data, 100, scope='fc1')
        net = slim.fully_connected(net, 200, scope='fc2')
        ....
        # Don't use activation_fn nor batch_norm in the last layer        
        net = slim.fully_connected(net, 10, activation_fn=None, normalizer_fn=None, scope='fc10')
       return net

@sguada Terima kasih, saya membangun jaringan dengan bathnorm yang diimplementasikan seperti yang Anda sebutkan di atas

z = batch_norm(x, decay=0.9, center=False, scale=True, updates_collections=None, 
                             is_training=train_phase, scope=scope_bn)

kecepatannya lambat, saya menggunakan benchmark tensorflow untuk mendapatkan waktu komputasi seperti di bawah ini:
Saya tensorflow / core / util / stat_summarizer.cc: 392] ============================== Atas berdasarkan Waktu Perhitungan === ===========================
I tensorflow / core / util / stat_summarizer.cc: 392] [jenis node] [mulai] [pertama] [rata-rata ms] [%] [cdf%] [mem KB] [Nama]
I tensorflow / core / util / stat_summarizer.cc: 392] Konv2D 106.164 51.354 51.004 23.145% 23.145% 692.224 konv8 / Konv2D
I tensorflow / core / util / stat_summarizer.cc: 392] Konv2D 85.187 19.115 19.283 8.750% 31.896% 692.224 konv7 / Konv2D
I tensorflow / core / util / stat_summarizer.cc: 392] SquaredDifference 11.967 15.105 14.331 6.503% 38.399% 11075.584 konv1 / batch_norm / momen / cukup_statistik / SquaredDifference
I tensorflow / core / util / stat_summarizer.cc: 392] Mul 11.970 14.162 13.495 6.124% 44.523% 11075.584 konv1 / batch_norm / batchnorm / mul_1
I tensorflow / core / util / stat_summarizer.cc: 392] Konv2D 3.948 8.170 7.986 3.624% 48.146% 11075.584 konv1 / Konv2D
I tensorflow / core / util / stat_summarizer.cc: 392] Sub 11.960 10.176 7.943 3.604% 51.751% 11075.584 konv1 / batch_norm / momen / cukup_statistik / Sub
I tensorflow / core / util / stat_summarizer.cc: 392] SquaredDifference 45.570 5.908 7.177 3.257% 55.007% 5537.792 konv2 / batch_norm / momen / cukup_statistik / SquaredDifference
I tensorflow / core / util / stat_summarizer.cc: 392] Mul 45.574 7.755 6.902 3.132% 58.140% 5537.792 konv2 / batch_norm / batchnorm / mul_1
I tensorflow / core / util / stat_summarizer.cc: 392] Konv2D 40.692 5.408 4.845 2.199% 60.338% 5537.792 konv2 / Konv2D
I tensorflow / core / util / stat_summarizer.cc: 392] Sub 45.563 6.067 4.784 2.171% 62.509% 5537.792 con

Saya tidak mengerti mengapa beberapa operasi pada saat dijalankan selama pengujian dan itu menghabiskan banyak waktu, seperti konv1 / batch_norm / momen / cukup_statistics / SquaredDifference.

Momen tidak diperlukan dalam pengujian, mengapa beberapa operasi sedang dijalankan?

Hai,

Menggunakan layer batch_norm di atas di contrib.layers , saya mendapatkan nan sebagai output untuk grafik validasi sementara grafik kereta berjalan mulus. Apakah ada sesuatu yang mungkin saya lewatkan?

Saya menggunakan:

def batchnormlayer(inputs, numout, train_model):
    with tf.variable_scope("batch_norm") as scope_bn:
        epsilon = 1e-3
        return tf.contrib.layers.batch_norm(inputs, decay=0.9, updates_collections=None,
                                            scale=True, scope=scope_bn,
                                            is_training=train_model, epsilon=epsilon,
                                            fused=True, reuse=scope_bn.reuse)

Terima kasih

Sebagai tindak lanjut, saya menggunakan kembali 16 lapisan batch_norm.
Namun, saya menemukan bahwa menggunakan kembali 4 lapisan berfungsi.

Saya baru saja memperhatikan bahwa jika saya mematikan proses tensorflow dan memulai ulang, kesalahan saya menjadi lebih buruk selama beberapa zaman (yaitu lebih buruk daripada yang seharusnya terjadi di pos pemeriksaan terakhir). Saya juga mengamati bahwa jika saya menghapus batch_norm, masalah ini akan hilang. Setelah melihat kode beberapa saat, saya pikir ini mungkin karena nilai variabel tidak dikembalikan dari variabel bayangan seperti jika kelas ExponentialMovingAverages digunakan untuk mengelola rata-rata bergerak. Ini juga berarti bahwa jika saya menggunakan proses terpisah untuk mengevaluasi, saya mendapatkan nilai terakhir variabel apa pun dan bukan rata-rata bergerak. Apakah saya menafsirkan ini dengan benar dan apakah ini perilaku yang dimaksudkan? Sepertinya Anda ingin nilai variabel bayangan dipulihkan ...

Saya menangkap masalahnya, varian bergerak dalam kasus saya menjadi negatif setelah beberapa pengulangan.

Output dari tensor: Model/clip_logits/batch_norm/moving_variance:0 hadir dalam tf.model_variables() adalah

Moving variance (shape = (101,)) = 
[ 214.70379639   95.36338043    0.57885742  189.49542236  102.72473145
  137.14886475  286.57333374  111.06427002  154.98750305  167.75219727
  207.83955383  211.14007568  158.23495483  171.61665344  116.81361389
  115.77380371   43.59399796  137.75064087  181.75245667  161.37339783
  215.21934509   92.88521576  191.23846436  336.3946228   259.85919189
  299.47039795  186.23222351  165.19311523  262.82446289  170.11567688
  233.56843567  209.35050964  115.96807861  154.34109497  295.5770874
  123.6055603   295.76187134  296.88583374  240.88217163  247.32983398
   87.15661621  217.69897461  133.00698853   -4.80375671  344.77462769
  291.50601196  117.77174377  265.83712769  207.90093994  194.186203
  220.21418762  178.03738403  115.27571869  196.62184143  228.8089447
  191.53205872  331.36807251  151.55435181  197.2951355   179.67504883
  181.09727478   90.09922791  173.30133057  102.6836853   160.9434967
  236.59512329  168.05305481  403.36340332   41.14326096  185.93409729
  130.57434082  266.31509399  101.44387817  163.88059998  290.25015259
  244.52597046  229.86647034  158.14352417  202.68774414  187.78227234
  248.78218079  126.0978241   171.41891479  274.40740967  119.84254456
  202.53045654  200.20608521  214.04730225  111.53284454  222.03184509
  244.81187439  172.23052979  187.09806824  194.62802124  255.26345825
  293.63598633  307.91036987  210.86982727  308.88919067  144.94792175
  229.69013977]

Seperti yang Anda lihat, ada varian negatif untuk salah satu dimensi. Bagaimana ini mungkin?
PS Lapisan norma batch digunakan tepat setelah lapisan jaringan yang terhubung sepenuhnya terakhir dan sebelum softmax.

@ raghavgoyal14 apakah Anda menggunakannya dengan fused = True? Punya masalah serupa dan hilang saat saya menggunakan versi fusi

@abred : Ya, saya menggunakan fused=True , masalah yang sama.

@sguada Hai, sguada, saya punya masalah.
Definisi contrib.layers.batch_norm di tensorflow:
def batch_norm (masukan,
peluruhan = 0,999,
center = Benar,
scale = False,
epsilon = 0,001,
activation_fn = Tidak ada,
param_initializers = Tidak ada,
param_regularizers = Tidak ada,
updates_collections = ops.GraphKeys.UPDATE_OPS,
is_training = Benar,
reuse = Tidak ada,
variable_collections = Tidak ada,
outputs_collections = Tidak ada,
trainable = Benar,
batch_weights = Tidak ada,
fused = False,
data_format = DATA_FORMAT_NHWC,
zero_debias_moving_mean = Salah,
scope = Tidak ada,
renorm = False,
renorm_clipping = Tidak ada,
renorm_decay = 0.99):
skala: Jika Benar, kalikan dengan gamma. Jika Salah, gamma adalah
tidak digunakan. Jika lapisan berikutnya adalah linier (juga misalnya nn.relu), ini bisa jadi
dinonaktifkan karena penskalaan dapat dilakukan oleh lapisan berikutnya.

Jika saya menggunakan tf.contrib.layers.batch_norm (input, scale = False), "scale = False" berarti apakah gamma nol dalam "y = gamma * x + beta" saat pelatihan. Terima kasih banyak.

Ketika skala = False, gamma adalah konstanta 1.

@ppwwyyxx Terima kasih banyak atas bantuan Anda. Saya menggunakan tf.contrib.layers.batch_norm (input, scale = False) di Tensorflow, dan sekarang saya mengubah batchnorm dari Tensorflow ke Caffe. Bagaimana cara mengatur parameter BatchNormLayer dan ScaleLayer di Caffe?
Terima kasih banyak.

@ MisayaZ Saya mengalami perilaku yang sama menggunakan Batchnorm dengan placeholder untuk "is_training". Saya melihat di jejak bahwa momen sedang dihitung bahkan pada waktu tes, jadi saya memutuskan untuk masuk ke kode sumber dan saya menemukan ini:

    # If `is_training` doesn't have a constant value, because it is a `Tensor`,
    # a `Variable` or `Placeholder` then is_training_value will be None and
    # `needs_moments` will be true.
    is_training_value = utils.constant_value(is_training)
    need_moments = is_training_value is None or is_training_value
    if need_moments:
        # here it defines the moments

Sepertinya saat "is_training" adalah variabel atau placeholder, momen dapat ditentukan dan juga dihitung saat runtime, bahkan saat Anda menyetel placeholder ke "False". Saya lebih suka membiarkannya sebagai placeholder karena dengan cara ini saya dapat melakukan pengujian berkala selama pelatihan tanpa mendefinisikan ulang grafik, tetapi saya memutuskan untuk menggunakannya sebagai konstanta dan menentukan perilaku berbeda untuk tes kereta vs, dan sekarang momen tidak dihitung pada waktu ujian.

@ tano297 Terima kasih. Saya sekarang juga menggunakan 'is_training' sebagai konstanta. Biarkan sebagai placeholder dan lakukan pengujian berkala akan mengubah nilai moving mean dan moving variance. Dan waktu inferensi akan lebih lama karena itu akan menghitung mean dan varians dari input dan memperbarui mean bergerak dan varians bergerak. Cara yang tepat untuk melakukan pengujian adalah dengan menentukan perilaku berbeda untuk latihan dan pengujian seperti yang Anda sebutkan.

@ tano297
tapi bukan "smart_cond" di

is_training_value = utils.constant_value(is_training)
need_updates = is_training_value is None or is_training_value
if need_updates:
  ...
  outputs = utils.smart_cond(is_training, _force_updates, no_updates)

pastikan bahwa pembaruan hanya dihitung dan diterapkan jika is_training mengevaluasi ke True?

@abred Ya memang, tetapi Anda merujuk ke baris 391, di mana ia memperbarui rata-rata bergerak dalam _fused_batch_norm ():

    # If `is_training` doesn't have a constant value, because it is a `Tensor`,
    # a `Variable` or `Placeholder` then is_training_value will be None and
    # `need_updates` will be true.
    is_training_value = utils.constant_value(is_training)
    need_updates = is_training_value is None or is_training_value
    if need_updates:
        ...
        outputs = utils.smart_cond(is_training, _force_updates, no_updates)
        ...

Saya berbicara tentang baris 753 dalam batch_norm ():

    # If `is_training` doesn't have a constant value, because it is a `Tensor`,
    # a `Variable` or `Placeholder` then is_training_value will be None and
    # `needs_moments` will be true.
    is_training_value = utils.constant_value(is_training)
    need_moments = is_training_value is None or is_training_value
    if need_moments:
        ...
        mean, variance = utils.smart_cond(is_training,
                                          _force_updates,
                                          moving_vars_fn) 
        ...

Kondisi pintar dalam hal itu (sejauh yang saya ketahui) memutuskan apakah akan memperbarui rata-rata bergerak atau tidak, tetapi momennya masih dihitung.

@ tano297 Anda benar tentang itu, saya berada di tempat yang salah, tetapi tetap saja:
baris 755-770 menghitung momen, tetapi momen hanya digunakan dalam _force_updates yang hanya dijalankan jika is_training mengevaluasi ke True, bukan?
Dan dengan demikian

mean, variance = utils.smart_cond(is_training, _force_updates, moving_vars_fn) 

harus sama dengan baris 804:

mean, variance = moving_mean, moving_variance

if is_training bernilai False sehingga bagian "momen" dari grafik tidak pernah digunakan dan karenanya tidak boleh dijalankan

tetapi saya belum menguji, jadi saya mungkin salah tentang itu :)

@ tano297 @red Anda benar. Moving mean dan moving variance diubah ketika saya menggunakan batchnorm seperti ini:

def batch_norm_layer(self, x,train_phase, scope_bn):
        bn_train = batch_norm(x, decay=0.9, center=False, scale=True,
        updates_collections=None,
        is_training=True,
        reuse=None,
        variables_collections= [UPDATE_OPS_COLLECTION],
        trainable=True,
        scope=scope_bn)
        bn_inference = batch_norm(x, decay=0.9, center=False, scale=True,
        updates_collections=None,
        is_training=False,
        reuse=True,
        variables_collections= [UPDATE_OPS_COLLECTION],
        trainable=True,
        scope=scope_bn)
        z = tf.cond(train_phase, lambda: bn_train, lambda: bn_inference)
        return z

Jika Anda menggunakan seperti berikut:

z = batch_norm(x, decay=0.9, center=False, scale=True, updates_collections=None, 
                         is_training=train_phase, scope=scope_bn)

Rata-rata pergerakan dan varian bergerak tidak akan berubah selama pengujian, tetapi kecepatannya sangat lambat.

Hai @zhongy ,

Saya juga menemui masalah bahwa saya bisa mendapatkan hasil yang baik saat menggunakan is_training = True untuk pelatihan dan inferensi, tetapi mendapatkan hasil yang buruk saat menyetel is_training = False selama inferensi (lebih buruk daripada kasus menggunakan is_training = True). Menurut analisis Anda, Jika saya mengerti dengan benar, hanya dengan mengatur decay = 0,9 di BN dapat menyelesaikan masalah ini. Apakah saya benar?

BTW, apakah saya perlu melatih ulang model menggunakan peluruhan = 0,9 dari awal? Atau melanjutkan pelatihan dari pos pemeriksaan (yaitu, dilatih saat peluruhan = 0,999) juga oke?

Terima kasih!

@nmduc @ davek44

Hai, Saya juga menemui masalah bahwa saya bisa mendapatkan hasil yang baik saat menggunakan is_training = True untuk pelatihan dan inferensi, tetapi mendapatkan hasil yang buruk saat menyetel is_training = False selama inferensi (lebih buruk daripada kasus menggunakan is_training = True). Sudahkah kalian memecahkan masalah ini? Terima kasih!

@tyshiwo Saya baru saja menetapkan decay = 0,9 untuk batch_norm dan sejauh ini berfungsi dengan baik.

Saya bingung setelah semua komentar ini tentang cara menggunakan Batch Norm dengan benar: Jadi inilah yang saya miliki. Harap perbaiki saya jika saya salah.

batch_norm = tf.contrib.layers.batch_norm(conv, center=True, scale=True, reuse=phase_train_py, scope='bn', is_training=is_training)

di mana phase_train_py adalah variabel boolean python dan is_training adalah placeholder yang mengambil variabel boolean. Saya kira menggunakan tf.cond salah, jika tidak maka fungsinya akan datang dengan parameter boolean. Dengan kata lain, jika tf.cond benar, maka kita harus memiliki fungsi batch_norm untuk pelatihan dan satu lagi untuk pengujian. Jadi, pengembang mengizinkan kami untuk mengubah variabel boolean ini untuk mengubah perilaku fungsi. Jadi Yang saya lakukan adalah: menyetel phase_train_py menjadi False saat pelatihan sementara is_training menjadi True. Dan kebalikannya saat Pengujian. Karena kita hanya dapat mengubah tensor atau placeholder dengan sess.run , saya mengubah phase_train_py sengaja sebelum menjalankan grafik. Ex:

if condition: phase_train_py = False sess.run(to_run_list, feed_dict={phase_train: True}) else: phase_train_py = True sess.run(to_run_list, feed_dict={phase_train: False})

+++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++
MUNGKIN ANDA PERLU MEMBACA INI
+++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++

Sepertinya masih ada masalah dengan TF v1.3. Saya yakin saya mencatat detail berikut, tetapi masih gagal menggunakan tf.contrib.layers.batch_norm resmi, dengan is_training=False selama evaluasi (tetapi ketika saya menyimpan is_training=True tidak berubah selama evaluasi, itu baik):
1. decay , rata-rata bergerak eksponensial sebenarnya adalah filter alfa dalam pemrosesan sinyal, waktu untuk berkumpul kira-kira 1 / (1-peluruhan) langkah kereta. Untuk peluruhan = 0,999, Anda membutuhkan 1 / 0,001 = 1000 langkah untuk menyatu. Jadi atur peluruhan yang sesuai untuk nomor langkah pelatihan Anda.

  1. menggunakan placeholder untuk beralih antara evaluasi latihan dan ujian
  2. gunakan updates_collections=None jika Anda tidak ingin menambahkan dependensi kontrol dari operasi pembaruan ke train_op
  3. set reuse ke nilai yang sesuai.

Tampaknya satu-satunya cara untuk menggunakan batch_norm resmi adalah dengan membuat dua grafik, satu untuk kereta api dan satu lagi untuk evaluasi, masing-masing dengan is_training=True dan is_training=False . Dengan cara ini, Anda tidak perlu beralih secara dinamis antara latihan dan evaluasi. Tetapi ini cara yang bodoh karena Anda perlu membuat lebih dari satu grafik.

Akhirnya, saya menulis rata-rata bergerak sendiri, dan ternyata berhasil! Itu sebagai berikut (berdasarkan kode di web dan dimodifikasi sendiri)

def bn_layer(x, scope, is_training, epsilon=0.001, decay=0.99, reuse=None):
    """
    Performs a batch normalization layer

    Args:
        x: input tensor
        scope: scope name
        is_training: python boolean value
        epsilon: the variance epsilon - a small float number to avoid dividing by 0
        decay: the moving average decay

    Returns:
        The ops of a batch normalization layer
    """
    with tf.variable_scope(scope, reuse=reuse):
        shape = x.get_shape().as_list()
        # gamma: a trainable scale factor
        gamma = tf.get_variable("gamma", shape[-1], initializer=tf.constant_initializer(1.0), trainable=True)
        # beta: a trainable shift value
        beta = tf.get_variable("beta", shape[-1], initializer=tf.constant_initializer(0.0), trainable=True)
        moving_avg = tf.get_variable("moving_avg", shape[-1], initializer=tf.constant_initializer(0.0), trainable=False)
        moving_var = tf.get_variable("moving_var", shape[-1], initializer=tf.constant_initializer(1.0), trainable=False)
        if is_training:
            # tf.nn.moments == Calculate the mean and the variance of the tensor x
            avg, var = tf.nn.moments(x, np.arange(len(shape)-1), keep_dims=True)
            avg=tf.reshape(avg, [avg.shape.as_list()[-1]])
            var=tf.reshape(var, [var.shape.as_list()[-1]])
            #update_moving_avg = moving_averages.assign_moving_average(moving_avg, avg, decay)
            update_moving_avg=tf.assign(moving_avg, moving_avg*decay+avg*(1-decay))
            #update_moving_var = moving_averages.assign_moving_average(moving_var, var, decay)
            update_moving_var=tf.assign(moving_var, moving_var*decay+var*(1-decay))
            control_inputs = [update_moving_avg, update_moving_var]
        else:
            avg = moving_avg
            var = moving_var
            control_inputs = []
        with tf.control_dependencies(control_inputs):
            output = tf.nn.batch_normalization(x, avg, var, offset=beta, scale=gamma, variance_epsilon=epsilon)

    return output


def bn_layer_top(x, scope, is_training, epsilon=0.001, decay=0.99):
    """
    Returns a batch normalization layer that automatically switch between train and test phases based on the 
    tensor is_training

    Args:
        x: input tensor
        scope: scope name
        is_training: boolean tensor or variable
        epsilon: epsilon parameter - see batch_norm_layer
        decay: epsilon parameter - see batch_norm_layer

    Returns:
        The correct batch normalization layer based on the value of is_training
    """
    #assert isinstance(is_training, (ops.Tensor, variables.Variable)) and is_training.dtype == tf.bool

    return tf.cond(
        is_training,
        lambda: bn_layer(x=x, scope=scope, epsilon=epsilon, decay=decay, is_training=True, reuse=None),
        lambda: bn_layer(x=x, scope=scope, epsilon=epsilon, decay=decay, is_training=False, reuse=True),
    )

Cukup gunakan fungsi bn_layer_top selama membuat grafik, parameter is_training adalah tf.placeholder
. Kemudian Anda bebas untuk mengganti placeholder ke True selama kereta dan Salah selama evaluasi, dengan feed_dict .

Semoga bisa membantu masyarakat.

Saat Anda menggunakan slim.batch_norm, pastikan untuk menggunakan "slim.learning.create_train_op" bukan "tf.train.GradientDecentOptimizer (lr) .minimize (loss)" atau pengoptimal lainnya. Cobalah untuk melihat apakah itu berhasil!

@vincentvanhoucke Anda menulis di posting lain di utas ini:

Slim batch_norm wrapper dinormalisasi selama dimensi terakhir tensor input Anda. Jadi jika tensor input 2D yang berasal dari lapisan yang sepenuhnya terhubung, ia akan dinormalisasi melalui batch, dan dengan demikian melakukan normalisasi per aktivasi. Jika tensor 4D berasal dari konvolusi, ia akan dinormalisasi pada tiga dimensi pertama (batch, lebar, kedalaman), dan dengan demikian melakukan normalisasi per fitur. @sguada mungkin sedikit lebih deskriptif tentang ini.

Apakah yang Anda maksud dengan "slim batch_norm wrapper" fungsi tf.contrib.layers.batch_norm ? Jika demikian, saya akan menyarankan untuk menambahkan informasi ini ke teks dokumentasi fungsi ini. Jadi menjadi sangat jelas, bahwa fungsi ini melakukan normalisasi batch persis seperti yang dijelaskan di kertas ... untuk FC-Layer dan Conv2D-Layer. Saat ini hanya ada teks "Dapat digunakan sebagai fungsi normalizer untuk conv2d dan fully_connected.", Di mana tidak jelas apakah ini terkait dengan topik sumbu normalisasi.

@ZahlGraf Saya akan dengan senang hati mempertimbangkan PR yang mengklarifikasi dokumentasi. Kami telah melakukan ini begitu lama sehingga saya tidak lagi memahami apa yang jelas atau tidak, dan akan menerima dokumentasi klarifikasi untuk seseorang dengan perspektif baru tentang topik tersebut.

@bayu_joo
Saya membuat PR dengan deskripsi yang lebih detail, terutama berdasarkan pernyataan Anda di utas ini:
https://github.com/tensorflow/tensorflow/pull/15653

Harap hapus penerima hak, karena masalah ini mengundang kontribusi eksternal. Jika tidak, hapus label contributions welcome . Terima kasih.

Harap hapus penerima hak, karena masalah ini mengundang kontribusi eksternal. Jika tidak, hapus label contributions welcome . Terima kasih.

Menutup bug ini sejak permintaan asli untuk menambahkan lapisan norma batch telah ditangani. Beberapa masalah terbaru dengan dokumentasi tampaknya memiliki PR sendiri
Jika Anda melihat masalah apa pun dengan batch_norm, ajukan pertanyaan di StackOverflow atau buka masalah lain.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat