Ünite Testi Arkadaşınız
Yazarlar arasında “Tüm yazılar yeniden yazmaktır” diye bir söz vardır - yani, yazının büyük kısmı gözden geçirilir. Programcılar için (veya en azından veri bilimcileri) ifade, "Tüm kodlama hata ayıklama" şeklinde yeniden ifade edilebilir.
Ne zaman kod yazıyorsanız, kullanım amacına uygun olduğunu doğrulamanız gerekir. Doğruluğunu onaylamak için şimdiye kadar bulduğum en iyi yöntem, kodunuzu küçük bölümlere ayırmak ve her bölümün çalıştığını doğrulamaktır. Bu, segment çıktısını, doğru cevap olduğunu bildiğinizle karşılaştırarak yapılabilir. Buna birim testi denir . İyi birim testleri yazmak, iyi bir istatistikçi / veri bilimci / makine öğrenimi uzmanı / sinir ağı pratisyeni olmanın anahtar bir parçasıdır. Sadece hiçbir yedek yoktur.
Ağ performansını ayarlamadan önce, kodunuzun hatasız olup olmadığını kontrol etmeniz gerekir! Aksi takdirde, RMS Titanic'teki şezlongları yeniden düzenliyor olabilirsiniz .
Doğrulamayı, diğer makine öğrenim tiplerine veya istatistiksel modellere göre daha önemli kılan iki sinir ağı özelliği vardır.
Yapay sinir ağları rasgele orman veya lojistik regresyonun olduğu gibi “kullanıma hazır” algoritmalar değildir. Basit, ileri beslemeli ağlar için bile, kullanıcı ağın nasıl yapılandırıldığı, bağlandığı, başlatıldığı ve optimize edildiği konusunda çok sayıda karar vermek için büyük ölçüde kullanıcı üzerindedir. Bu kod yazma, kod yazma ise hata ayıklama anlamına gelir.
Bir sinir ağı kodu bir istisna oluşturmadan çalıştırsa bile, ağda hala hatalar olabilir! Bu hatalar, ağın eğitim alacağı sinsi tür bile olabilir, ancak optimal olmayan bir çözümde sıkışıp kalmış veya ortaya çıkan ağ istenen yapıya sahip değildir. ( Bu, sözdizimsel ve anlamsal hata arasındaki farkın bir örneğidir .)
Bu Orta posta yazısında, Chase Roberts tarafından " Makine öğrenme kodunun nasıl test edileceğini " yazıyor. Makaleden buggy kodu örneğini ödünç aldım:
def make_convnet(input_image):
net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool2')
net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool3')
net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
return net
Hatayı görüyor musun? Farklı işlemlerin çoğu aslında kullanılmaz, çünkü önceki sonuçlar yeni değişkenlerle yazılmıştır. Bir ağda bu kod bloğunun kullanılması hala çalışacak ve ağırlıklar güncellenecek ve kayıp bile düşebilir - ancak kod kesinlikle amaçlananı yapmıyor. (Yazar aynı zamanda tek veya çift tırnak kullanılması konusunda tutarsız ancak bu tamamen stilize.)
Yapay sinir ağlarına ilişkin en yaygın programlama hataları
- Değişkenler oluşturulur ancak asla kullanılmaz (genellikle kopyala-yapıştır hataları nedeniyle);
- Degrade güncellemeleri için ifadeler yanlıştır;
- Ağırlık güncellemeleri uygulanmaz;
- Kayıp fonksiyonları doğru ölçekte ölçülmez (örneğin, çapraz entropi kaybı olasılık veya logit olarak ifade edilebilir)
- Kayıp görev için uygun değildir (örneğin, bir regresyon görevi için kategorik çapraz entropi kaybının kullanılması).
Yürüymeden Önce Sürün; Koşmadan Önce Yürü
Geniş ve derin sinir ağları ve egzotik kablolamalı sinir ağları şu anda makine öğreniminde Sıcak Şey. Ancak bu ağlar tamamen oluşmuş bir şekilde yayılmadı; tasarımcıları kendilerine daha küçük birimlerden inşa ettiler. İlk önce, tek bir gizli katmana sahip küçük bir ağ kurun ve doğru çalıştığını doğrulayın. Sonra adım adım ilave model karmaşıklığı ekleyin ve bunların her birinin de çalıştığını doğrulayın.
Bir katmandaki çok az sayıda nöron , şebekenin öğrendiği gösterimini kısıtlayarak yetersiz uyuma neden olabilir. Çok fazla nöron aşırı uyuşmaya neden olabilir, çünkü ağ eğitim verilerini "ezberler".
Bir problemi modellemek için gerekli matematiksel olarak sadece az sayıda nöron olduğunu kanıtlasanız bile, genellikle "birkaç daha fazla" nöronun olması , optimizer'ın "iyi" bir konfigürasyon bulmasını kolaylaştırır . (Ancak bunun neden böyle olduğunu tam olarak anlayabileceğini sanmıyorum.) Buna XOR problemi bağlamında bir örnek vereceğim: İterasyonlarımın NE'yi XOR için MSE <0.001 ile çok yüksek olması gerekmez mi? .
Gizli katmanların sayısını seçmek, ağın ham verilerden bir soyutlama öğrenmesini sağlar. Derin öğrenme bugünlerde bütün öfke ve çok sayıda katmana sahip ağlar etkileyici sonuçlar göstermiştir. Ancak çok fazla gizli katman eklemek, riskin fazla takılmasına neden olabilir veya ağı optimize etmeyi çok zorlaştırabilir.
Akıllı bir ağ kablosu seçmek sizin için işin çoğunu yapabilir. Veri kaynağınız özel ağ mimarilerine uygun mu? Evrişimli sinir ağları "yapılandırılmış" veri kaynakları, görüntü veya ses verileri üzerinde etkileyici sonuçlar elde edebilir. Tekrarlayan sinir ağları, doğal dil veya zaman serisi verileri gibi sıralı veri türlerinde iyi yapabilir. Artık bağlantılar derin ileri beslemeli ağları iyileştirebilir.
Yapay Sinir Ağı Eğitimi Kilit Toplama Gibi
Son teknolojiye ulaşmak veya hatta sadece iyi sonuçlar elde etmek için, birlikte iyi çalışacak şekilde yapılandırılmış tüm parçaları ayarlamanız gerekir . Aslında öğrenen bir sinir ağı yapılandırması ayarlamak, bir kilit seçmek gibi bir şeydir: tüm parçaların tam olarak sıralanması gerekir . Doğru yerde tek bir tamburun olması yeterli olmadığı gibi, sadece mimarinin veya yalnızca en iyi duruma getiricinin doğru şekilde ayarlanmış olması da yeterli değildir.
Yapılandırma seçeneklerinin ayarlanması, bir tür yapılandırma seçeneğinin (örneğin, öğrenme hızı) diğerlerinden daha az ya da çok önemli olduğunu söylemek kadar basit değildir, çünkü bu seçeneklerin tümü diğer seçeneklerin tümü ile etkileşime girer. seçim, başka bir yerde yapılan başka bir seçenekle birlikte iyi yapabilir .
Düzenleme seçenekleri veya sayısal optimizasyon seçenekleri olmayan konfigürasyon seçeneklerinin kapsamlı bir listesidir.
Bu konuların tümü aktif araştırma alanlarıdır.
Ağın başlatılması genellikle bir sinir ağı ağının kaynağı olarak göz ardı edilir. Çok geniş bir aralıkta başlatma, başlangıç ağırlıklarını çok büyük ayarlayabilir, yani tek nöronların ağ davranışı üzerinde büyük bir etkisi vardır.
Bir sinir ağı ve bir regresyon modeli arasındaki temel fark, sinir ağının, aktivasyon fonksiyonları olarak adlandırılan birçok doğrusal olmayan fonksiyonun bir bileşimi olmasıdır . (Bakınız: sinir ağı ve lineer regresyon arasındaki temel fark nedir )
Klasik sinir ağı sonuçları sigmoidal aktivasyon fonksiyonlarına (lojistik veya fonksiyonları) odaklandı . Yeni bir sonuç, ReLU (veya benzeri) ünitelerin daha iyi çalışma eğiliminde olduğunu, çünkü daha dik gradyanlara sahip olduğunu, bu nedenle güncellemelerin hızlı bir şekilde uygulanabileceğini buldu. (Bkz: Neden ReLU'yu sinir ağlarında kullanıyoruz ve onu nasıl kullanıyoruz? ) ReLU'larla ilgili dikkat çeken bir şey, öğrenmeyi uyaran “ölü nöron” olgusudur; sızdıran relus ve benzeri değişkenler bu sorunu önler. Görmektanh
Başka seçenekler de var. Bkz: Artıları / eksileri olan sinir ağlarında kapsamlı aktivasyon fonksiyonları listesi
Artık bağlantılar, sinir ağlarını eğitmeyi kolaylaştıracak temiz bir gelişmedir. "Görüntü Tanıma için Derin Kalıcı Öğrenme"
Kaiming, Xiangyu Zhang, Shaoqing Ren, Jian Sun, In: CVPR. (2016). Ek olarak, artık blok içindeki işlemlerin sırasının değiştirilmesi, sonuçta ortaya çıkan ağı daha da iyileştirebilir. " Derin Artık Ağlarda Kimlik Eşlemeler Kaiming He, Xiangyu Zhang, Shaoqing Ren ve Jian güneş tarafından"
Dışbükey olmayan optimizasyon zordur
Bir sinir ağının nesnel işlevi sadece gizli birimler olmadığında, tüm aktivasyonların doğrusal olduğu ve tasarım matrisinin tam dereceli olduğu durumlarda dışbükeydir - çünkü bu konfigürasyon aynı şekilde sıradan bir regresyon problemidir.
Diğer tüm durumlarda, optimizasyon sorunu dışbükey değildir ve dışbükey olmayan optimizasyon zordur. Sinir ağlarını eğitmenin zorlukları iyi bilinmektedir (bakınız: Derin sinir ağlarını eğitmek neden bu kadar zor? ). Ek olarak, sinir ağları, bizi yalnızca birinci dereceden yöntemlerle kısıtlayan çok sayıda parametreye sahiptir (bakınız: Neden Newton'un yöntemi makine öğrenmesinde yaygın olarak kullanılmıyor? ). Bu çok aktif bir araştırma alanı.
Öğrenme hızını çok fazla ayarlamak, optimizasyonun farklılaşmasına neden olacaktır, çünkü "kanyonun" bir tarafından diğerine sıçrayacaksınız. Bunu çok küçük olarak ayarlamak, gerçek bir ilerleme kaydetmenizi önleyecektir ve SGD'de bulunan gürültünün degrade tahminlerinizi bastırmasına izin verecektir.
Degrade kırpma , bazı eşiğin üstünde olduğunda degradenin normunu yeniden ölçeklendirir. Bunun tipik olarak 1.0 değerinde bir set ve unut parametresi olduğunu düşünürdüm, ancak LSTM dil modelini 0.25 olarak ayarlayarak çarpıcı biçimde daha iyi hale getirebileceğimi öğrendim. Bunun neden olduğunu bilmiyorum.
Öğrenme hızı planlaması , eğitim süresince öğrenme oranını azaltabilir. Tecrübelerime göre, zamanlamayı kullanmaya çalışmak regex'e çok benziyor : bir problemle (“belli bir dönemin ardından nasıl devam edeceğimi öğrenirim?”) İki problemle (“Belirli bir dönemin ardından devam etmeyi nasıl öğrenirim?”) ? "ve" İyi bir program nasıl seçerim? "). Diğer insanlar, zamanlamanın şart olduğu konusunda ısrar ediyor. Karar vermene izin vereceğim.
İyi bir minibatch boyutu seçmek , öğrenme sürecini dolaylı olarak etkileyebilir, çünkü daha büyük bir mini parti, daha küçük bir mini partiden daha küçük bir varyansa ( büyük sayılar yasası) sahip olma eğiliminde olacaktır . Mini partinin degradenin yönü hakkında bilgilendirici olacak kadar büyük, SGD'nin ağınızı düzenleyebileceği kadar küçük olmasını istiyorsunuz.
Vanilya SGD'sini geliştirmek için momentum, adaptif öğrenme oranları, Nesterov güncellemeleri vb. Kullanan stokastik gradyan inişlerinde çeşitli varyasyonlar vardır . Daha iyi bir optimize edici tasarlamak çok aktif bir araştırma alanıdır. Bazı örnekler:
İlk çıktığında, Adam optimizer çok ilgi yarattı. Ancak bazı yeni araştırmalar, momentumlu SGD'nin sinir ağları için uyarlamalı gradyan yöntemleri gerçekleştirebildiğini buldu. " Machine Learning'de Adaptif Gradyan Yöntemlerinin Marjinal Değer Ashia C. Wilson, Rebecca Roelofs'un Mitchell Stern, Nathan Srebro Benjamin Recht tarafından"
Ancak öte yandan, bu çok yeni makale, adaptif oran yöntemleri ile SGD arasındaki boşluğu momentum ile kapatan sözde yeni bir adaptif öğrenme hızı optimizeri önermektedir. " Derin Sinir Ağları Eğitiminde Uyarlamalı Gradyan Yöntemlerinin Genelleştirme Boşluğunun Kapatılması", Jinghui Chen, Quanquan Gu
Öğrenme hızını otomatik olarak ayarlamak için tarihsel gradyan bilgisini benimseyen uyarlamalı gradyan yöntemlerinin, derin sinir ağlarının eğitiminde momentum ile stokastik gradyan inişinden (SGD) daha kötü genelleme yaptığı gözlemlenmiştir. Bu, adaptif gradyan yöntemlerinin genelleme boşluğunun açık bir problemin nasıl kapatılacağını bırakır. Bu çalışmada, Adam, Amsgrad gibi uyarlamalı gradyan yöntemlerinin bazen "aşırı uyarlanmış" olduğunu gösteriyoruz. Her iki dünyanın da en iyisini elde etmek için Adam / Amsgrad'ı SGD ile birleştiren Kısmen uyarlamalı momentum tahmin yöntemi (Padam) adlı yeni bir algoritma tasarlıyoruz. Standart kriterler üzerinde yapılan deneyler, Padam'ın, derin sinir ağlarının eğitiminde SGD'nin yanı sıra genelleme yaparken Adam / Amsgrad gibi hızlı yakınsama oranını koruyabildiğini göstermektedir.
normalleştirme
Verilerin ölçeği eğitim konusunda büyük bir fark yaratabilir.
Bir sinir ağına veri sunmadan önce , verileri 0 ortalama ve birim varyansa sahip olacak şekilde standartlaştırmak ya da gibi küçük bir aralıkta yatmak eğitimi iyileştirebilir. Bu ön koşullandırma için yeterlidir ve birimlerdeki bir seçimin ağ ağırlıkları üzerindeki etkisini kaldırır. Örneğin milimetre cinsinden uzunluk ve kilometre cinsinden uzunluk, aynı konsepti temsil eder, ancak farklı ölçeklerdedir. Verilerin nasıl standartlaştırılacağının tam ayrıntıları, verilerinizin nasıl göründüğüne bağlıdır.[ - 0,5 , 0,5 ]
Katman normalizasyonu , nöronların aktivasyonları için çalışan bir ortalama ve standart sapma tutarak ağ eğitimini iyileştirebilir. Bunun neden eğitime yardımcı olduğu ve aktif bir araştırma alanı olmaya devam ettiği tam olarak bilinmemektedir.
Düzenlileştirme
Ağ düzenini seçmek ve ayarlamak, iyi bir şekilde genelleşen bir model oluşturmanın (yani, eğitim verilerine uygun olmayan bir model) inşa etmenin kilit bir parçasıdır. Bununla birlikte, ağınızın eğitim verilerindeki kaybı azaltmak için uğraştığı sırada - ağ öğrenmediğinde - düzenli olma sorunun ne olduğunu gizleyebilir.
Ağım öğrenemediğinde, tüm düzenlileştirmeyi kapatırım ve düzenli olmayan ağın düzgün çalıştığını doğrularım. Sonra her bir düzenleme parçasını geri ekledim ve bunların her birinin yol boyunca çalıştığını doğruladım.
Bu taktik, bazı düzenlileşmelerin zayıf olarak belirlenebileceği yerleri belirleyebilir. Bazı örnekler
L2 düzenlenmesi (diğer bir deyişle ağırlık azalması) veya düzenlenmesi çok fazla ayarlandığı için ağırlıklar hareket edemez.L1
Düzenlemenin iki parçası çatışma içinde. Örneğin, katman normalizasyonunun ve bırakmanın birlikte kullanılması zor olduğu yaygın olarak görülmektedir. Her ikisi de kendi başına çok yararlı olduğundan, her ikisinin de nasıl kullanılacağını anlamak etkin bir araştırma alanıdır.
Bir Kayıt Defteri Deneyimi Tutun
Bir sinir ağı kurduğumda hiçbir parametre ayarını zorlamıyorum. Bunun yerine, çalışma zamanında ağ yapılandırma ayrıntılarını doldurmak için kullanılan ve kullanılan bir yapılandırma dosyasında (örn. JSON) yapıyorum. Bütün bu konfigürasyon dosyalarını saklıyorum. Herhangi bir parametre değişikliği yaparsam, yeni bir yapılandırma dosyası yaparım. Son olarak, eğitim ve onaylama için tüm dönem başına kayıpları yorum olarak ekliyorum.
Eski sonuçları korumak konusunda bu kadar takıntılı olmamın nedeni, bunun önceki deneyleri tekrar gözden geçirmeyi ve gözden geçirmeyi çok kolaylaştırmasıdır. Ayrıca, aynı çıkmaz denemeyi yanlışlıkla tekrarlamaya karşı da önlem alır. Psikolojik olarak, geriye bakıp gözlemlemenizi de sağlar: "Proje bugün olmasını istediğim yerde olmayabilir, ama haftalar öncesine göre ilerleme kaydediyorum ."k
Örnek olarak, LSTM dil modelleri hakkında bilgi edinmek istedim, bu yüzden diğer Twitter kullanıcılarına cevap olarak yeni tweet yazan bir Twitter botu yapmaya karar verdim. Bu konuda boş zamanlarında, yüksek okul ve iş arasında çalıştım. Yaklaşık bir yıl sürdü ve istediğimi yapan bir modele geçmeden önce yaklaşık 150 farklı model yineledim: (tür) bir anlam ifade eden yeni bir İngilizce metin oluşturun. (Önemli bir kilitlenme noktası ve bu kadar çok girişimde bulunma nedeninin bir parçası, erken düşük kayıplı modeller eğitim verilerini ezberlemeyi başardığı için örneklem dışı bir kayıp elde etmenin yeterli olmamasıydı, bu yüzden sadece istemlere cevap olarak almanca yazılmış metin bloklarını yeniden üretiyordu - modeli daha spontan ve hala düşük kayıplı hale getirmek için biraz ince ayar yapıldı.)