1. Genel Bakış
Bu laboratuvarda Keras ve Tensorflow 2 ile kendi konvolüsyonlu nöral ağlarınızı sıfırdan oluşturmayı, eğitmeyi ve ayarlamayı öğreneceksiniz. Artık TPU'ların gücünü kullanarak bu işlemi dakikalar içinde yapabilirsiniz. Ayrıca çok basit aktarımla öğrenmeden Squeezenet gibi modern evrişimli mimarilere kadar çeşitli yaklaşımları keşfedeceksiniz. Bu laboratuvar, nöral ağlarla ilgili teorik açıklamalar içerir ve derin öğrenme hakkında bilgi edinen geliştiriciler için iyi bir başlangıç noktasıdır.
Derin öğrenme makalelerini okumak zor ve kafa karıştırıcı olabilir. Modern konvolüsyonel nöral ağ mimarilerine uygulamalı olarak göz atalım.
Neler öğreneceksiniz?
- Özel modellerinizi daha hızlı oluşturmak için Keras ve Tensor İşleme Birimlerini (TPU'lar) kullanma.
- Eğitim verilerini verimli bir şekilde yüklemek üzere tf.data.Dataset API'yi ve TFRecord biçimini kullanmak için.
- Hile yapmak için 😈, kendi modellerinizi oluşturmak yerine aktarımla öğrenmeyi kullanın.
- Keras sıralı ve işlevsel model stillerini kullanmak için:
- Softmax katmanı ve çapraz entropi kaybıyla kendi Keras sınıflandırıcınızı oluşturmak için.
- İyi bir kıvrımlı katman seçimiyle modelinizde ince ayar yapmak için.
- Modüller, küresel ortalama havuz vb. gibi modern dönüşüm ağı mimarisi fikirlerini keşfetmek için
- Squeezenet mimarisini kullanarak basit ve modern bir dönüşüm ağı oluşturmak için.
Geri bildirim
Bu kod laboratuvarında bir yanlışlık görürseniz lütfen bize bildirin. Geri bildirimlerinizi, GitHub sorunları [feedback link] sayfasında bulabilirsiniz.
2. Google Colaboratory hızlı başlangıç kılavuzu
Bu laboratuvarda Google Collaboratory kullanılır ve sizin herhangi bir kurulum yapmanız gerekmez. Bu uygulamayı Chromebook'tan çalıştırabilirsiniz. Lütfen aşağıdaki dosyayı açın ve Colab not defterleri hakkında bilgi edinmek için hücreleri yürütün.
TPU arka ucu seçin
Colab menüsünde Çalışma zamanı > Çalışma zamanı türünü değiştirin ve ardından TPU'yu seçin. Bu kod laboratuvarında, donanım hızlandırmalı eğitim için desteklenen güçlü bir TPU (Tensör İşleme Birimi) kullanacaksınız. Çalışma zamanı bağlantısı ilk çalıştırma sırasında otomatik olarak kurulur. Alternatif olarak, düğmesini tıklayın.
Not defteri yürütme
Bir hücreyi tıklayıp Üst Karakter-ENTER tuşlarını kullanarak hücreleri tek tek yürütün. Not defterinin tamamını da Çalışma zamanı > Tümünü çalıştır
İçindekiler
Tüm not defterlerinin bir içindekiler tablosu vardır. Soldaki siyah oku kullanarak açabilirsiniz.
Gizli hücreler
Bazı hücrelerde yalnızca başlık gösterilir. Bu, Colab'e özel bir not defteri özelliğidir. Üzerlerini çift tıklayarak içindeki kodu görebilirsiniz, ancak bu durum genellikle pek de ilgi çekici değildir. Genellikle işlevleri destekler veya görselleştirme yapar. İçerideki işlevlerin tanımlanması için bu hücreleri yine de çalıştırmanız gerekir.
Kimlik Doğrulama
Yetkili bir hesapla kimlik doğrulaması yapmanız koşuluyla Colab, gizli Google Cloud Storage paketlerinize erişebilir. Yukarıdaki kod snippet'i bir kimlik doğrulama işlemini tetikler.
3. [BİLGİ] Tensor İşleme Birimleri (TPU'lar) nedir?
Özet
Keras'ta TPU'da model eğitme (ve TPU yoksa GPU veya CPU kullanma) kodu:
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
Bugün etkileşimli hızlarda (eğitim çalıştırması başına dakika) çiçek sınıflandırıcı oluşturmak ve optimize etmek için TPU'ları kullanacağız.
Neden TPU'ları kullanmalısınız?
Modern GPU'lar, programlanabilir "çekirdekler" etrafında düzenlenmiştir. Bu, 3D oluşturma, derin öğrenme, fiziksel simülasyonlar gibi çeşitli görevleri gerçekleştirmelerine olanak tanıyan çok esnek bir mimaridir. Öte yandan TPU'lar, bir klasik vektör işlemciyi özel bir matris çarpım birimiyle eşleştirir ve nöral ağlar gibi büyük matris çarpımlarının baskın olduğu tüm görevlerde üstün başarı elde eder.
Çizim: Bir matris çarpımı olarak yoğun bir nöral ağ katmanı ve aynı anda nöral ağ üzerinden işlenen sekiz görüntüden oluşan bir katman. Bir resmin tüm piksel değerlerinin ağırlıklı toplamını yaptığını doğrulamak için lütfen bir satır x sütun çarpım işlemini gerçekleştirin. Kıvrımlı katmanlar, biraz daha karmaşık olsa da matris çarpımları olarak da ifade edilebilir ( açıklama, 1. bölümdeki).
Donanım
MXU ve VPU
TPU v2 çekirdeği, matris çarpımları çalıştıran bir Matris Çarpma Biriminden (MXU) ve etkinleştirmeler, softmax vb. diğer tüm görevler için bir Vektör İşleme Birimi (VPU)ndan oluşur. VPU, float32 ve int32 hesaplamalarını yürütür. Diğer yandan MXU, karma hassasiyetli 16-32 bit kayan nokta biçiminde çalışır.
Karma hassasiyetli kayan nokta ve bfloat16
MXU, bfloat16 girişlerini ve float32 çıkışlarını kullanarak matris çarpımlarını hesaplar. Ara birikimler, float32 hassasiyetinde gerçekleştirilir.
Sinir ağı eğitimi genellikle daha düşük kayan nokta hassasiyetinden kaynaklanan gürültüye karşı dirençlidir. Gürültünün optimize edicinin yakınlaşmasına bile yardımcı olduğu durumlar vardır. 16 bit kayan nokta hassasiyeti geleneksel olarak hesaplamaları hızlandırmak için kullanılır, ancak float16 ve float32 biçimleri çok farklı aralıklara sahiptir. Hassasiyeti float32'den float16'ya düşürmek, genellikle fazla ve az akışlara yol açar. Bunun için çeşitli çözümler mevcuttur ancak float16'nın çalışması için genellikle ek işlemler gerekir.
Bu nedenle Google, TPU'larda bfloat16 biçimini kullanıma sunmuştur. bfloat16, float32 ile tam olarak aynı üs bitlerine ve aralığa sahip kısaltılmış bir float32'dir. Buna ek olarak TPU'lar, matris çarpımlarını bfloat16 girişleriyle ancak float32 çıkışlarıyla karışık hassasiyetle hesaplıyordur, böylece daha düşük hassasiyetten faydalanmak için genellikle hiçbir kod değişikliği gerekmez.
Sistolik dizi
MXU, "sistolik dizi" adı verilen bir donanım kullanarak donanımda matris çarpımlarını uygular veri öğelerinin bir dizi donanım hesaplama biriminden geçtiği mimari. (Tıpta "sistolik" terimi, kalp kasılmalarını ve buradan veri akışını ifade eder.)
Matris çarpımlarının temel öğesi, bir matristeki çizgi ile diğer matristeki bir sütun arasındaki nokta çarpımıdır (bu bölümün üst kısmındaki resme bakın). Y=X*W matris çarpımı için sonucun bir öğesi şu şekilde olur:
Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]
GPU'da bu nokta ürünü bir GPU "çekirdek" olarak programlanır ve ardından tüm bu çekirdeklerde Böylece, sonuç matrisin her değerini bir kerede hesaplamayı deneyebilirsiniz. Sonuç matris 128x128 büyükse 128x128=16K "çekirdek" gerektirir kullanılabilir ve genellikle bu mümkün değildir. En büyük GPU'lar yaklaşık 4.000 çekirdeğe sahiptir. TPU'da ise MXU'daki işlem birimleri için minimum donanım kullanılır: Yalnızca bfloat16 x bfloat16 => float32
çarpma toplayıcısı kullanılır, başka hiçbir şey yoktur. Bunlar o kadar küçüktür ki TPU, bunların 16K'sını 128x128 MXU'ya uygulayabilir ve bu matris çarpımını tek seferde işleyebilir.
Çizim: MXU sistolik dizisi. Compute elemanları çarpma toplayıcılarıdır. Bir matrisin değerleri diziye (kırmızı noktalar) yüklenir. Diğer matrisin değerleri, diziden (gri noktalar) geçer. Dikey çizgiler, değerleri yukarı doğru yayar. Yatay çizgiler kısmi toplamları yayar. Veriler, diziden geçerken sağ taraftan çıkan matris çarpımının sonucunu elde ettiğinizi doğrulamak için kullanıcıya bir alıştırma olarak bırakılır.
Buna ek olarak nokta çarpımları, MXU cinsinden hesaplanırken ara toplamlar, bitişik hesap birimleri arasında geçiş yapar. Depolanmaları ve belleğe, hatta bir kayıt dosyasına/belgeden alınmalarına gerek yoktur. Sonuçta TPU sistolik dizi mimarisi önemli bir yoğunluk ve güç avantajına sahip olmanın yanı sıra matris çarpımlarını hesaplarken GPU'ya göre göz ardı edilemez bir hız avantajına sahiptir.
Cloud TPU
Bir " Cloud TPU v2 inç Google Cloud Platform'da, PCI'ye bağlı TPU kartı olan bir sanal makine alırsınız. TPU kartında dört adet çift çekirdekli TPU çipi bulunur. Her TPU çekirdeğinde bir VPU (Vektör İşleme Birimi) ve 128x128 MXU (MatriX çarpma Birimi) bulunur. Bu "Cloud TPU" daha sonra genellikle ağ üzerinden bunu isteyen sanal makineye bağlanır. Tam tablo şu şekilde görünür:
Çizim: Ağa bağlı "Cloud TPU" ile sanal makineniz hızlandırıcı. "Cloud TPU" kendisi üzerinde dört adet çift çekirdekli TPU çipi bulunan PCI'ye bağlı TPU kartı bulunan bir sanal makineden oluşuyor.
TPU kapsülleri
Google'ın veri merkezlerinde TPU'lar, yüksek performanslı bir bilgi işlem (HPC) ara bağlantısına bağlıdır. Bu bağlantı, TPU'ların çok büyük bir hızlandırıcı gibi görünmesini sağlayabilir. Google bunlara kapsül adını verir ve en fazla 512 TPU v2 çekirdek veya 2048 TPU v3 çekirdeklerini kapsayabilir.
Çizim: TPU v3 kapsülü. HPC ara bağlantısı üzerinden bağlanan TPU kartları ve rafları.
Eğitim sırasında, tamamen azaltma algoritması kullanılarak TPU çekirdekleri arasında gradyanlar değiştirilir ( tüm azaltmaların iyi açıklamasını burada bulabilirsiniz). Eğitilen model, büyük toplu boyutlar üzerinde eğitim yaparak donanımdan yararlanabilir.
Çizim: Google TPU'nun 2D toroidal örgü HPC ağında tamamen azaltma algoritması kullanılarak eğitim sırasında gradyanların senkronizasyonu.
Yazılım
Büyük gruplar için eğitim
TPU'lar için ideal toplu iş boyutu, TPU çekirdeği başına 128 veri öğesidir ancak donanım zaten TPU çekirdeği başına 8 veri öğesinden iyi bir kullanım gösterebilmektedir. Cloud TPU'da 8 çekirdek olduğunu unutmayın.
Bu kod laboratuvarında Keras API'yi kullanacağız. Keras'ta belirttiğiniz grup, tüm TPU için genel grup boyutudur. Gruplarınız otomatik olarak 8'e bölünecek ve TPU'nun 8 çekirdeği üzerinde çalıştırılacaktır.
Ek performans ipuçları için TPU Performans Kılavuzu'na bakın. Çok büyük toplu reklam boyutları için bazı modellerde özel dikkat gösterilmesi gerekebilir. Daha fazla ayrıntı için LARSOptimizer bölümüne bakın.
Gelişmiş seçenekler: XLA
Tensorflow programları hesaplama grafiklerini tanımlar. TPU, Python kodunu doğrudan çalıştırmaz, Tensorflow programınız tarafından tanımlanan hesaplama grafiğini çalıştırır. Tüm bunların altında XLA (hızlandırılmış doğrusal cebir derleyici) adlı bir derleyici, hesaplama düğümlerinin Tensorflow grafiğini TPU makine koduna dönüştürür. Bu derleyici, kodunuzda ve bellek düzeninizde birçok gelişmiş optimizasyon da gerçekleştirir. İş TPU'ya gönderilirken derleme otomatik olarak gerçekleşir. Derleme zincirinize açıkça XLA eklemeniz gerekmez.
Çizim: TPU'da çalışmak için Tensorflow programınız tarafından tanımlanan hesaplama grafiği önce XLA (hızlandırılmış doğrusal cebir derleyici) temsiline dönüştürülür, ardından XLA tarafından TPU makine koduna derlenir.
Keras'ta TPU'ları kullanma
TPU'lar, Tensorflow 2.1 itibarıyla Keras API aracılığıyla desteklenmektedir. Keras desteği, TPU'lar ve TPU kapsülleri üzerinde çalışır. Aşağıda TPU, GPU ve CPU'da çalışan bir örnek verilmiştir:
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
Bu kod snippet'inde:
TPUClusterResolver().connect()
, ağda TPU'yu bulur. Çoğu Google Cloud sisteminde (AI Platform işleri, Colaboratory, Kubeflow, "ctpu up" yardımcı programıyla oluşturulan derin öğrenme sanal makineleri) parametre olmadan çalışır. Bu sistemler, TPU_NAME ortam değişkeni sayesinde TPU'larının nerede olduğunu bilir. Elle bir TPU oluşturursanız TPU_NAME env. var. sanal makinede arayın veya açık parametrelerleTPUClusterResolver
işlevini çağırın:TPUClusterResolver(tp_uname, zone, project)
TPUStrategy
, dağıtım ve "all-reduce"un uygulandığı kısımdır. gradyan senkronizasyon algoritmasından yararlanabilirsiniz.- Strateji bir kapsam aracılığıyla uygulanır. Model, strategy scope() içinde tanımlanmalıdır.
tpu_model.fit
işlevi, TPU eğitimi girişi için bir tf.data.Dataset nesnesi bekler.
Genel TPU bağlantı noktası görevleri
- Tensorflow modelinde veri yüklemenin birçok yolu olsa da TPU'lar için
tf.data.Dataset
API'nin kullanılması gerekir. - TPU'lar çok hızlıdır ve üzerinde çalışırken veri kullanımı genellikle performans sorunlarına yol açar. TPU Performans Kılavuzu'nda, veri sorunlarını tespit etmek için kullanabileceğiniz araçlar ve diğer performans ipuçlarını bulabilirsiniz.
- int8 veya int16 sayıları, int32 olarak kabul edilir. TPU'nun, 32 bitten düşük değerler üzerinde çalışan tam sayı donanımı yoktur.
- Bazı Tensorflow işlemleri desteklenmez. Listeyi burada bulabilirsiniz. Neyse ki bu sınırlama, yalnızca eğitim kodu (modelinizde ileri ve geri geçiş) için geçerlidir. CPU'da yürütüldüğünden, veri girişi ardışık düzeninizdeki tüm Tensorflow işlemlerini kullanmaya devam edebilirsiniz.
tf.py_func
, TPU'da desteklenmez.
4. Veriler Yükleniyor
Çiçek resimleri veri kümesiyle çalışacağız. Amaç, bu bitkileri 5 çiçek türüne ayırmayı öğrenmek. Veri yükleme, tf.data.Dataset
API kullanılarak gerçekleştirilir. Öncelikle API'yi tanımamız gerekir.
Uygulamalı
Lütfen aşağıdaki not defterini açın, hücreleri yürütün (Üst Karakter-ENTER) ve "İŞ GEREKLİ" yazan her yerde talimatları uygulayın. etiket.
Fun with tf.data.Dataset (playground).ipynb
Ek bilgiler
"Çiçekler" hakkında veri kümesi
Veri kümesi 5 klasörde düzenlenmiştir. Her klasörde bir türden çiçekler bulunur. Klasörler ayçiçeği, papatya, karahindiba, lale ve gül olarak adlandırılmıştır. Veriler, Google Cloud Storage'da herkese açık bir pakette barındırılır. Alıntı:
gs://flowers-public/sunflowers/5139971615_434ff8ed8b_n.jpg
gs://flowers-public/daisy/8094774544_35465c1c64.jpg
gs://flowers-public/sunflowers/9309473873_9d62b9082e.jpg
gs://flowers-public/dandelion/19551343954_83bb52f310_m.jpg
gs://flowers-public/dandelion/14199664556_188b37e51e.jpg
gs://flowers-public/tulips/4290566894_c7f061583d_m.jpg
gs://flowers-public/roses/3065719996_c16ecd5551.jpg
gs://flowers-public/dandelion/8168031302_6e36f39d87.jpg
gs://flowers-public/sunflowers/9564240106_0577e919da_n.jpg
gs://flowers-public/daisy/14167543177_cd36b54ac6_n.jpg
Neden tf.data.Dataset?
Keras ve Tensorflow, tüm eğitim ve değerlendirme işlevlerinde veri kümelerini kabul eder. Bir veri kümesine veri yüklediğinizde API, nöral ağ eğitimi verileri için yararlı olabilecek tüm yaygın işlevleri sunar:
dataset = ... # load something (see below)
dataset = dataset.shuffle(1000) # shuffle the dataset with a buffer of 1000
dataset = dataset.cache() # cache the dataset in RAM or on disk
dataset = dataset.repeat() # repeat the dataset indefinitely
dataset = dataset.batch(128) # batch data elements together in batches of 128
AUTOTUNE = tf.data.AUTOTUNE
dataset = dataset.prefetch(AUTOTUNE) # prefetch next batch(es) while training
Performansla ilgili ipuçlarını ve veri kümesi en iyi uygulamalarını bu makalede bulabilirsiniz. Referans belgeleri burada bulabilirsiniz.
tf.data.Dataset ile ilgili temel bilgiler
Veriler genellikle birden fazla dosya halinde gelir (burada resimler). Aşağıdakileri çağırarak dosya adlarından bir veri kümesi oluşturabilirsiniz:
filenames_dataset = tf.data.Dataset.list_files('gs://flowers-public/*/*.jpg')
# The parameter is a "glob" pattern that supports the * and ? wildcards.
Ardından "haritalar" her bir dosya adına, genellikle dosyayı yükleyip kodu çözerek bellekteki gerçek verilere dönüştürecek bir işleve dönüştürür:
def decode_jpeg(filename):
bits = tf.io.read_file(filename)
image = tf.io.decode_jpeg(bits)
return image
image_dataset = filenames_dataset.map(decode_jpeg)
# this is now a dataset of decoded images (uint8 RGB format)
Bir veri kümesini yinelemek için:
for data in my_dataset:
print(data)
Tuple'ların veri kümeleri
Gözetimli öğrenmede, eğitim veri kümesi genellikle eğitim verisi çiftlerinden ve doğru yanıtlardan oluşur. Buna izin vermek için kod çözme işlevi demetleri döndürebilir. Daha sonra, üzerinde iterasyon yaptığınızda tuple ve tuplelardan oluşan bir veri kümeniz olur. Döndürülen değerler, modeliniz tarafından kullanılmaya hazır Tensorflow tensörleridir. İşlenmemiş değerleri görmek için bu öğelerde .numpy()
yöntemini çağırabilirsiniz:
def decode_jpeg_and_label(filename):
bits = tf.read_file(filename)
image = tf.io.decode_jpeg(bits)
label = ... # extract flower name from folder name
return image, label
image_dataset = filenames_dataset.map(decode_jpeg_and_label)
# this is now a dataset of (image, label) pairs
for image, label in dataset:
print(image.numpy().shape, label.numpy())
Sonuç:Resimleri tek tek yüklemek uzun sürüyor!
Bu veri kümesini tekrarlarken saniyede 1-2 görüntü gibi bir şey yükleyebileceğinizi göreceksiniz. Bu çok yavaş! Eğitim için kullanacağımız donanım hızlandırıcılar bu hızı birkaç kat sürdürebilir. Bunu nasıl başaracağımızı görmek için sonraki bölüme geçin.
Çözüm
Çözüm not defterini burada bulabilirsiniz. Takılırsanız kullanabilirsiniz.
Fun with tf.data.Dataset (solution).ipynb
İşlediklerimiz
- 🤔 tf.data.Dataset.list_files
- 🤔 tf.data.Dataset.map
- 🤔 Tuple'ların veri kümeleri
- 😀 Veri kümeleriyle yineleme
Lütfen bir dakikanızı ayırarak bu yapılacaklar listesini zihninizde inceleyin.
5. Veriler hızlı yükleniyor
Bu laboratuvarda kullanacağımız Tensor İşleme Birimi (TPU) donanım hızlandırıcıları çok hızlıdır. İşin zor kısmı, genellikle onları meşgul edecek kadar hızlı şekilde verileri beslemektir. Google Cloud Storage (GCS), çok yüksek işleme hızını sürdürebilir ancak tüm bulut depolama sistemlerinde olduğu gibi, bağlantı başlatmak için bazı ağlar arasında bağlantı kurmanız gerekir. Bu nedenle, verilerimizin binlerce ayrı dosya halinde depolanması ideal değildir. Bunları daha az sayıda dosya halinde gruplandıracağız ve paralel olarak birden çok dosyadan okuma yapmak için tf.data.Dataset'in gücünü kullanacağız.
Okuma
Resim dosyalarını yükleyen, ortak bir boyuta getiren ve 16 TFRecord dosyası genelinde depolayan kod aşağıdaki not defterinde bulunur. Lütfen hızlıca okuyun. Codelab'in geri kalanı için TFRecord biçimindeki veriler doğru şekilde sağlanacağından bu işlemin yürütülmesi gerekmez.
Flower pictures to TFRecords.ipynb
Optimum GCS işleme hızı için ideal veri düzeni
TFRecord dosya biçimi
Verileri depolamak için Tensorflow'un tercih ettiği dosya biçimi protobuf tabanlı TFRecord biçimidir. Diğer serileştirme biçimleri de işe yarar ancak şunları yazarak TFRecord dosyalarından doğrudan veri kümesi yükleyebilirsiniz:
filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...) # do the TFRecord decoding here - see below
En iyi performans için aşağıdaki daha karmaşık kodu kullanarak birden çok TFRecord dosyasını aynı anda okumanız önerilir. Bu kod paralel olarak N dosyadan okur ve veri sırasını dikkate alarak okuma hızını dikkate alır.
AUTOTUNE = tf.data.AUTOTUNE
ignore_order = tf.data.Options()
ignore_order.experimental_deterministic = False
filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTOTUNE)
dataset = dataset.with_options(ignore_order)
dataset = dataset.map(...) # do the TFRecord decoding here - see below
TFRecord hakkında yardımcı kısa bilgiler
TFRecord'larda üç tür veri depolanabilir: bayt dizeleri (bayt listesi), 64 bit tamsayılar ve 32 bit kayan değerler. Her zaman liste olarak depolanırlar. Tek bir veri öğesi, 1 boyutunda bir liste olur. Verileri TFRecord'larda depolamak için aşağıdaki yardımcı işlevleri kullanabilirsiniz.
bayt dizeleri yazma
# warning, the input is a list of byte strings, which are themselves lists of bytes
def _bytestring_feature(list_of_bytestrings):
return tf.train.Feature(bytes_list=tf.train.BytesList(value=list_of_bytestrings))
tam sayılar yazma
def _int_feature(list_of_ints): # int64
return tf.train.Feature(int64_list=tf.train.Int64List(value=list_of_ints))
kayan metinler yazma
def _float_feature(list_of_floats): # float32
return tf.train.Feature(float_list=tf.train.FloatList(value=list_of_floats))
yukarıdaki yardımcıları kullanarak bir TFRecord yazarak
# input data in my_img_bytes, my_class, my_height, my_width, my_floats
with tf.python_io.TFRecordWriter(filename) as out_file:
feature = {
"image": _bytestring_feature([my_img_bytes]), # one image in the list
"class": _int_feature([my_class]), # one class in the list
"size": _int_feature([my_height, my_width]), # fixed length (2) list of ints
"float_data": _float_feature(my_floats) # variable length list of floats
}
tf_record = tf.train.Example(features=tf.train.Features(feature=feature))
out_file.write(tf_record.SerializeToString())
TFRecord'lardaki verileri okumak için öncelikle depoladığınız kayıtların düzenini beyan etmeniz gerekir. Bildirimde, adlandırılmış herhangi bir alana sabit uzunlukta liste veya değişken uzunlukta liste olarak erişebilirsiniz:
TFRecords'tan okuma
def read_tfrecord(data):
features = {
# tf.string = byte string (not text string)
"image": tf.io.FixedLenFeature([], tf.string), # shape [] means scalar, here, a single byte string
"class": tf.io.FixedLenFeature([], tf.int64), # shape [] means scalar, i.e. a single item
"size": tf.io.FixedLenFeature([2], tf.int64), # two integers
"float_data": tf.io.VarLenFeature(tf.float32) # a variable number of floats
}
# decode the TFRecord
tf_record = tf.io.parse_single_example(data, features)
# FixedLenFeature fields are now ready to use
sz = tf_record['size']
# Typical code for decoding compressed images
image = tf.io.decode_jpeg(tf_record['image'], channels=3)
# VarLenFeature fields require additional sparse.to_dense decoding
float_data = tf.sparse.to_dense(tf_record['float_data'])
return image, sz, float_data
# decoding a tf.data.TFRecordDataset
dataset = dataset.map(read_tfrecord)
# now a dataset of triplets (image, sz, float_data)
Yararlı kod snippet'leri:
tek veri öğelerini okuma
tf.io.FixedLenFeature([], tf.string) # for one byte string
tf.io.FixedLenFeature([], tf.int64) # for one int
tf.io.FixedLenFeature([], tf.float32) # for one float
sabit boyutlu öğe listelerini okuma
tf.io.FixedLenFeature([N], tf.string) # list of N byte strings
tf.io.FixedLenFeature([N], tf.int64) # list of N ints
tf.io.FixedLenFeature([N], tf.float32) # list of N floats
değişken sayıda veri öğesini okuma
tf.io.VarLenFeature(tf.string) # list of byte strings
tf.io.VarLenFeature(tf.int64) # list of ints
tf.io.VarLenFeature(tf.float32) # list of floats
VarLenFeature bir seyrek vektör döndürür ve TFRecord kodunun çözülmesinden sonra ek bir adım gerekir:
dense_data = tf.sparse.to_dense(tf_record['my_var_len_feature'])
TFRecords'ta isteğe bağlı alanlar da bulunabilir. Bir alanı okurken varsayılan bir değer belirtirseniz alan eksikse hata yerine varsayılan değer döndürülür.
tf.io.FixedLenFeature([], tf.int64, default_value=0) # this field is optional
İşlediklerimiz
- 🤔 GCS'den hızlı erişim için veri dosyalarını parçalama
- 🔗 TFRecord'lar nasıl yazılır? (Söz dizimini unuttunuz mu? Sorun değil, bu sayfayı yardımcı kısa bilgiler olarak yer işaretlerine ekleyin)
- 🤔 TFRecordDataset kullanarak TFRecords'tan veri kümesi yükleme
Lütfen bir dakikanızı ayırarak bu yapılacaklar listesini zihninizde inceleyin.
6. [INFO] Nöral ağ sınıflandırıcı 101
Özet
Bir sonraki paragrafta yer alan kalın yazı tipindeki tüm terimleri zaten biliyorsanız bir sonraki alıştırmaya geçebilirsiniz. Derin öğrenmeye yeni başlıyorsanız hoş geldiniz. Lütfen okumaya devam edin.
Keras, bir dizi katman olarak oluşturulan modeller için Sequential API'yi sunmaktadır. Örneğin, üç yoğun katman kullanan bir resim sınıflandırıcı Keras'ta şu şekilde yazılabilir:
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
tf.keras.layers.Dense(500, activation="relu"),
tf.keras.layers.Dense(50, activation="relu"),
tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])
# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy']) # % of correct answers
# train the model
model.fit(dataset, ... )
Yoğun nöral ağ
Bu, görüntüleri sınıflandırmak için kullanılan en basit nöral ağdır. "Nöronlardan" oluşur. katmanlar halinde düzenlenir. Birinci katman giriş verilerini işler ve çıkışlarını diğer katmanlara iletir. "Yoğun" deniyor çünkü her nöron bir önceki katmandaki tüm nöronlara bağlıdır.
Bir resmi, tüm piksellerinin RGB değerlerini uzun bir vektörde birleştirerek ve bunu giriş olarak kullanarak böyle bir ağa besleyebilirsiniz. Bu, görüntü tanıma için en iyi teknik değildir, ancak daha sonra bunu iyileştireceğiz.
Nöronlar, aktivasyonlar, RELU
Bir "nöron" tüm girişlerinin ağırlıklı bir toplamını hesaplar, buna "önyargı" adı verilen bir değer ekler ve sonucu "etkinleştirme işlevi" adı verilen bir şekilde iletir. Ağırlıklar ve yanlılık başlangıçta bilinmiyor. Rastgele bir şekilde başlatılır ve "öğrenilir" bilinen çok sayıda veri üzerinde nöral ağını eğiterek olumsuz bir etki yarattı.
En popüler etkinleştirme işlevi, Doğrulanmış Doğrusal Birim için RELU olarak adlandırılır. Yukarıdaki grafikte de görebileceğiniz gibi çok basit bir fonksiyondur.
Softmax etkinleştirme
Yukarıdaki ağ, çiçekleri 5 kategoriye (gül, lale, karahindiba, papatya, ayçiçeği) sınıflandırdığımız için 5 nöronlu bir katmanla sona ermektedir. Ara katmanlardaki nöronlar, klasik RELU aktivasyon işlevi kullanılarak etkinleştirilir. Ancak son katmanda, bu çiçeğin gül, lale vb. olma olasılığını temsil eden 0 ile 1 arasındaki sayıları hesaplamak istiyoruz. Bunun için "softmax" adlı bir etkinleştirme işlevi kullanacağız.
Bir vektöre softmax (softmax) uygulanması, her elementin üssü alınıp ardından genellikle L1 normunun (mutlak değerlerin toplamı) kullanılmasıyla vektör normalleştirilir. Böylece, değerlerin toplamı 1'e eşit olur ve olasılık olarak yorumlanabilir.
Çapraz entropi kaybı
Nöral ağımız artık giriş görüntülerinden tahminler ürettiğine göre, bunların ne kadar iyi olduğunu, yani ağın bize bildirdiği bilgiler ile doğru yanıtlar arasındaki mesafeyi, yani genellikle "etiketler"i ölçmemiz gerekir. Veri kümesindeki tüm görüntüler için doğru etiketlere sahip olduğumuzu unutmayın.
Herhangi bir mesafe işe yarar ancak sınıflandırma sorunları için "çapraz entropi mesafesi" en etkili olandır. Bunu hatamız veya "kayıp" olarak adlandıracağız işlev:
Gradyan inişi
"Eğitim" nöral ağ aslında çapraz entropi kayıp işlevini en aza indirmek amacıyla ağırlıkları ve yanlılıkları ayarlamak için eğitim görüntülerini ve etiketleri kullanmayı ifade eder. İşleyiş şekline bakalım.
Çapraz entropi, eğitim görüntüsünün ağırlıklarının, sapmalarının, piksellerinin ve bilinen sınıfının bir fonksiyonudur.
Tüm ağırlıklara ve tüm sapmalara göre çapraz entropinin kısmi türevlerini hesaplarsak, belirli bir görüntü, etiket ve ağırlıkların ve yanlılığın mevcut değeri için hesaplanan bir "gradyan" elde ederiz. Milyonlarca ağırlığa ve sapmaya sahip olabileceğimizi, bu nedenle gradyanı hesaplamanın çok büyük bir iş olduğunu unutmayın. Neyse ki Tensorflow bunu bizim için yapıyor. Bir renk geçişinin matematiksel özelliği, "yukarı" işaret etmesidir. Çapraz entropinin düşük olduğu yere gitmek istediğimizden ters yönde ilerliyoruz. Ağırlıkları ve sapmaları gradyanın bir kısmına göre güncelleriz. Daha sonra, bir eğitim döngüsünde sonraki eğitim görüntüsü ve etiketi gruplarını kullanarak aynı şeyi tekrar tekrar yaparız. Bunun, çapraz entropinin minimum düzeyde olduğu bir yere yaklaşacağını umuyoruz, ancak bu minimum değerin benzersiz olduğunu hiçbir şey garanti etmemektedir.
Mini toplanma ve momentum
Renk geçişinizi tek bir örnek resim üzerinde hesaplayıp ağırlıkları ve sapmaları hemen güncelleyebilirsiniz. Ancak, örneğin 128 resimden oluşan bir grup üzerinde bunu yaptığınızda, farklı örnek resimlerin uyguladığı kısıtlamaları daha iyi temsil eden ve dolayısıyla çözüme daha hızlı yaklaşma olasılığı yüksek bir gradyan elde edilir. Mini grubun boyutu ayarlanabilir bir parametredir.
Bazen "olasılıksal gradyan inişi" olarak da adlandırılan bu teknik daha pragmatik bir faydası da var: Gruplarla çalışmak daha büyük matrislerle çalışmak anlamına geliyor. Bunların GPU ve TPU'larda optimize edilmesi genellikle daha kolay.
Ancak yakınsaklık yine de biraz kaotik olabilir ve gradyan vektörü sıfır olsa bile durabilir. Bu, minimum değer bulduğumuz anlamına mı geliyor? Her zaman değil Gradyan bileşeni minimum veya maksimum sıfır olabilir. Milyonlarca öğe içeren bir gradyan vektöründe, hepsi sıfırsa, her sıfırın bir minimum değere karşılık gelme ve hiçbirinin bir maksimum noktaya ulaşma olasılığı oldukça küçüktür. Birçok boyutu olan bir alanda, eyer noktaları oldukça yaygındır ve bunlarla yetinmek istemeyiz.
Çizim: Eyer noktası. Gradyan 0'dır, ancak tüm yönlerde minimum değer değildir. (Resim atfı Wikimedia: Yazan: Nicoguaro - Kendi eseri, CC BY 3.0)
Çözüm, optimizasyon algoritmasına bir hız eklemektir. Böylece, algoritma durmadan bağlı noktaların ötesine geçebilir.
Sözlük
toplu veya mini toplu: Eğitim, her zaman eğitim verisi ve etiket grupları üzerinde gerçekleştirilir. Bu, algoritmanın yakınlaşmasına yardımcı olur. "Toplu" boyut, genellikle veri tensörlerinin ilk boyutudur. Örneğin, [100, 192, 192, 3] şeklindeki bir tensör, piksel başına üç değer (RGB) içeren 192x192 piksellik 100 resim içerir.
çapraz entropi kaybı: Sınıflandırıcılarda genellikle kullanılan özel bir kayıp işlevi.
yoğun katman: Her nöronun bir önceki katmandaki tüm nöronlara bağlı olduğu bir nöron katmanı.
özellikler: Bir nöral ağın girişleri bazen "özellikler" olarak adlandırılır. İyi tahminler elde etmek için veri kümesinin hangi bölümlerinin (veya parça kombinasyonlarının) bir nöral ağa besleneceğini bulma sanatına "özellik mühendisliği" denir.
labels: "sınıflar" için başka bir ad veya doğru cevapları içeren gözetimli
öğrenme hızı: Ağırlıkların ve sapmaların, eğitim döngüsündeki her iterasyonda güncellendiği gradyanın oranı.
logits: Aktivasyon işlevi uygulanmadan önce bir nöron katmanının çıktılarına "logit" adı verilir. Terim, "mantıksal fonksiyon"dan gelir "sigmoid işlevi" olarak da bilinir. eskiden en popüler aktivasyon fonksiyonuydu. "Lojistik fonksiyondan önce nöron çıkışları" kısaltılmıştı "logits" olarak değiştirildi.
loss: nöral ağ çıkışlarını doğru yanıtlarla karşılaştıran hata işlevi
nöron: Girişlerinin ağırlıklı toplamını hesaplar, bir ağırlık ekler ve sonucu bir aktivasyon işlevi aracılığıyla iletir.
tek sıcak kodlama: 5 üzerinden 3. sınıf, 5 öğeden oluşan bir vektör olarak kodlanır. 3'üncü olan (1) hariç tüm sıfırlar kullanılır.
relu: Düzeltilmiş doğrusal birim. Nöronlar için popüler bir aktivasyon fonksiyonu.
sigmoid: Eskiden popüler olan ve özel durumlarda yararlı olan başka bir etkinleştirme işlevidir.
softmax: Bir vektör üzerinde etki eden, en büyük bileşen ile diğer bileşenler arasındaki farkı artıran ve vektörü, olasılıkların vektörü olarak yorumlanabilmesi için toplam 1 olacak şekilde normalleştiren özel bir aktivasyon fonksiyonu. Sınıflandırıcılarda son adım olarak kullanılır.
tensor: Bir "tensor" bir matrise benzer ancak rastgele sayıda boyuta sahiptir. 1 boyutlu tensör bir vektördür. 2 boyutlu tensör, bir matristir. 3, 4, 5 veya daha fazla boyutlu tensörleriniz de olabilir.
7. Öğrenimi Aktar
Görüntü sınıflandırma sorunları için yoğun katmanlar muhtemelen yeterli olmayacaktır. Evrimsel katmanlar ve bunları çeşitli şekillerde düzenlemenin yolları hakkında bilgi edinmemiz gerekiyor.
Ama bir kısayol da kullanabiliriz! İndirebileceğiniz tam eğitimli konvolüsyonlu nöral ağlar mevcuttur. Bunların son katmanı olan softmax sınıflandırma başlığını kesip kendi katmanınızla değiştirebilirsiniz. Eğitilen tüm ağırlıklar ve ağırlıklar olduğu gibi kalır, yalnızca eklediğiniz softmax katmanını yeniden eğitirsiniz. Bu tekniğe aktarım öğrenmesi denir ve nöral ağın önceden eğitildiği veri kümesi "yeterince yakın" olduğu sürece çalışır. hale getirebilirsiniz.
Uygulamalı
Lütfen aşağıdaki not defterini açın, hücreleri yürütün (Üst Karakter-ENTER) ve "İŞ GEREKLİ" yazan her yerde talimatları uygulayın. etiket.
Keras Flowers transfer learning (playground).ipynb
Ek bilgiler
Aktarımla öğrenme sayesinde, hem üst düzey araştırmacılar tarafından geliştirilen gelişmiş konvolüsyonel nöral ağ mimarilerinden hem de görüntülerden oluşan devasa veri kümesi üzerinde ön eğitimden yararlanabilirsiniz. Bu örnekte, çok sayıda bitki ve dış mekan sahneleri içeren ve çiçeklere yeterince yakın olan bir görüntü veritabanı olan ImageNet'te eğitimli bir ağdan bilgi aktaracağız.
Çizim: Daha önce eğitilmiş, kara kutu olarak eğitilmiş karmaşık bir konvolüsyonel nöral ağ kullanılarak yalnızca sınıflandırma başı yeniden eğitilmiştir. Bu, aktarım öğrenmedir. Konvolüsyonel katmanlardan oluşan bu karmaşık düzenlemelerin nasıl işlediğini daha sonra göreceğiz. Şimdilik bu başka birisiyle ilgili.
Keras'ta öğrenimi aktarın
Keras'ta, tf.keras.applications.*
koleksiyonundan önceden eğitilmiş bir model oluşturabilirsiniz. Örneğin MobileNet V2, makul boyutta kalan çok iyi bir kıvrımlı mimaridir. include_top=False
öğesini seçtiğinizde, son softmax katmanı olmadan önceden eğitilmiş modeli elde edersiniz. Böylece kendi modelinizi ekleyebilirsiniz:
pretrained_model = tf.keras.applications.MobileNetV2(input_shape=[*IMAGE_SIZE, 3], include_top=False)
pretrained_model.trainable = False
model = tf.keras.Sequential([
pretrained_model,
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(5, activation='softmax')
])
pretrained_model.trainable = False
ayarına da dikkat edin. Yalnızca softmax katmanınızı eğitmeniz için önceden eğitilmiş modelin ağırlıklarını ve sapmalarını dondurur. Bu işlem genellikle nispeten az ağırlık içerir ve çok büyük bir veri kümesi gerektirmeden hızlı bir şekilde yapılabilir. Ancak çok fazla veriniz varsa öğrenim aktarımı özelliğini pretrained_model.trainable = True
ile çok daha iyi kullanabilirsiniz. Daha sonra, önceden eğitilmiş ağırlıklar mükemmel başlangıç değerleri sağlar ve sorununuza daha iyi uyacak şekilde eğitim tarafından ayarlanabilir.
Son olarak, yoğun softmax katmanınızın önüne Flatten()
katmanının eklendiğine dikkat edin. Yoğun katmanlar, düz veri vektörlerinde çalışır ancak önceden eğitilmiş modelin bunu döndürüp döndürmediğini bilmiyoruz. Bu nedenle düzeltmemiz gerekiyor. Bir sonraki bölümde kıvrımlı mimarileri ele alırken kıvrımlı katmanların döndürdüğü veri biçimini açıklayacağız.
Bu yaklaşımda doğruluk oranı% 75'e yaklaşır.
Çözüm
Çözüm not defterini burada bulabilirsiniz. Takılırsanız kullanabilirsiniz.
Keras Flowers transfer learning (solution).ipynb
İşlediklerimiz
- 🤔 Keras'ta sınıflandırıcı yazma
- 🤓, softmax son katmanı ve çapraz entropi kaybıyla yapılandırılmış
- 😈 Öğrenmeyi aktarın
- 🤔 İlk modelinizi eğitme
- 🧐 Eğitim sırasında veri kaybını ve doğruluğu takip etme
Lütfen bir dakikanızı ayırarak bu yapılacaklar listesini zihninizde inceleyin.
8. [INFO] Konvolüsyonlu nöral ağlar
Özet
Bir sonraki paragrafta yer alan kalın yazı tipindeki tüm terimleri zaten biliyorsanız bir sonraki alıştırmaya geçebilirsiniz. Konvolüsyonel nöral ağlarla yeni başlıyorsanız lütfen okumaya devam edin.
Çizim: Bir resmi, her biri 4x4x3=48 öğrenilebilir ağırlıklardan oluşan art arda iki filtreyle filtreleme.
Basit bir konvolüsyonel nöral ağ Keras'ta şöyle görünür:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=6, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])
Konvolüsyonel nöral ağlar 101
Konvolüsyonel ağ katmanında, bir "nöron" yalnızca resmin küçük bir bölgesinde, hemen üzerindeki piksellerin ağırlıklı bir toplamını yapar. Normal yoğun bir katmandaki bir nöronun yaptığı gibi, bir eğilim ekler ve toplamı bir aktivasyon fonksiyonu aracılığıyla iletir. Daha sonra bu işlem, aynı ağırlıklar kullanılarak resmin tamamında tekrarlanır. Yoğun katmanlarda her nöronun kendi ağırlıkları olduğunu unutmayın. Burada tek bir "yama" resimdeki ağırlıkların her iki yönde ("büyütme") kaydığını gösterir. Çıkış, resimde piksel sayısı kadar değere sahiptir (yine de kenarlarda bazı dolgu yapılması gerekir). 4x4x3=48 ağırlıklardan oluşan bir filtre kullanan bir filtreleme işlemidir.
Ancak 48 ağırlık yeterli olmayacaktır. Daha fazla serbestlik derecesi eklemek için aynı işlemi yeni bir ağırlık grubuyla tekrarlarız. Bu işlem yeni bir filtre çıktıları kümesi oluşturur. Buna "kanal" diyelim. giriş resmindeki R,G,B kanallarına benzeterek çıktıların performansını görebilirsiniz.
İki (veya daha fazla) ağırlık kümesi, yeni bir boyut eklenerek tek bir tensör olarak toplanabilir. Bu şekilde, konvolüsyonlu bir katman için ağırlık tensörünün genel şeklini elde ederiz. Giriş ve çıkış kanallarının sayısı parametre olduğundan, konvolüsyonel katmanları yığmaya ve zincirlemeye başlayabiliriz.
Çizim: konvolüsyonel nöral ağ "küpleri" dönüştürüyor başka "küplere" açısından son derece önemlidir.
Sıralı konvolüsyon, maksimum havuz hızı
Evrimleri 2 veya 3 adımla yaparak elde edilen veri küpünü yatay boyutlarında da küçültebiliriz. Bunu iki şekilde yapabilirsiniz:
- Aşamalı konvolüsyon: Yukarıdaki gibi ancak adımı 1'den büyük olan kayan bir filtre
- Maks. havuz: MAX işlemini uygulayan bir kayan pencere (genellikle 2x2 yamalarda, her 2 pikselde bir tekrarlanır)
Çizim: Hesaplama penceresinin 3 piksel kaydırılması daha az çıkış değerine neden olur. Katmanlı kıvrımlar veya maksimum havuz (2x2 kaydırılan 2x2 pencere için en fazla) veri küpünü yatay boyutlarda daraltmanın bir yoludur.
Konvolüsyonsal sınıflandırıcı
Son olarak, son veri küpünü düzleştirip softmax'ın etkin olduğu yoğun bir katmandan besleyerek bir sınıflandırma başlığı ekleriz. Tipik bir konvolüsyonel sınıflandırıcı aşağıdaki gibi görünebilir:
Çizim: Konvolüsyon ve softmax katmanları kullanan bir resim sınıflandırıcı. 3x3 ve 1x1 filtreler kullanır. Maxpool katmanları, en fazla 2x2 veri noktası grubunu alır. Sınıflandırma başlığı, softmax etkinleştirmesine sahip yoğun bir katmanla uygulanmıştır.
Keras'ta
Yukarıda gösterilen kıvrımlı yığın, Keras'ta şöyle yazılabilir:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=16, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=8, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])
9. Özel dönüşümünüz
Uygulamalı
Şimdi sıfırdan konvolüsyonel bir nöral ağ oluşturup eğitelim. TPU kullanmak çok hızlı iterasyonlar yapmamızı sağlar. Lütfen aşağıdaki not defterini açın, hücreleri yürütün (Üst Karakter-ENTER) ve "İŞ GEREKLİ" yazan her yerde talimatları uygulayın. etiket.
Keras_Flowers_TPU (playground).ipynb
Amaç, öğrenim aktarma modelinin% 75'lik doğruluk oranını geçmektir. Elimizde yalnızca 3.670 görüntü varken milyonlarca görüntüden oluşan bir veri kümesiyle önceden eğitilmiş olması sayesinde bu model bir avantaja sahipti. En azından bunu eşleştirebilir misiniz?
Ek bilgiler
Kaç katman, ne kadar büyük?
Katman boyutlarını seçmek, bilimden çok sanata benzer. Çok az veya çok fazla parametreye (ağırlıklar ve sapmalar) sahip olmak arasında doğru dengeyi bulmanız gerekir. Çok az ağırlıkla nöral ağ, çiçek şekillerinin karmaşıklığını temsil edemez. Çok fazla resim varsa "fazlasıyla uyumlu" olabilir. Diğer bir deyişle, eğitim resimlerine odaklanıp genelleme yapamamanıza neden olabilir. Çok sayıda parametre olduğunda, modelin eğitilmesi de yavaş olur. Keras'ta model.summary()
işlevi, modelinizin yapısını ve parametre sayısını gösterir:
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 192, 192, 16) 448
_________________________________________________________________
conv2d_1 (Conv2D) (None, 192, 192, 30) 4350
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 96, 96, 30) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 96, 96, 60) 16260
_________________________________________________________________
...
_________________________________________________________________
global_average_pooling2d (Gl (None, 130) 0
_________________________________________________________________
dense (Dense) (None, 90) 11790
_________________________________________________________________
dense_1 (Dense) (None, 5) 455
=================================================================
Total params: 300,033
Trainable params: 300,033
Non-trainable params: 0
_________________________________________________________________
Birkaç ipucu:
- Birden fazla katmanın olması "derin"dir Nöral ağlardır. Bu basit çiçek tanıma problemi için 5 ila 10 katman anlamlıdır.
- Küçük filtreler kullanın. 3x3 boyutlu filtreler genellikle her yerde işe yarar.
- 1x1 filtreler de kullanılabilir ve ucuzdur. "Filtre uygulama" veya doğrusal kanal kombinasyonlarını hesaplamaktan kaçının. Bunların yerine gerçek filtreler kullanın. ("1x1 kıvrımlar" hakkında daha fazla bilgiyi bir sonraki bölümde bulabilirsiniz.)
- Bu tür bir sınıflandırma problemlerinde, maksimum havuz katmanlarıyla (veya basamak > 1 olan kıvrımlarla) sıklıkla aşağı örnekleme yapın. Çiçeğin nerede olduğu önemli değildir, yalnızca gül veya karahindiba çiçeği olduğu için x ve y bilgilerini kaybetmek önemli değildir, daha küçük alanları filtrelemek ise daha ucuzdur.
- Filtrelerin sayısı genellikle ağın sonundaki sınıf sayısına benzer olur (neden? aşağıdaki "küresel ortalama havuz" hilesine bakın). Yüzlerce sınıfa sınıflandırıyorsanız filtre sayısını ardışık katmanlar halinde kademeli olarak artırın. 5 sınıflı çiçek veri kümesi için yalnızca 5 filtreyle filtreleme yeterli olmaz. Çoğu katmanda aynı filtre sayısını (ör. 32) kullanabilir ve sonuna doğru azaltabilirsiniz.
- Son yoğun katmanlar pahalıdır. Tüm kıvrımlı katmanlardan daha fazla ağırlığa sahip olabilirler. Örneğin, 24x24x10 boyutundaki son veri küpünden elde edilen çok makul bir çıkış olsa bile, 100 nöronlu bir katmanın maliyeti 24x24x10x100=576.000 ağırlık olacaktır !!! Dikkatli olmaya çalışın veya dünya geneli ortalama havuzunu deneyin (aşağıya bakın).
Dünya genelinde ortalama havuz
Bir kıvrımlı nöral ağın ucundaki pahalı bir yoğun katman kullanmak yerine, gelen veriyi "küp" olarak bölebilirsiniz mümkün olduğunca çok bölüme ayırabilir, değerlerini ortalamasını alabilir ve bir softmax etkinleştirme işleviyle besleyebilirsiniz. Sınıflandırma başlığını oluşturmanın bu şekilde maliyeti 0 ağırlıktır. Keras'ta söz dizimi tf.keras.layers.GlobalAveragePooling2D().
şeklindedir
Çözüm
Çözüm not defterini burada bulabilirsiniz. Takılırsanız kullanabilirsiniz.
Keras_Flowers_TPU (solution).ipynb
İşlediklerimiz
- 🤔 Evrimsel katmanlarla oynandı
- 🤓 Maksimum havuz, adım, global ortalama havuz ve ...
- 😀
Lütfen bir dakikanızı ayırarak bu yapılacaklar listesini zihninizde inceleyin.
10. [INFO] Modern evrimsel mimariler
Özet
Çizim: konvolüsyonlu "modül". Bu noktada en iyisi hangisi? Ardından maksimum havuz katmanı ve ardından 1x1 konvolüsyonlu bir katman mı yoksa farklı bir katman kombinasyonu mu gelir? Tümünü deneyin, sonuçları birleştirin ve ağ karar versin. Sağda: " ilk" kıvrımlı mimariyi nasıl koruduğunu konuştuk.
Keras'ta, veri akışının farklı alanlara yayılabileceği modeller oluşturmak için "işlevsel" model stili. Örnek:
l = tf.keras.layers # syntax shortcut
y = l.Conv2D(filters=32, kernel_size=3, padding='same',
activation='relu', input_shape=[192, 192, 3])(x) # x=input image
# module start: branch out
y1 = l.Conv2D(filters=32, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')(y)
y = l.concatenate([y1, y3]) # output now has 64 channels
# module end: concatenation
# many more layers ...
# Create the model by specifying the input and output tensors.
# Keras layers track their connections automatically so that's all that's needed.
z = l.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, z)
Diğer ucuz püf noktaları
Küçük 3x3 filtreleri
Bu görselde art arda iki tane 3x3 filtresinin sonucunu görüyorsunuz. Hangi veri noktalarının sonuca katkıda bulunduğunu izlemeye çalışın: Bu iki ardışık 3x3 filtre, 5x5 boyutunda bir bölgenin bir kombinasyonunu hesaplar. Bu, bir 5x5 filtresinin hesapladığı kombinasyon değildir, ancak art arda gelen iki 3x3 filtresi tek bir 5x5 filtresinden daha ucuz olduğu için denemekte fayda vardır.
1x1 evrişimler ?
Matematiksel anlamda bir "1x1", konvolüsyon sabit bir sayıyla çarpılır ve çok yararlı bir kavram değildir. Bununla birlikte, konvolüsyonlu nöral ağlarda filtrenin yalnızca 2D görüntüye değil, bir veri küpüne uygulandığını unutmayın. Dolayısıyla, bir "1x1" filtresi, 1x1'lik bir veri sütununun ağırlıklı toplamını hesaplar (resme bakın) ve sütunu veriler üzerinde kaydırdıkça giriş kanallarının doğrusal bir kombinasyonunu elde edersiniz. Bu aslında yararlı bir özelliktir. Kanalları, bağımsız filtreleme işlemlerinin sonuçları olarak düşünürseniz (ör. "noktalı kulaklar", "bıyıklanma" için başka bir filtre) üçüncüsü ise "yarık gözler" için ardından bir "1x1" konvolüsyonel katman, bu özelliklerin birden çok olası doğrusal kombinasyonunu hesaplayacaktır. Bu, bir "kedi" ararken yararlı olabilir. Üstelik 1x1 katmanlar daha az ağırlık kullanır.
11. Sıkıştırmalı
Bu fikirleri bir araya getirmenin basit bir yolu "Squeezenet" bakın. Yazarlar yalnızca 1x1 ve 3x3 konvolüsyonel katmanlar kullanan çok basit bir kıvrımlı modül tasarımını öne çıkarmıştır.
Çizim: "Ateş modülleri"ne dayalı squeezenet mimarisi. Birbiriyle "sıkıştıran" 1x1'lik bir katman Dikey boyutta gelen veriler ve ardından "genişleyen" iki paralel 1x1 ve 3x3 konvolüsyon katmanı gelir derinliğini tekrar azaltır.
Uygulamalı
Önceki not defterinizde devam ederek squeezenet'ten ilham alan konvolüsyonel nöral ağ oluşturun. Model kodunu Keras "işlevsel stili" olarak değiştirmeniz gerekir.
Keras_Flowers_TPU (playground).ipynb
Ek bilgi
Bu alıştırmada squeezenet modülü için yardımcı bir fonksiyon tanımlamak faydalı olacaktır:
def fire(x, squeeze, expand):
y = l.Conv2D(filters=squeeze, kernel_size=1, padding='same', activation='relu')(x)
y1 = l.Conv2D(filters=expand//2, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=expand//2, kernel_size=3, padding='same', activation='relu')(y)
return tf.keras.layers.concatenate([y1, y3])
# this is to make it behave similarly to other Keras layers
def fire_module(squeeze, expand):
return lambda x: fire(x, squeeze, expand)
# usage:
x = l.Input(shape=[192, 192, 3])
y = fire_module(squeeze=24, expand=48)(x) # typically, squeeze is less than expand
y = fire_module(squeeze=32, expand=64)(y)
...
model = tf.keras.Model(x, y)
Bu defaki hedef% 80 doğruluk oranına ulaşmaktır.
Denenebilecekler
Tek bir kıvrımlı katmanla başlayın, ardından MaxPooling2D(pool_size=2)
katmanla dönüşümlü olarak "fire_modules
" ile devam edin. Ağda maksimum 2 ila 4 havuz katmanıyla ve maksimum havuz katmanları arasında 1, 2 veya 3 ardışık yangın modülüyle deneme yapabilirsiniz.
Ateş modüllerinde "sıkıştırma" parametresi genellikle "expand" parametresinden sonra bir değer girin. Bu parametreler aslında filtre sayısıdır. Genellikle 8 ile 196 arasında olabilir. Ağda filtre sayısının kademeli olarak arttığı mimariler veya tüm yangın modüllerinin aynı sayıda filtreye sahip olduğu basit mimarilerle denemeler yapabilirsiniz.
Örnek:
x = tf.keras.layers.Input(shape=[*IMAGE_SIZE, 3]) # input is 192x192 pixels RGB
y = tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu')(x)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.GlobalAveragePooling2D()(y)
y = tf.keras.layers.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, y)
Bu noktada denemelerinizin pek iyi gitmediğini ve% 80 doğruluk hedefinin uzak gibi göründüğünü fark edebilirsiniz. Birkaç tane daha ucuz numaraya geçelim.
Toplu Normalleştirme
Toplu norm, yaşadığınız yakınlaşma sorunlarına yardımcı olur. Bir sonraki atölyede bu teknikle ilgili ayrıntılı açıklamalar bulunacaktır. Şimdilik lütfen bunu bir kara kutu "sihir" olarak kullanın yardımcı olacak şekilde, fire_module fonksiyonunuzun içindeki katmanlar da dahil olmak üzere ağınızdaki her konvolüsyonel katmanın arkasına bu satırı ekleyebilirsiniz:
y = tf.keras.layers.BatchNormalization(momentum=0.9)(y)
# please adapt the input and output "y"s to whatever is appropriate in your context
Veri kümeniz küçük olduğundan momentum parametresinin varsayılan değeri olan 0,99'dan 0,9'a düşürülmesi gerekir. Şimdilik bu ayrıntıyı boşver.
Veri genişletme
Doygunluk değişikliklerinin sola doğru çevrilmesi gibi kolay dönüşümlerle verileri genişleterek birkaç yüzde puanı daha elde edebilirsiniz:
Bu işlemi Tensorflow'da tf.data.Dataset API ile kolayca yapabilirsiniz. Verileriniz için yeni bir dönüştürme işlevi tanımlayın:
def data_augment(image, label):
image = tf.image.random_flip_left_right(image)
image = tf.image.random_saturation(image, lower=0, upper=2)
return image, label
Daha sonra, bunu son veri dönüştürmenizde kullanın (hücre "eğitim ve doğrulama veri kümeleri", "get_batched_dataset" işlevi):
dataset = dataset.repeat() # existing line
# insert this
if augment_data:
dataset = dataset.map(data_augment, num_parallel_calls=AUTO)
dataset = dataset.shuffle(2048) # existing line
Veri genişletmeyi isteğe bağlı yapmayı ve yalnızca eğitim veri kümesinin genişletildiğinden emin olmak için gerekli kodu eklemeyi unutmayın. Doğrulama veri kümesini genişletmek anlamlı değildir.
Artık 35 dönemde% 80 doğruluk oranına ulaşabilirsiniz.
Çözüm
Çözüm not defterini burada bulabilirsiniz. Takılırsanız kullanabilirsiniz.
Keras_Flowers_TPU_squeezenet.ipynb
İşlediklerimiz
- 🤔 Keras "işlevsel tarz" modeller
- 🤓 Squeezenet mimarisi
- 🤓 tf.data.datset ile veri genişletme
Lütfen bir dakikanızı ayırarak bu yapılacaklar listesini zihninizde inceleyin.
12. Xception ince ayarı yapıldı
Ayrılabilir kıvrımlar
Konvolüsyonel katmanları uygulamanın farklı bir yolu da son zamanlarda popülerlik kazanıyordu: derinlikten ayrılabilen kıvrımlar. Çok ağızlı bir konu olduğunu biliyorum ancak konsept son derece basit. Tensorflow ve Keras'ta tf.keras.layers.SeparableConv2D
olarak uygulanır.
Ayrılabilir evrişim, resim üzerinde bir filtre de çalıştırır, ancak giriş resminin her bir kanalı için ayrı bir ağırlık grubu kullanır. Ardından, filtrelenen kanalların ağırlıklı toplamıyla sonuçlanan bir dizi nokta ürünü olan "1x1 konvolüsyon" gelir. Her seferinde yeni ağırlıklarla, kanalların mümkün olduğunca çok sayıda ağırlıklı rekombinasyonu gerektiğinde hesaplanır.
Çizim: ayrılabilir kıvrımlar. 1. Aşama: Her bir kanal için ayrı bir filtreyle evrişimler. 2. Aşama: Kanalların doğrusal rekombinasyonları. İstenen çıkış kanalı sayısına ulaşılana kadar yeni bir ağırlık grubuyla tekrarlanır. 1. aşama da her seferinde yeni ağırlıklarla tekrarlanabilir ancak pratikte bu nadiren yaşanır.
Ayrılabilir konvolüsyonlar en yeni konvolüsyonlu ağ mimarilerinde kullanılır: MobileNetV2, Xception, EfficientNet. Bu arada, MobileNetV2, daha önce aktarım öğrenmesi için kullanmıştınız.
Normal kıvrımlardan daha ucuzdur ve pratikte aynı derecede etkili oldukları tespit edilmiştir. Yukarıda gösterilen örneğin ağırlık sayısını aşağıda görebilirsiniz:
Konvolüsyonel katman: 4 x 4 x 3 x 5 = 240
Ayrılabilir konvolüsyonel katman: 4 x 4 x 3 + 3 x 5 = 48 + 15 = 63
Bu, okuyucunun her kıvrımlı katman ölçeği stilini benzer şekilde uygulamak için gereken çarpma sayısından daha fazla hesaplama yapması için bir alıştırma olarak bırakılır. Ayrılabilir kıvrımlar daha küçüktür ve hesaplama açısından çok daha etkilidir.
Uygulamalı
"Öğrenmeyi aktar" bölümünden yeniden başlatma Ancak bu kez önceden eğitilmiş model olarak Xception'ı seçiyor. Xception yalnızca ayrılabilir kıvrımlar kullanır. Tüm ağırlıkları eğitilebilir bırakın. Önceden eğitilmiş katmanları bu şekilde kullanmak yerine, verilerimiz üzerindeki önceden eğitilmiş ağırlıklara ince ayar yapacağız.
Keras Flowers transfer learning (playground).ipynb
Hedef: doğruluk > %95 (Hayır, cidden mümkün!)
Bu son alıştırma olduğundan biraz daha fazla kod ve veri bilimi çalışması gerektiriyor.
İnce ayarlar hakkında ek bilgi
Xception, tf.keras.application konumundaki önceden eğitilmiş standart modellerde kullanılabilir.* Bu kez tüm ağırlıkları eğitilebilir bırakmayı unutmayın.
pretrained_model = tf.keras.applications.Xception(input_shape=[*IMAGE_SIZE, 3],
include_top=False)
pretrained_model.trainable = True
Bir modelde ince ayarlar yaparken iyi sonuçlar almak için öğrenme hızına dikkat etmeniz ve kampanya gelişim dönemi olan bir öğrenme hızı programı kullanmanız gerekir. Aşağıdaki gibi:
Standart bir öğrenme hızıyla başlamak modelin önceden eğitilmiş ağırlıklarını bozar. Başlatma işlemi, verileriniz model tarafından mantıklı bir şekilde değiştirilinceye kadar kademeli olarak korunur. Rampadan sonra, sabit veya katlanarak artan bir öğrenme hızıyla devam edebilirsiniz.
Keras'ta öğrenme hızı, her bir dönem için uygun öğrenme hızını hesaplayabileceğiniz bir geri çağırma ile belirtilir. Keras, her bir dönem için doğru öğrenme hızını optimize ediciye iletir.
def lr_fn(epoch):
lr = ...
return lr
lr_callback = tf.keras.callbacks.LearningRateScheduler(lr_fn, verbose=True)
model.fit(..., callbacks=[lr_callback])
Çözüm
Çözüm not defterini burada bulabilirsiniz. Takılırsanız kullanabilirsiniz.
07_Keras_Flowers_TPU_xception_fine_tuned_best.ipynb
İşlediklerimiz
- 🤔 Derinlikten ayrılabilen konvolüsyon
- 🤓 Öğrenme oranı programları
- 😈 Önceden eğitilmiş bir modelde ince ayar yapma.
Lütfen bir dakikanızı ayırarak bu yapılacaklar listesini zihninizde inceleyin.
13. Tebrikler!
İlk modern konvolüsyonlu nöral ağınızı oluşturup% 90'dan fazla doğruluk sağlayacak şekilde eğittiniz. TPU'lar sayesinde sadece dakikalar içinde ardışık eğitim çalışmalarını tekrarlarsınız.
Uygulamada TPU'lar
TPU'lar ve GPU'lar, Google Cloud'un Vertex AI'ında bulunur:
Son olarak, geri bildirimlere değer veriyoruz. Bu laboratuvarda bir eksiklik görürseniz veya bir şeylerin iyileştirilmesi gerektiğini düşünüyorsanız lütfen bize bildirin. Geri bildirimlerinizi, GitHub sorunları [feedback link] sayfasında bulabilirsiniz.
|