Yazar: Faizan Shaikh
Çeviri: Li Wenjing
Düzeltme: Zhang Yihao
Bu makale hakkında 4300 Word, önerilen okuma 10+ dakika.
Bu makale, tipik bir NN modelinin temel parçalarına hızlı bir genel bakış sunar ve ilgili sorunları çözmek için size RNN oluşturmayı öğretir.
Girişİnsanlar her cümle duyduklarında dili yeniden anlamazlar. Bir makale gördüğümüzde, bu kelimeleri önceki anlayışımıza dayanarak arka planı anlayacağız. Bunu hafıza olarak tanımlıyoruz.
Algoritmalar bu kalıbı kopyalayabilir mi? Sinir ağı (NN) akla gelen ilk teknolojidir. Ne yazık ki, geleneksel sinir ağları bunu henüz yapamıyor. Örneğin, geleneksel bir sinir ağı bir videoda daha sonra ne olacağını tahmin ederse, doğru sonuçlar elde etmek zordur.
Tekrarlayan Sinir Ağı'nın (RNN) devreye girdiği yer burasıdır. Tekrarlayan sinir ağları, derin öğrenme alanında çok popülerdir, bu nedenle tekrarlayan sinir ağlarını öğrenmek zorunludur. Gerçek hayatta tekrarlayan sinir ağlarının bazı pratik uygulamaları:
Bu makalede, ilk olarak tipik bir tekrarlayan sinir ağı modelinin temel kısımlarına hızlı bir genel bakış yapacağız. Ardından problem ifadeleri oluşturacağız ve son olarak bu problem ifadelerini çözmek için Python'da sıfırdan tekrarlayan bir sinir ağı modeli oluşturacağız.
Her zaman yüksek seviyeli Python kitaplıkları ile tekrarlayan sinir ağları yazmaya alışkınız. O halde neden sıfırdan kodlamaya başlayasınız? Bir kavramı öğrenmek ve gerçekten anlamak için sıfırdan öğrenmenin en iyi yol olduğuna kesinlikle inanıyorum. Bu eğitimde göstereceğim şey bu.
Bu makale, okuyucunun tekrarlayan sinir ağları hakkında temel bir anlayışa sahip olduğunu varsayar. Hızlı bir incelemeye ihtiyacınız varsa veya tekrarlayan sinir ağlarının temellerini öğrenmek istiyorsanız, önce aşağıdaki iki makaleyi okumanızı öneririm:
1. Hızlı bir inceleme: tekrarlayan sinir ağları kavramının gözden geçirilmesi
İkinci olarak, dizi tahmini için tekrarlayan sinir ağını kullanın
Üç, tekrarlayan bir sinir ağı modeli oluşturmak için Python kullanın
1. Hızlı bir inceleme: tekrarlayan sinir ağları kavramının gözden geçirilmesiTekrarlayan sinir ağlarının temel kavramlarını hızlıca gözden geçirelim. Örnek olarak bir şirketin hisselerinin seri verilerini alacağız. Basit bir makine öğrenimi modeli veya yapay sinir ağı, hisse senedi sayısı ve açılış değeri gibi bazı özelliklere dayalı olarak hisse senedi fiyatlarını tahmin edebilir. Ayrıca hisse senedinin önceki gün ve haftalardaki performansı da hisse senedi fiyatını etkiler. Tüccarlar için, bu tarihsel veriler aslında beklentinin ana belirleyicileridir.
Geleneksel ileri beslemeli sinir ağlarında, tüm test durumları bağımsız olarak kabul edilir. Hisse senedi fiyatlarını tahmin ederken bunun uygun bir seçim olmadığını görebiliyor musunuz? Sinir ağı modeli, önceki hisse senedi fiyatlarını dikkate almaz - bu iyi bir fikir değil!
Zamana duyarlı verilerle karşı karşıya kaldığımızda, başka bir kavram kullanabiliriz. Tekrarlayan Sinir Ağı (RNN) !
Tipik bir tekrarlayan sinir ağı aşağıdaki gibidir:
Bu ilk bakışta korkutucu görünebilir. Ancak genişlersek, işler daha basitleşmeye başlar:
Şimdi, bu tekrarlayan sinir ağlarının hisse senedi fiyatlarının eğilimini nasıl tahmin ettiğini hayal etmek bizim için daha kolay. Bu, günün fiyatını tahmin etmemize yardımcı olur. Burada, t (h_t) zamanı hakkındaki her tahminin önceki tüm tahminlere ve onlardan öğrenilen bilgilere dayanması gerekir. Oldukça basit, değil mi?
Tekrarlayan sinir ağları, dizi işleme problemlerini büyük ölçüde çözmemize yardımcı olabilir.
Metin, sıra verilerinin başka bir güzel örneğidir. Metin verildikten sonra, tekrarlayan sinir ağı, daha sonra görünecek olan kelimeleri veya cümleleri tahmin edebilir ve bu çok yararlı bir varlık olabilir. Tekrarlayan sinir ağımızın Shakespeare'in sonelerini yazabileceğini umuyoruz!
Şimdi, tekrarlayan sinir ağları, kısa veya küçük ortamlar söz konusu olduğunda harikadır. Ancak bir hikaye oluşturabilmek ve onu hatırlayabilmek için, tekrarlayan sinir ağı modelimiz, tıpkı bir insan beyni gibi, dizinin arkasındaki arka planı anlayabilmelidir.
İkinci olarak, dizi tahmini için tekrarlayan sinir ağını kullanınBu yazıda, dizi tahmin problemleriyle başa çıkmak için tekrarlayan sinir ağlarını kullanacağız. Bunun en basit örneklerinden biri sinüs dalgası tahminidir. Sıra, görünür eğilimler içerir ve buluşsal yöntemler kullanılarak kolayca çözülebilir. İşte bir sinüs dalgası şöyle görünür:
Bu sorunu çözmek için önce sıfırdan tekrarlayan bir sinir ağı tasarlıyoruz. Tekrarlayan sinir ağı modelimiz de, onu diğer sekans problemlerine uygulayabilmemiz için iyi bir şekilde genelleştirilmelidir. Problemimizi şu şekilde formüle edeceğiz: Bir sinüs dalgasına ait 50 numara dizisi verildiğinde, serideki 51. sayıyı tahmin edin. Seçtiğiniz Jupyter dizüstü bilgisayarınızı (40'tan fazla programlama dilini destekleyen etkileşimli bir dizüstü bilgisayar) veya IDE'yi (Entegre Geliştirme Ortamı, bir programlama yazılımı) açmanın zamanı geldi!
Üçüncüsü, tekrarlayan sinir ağlarını kodlamak için Python kullanınAdım 0: Veri hazırlama
Başka bir şey yapmadan önce, veri hazırlama, herhangi bir veri bilimi projesinde kaçınılmaz ilk adımdır. Ağ modelimizin beklenen verileri nedir? Tek bir uzunluk dizisi 50 girecektir. Dolayısıyla, giriş verilerinin şekli şöyle olacaktır:
(number_of_records x length_of_sequence x types_of_sequences)Burada, types_of_sequence 1'dir, çünkü yalnızca bir tür dizilimimiz vardır - sinüs dalgası.
Öte yandan, kaydedilen her çıktı için yalnızca bir değer vardır. Bu, giriş dizisindeki 51. değerdir. Yani şekli şöyle olacak:
(number_of_records x types_of_sequences) # where types_of_sequences 1Bu kodu inceleyelim. İlk önce gerekli kitaplıkları içe aktarın:
% pylab satır içi matematik ithal etmekSinüs dalgası benzeri bir veri oluşturmak için Python matematik kütüphanesindeki sinüs fonksiyonunu kullanacağız:
sin_wave = np.array ()Yeni oluşturulan sinüs dalgasını görselleştirin:
plt.plot (sin_wave)Şimdi verileri aşağıdaki kod bloğunda oluşturacağız:
X = Y = seq_len = 50 num_records = len (sin_wave) -seq_len aralıktaki i için (num_records-50): X.append (sin_wave) Y.append (sin_wave) X = np.array (X) X = np.expand_dims (X, eksen = 2) Y = np.array (Y) Y = np.expand_dims (Y, eksen = 1)Baskı verilerinin şekli:
X.shape, Y.shape ((100, 50, 1), (100, 1))Lütfen (num_records-50) döngüsüne dikkat edin çünkü doğrulama verisi olarak 50 kaydı bir kenara koymak istiyoruz. Şimdi bu doğrulama verilerini oluşturabiliriz:
X_val = Y_val = aralıktaki i için (num_records-50, num_records): X_val.append (sin_wave) Y_val.append (sin_wave) X_val = np.array (X_val) X_val = np.expand_dims (X_val, axis = 2) Y_val = np.array (Y_val) Y_val = np.expand_dims (Y_val, axis = 1)Adım 1: Tekrarlayan sinir ağı modelimiz için mimariyi oluşturun
Bir sonraki görevimiz, tekrarlayan sinir ağı modelinde kullandığımız tüm gerekli değişkenleri ve fonksiyonları tanımlamaktır. Tekrarlayan sinir ağı modelimiz bir girdi dizisini kabul edecek, onu 100 birimlik gizli bir katmanda işleyecek ve tek bir değer çıktısı üretecektir:
öğrenme_ hızı = 0.0001 nepoch = 25 T = 50 # dizi uzunluğu hidden_dim = 100 output_dim = 1 bptt_truncate = 5 min_clip_value = -10 max_clip_value = 10Ardından ağın ağırlığını tanımlayacağız:
U = np.random.uniform (0, 1, (gizli_dim, T))
W = np.random.uniform (0, 1, (gizli_dim, gizli_dim))
V = np.random.uniform (0, 1, (output_dim, hidden_dim))
onların arasında:
Son olarak, gizli katmanda kullanılan sigmoid işlevini tanımlayacağız:
def sigmoid (x): return 1 / (1 + np.exp (-x))2. Adım: Modeli eğitin
Artık modeli tanımladığımıza göre, sonunda sıra verilerimizi eğitmeye devam edebiliriz. Eğitim sürecini daha küçük adımlara ayırabiliriz, yani:
Adım 2.1: Eğitim verilerinin eksik olup olmadığını kontrol edin Adım 2.1.1: İleri beslemeli iletim Adım 2.1.2: Hatayı hesaplayın Adım 2.2: Verilerin kaybolup kaybolmadığını kontrol edin ve doğrulayın Adım 2.2.1 İleri beslemeli iletim Adım 2.2.2: Hatayı hesaplayın Adım 2.3: Gerçek eğitime başlayın Adım 2.3.1: İleri yöntem Adım 2.3.2: Geriye aktarım hatası Adım 2.3.3: Ağırlığı güncelleyinVeriler birleşene kadar bu adımları tekrar etmemiz gerekiyor. Model aşırı yüklenmeye başlarsa, durun! Ya da sadece dönem sayısını önceden tanımlayın.
Tekrarlayan sinir ağı modelimiz aracılığıyla ileri çıkarım yapacağız ve kayıp değerini elde etmek için kaydedilen tüm tahminlerin kare hatasını hesaplayacağız.
aralıktaki çağ için (nepoch): # trendeki kaybı kontrol et kayıp = 0.0 # tahmin almak için ileri geçiş yapın aralıktaki i için (Y.shape): x, y = X , Y # her kaydın girdi, çıktı değerlerini alın prev_s = np.zeros ((hidden_dim, 1)) # burada, prev-s gizli katmanın önceki aktivasyonunun değeridir; tüm sıfırlar olarak başlatılır aralıktaki t için (T): new_input = np.zeros (x.shape) # daha sonra dizideki her zaman adımı için bir ileri geçiş yaparız new_input = x # bunun için, o zaman adımı için tek bir girdi tanımlıyoruz mulu = np.dot (U, new_input) mulw = np.dot (W, önceki_s) ekle = mulw + mulu s = sigmoid (ekle) mulv = np.dot (V, s) prev_s = s # hesaplama hatası loss_per_record = (y-mulv) ** 2/2 kayıp + = loss_per_record kayıp = kayıp / kayan (y.shape)Doğrulama verilerinin kaybını hesaplamak için aynı şeyi (aynı döngüde) yapacağız:
# val üzerindeki kaybı kontrol et val_loss = 0.0 aralıktaki i için (Y_val.shape): x, y = X_val , Y_val prev_s = np.zeros ((gizli_dim, 1)) aralıktaki t için (T): new_input = np.zeros (x.shape) new_input = x mulu = np.dot (U, new_input) mulw = np.dot (W, önceki_s) ekle = mulw + mulu s = sigmoid (ekle) mulv = np.dot (V, s) prev_s = s loss_per_record = (y-mulv) ** 2/2 val_loss + = loss_per_record val_loss = val_loss / float (y.shape) print ('Dönem:', epoch + 1, ', Kayıp:', kayıp ', Değer Kaybı:', değer_ kaybı)Aşağıdaki çıktıyı almalısınız:
Dönem: 1, Kayıp :, Değer Kaybı: ... ...Şimdi ağın gerçek eğitimine başlıyoruz. Burada, hataları hesaplamak için önce ileriye dönük tahmin gerçekleştiriyoruz ve ardından gradyanları hesaplamak ve güncellemek için geriye doğru tahmin kullanıyoruz. Bunu size adım adım göstermeme izin verin, böylece nasıl çalıştığını sezgisel olarak anlayabilirsiniz.
İleri itme yöntemi aşağıdaki gibidir:
Bu, ileri itme yöntemini gerçekleştiren koddur (yukarıdaki döngünün devamı olduğuna dikkat edin):
# tren modeli aralıktaki i için (Y.shape): x, y = X , Y katmanlar = prev_s = np.zeros ((gizli_dim, 1)) dU = np.zeros (U.shape) dV = np.zeros (V. şekli) dW = np.zeros (W. şekli) dU_t = np.zeros (U.shape) dV_t = np.zeros (V.shape) dW_t = np.zeros (W. şekli) dU_i = np.zeros (U.shape) dW_i = np.zeros (W. şekli) # doğrudan geçiş aralıktaki t için (T): new_input = np.zeros (x.shape) new_input = x mulu = np.dot (U, new_input) mulw = np.dot (W, önceki_s) ekle = mulw + mulu s = sigmoid (ekle) mulv = np.dot (V, s) layer.append ({'s': s, 'önceki_s': önceki_s}) prev_s = sİleri yayılma adımından sonra, her katmanın gradyanını hesaplar ve hatayı geriye doğru yayarız. Vanilya geri yayılımı yerine kesilmiş geri yayılma süresi (TBPTT) kullanacağız (geri yayılmanın sezgisel olmayan etkisine bir örnek). Bu karmaşık gelebilir ama aslında çok basittir.
BPTT ve backprop arasındaki temel fark, yinelenen sinir ağı katmanındaki tüm zaman adımlarının geri yayılmış olmasıdır. Bu nedenle, sıra uzunluğumuz 50 ise, mevcut zaman adımından önce tüm zaman adımlarını geri yayacağız.
Doğru tahmin ettiyseniz, BPTT hesaplama açısından çok pahalı görünüyor. Bu nedenle, önceki tüm zaman adımlarını geri yaymak yerine, bilgi işlem gücünden tasarruf etmek için x zaman adımlarına kadar geri yayılırız. Bunun kavramsal olarak stokastik gradyan inişine benzer olduğunu düşünürsek, tüm veri noktaları yerine bir grup veri noktası ekleriz.
Geri yayılma hatası kodu aşağıdadır:
# önceden türevi dmulv = (mulv-y) # geri geçiş aralıktaki t için (T): dV_t = np.dot (dmulv, np.transpose (katmanlar)) dsv = np.dot (np.transpose (V), dmulv) ds = dsv dadd = ekle * (1-ekle) * ds dmulw = baba * np.ones_like (mulw) dprev_s = np.dot (np.transpose (W), dmulw) aralıktaki i için (t-1, max (-1, t-bptt_truncate-1), -1): ds = dsv + dprev_s dadd = ekle * (1-ekle) * ds dmulw = baba * np.ones_like (mulw) dmulu = baba * np.ones_like (mulu) dW_i = np.dot (W, katmanlar) dprev_s = np.dot (np.transpose (W), dmulw) new_input = np.zeros (x.shape) new_input = x dU_i = np.dot (U, new_input) dx = np.dot (np.transpose (U), dmulu) dU_t + = dU_i dW_t + = dW_i dV + = dV_t dU + = dU_t dW + = dW_tSon olarak, hesaplanan ağırlık gradyanını kullanarak ağırlıkları güncelliyoruz. Hatırlamamız gereken bir şey, eğer kontrol edilmezlerse, eğimin genellikle patlayacağıdır. Bu, gradyan patlama problemi adı verilen sinir ağlarını eğitmenin temel bir problemidir. Bu yüzden onları çok hızlı büyümemeleri için bir aralıkta sıkıştırmalıyız. Bunu yapabiliriz:
dU.max () ise > max_clip_value: dU = max_clip_value dV.max () ise > max_clip_value: dV = max_clip_value dW.max () ise > max_clip_value: dW = max_clip_value dU.min () ise < min_clip_value: dU = min_clip_value dV.min () ise < min_clip_value: dV = min_clip_value dW.min () ise < min_clip_value: dW = min_clip_value # Güncelleme U - = öğrenme_ hızı * dU V - = öğrenme_ hızı * dV W - = öğrenme_ hızı * dWYukarıdaki modeli eğitirken şu çıktıyı aldık:
Dönem: 1, Kayıp :, Değer Kaybı: Dönem: 2, Kayıp :, Değer Kaybı: Dönem: 3, Kayıp :, Değer Kaybı: Dönem: 4, Kayıp :, Değer Kaybı: Epoch: 5, Loss :, Val Loss: Dönem: 6, Kayıp :, Değer Kaybı: Dönem: 7, Kayıp :, Değer Kaybı: Dönem: 8, Kayıp :, Değer Kaybı: Dönem: 9, Kayıp :, Değer Kaybı: Dönem: 10, Kayıp :, Değer Kaybı: Dönem: 11, Kayıp :, Değer Kaybı: Dönem: 12, Kayıp :, Değer Kaybı: Dönem: 13, Kayıp :, Değer Kaybı: Dönem: 14, Kayıp :, Değer Kaybı: Dönem: 15, Kayıp :, Değer Kaybı: Dönem: 16, Kayıp :, Değer Kaybı: Dönem: 17, Kayıp :, Değer Kaybı: Dönem: 18, Kayıp :, Değer Kaybı: Dönem: 19, Kayıp :, Değer Kaybı: Dönem: 20, Kayıp :, Değer Kaybı: Dönem: 21, Kayıp :, Değer Kaybı: Dönem: 22, Kayıp :, Değer Kaybı: Dönem: 23, Kayıp :, Değer Kaybı: Dönem: 24, Kayıp :, Değer Kaybı: Dönem: 25, Kayıp :, Değer Kaybı:harika görünüyor! Tasarımımızın görsel algısını elde etmek için tahminler yapma ve bunları çizme zamanı.
3. Adım: Tahminleri alın
Eğitimin ağırlıkları aracılığıyla tahminler elde etmek için ileri çıkarım yöntemini kullanacağız:
preds = aralıktaki i için (Y.shape): x, y = X , Y prev_s = np.zeros ((gizli_dim, 1)) # Doğrudan geçiş aralıktaki t için (T): mulu = np.dot (U, x) mulw = np.dot (W, önceki_s) ekle = mulw + mulu s = sigmoid (ekle) mulv = np.dot (V, s) prev_s = s preds.append (mulv) preds = np.array (preds)Bu tahminleri gerçek değerlerle çizin:
plt.plot (önsözler, 'g') plt.plot (Y, 'r') plt.show ()Bu eğitim verileriyle ilgili. Modelimizin fazla uygun olup olmadığını nasıl anlarız? Bu, daha önce oluşturduğumuz doğrulama seti devreye girdiğinde:
preds = aralıktaki i için (Y_val.shape): x, y = X_val , Y_val prev_s = np.zeros ((gizli_dim, 1)) # Her zaman adımı için ... aralıktaki t için (T): mulu = np.dot (U, x) mulw = np.dot (W, önceki_s) ekle = mulw + mulu s = sigmoid (ekle) mulv = np.dot (V, s) prev_s = s preds.append (mulv) preds = np.array (preds) plt.plot (önsözler, 'g') plt.plot (Y_val, 'r') plt.show ()Fena değil. Tahmin etkileyici görünüyor. Doğrulama verilerinin kök ortalama karesel hata puanı da kabul edilebilir:
sklearn.metrics'ten import mean_squared_error math.sqrt (mean_squared_error (Y_val * max_val, preds * max_val)) 0,127191931509431 sonuç olarakSıralı verilerle uğraşırken, tekrarlayan sinir ağlarının ne kadar yararlı olduğunu yeterince vurgulamadım. Herkesi bunu öğrenmeye ve veri setine uygulamaya çağırıyorum. NLP sorununu çözmeye çalışın ve bir çözüm bulup bulamayacağınızı görün. Herhangi bir sorunuz varsa aşağıdaki yorumlar bölümünden benimle her zaman iletişime geçebilirsiniz.
Bu makalede, numpy kitaplığını kullanarak sıfırdan tekrarlayan bir sinir ağı modelinin nasıl oluşturulacağını öğrendik. Keras veya Caffe gibi üst düzey kitaplıkları da kullanabilirsiniz, ancak uyguladığınız kavramı anlamak önemlidir.
Lütfen bu makale ile ilgili düşüncelerinizi, sorularınızı ve görüşlerinizi aşağıda paylaşın. mutlu öğrenme!
Bu makaleyi Analytics Vidhya'nın Android APP'sinde de okuyabilirsiniz.
Orjinal başlık:
Python'da Sıfırdan Tekrarlayan Bir Sinir Ağı Oluşturun - Veri Bilimcileri İçin Önemli Bir Okuma
Orijinal bağlantı: https://www.analyticsvidhya.com/blog/2019/01/fundamentals-deep-learning-recurrent-neural-networks-scratch-python/
Editör: Huang JiyanÇevirmen Profili
Li Wenjing , Kuzey Çin Elektrik Enerjisi Üniversitesi'nde İngilizce branşında son sınıf öğrencisi. Veriler ve İnternet ile ilgili bilgilerle ilgileniyor. Veri bilimi hakkındaki makaleleri çevirerek ilgili bilgileri öğrenmeyi umuyorum ve ayrıca burada benzer düşünen arkadaşlar edinmeyi umuyorum.
- Bitiş -Tsinghua-Qingdao Veri Bilimi Enstitüsü'nün resmi WeChat kamu platformunu takip edin " THU Veri Pastası "Ve kız kardeş numarası" Veri Pastası THU "Daha fazla ders avantajı ve kaliteli içerik elde edin.