Lei Feng Net Not: Bu makalenin yazarı Lu Chi, orijinal metin yazar tarafından yayınlandı kişisel blog Leifeng.com yetkilendirildi.
Bir süre tensör akışını öğrendikten sonra denemek için bir proje bulmak istedim.Sonra Theano dersinde bir metin sınıflandırma örneği hatırladım. Bu hafta tensorflow ile uyguladım. Daha önce kullandığım theano'ya hala çok benzediğini hissediyorum. En büyük fark, özetlemek ve işaretlemek gerekiyor.
Sınıflandırma modeli aslında çok basittir. Esas olarak tek katmanlı bir LSTM modelidir. Elbette çok katmanlı modeller de uygulanabilir. Çok katmanlı modellerin kullanımı özellikle basittir Tensorflow. Aşağıda bu modelin bir diyagramı bulunmaktadır.
Bu resmi kısaca açıklayın.Her kelime gömüldükten sonra, LSTM'nin standart bir LSTM olduğu LSTM katmanına ve daha sonra bir zaman serisiyle elde edilen gizli LSTM sinir birimlerinin vektörlerine girer.Bu vektörler, ortalama havuzlama katmanından geçtikten sonra elde edilebilir. Bir kategori dağıtım vektörü elde etmek için bir h vektörü, ardından basit bir lojistik regresyon katmanı (veya bir softmax katmanı).
Formüller tek tek tanıtılmamıştır, çünkü bu deney Theano'nun uygulamasını yeniden üretmek için Tensorflow'u kullanır, bu nedenle belirli formül LSTM Networks for Sentiment Analysis bağlantısında bulunabilir.
Uzun süredir tensör akışıyla temas halinde değildim ve yavaş yavaş keşfediyorum, ancak Theano'yu kullanmanın önceki deneyiminden dolayı sembolik programlamaya aşina değilim, bu yüzden Tensorflow'a başlamak çok kolay. Ama tensorflow'un, burada bahsedilecek olan theano'dan hala birçok farklı olduğunu hissediyorum.
Ana kod modeli aşağıdaki gibidir:
tensorflow'u tf olarak içe aktar
numpy'yi np olarak içe aktar
sınıf RNN_Model (nesne):
def __init __ (self, config, is_training = True):
self.keep_prob = config.keep_prob
self.batch_size = tf.Variable (0, dtype = tf.int32, trainable = False)
num_step = config.num_step
self.input_data = tf.placeholder (tf.int32,)
self.target = tf.placeholder (tf.int64,)
self.mask_x = tf.placeholder (tf.float32,)
class_num = config.class_num
hidden_neural_size = config.hidden_neural_size
wordabulary_size = config.vocabulary_size
embed_dim = config.embed_dim
hidden_layer_num = config.hidden_layer_num
self.new_batch_size = tf.placeholder (tf.int32, şekil =, name = "new_batch_size")
self._batch_size_update = tf.assign (self.batch_size, self.new_batch_size)
#build LSTM ağı
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell (hidden_neural_size, Forgot_bias = 0.0, state_is_tuple = True)
eğer self.keep_prob
lstm_cell = tf.nn.rnn_cell.DropoutWrapper (
lstm_cell, output_keep_prob = self.keep_prob
)
hücre = tf.nn.rnn_cell.MultiRNNCell (* hidden_layer_num, state_is_tuple = True)
self._initial_state = hücre.zero_state (self.batch_size, dtype = tf.float32)
#embedding tabakası
tf.device ("/ cpu: 0"), tf.name_scope ("embedding_layer") ile:
embedding = tf.get_variable ("yerleştirme" ,, dtype = tf.float32)
inputs = tf.nn.embedding_lookup (gömme, self.input_data)
eğer self.keep_prob
inputs = tf.nn.dropout (girişler, self.keep_prob)
out_put =
durum = self._initial_state
tf.variable_scope ("LSTM_layer") ile:
aralıktaki time_step için (num_step):
time_step ise > 0: tf.get_variable_scope.reuse_variables
(hücre çıkışı, durum) = hücre (girişler, durum)
out_put.append (cell_output)
out_put = out_put * self.mask_x
tf.name_scope ("mean_pooling_layer") ile:
out_put = tf.reduce_sum (out_put, 0) / (tf.reduce_sum (self.mask_x, 0))
tf.name_scope ("Softmax_layer_and_output") ile:
softmax_w = tf.get_variable ("softmax_w" ,, dtype = tf.float32)
softmax_b = tf.get_variable ("softmax_b" ,, dtype = tf.float32)
self.logits = tf.matmul (out_put, softmax_w) + softmax_b
tf.name_scope ("kayıp") ile:
self.loss = tf.nn.sparse_softmax_cross_entropy_with_logits (self.logits + 1e-10, self.target)
self.cost = tf.reduce_mean (self.loss)
tf.name_scope ("doğruluk") ile:
self.prediction = tf.argmax (self.logits, 1)
right_prediction = tf.equal (self.prediction, self.target)
self.correct_num = tf.reduce_sum (tf.cast (right_prediction, tf.float32))
self.accuracy = tf.reduce_mean (tf.cast (right_prediction, tf.float32), name = "doğruluk")
#add özeti
loss_summary = tf.scalar_summary ("kayıp", kendi kendine maliyet)
#add özeti
doğruluk_sumary = tf.scalar_summary ("doğruluk_sumaryası", self.accuracy)
is_training değilse:
dönüş
self.globle_step = tf.Variable (0, name = "globle_step", trainable = False)
self.lr = tf.Variable (0.0, eğitilebilir = Yanlış)
tvars = tf.trainable_variables
grads, _ = tf.clip_by_global_norm (tf.gradients (self.cost, tvars),
config.max_grad_norm)
# Gradyan değerlerini ve seyrekliği takip edin (isteğe bağlı)
grad_summaries =
zip için g, v için (grads, tvars):
g Yok değilse:
grad_hist_summary = tf.histogram_summary ("{} / grad / hist" .format (v.name), g)
sparsity_summary = tf.scalar_summary ("{} / grad / sparsity" .format (v.name), tf.nn.zero_fraction (g))
grad_summaries.append (grad_hist_summary)
grad_summaries.append (sparsity_summary)
self.grad_summaries_merged = tf.merge_summary (grad_summaries)
self.summary = tf.merge_summary ()
optimizer = tf.train.GradientDescentOptimizer (self.lr)
optimizer.apply_gradients (zip (grads, tvars))
self.train_op = optimizer.apply_gradients (zip (grads, tvars))
self.new_lr = tf.placeholder (tf.float32, şekil =, name = "new_learning_rate")
self._lr_update = tf.assign (self.lr, self.new_lr)
def assign_new_lr (self, session, lr_value):
session.run (self._lr_update, feed_dict = {self.new_lr: lr_value})
def assign_new_batch_size (self, session, batch_size_value):
session.run (self._batch_size_update, feed_dict = {self.new_batch_size: batch_size_value})
Model karmaşık değil, bu yüzden onları tek tek açıklamayacağım Hata ayıklarken, hala birkaç tensorflow çukuru var, bu yüzden bu çukurlardan ayrı ayrı konuşmak istiyorum.
Pit 1: Tensör akışının LSTM uygulaması
Tensorflow, çok rahat bir şekilde kullanılabilen birkaç LSTM uygulama sınıfı yazmıştır ve ayrıca Temel, Çift Yönlü vb. Dahil olmak üzere çeşitli LSTM türlerini de seçebilirsiniz.
Bu kod BasicLSTM kullanır:
#build LSTM ağı
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell (hidden_neural_size, Forgot_bias = 0.0, state_is_tuple = True)
eğer self.keep_prob
lstm_cell = tf.nn.rnn_cell.DropoutWrapper (
lstm_cell, output_keep_prob = self.keep_prob
)
hücre = tf.nn.rnn_cell.MultiRNNCell (* hidden_layer_num, state_is_tuple = True)
self._initial_state = hücre.zero_state (self.batch_size, dtype = tf.float32)
out_put =
durum = self._initial_state
tf.variable_scope ("LSTM_layer") ile:
aralıktaki time_step için (num_step):
time_step ise > 0: tf.get_variable_scope.reuse_variables
(hücre çıkışı, durum) = hücre (girişler, durum)
out_put.append (cell_output)
Bu kodda, tf.nn.rnn_cell.BasicLSTMCell'in başlatılmasının yalnızca LSTM nöronunun gizli nöronlarının sayısını belirtmesi gerekir ve sonra LSTM ağının parametrelerinin başlatılması gerekir: self._initial_state = cell.zero_state (self. batch_size, dtype = tf.float32), bu kod ilk bakışta çok karışık ve ilk başta ne anlama geldiğini bilmiyorum. Kaynak kodunu denedikten ve danıştıktan sonra, döndürülen cümle, iki boyutun batch_size * hidden_neural_size sıfır olduğudur Vektör demeti aslında LSTM tarafından başlatılan c0 ve h0 vektörleridir. Elbette bu, tek katmanlı bir LSTM'ye atıfta bulunur. Çok katmanlı bir LSTM için birden çok demet döndürülür.
Pit 2: Bu kodda hem zero_state hem de döngüsel cebir num_step'in formüle edilmesi gerekir
Burada biraz acı verici, bu da tensorflow'daki değişken uzunluğun doldurma gerektirdiği ve hepsinin aynı uzunlukta olması gerektiği anlamına geliyor, ancak veri kümesi nedeniyle her bir partinin boyutunun aynı olması imkansız, bu yüzden burada gerekli Her çalıştırmadan önce, dinamik olarak batch_size boyutunu ayarlayın; kod, bunun assign_new_batch_size işlevi olduğunu yansıtır, ancak num_step parametresi dinamik olarak belirtilemez (belki yazar onu bulmadığı, ancak belirtilen tf.Variable () yöntemi çalışmadığı için), çünkü İsteksizce, tüm veri seti belirtilen boyutta doldurulabilir.Tabii ki dolgu kullanıldığı için hesaplama için maske matrisi kullanılmalıdır.
Çukur 3: Maliyet
Non'a maliyet dönüşü genellikle çapraz entropi kullanılırken günlükler tarafının 0 değerine sahip olmasıdır, bu nedenle yığın taşması için önerilen yöntem: sparse_softmax_cross_entropy_with_logits (self.logits + 1e-10, self.target).
Deneysel arka plan:
tensör akışı: tensör akışı 1.1
platform: mac OS
Veri kümesi: konu veri kümesi, veri kümesi önceden işlenmiştir ve elde ettiğiniz şey, kelime dağarcığındaki indeksi
Tensorboardun her parametresinin eğitim sürecinin görselleştirilmesi sayesinde, aşağıdaki deneysel eğitim sonucudur:
Eğitim setinin eğitim sonucu:
Doğrulama seti eğitim sonuçları:
Kayıp fonksiyonu eğitim süreci:
Her parametrenin eğitim sonuçları:
Sonuç olarak, test setinde doğruluk yaklaşık% 85'tir ve bu fena değildir.
tensor flow ve theano, son zamanlarda daha popüler olan derin öğrenme çerçeveleri. İkisi birbirine çok benziyor ama farklılar.İşte, ikisi arasındaki benzerlikleri ve farklılıkları karşılaştırmak için benim kişisel deneyimim.
1. Zorluk derecesi
Kullanım zorluğu açısından tensorflow, theanodan çok daha uygundur.Ne de olsa, theano bir grup bilim insanı tarafından araştırılır ve tensorflow, daha endüstrileşmiş Google tarafından araştırılır. tensör akışı, akademik ortamdaki RNN, LSTM, vb. gibi birçok yöntemi doğrudan entegre eder, tensorflow ile entegre edilmiştir ve gradyan inişi, Adadelta vb. gibi parametre güncelleme yöntemleri de tensorflow tarafından yazılmıştır, ancak theano için Elbette kendi başınıza yazmak, zorluk derecesi farklıdır.
2. Esneklik
Esneklik açısından Theano, tensör akışından daha iyidir.Tam olarak bir önceki noktadaki theano'nun biraz daha yüksek eşiği nedeniyle, anoyu daha esnek hale getirir ve keyfi olarak tanımlanmış ağ sonuçları elde edebilir.Bu, tensorflow'un iyi olmadığı anlamına gelmez. , Tensorflow da yazılabilir, ancak tensorflow'u uzun süre kullandıktan sonra, LSTM'deki bazı yapıları değiştirmek gibi bazı özel yapılar yazma yeteneği alışılmadık hale gelecektir. Theano'da bu kısıtlama yoktur.
3. Hata toleransı
Şahsen, theano'nun hata toleransının tensör akışından daha yüksek olduğunu hissediyorum. Theano değişkenleri tanımlar ve yalnızca, girdiğiniz veriler ve ağ yapısı diyagramınız olabildiği sürece herhangi bir boyut formüle etmeden, imatrix, ivertor ve benzeri gibi türleri formüle etmeye ihtiyaç duyar. Eğer doğruysa sorun değil ve tensorflow'un önceden bazı parametreleri belirtmesi gerekiyor (yukarıdaki kodun num_step parametresi gibi). Buna karşılık, theano'nun hata toleransı çok daha fazla. Elbette, bir dezavantaj da var, yani kod yanlış olabilir. Hata ayıklamak daha zahmetlidir.
Son olarak, tam kaynak kodunu ekleyin: https://github.com/luchi007/RNN_Text_Classify
Leifeng.com'da İlgili Okumalar:
DNN tabanlı metin sınıflandırması uygulamak için TensorFlow'u nasıl kullanacağınızı öğretin
LSTM'yi Jin Yong ve eski ejderhaların isimleriyle eğitin, hangi harika isimler üretilecek?