"Hafta Sonu Yapay Zeka Sınıfı" SELU ve ResNet (kod makalesi) karşılaşacağınız makine öğrenimi "çukurları"

Ö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:

  • Giriş verilerinin X standart bir Gauss dağılımına uygun olduğunu varsayar. Başlangıçta kullandığımız standardizasyon yöntemi basit ölçeklendirmedir:

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)

  • Ağırlık katsayısının ortalama sıfır değerine uyduğunu ve varyansın girdi boyutunun tersi olduğunu varsayar.Her bir SELU'nun ağırlık katsayısının eğitim süreci sırasında dağılıma uyduğunu garanti etmemiz zordur, ancak bunu en azından başlatma işlemi sırasında yapabiliriz Keras, lecun_normal başlatıcı sağlar, her katman için başlatmayı kolayca ayarlayabiliriz:

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şturun

Kimlik 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
Xinsheng Today Tek avantajlar: Android kurucusu, randevulaşmanıza yardımcı olabilecek bir telefon piyasaya sürmeyi planlıyor
önceki
Honda hala güvenilir, sadece Lingpai'ime bakın.
Sonraki
SELU ve ResNet (Teori) Makine öğreniminde karşılaşacağınız "çukurlar"
Güçlü envanter temizliği: GIGABYTE, iki GDDR5X bellek sürümü GTX 10606GB'yi piyasaya sürdü
Android 10 sistem maruziyeti: akıcılık nihayet Apple'ı geride bıraktı! Netizen: Bunu 6 yıldır duyuyorum
Konsept otomobiller mutlaka süper otomobil değildir. GAC Trumpchi konsept otomobili ENTRANZE, Çin'de görücüye çıktı
Hoşçakal klasik: Sony bu klasik ürünü tamamen durdurdu
Toplam çevrimiçi oyun miktarının düzenlenmesi: Tencent ve NetEase'in geçici acısı VS küçük üreticilerin felaketi
ASUS, çok sayıda siyah teknolojiye sahip çeşitli X299 anakartlar ve ROG gişe rekorları kıran yeni ürünler piyasaya sürdü
Lotus Evora GT410 Sport satışa çıktı, 972 bin yuan sattı / 4.1 saniye yüz kırdı
Lenovo ThinkPad E580 dizüstü bilgisayar tushang: 6,9 mm mikro çerçeve
En çok bilgisayar şovuna benzemeyen! Computex2017 ilk gün
Küçük, saf elektrikli SUV'nin yeni üyesi Cheetah CS3 BEV tanıtıldı ve "Binge" olarak adlandırıldı
HTC U12 Life piyasaya çıktı, Google Pixel 2'nin uzun süredir kayıp olan kardeşi olabilir
To Top