Önceki bölümde, daha ileriye dönük bir teknolojiyi, optimize etmesi daha kolay olan SELU ve ResNet adlı gizli bir birimi tanıttık.SELU, Batch Normaliztion'da bulunan katman normalleştirme fikirlerini nöron davranışına ve ResNet'e daha da basitleştirir Kimlik bağlantılarının eklenmesi, derin ağın eğitim süreci sırasında daha büyük bir gradyan akışına sahip olmasını sağlar ve gradyanın kaybolmasını hafifletir.
Öncelikle fashion-MNIST verisi üzerine sırasıyla 56 katmanlı ve 20 katmanlı basit bir sinir ağı oluşturalım ve önceki derslerde anlattığımız genel teknikleri kullanalım Optimizasyon algoritması olarak Adam ve gizli birim olarak ReLU kullanıyoruz. Burada evrişim işlemini kullanmadığımıza dikkat edin, çünkü daha iyi bir temsil elde etmek yerine, ikisinin optimizasyon sürecindeki rolünü görmek istiyoruz.
Keras'ta, daha önce öğrendiğimiz bilgilere göre bunu başarmak çok kolaydır.Aşağıdaki iki ağı hızlı bir şekilde kurabiliriz:
numpy'yi np olarak içe aktar
keras.layers'dan girişi içe aktar
keras.datasets'den moda_mnist, mnist'i içe aktar
keras'tan içe aktarma modelleri, katmanları
matplotlib.pyplot dosyasını plt olarak içe aktar
keras.models'ten içe aktarma Modeli
keras.models'den Sıralı içe aktarma
keras içe aktarma optimize edicilerden
keras.layers'dan Yoğun, Bırakma, Etkinleştirme içe aktar
keras.utils'den içe_categorical'a aktar
keras.layers'dan BatchNormalization'ı BN olarak içe aktarın
(X_test, y_test), (X_train, y_train) = fashion_mnist.load_data ()
train_labels = to_categorical (y_train)
test_labels = to_categorical (y_test)
X_train = X_train.reshape (10000,28 * 28)
X_train = X_train.astype ('float32') / 255
X_test = X_test.reshape (60000, 28 * 28)
X_test = X_test.astype ('float32') / 255
def model (n):
model = modeller.Sequential ()
model.add (Yoğun (512, aktivasyon = 'relu', input_shape = (28 * 28,)))
için ben içinde aralık (n):
model.add (Yoğun (256, aktivasyon = 'relu'))
model.add (Yoğun (10, aktivasyon = 'softmax'))
model.compile (optimizer = optimizers.Adam (), loss = 'categorical_crossentropy', \
metrics =)
dönüş (model)
model1 = model (20)
his1 = model1.fit (X_train, train_labels, batch_size = 128, validation_split = 0.3, ayrıntılı = 1, epochs = 10)
model2 = model (56)
his2 = model2.fit (X_train, train_labels, batch_size = 128, validation_split = 0.3, ayrıntılı = 1, epochs = 10)
Katman sayısının birikimini basitçe gerçekleştirmek için burada bir döngü kullanıyoruz (burada 21 ve 57 katman olduğuna dikkat edin, çünkü giriş katmanı aslında gizli bir katmandır, ancak etkiyi yorumlamamızı etkilemeyecektir, affet beni Dikkatsizliğim) Ardından, eğitim seti ve test setindeki hataların çağlarla nasıl değiştiğini gözlemleyin:
w1 = his1.history
w2 = his2.history
matplotlib.pyplot dosyasını plt olarak içe aktar
seaborn'u sns olarak ithal etmek
sns.set (stil = 'beyaz')
plt.plot (aralık (10) ,, 'y -', etiket = '20-katman ')
plt.plot (aralık (10) ,, 'r -', etiket = '56-katman ')
plt.xlabel ('epochs')
plt.ylabel ('test hatası')
plt.legend ()
Test setindeki hata performansına göre 56 katmanlı basit modelin performansı 20 katmanlı modelden çok daha azdır.Şu anda 56 katmanlı basit modelin elde edilip edilmediğini belirlemek için eğitim setindeki hata performansını gözlemlememiz gerekiyor. İyi eğitim, çünkü teorik olarak, sinir ağının ne kadar çok katmanı olursa, modelin kapasitesi o kadar büyük olur.Modelin yerleştirilip yerleştirilmediğini sadece test setine bakarak anlayamayız:
plt.figure ()
plt.plot (aralık (10) ,, 'y -', etiket = '20-katman ')
plt.plot (aralık (10) ,, 'r -', etiket = '56-katman ')
plt.xlabel ('epochs')
plt.ylabel ('eğitim hatası')
plt.legend ()
plt.show ()
56 katmanlı modelin neredeyse hiç eğitim almadığını ve sinir ağının parametrelerinin büyük ölçüde başlatma düzeyinde tutulduğunu görebiliriz.Bu, çözmek için SELU ve ResNet kullanmamız gereken optimizasyon problemidir.
SELU'nun keras'ta kullanımıSELU'nun keras'ta kullanımı nispeten basittir. Katmanda aktivasyon fonksiyonu parametre aktivasyonunu doğrudan "selu" olarak ayarlayabiliriz (tabii ki, sonraki derslerde açıklanacak olan kendi katmanlarımızı da bağımsız olarak ekleyebiliriz):
def lay56_model (n):
model = modeller.Sequential ()
model.add (Yoğun (512, aktivasyon = 'selu', input_shape = (28 * 28,)))
için ben içinde aralık (n):
model.add (Yoğun (256, activation = 'selu')) # relu'yu selu'ya değiştir
model.add (Yoğun (10, aktivasyon = 'softmax'))
model.compile (optimizer = optimizers.Adam (), loss = 'categorical_crossentropy', \
metrics =)
dönüş (model)
Ve onu eğitmek için yukarıdaki adımları tekrarlayın ve eğitim setindeki hatayı ve test setindeki hatayı alın:
Relu'dan çok daha iyi olmasına rağmen optimizasyon sürecinin hala çok zayıf olduğu görülebilmektedir.Olası nedeni yineleme sayısının çok az olmasıdır, çünkü büyük kapasiteli modelin yakınsama hızı genellikle yavaştır, çağlar yaşayacağız Daha sonraki turlarda daha tatmin edici bir seviyeye yaklaşması beklenen 50 katına çıkarıldı:
Bununla birlikte, 56 katmanlı modelin genel test hatası ve eğitim hatasının 20 katmanlı modelin genel hatasından daha yüksek olduğu bu şekilden görülebilir .. Bunun sebebi SELU'nun çalışmaması mı? Kendi kendine normalleştirilmiş bir sinir ağı kurmak imkansız mı?
Burada SELU'nun iki kullanım şartına dikkat etmemiz gerekiyor:
X_train = X_train.astype ('float32') / 255
Ancak bunu standart bir Gauss dağılımına çevirmemiz gerekiyor. Gri tonlamalı görüntünün kendisi ikinci dereceden bir tensördür. Geleneksel yöntemlerle standartlaştırmak zordur. Standardizasyonu zorlamak görüntünün yapısını yok eder, ancak bizim için yerel korelasyonu kullanmayız. Sinir ağı, tüm verileri düzleştirin, orijinal standartlaştırılmış araçları kullanabilirsiniz:
sklearn.preprocessing'den import StandardScaler
X_train = X_train.reshape (10000,28 * 28)
scale = StandardScaler (). fit (X_train)
X_train = scale.transform (X_train)
def lay56_model (n):
model = modeller.Sequential ()
model.add (Yoğun (512, aktivasyon = 'selu', \
kernel_initializer = lecun_normal (), \
input_shape = (28 * 28,)))
için ben içinde aralık (n):
model.add (Yoğun (256, aktivasyon = 'selu', \
kernel_initializer = lecun_normal ()))
model.add (Yoğun (10, kernel_initializer = lecun_normal (), aktivasyon = 'softmax'))
model.compile (optimizer = optimizers.Adam (), loss = 'categorical_crossentropy', \
metrics =)
dönüş (model)
Daha sonra, değiştirilmiş modeli eğitiyoruz ve sonuçlar aşağıdaki gibi:
Şekilde görüldüğü gibi, standart Gauss dağılımına veri normalizasyonu ve ağırlıkların spesifik olarak başlatılmasıyla daha derin ağın, optimizasyon sürecinin sığ katmandan daha iyi olduğunu ve hatanın birkaç adımda daha büyük bir değere indirildiğini görebiliriz. Düşük seviye.
Kalan modülü Keras'ta oluşturunKimlik eşleme işlevine sahip bir ağ oluşturmamız gerekiyor. İşlevi, ilk birkaç katman tarafından kabul edilen girdiyi mevcut çıktıya eklemektir. Keras'ta bunu bir işlev olarak yazmamız gerekir:
def kimlik_blok (girdi, birimler, hareket):
x = katmanlar Dense (birimler, etkinleştirme = hareket) (giriş)
x = katmanlar Aktivasyon ('relu') (x)
x = katmanlar Yoğun (birimler, etkinleştirme = hareket) (x)
x = katmanlar Aktivasyon ('relu') (x)
x = katmanlar Yoğun (birimler, etkinleştirme = hareket) (x)
x = katmanlar Aktivasyon ('relu') (x)
x = katmanlar Yoğun (birimler, etkinleştirme = hareket) (x)
x = layer.add ()
x = katmanlar Aktivasyon ('relu') (x)
dönüş x
İki tensör eklemek için basit bir form kullandığımıza dikkat edilmelidir.Aslında, işlemleri tanımlamak için lambda fonksiyonlarını da kullanabiliriz. Sonra onu aktivasyon fonksiyonuna koyun, buradaki sıra en iyisi tersine çevirmemektir, çünkü son katman çıktı birimine bağlandığında, hala doğrusal olmadığını umuyoruz.
Daha sonra, kimlik_blok eklemek için işlevsel modeli kullanırız, çünkü işlevsel model daha esnektir:
def res_model ():
input_tensor = Giriş (şekil = (28 * 28,))
x = Yoğun (100, aktivasyon = 'relu') (input_tensor)
için ben içinde aralığı (14):
x = kimlik_block (x, 100, 'relu')
y = Yoğun (10, aktivasyon = 'softmax') (x)
model = Model (inputs = input_tensor, outputs = y)
model.compile (optimizer = optimizers.Adam (), loss = 'categorical_crossentropy', \
metrics =)
dönüş (model)
Her bir artık modül 4 katman içerdiğinden, burada yalnızca 14 kez döngü yaptık, ancak döngü başlamadan önce bir katman daha ekledik, toplam 57 katman, ancak etkilemiyor çünkü 57 katman 56'dan fazla katman olmalı Optimize etmek zor; kolay kullanım için gizli katman nöronları 100'e ayarlanmıştır (tabii ki 20 katmanlı ağ için gizli birimlerin sayısı da 100 olarak ayarlanmalıdır); açıklama kolaylığı için Toplu normalleştirme kullanmadık çünkü etki değişse bile Kalan modülün rolü mü yoksa BN'nin rolü mü açıklayamayız.
Doğrudan eğitiyoruz ve şunları elde edebiliyoruz:
Başlangıçta eğitilmesi daha zor olan 56 katmanlı sinir ağı, yalnızca artık modülü ekledikten sonra, eğitim yakınsama etkisi, 20 katmanlı sinir ağınınkinden çok daha yüksektir! ResNet'in gücünü ilk kez gören öğrenciler, lütfen yavaş yavaş sakinleşip bir fincan kahve içelim, şu anda artık modülümüz çok karmaşık bir yapı benimsemiyor. Başka bir deyişle, kimlik haritalama birbiriyle ilişkili değildir ve birçok görevde kullanılan artık modüllerin bağlantısı çok karmaşık hale gelebilir ancak temel ilkeler aynıdır.
Yazar: Monkey Head & Shoulders'ın yeniden yazdırılmasına gerek yoktur, lütfen sahne arkasında bir mesaj bırakın, normlara uyun yeniden yazdırın