TensorFlow.org'da görüntüleyin | Google Colab'da çalıştırın | Kaynağı GitHub'da görüntüleyin | Not defterini indir |
Kurmak
import numpy as np
import tensorflow as tf
from tensorflow import keras
Tanıtım
Aktarım öğrenme bir problem üzerinde öğrenilen özelliklerini alarak ve yeni, benzer problem üzerinde onları yararlanarak oluşmaktadır. Örneğin, rakunları tanımlamayı öğrenmiş bir modelin özellikleri, tanukileri tanımlamaya yönelik bir modeli başlatmak için faydalı olabilir.
Aktarım öğrenimi genellikle, veri kümenizin tam ölçekli bir modeli sıfırdan eğitmek için çok az veriye sahip olduğu görevler için yapılır.
Derin öğrenme bağlamında transfer öğreniminin en yaygın enkarnasyonu aşağıdaki iş akışıdır:
- Önceden eğitilmiş bir modelden katmanlar alın.
- Gelecekteki eğitim turlarında içerdikleri herhangi bir bilgiyi yok etmemek için onları dondurun.
- Dondurulmuş katmanların üzerine yeni, eğitilebilir katmanlar ekleyin. Eski özellikleri yeni bir veri kümesi üzerinde tahminlere dönüştürmeyi öğrenecekler.
- Veri kümenizdeki yeni katmanları eğitin.
Bir son, isteğe bağlı bir adımdır, (bunun veya bir kısmını) tüm yukarıda elde edilen modelin çözülürken oluşan ince ayar, ve çok düşük bir öğrenme oranı ile yeni veri üzerine yeniden eğitim olduğunu. Bu, önceden eğitilmiş özellikleri aşamalı olarak yeni verilere uyarlayarak potansiyel olarak anlamlı iyileştirmeler sağlayabilir.
İlk olarak, Keras üzerinde gidecek trainable
en aktarım öğrenme ve ince ayar iş akışlarını temelini detaylı olarak API.
Ardından, ImageNet veri kümesinde önceden eğitilmiş bir model alarak ve onu Kaggle "kediler vs köpekler" sınıflandırma veri kümesinde yeniden eğiterek tipik iş akışını göstereceğiz.
Bu uyarlanmıştır Python ile Derin Öğrenme ve 2016 blog post "çok az veri kullanarak güçlü bir resim sınıflandırma modellerini oluşturmak" .
Donma katmanları: anlama trainable
niteliğini
Katmanlar ve modeller üç ağırlık özelliğine sahiptir:
-
weights
tabakanın tüm ağırlıkları değişken listesi aşağıdadır. -
trainable_weights
(gradyan asıllı üzerinden) güncellenmesi içindir olanlar eğitim sırasında kaybını en aza indirmek için listesidir. -
non_trainable_weights
eğitilecek anlamına gelmez olanlar listesi aşağıdadır. Tipik olarak, ileri geçiş sırasında model tarafından güncellenirler.
Örnek: Dense
tabaka 2 eğitilebilen ağırlığa sahiptir (çekirdek ve önyargı)
layer = keras.layers.Dense(3)
layer.build((None, 4)) # Create the weights
print("weights:", len(layer.weights))
print("trainable_weights:", len(layer.trainable_weights))
print("non_trainable_weights:", len(layer.non_trainable_weights))
weights: 2 trainable_weights: 2 non_trainable_weights: 0
Genel olarak, tüm ağırlıklar eğitilebilir ağırlıklardır. Yalnızca yerleşik olmayan eğitilebilir ağırlıkları vardır katmanda olduğu BatchNormalization
katmanı. Eğitim sırasında girdilerinin ortalamasını ve varyansını takip etmek için eğitilemez ağırlıklar kullanır. Kendi özel katmanlarında olmayan eğitilebilir ağırlıkları kullanmak görmek öğrenmek için sıfırdan yeni katmanlar yazma rehberi .
Örnek: BatchNormalization
tabaka 2 eğitilebilen ağırlıkları ve 2-olmayan eğitilebilen tartılacak
layer = keras.layers.BatchNormalization()
layer.build((None, 4)) # Create the weights
print("weights:", len(layer.weights))
print("trainable_weights:", len(layer.trainable_weights))
print("non_trainable_weights:", len(layer.non_trainable_weights))
weights: 4 trainable_weights: 2 non_trainable_weights: 2
Katmanlar ve modeller de bir boolean nitelik özelliği trainable
. Değeri değiştirilebilir. Ayar layer.trainable
için False
olmayan eğitilebilir için hamle eğitilebilir tüm katmanın ağırlıklarını. Bu "dondurma" katmanı olarak adlandırılır: donmuş tabakanın devlet eğitimi sırasında güncelleştirilmiş olmayacak (ya zaman ile antrenman fit()
veya dayanan herhangi bir özel döngü ile eğitim trainable_weights
degrade güncelleştirmeleri uygulamak için).
Örnek: ayar trainable
için False
layer = keras.layers.Dense(3)
layer.build((None, 4)) # Create the weights
layer.trainable = False # Freeze the layer
print("weights:", len(layer.weights))
print("trainable_weights:", len(layer.trainable_weights))
print("non_trainable_weights:", len(layer.non_trainable_weights))
weights: 2 trainable_weights: 0 non_trainable_weights: 2
Eğitilebilir bir ağırlık eğitilemez hale geldiğinde, değeri artık eğitim sırasında güncellenmez.
# Make a model with 2 layers
layer1 = keras.layers.Dense(3, activation="relu")
layer2 = keras.layers.Dense(3, activation="sigmoid")
model = keras.Sequential([keras.Input(shape=(3,)), layer1, layer2])
# Freeze the first layer
layer1.trainable = False
# Keep a copy of the weights of layer1 for later reference
initial_layer1_weights_values = layer1.get_weights()
# Train the model
model.compile(optimizer="adam", loss="mse")
model.fit(np.random.random((2, 3)), np.random.random((2, 3)))
# Check that the weights of layer1 have not changed during training
final_layer1_weights_values = layer1.get_weights()
np.testing.assert_allclose(
initial_layer1_weights_values[0], final_layer1_weights_values[0]
)
np.testing.assert_allclose(
initial_layer1_weights_values[1], final_layer1_weights_values[1]
)
1/1 [==============================] - 1s 640ms/step - loss: 0.0945
Karıştırmayın layer.trainable
argüman ile öznitelik training
içinde layer.__call__()
(ki katman çıkarım modunda veya eğitim modunda onun ileri pas çalıştırılması gerekip gerekmediğini kontroller). Daha fazla bilgi için, bkz Keras SSS .
Yinelemeli ayar trainable
özniteliği
Eğer ayarlarsanız trainable = False
bir model üzerinde veya alt katmanları olan herhangi bir katman üzerinde, tüm çocukların katmanları sıra dışı eğitilebilir olur.
Örnek:
inner_model = keras.Sequential(
[
keras.Input(shape=(3,)),
keras.layers.Dense(3, activation="relu"),
keras.layers.Dense(3, activation="relu"),
]
)
model = keras.Sequential(
[keras.Input(shape=(3,)), inner_model, keras.layers.Dense(3, activation="sigmoid"),]
)
model.trainable = False # Freeze the outer model
assert inner_model.trainable == False # All layers in `model` are now frozen
assert inner_model.layers[0].trainable == False # `trainable` is propagated recursively
Tipik transfer-öğrenme iş akışı
Bu bizi Keras'ta tipik bir transfer öğrenme iş akışının nasıl uygulanabileceğine götürür:
- Bir temel model oluşturun ve buna önceden eğitilmiş ağırlıklar yükleyin.
- Ayarlayarak baz modelinde tüm katmanları dondur
trainable = False
. - Temel modelden bir (veya birkaç) katmanın çıktısının üzerine yeni bir model oluşturun.
- Yeni modelinizi yeni veri kümenizde eğitin.
Alternatif, daha hafif bir iş akışının da olabileceğini unutmayın:
- Bir temel model oluşturun ve buna önceden eğitilmiş ağırlıklar yükleyin.
- Yeni veri kümenizi bunun üzerinden çalıştırın ve temel modelden bir (veya birkaç) katmanın çıktısını kaydedin. Bu özellik çıkarma denir.
- Bu çıktıyı yeni, daha küçük bir model için girdi verileri olarak kullanın.
Bu ikinci iş akışının önemli bir avantajı, temel modeli eğitim dönemi başına bir kez yerine verilerinizde yalnızca bir kez çalıştırmanızdır. Yani çok daha hızlı ve daha ucuz.
Ancak bu ikinci iş akışıyla ilgili bir sorun, örneğin veri artırma yaparken gerekli olan eğitim sırasında yeni modelinizin giriş verilerini dinamik olarak değiştirmenize izin vermemesidir. Aktarım öğrenimi genellikle, yeni veri kümenizde sıfırdan tam ölçekli bir model eğitmek için çok az veriye sahip olduğunda ve bu tür senaryolarda veri büyütme çok önemli olduğunda görevler için kullanılır. Bundan sonra, ilk iş akışına odaklanacağız.
Keras'ta ilk iş akışı şöyle görünür:
İlk olarak, önceden eğitilmiş ağırlıklarla bir temel model oluşturun.
base_model = keras.applications.Xception(
weights='imagenet', # Load weights pre-trained on ImageNet.
input_shape=(150, 150, 3),
include_top=False) # Do not include the ImageNet classifier at the top.
Ardından, temel modeli dondurun.
base_model.trainable = False
Üstte yeni bir model oluşturun.
inputs = keras.Input(shape=(150, 150, 3))
# We make sure that the base_model is running in inference mode here,
# by passing `training=False`. This is important for fine-tuning, as you will
# learn in a few paragraphs.
x = base_model(inputs, training=False)
# Convert features of shape `base_model.output_shape[1:]` to vectors
x = keras.layers.GlobalAveragePooling2D()(x)
# A Dense classifier with a single unit (binary classification)
outputs = keras.layers.Dense(1)(x)
model = keras.Model(inputs, outputs)
Modeli yeni verilerle eğitin.
model.compile(optimizer=keras.optimizers.Adam(),
loss=keras.losses.BinaryCrossentropy(from_logits=True),
metrics=[keras.metrics.BinaryAccuracy()])
model.fit(new_dataset, epochs=20, callbacks=..., validation_data=...)
İnce ayar
Modeliniz yeni veriler üzerinde birleştiğinde, temel modelin tamamını veya bir kısmını çözmeyi deneyebilir ve tüm modeli uçtan uca çok düşük bir öğrenme oranıyla yeniden eğitebilirsiniz.
Bu, potansiyel olarak size artımlı iyileştirmeler sağlayabilecek isteğe bağlı bir son adımdır. Ayrıca potansiyel olarak hızlı bir şekilde fazla takmaya neden olabilir - bunu aklınızda bulundurun.
Donmuş katmanlarla modeli yakınsaması için eğitilmiş sonra sadece bu adımı yapmak için çok önemlidir. Rastgele başlatılmış eğitilebilir katmanları önceden eğitilmiş özellikleri tutan eğitilebilir katmanlarla karıştırırsanız, rastgele başlatılmış katmanlar eğitim sırasında çok büyük gradyan güncellemelerine neden olur ve bu da önceden eğitilmiş özelliklerinizi yok eder.
Bu aşamada çok düşük bir öğrenme oranı kullanmak da çok önemlidir, çünkü genellikle çok küçük olan bir veri kümesi üzerinde ilk eğitim turundan çok daha büyük bir model eğitiyorsunuz. Sonuç olarak, büyük ağırlık güncellemeleri uygularsanız çok hızlı bir şekilde fazla takma riskiniz vardır. Burada, yalnızca önceden eğitilmiş ağırlıkları kademeli olarak yeniden uyarlamak istiyorsunuz.
Tüm temel modelin ince ayarını şu şekilde uygulayabilirsiniz:
# Unfreeze the base model
base_model.trainable = True
# It's important to recompile your model after you make any changes
# to the `trainable` attribute of any inner layer, so that your changes
# are take into account
model.compile(optimizer=keras.optimizers.Adam(1e-5), # Very low learning rate
loss=keras.losses.BinaryCrossentropy(from_logits=True),
metrics=[keras.metrics.BinaryAccuracy()])
# Train end-to-end. Be careful to stop before you overfit!
model.fit(new_dataset, epochs=10, callbacks=..., validation_data=...)
İlgili önemli not compile()
ve trainable
Arayan compile()
amaçlanan bir model üzerinde bu modelin davranışını "dondurmak". Bu ima trainable
kadar modeli derlenmiş bir anda nitelik değerleri, o modelin ömrü boyunca muhafaza edilmelidir compile
yeniden adlandırılır. Eğer herhangi bir değişiklik yaparsanız Dolayısıyla, trainable
değeri, çağrı emin olun compile()
yaptığınız değişiklikler dikkate alınacak için model üzerinde tekrar.
İlgili önemli notlar BatchNormalization
tabakasının
Birçok görüntü modelleri içeriyor BatchNormalization
katmanları. Bu katman, akla gelebilecek her sayıda özel bir durumdur. İşte akılda tutulması gereken birkaç şey.
-
BatchNormalization
eğitim sırasında güncellenmelerini 2 olmayan eğitilebilir ağırlığını verir. Bunlar, girdilerin ortalamasını ve varyansını izleyen değişkenlerdir. - Ayarladığınızda
bn_layer.trainable = False
,BatchNormalization
katman çıkarım modunda çalışır ve onun ortalama ve varyans istatistiklerini güncelleme olmayacaktır. Bu şekilde genel olarak diğer katmanları için durum böyle değildir ağırlık trainability & çıkarım / eğitim modları iki dikey kavramlardır . Fakat iki durumunda bağlıdırBatchNormalization
tabakasının. - Eğer içeren bir model unfreeze zaman
BatchNormalization
ince ayar yapmak için katmanları, sen tutmalıBatchNormalization
geçirerek çıkarım modunda katmanlarıtraining=False
baz modeli çağrılırken. Aksi takdirde, eğitilebilir olmayan ağırlıklara uygulanan güncellemeler, modelin öğrendiklerini bir anda yok edecektir.
Bu kılavuzun sonundaki uçtan uca örnekte bu kalıbı çalışırken göreceksiniz.
Özel bir eğitim döngüsüyle öğrenimi ve ince ayarı aktarın
Yerine ise fit()
, kendi alt düzey eğitim döngü kullanırken, iş akışı kalır temelde aynı. Sadece dikkate liste almak için dikkatli olmalıdır model.trainable_weights
degrade güncellemelerini uygularken:
# Create base model
base_model = keras.applications.Xception(
weights='imagenet',
input_shape=(150, 150, 3),
include_top=False)
# Freeze base model
base_model.trainable = False
# Create new model on top.
inputs = keras.Input(shape=(150, 150, 3))
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
outputs = keras.layers.Dense(1)(x)
model = keras.Model(inputs, outputs)
loss_fn = keras.losses.BinaryCrossentropy(from_logits=True)
optimizer = keras.optimizers.Adam()
# Iterate over the batches of a dataset.
for inputs, targets in new_dataset:
# Open a GradientTape.
with tf.GradientTape() as tape:
# Forward pass.
predictions = model(inputs)
# Compute the loss value for this batch.
loss_value = loss_fn(targets, predictions)
# Get gradients of loss wrt the *trainable* weights.
gradients = tape.gradient(loss_value, model.trainable_weights)
# Update the weights of the model.
optimizer.apply_gradients(zip(gradients, model.trainable_weights))
Aynı şekilde ince ayar için.
Uçtan uca bir örnek: kedilere karşı köpekler veri kümesinde bir görüntü sınıflandırma modelinde ince ayar yapma
Bu kavramları sağlamlaştırmak için, somut bir uçtan uca aktarım öğrenimi ve ince ayar örneğinde size yol gösterelim. ImageNet üzerinde önceden eğitilmiş Xception modelini yükleyeceğiz ve bunu Kaggle "cats vs. Dog" sınıflandırma veri setinde kullanacağız.
verileri alma
İlk olarak, TFDS kullanarak kedilere karşı köpekler veri setini getirelim. Kendi veri kümesi varsa, muhtemelen yarar kullanmak isteyeceksiniz tf.keras.preprocessing.image_dataset_from_directory
benzer etiketli veri kümesi sınıfa özel klasörler halinde açılan diskteki görüntülerin bir dizi nesneleri oluşturmak için.
Aktarım öğrenimi en çok çok küçük veri kümeleriyle çalışırken yararlıdır. Veri kümemizi küçük tutmak için orijinal eğitim verilerinin %40'ını (25.000 görüntü) eğitim için, %10'unu doğrulama için ve %10'unu test için kullanacağız.
import tensorflow_datasets as tfds
tfds.disable_progress_bar()
train_ds, validation_ds, test_ds = tfds.load(
"cats_vs_dogs",
# Reserve 10% for validation and 10% for test
split=["train[:40%]", "train[40%:50%]", "train[50%:60%]"],
as_supervised=True, # Include labels
)
print("Number of training samples: %d" % tf.data.experimental.cardinality(train_ds))
print(
"Number of validation samples: %d" % tf.data.experimental.cardinality(validation_ds)
)
print("Number of test samples: %d" % tf.data.experimental.cardinality(test_ds))
Number of training samples: 9305 Number of validation samples: 2326 Number of test samples: 2326
Bunlar eğitim veri setindeki ilk 9 görüntü -- gördüğünüz gibi hepsi farklı boyutlarda.
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
for i, (image, label) in enumerate(train_ds.take(9)):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image)
plt.title(int(label))
plt.axis("off")
Ayrıca etiket 1'in "köpek" ve etiket 0'ın "kedi" olduğunu görebiliriz.
Verileri standartlaştırma
Ham görsellerimiz çeşitli boyutlara sahiptir. Ayrıca her piksel 0 ile 255 arasında (RGB seviye değerleri) 3 tamsayı değerinden oluşmaktadır. Bu, bir sinir ağını beslemek için pek uygun değil. 2 şey yapmamız gerekiyor:
- Sabit bir görüntü boyutuna standartlaştırın. 150x150 seçiyoruz.
- Normale piksel değerleri arasındaki -1 ve 1. Biz kullanarak yapacağım
Normalization
modelinin kendisinin bir parçası olarak katmanını.
Genel olarak, önceden işlenmiş verileri alan modellerin aksine, ham verileri girdi olarak alan modeller geliştirmek iyi bir uygulamadır. Bunun nedeni, modeliniz önceden işlenmiş veriler bekliyorsa, modelinizi başka bir yerde (bir web tarayıcısında, bir mobil uygulamada) kullanmak için dışa aktardığınızda, aynı ön işleme hattını yeniden uygulamanız gerekir. Bu çok çabuk çok zorlaşıyor. Bu nedenle, modele ulaşmadan önce mümkün olan en az miktarda ön işleme yapmalıyız.
Burada, veri hattında görüntü yeniden boyutlandırma yapacağız (çünkü derin bir sinir ağı yalnızca bitişik veri gruplarını işleyebilir) ve onu oluşturduğumuzda, modelin bir parçası olarak girdi değeri ölçeklendirmesini yapacağız.
Resimleri 150x150 olarak yeniden boyutlandıralım:
size = (150, 150)
train_ds = train_ds.map(lambda x, y: (tf.image.resize(x, size), y))
validation_ds = validation_ds.map(lambda x, y: (tf.image.resize(x, size), y))
test_ds = test_ds.map(lambda x, y: (tf.image.resize(x, size), y))
Ayrıca, verileri toplu hale getirelim ve yükleme hızını optimize etmek için önbelleğe alma ve önceden getirmeyi kullanalım.
batch_size = 32
train_ds = train_ds.cache().batch(batch_size).prefetch(buffer_size=10)
validation_ds = validation_ds.cache().batch(batch_size).prefetch(buffer_size=10)
test_ds = test_ds.cache().batch(batch_size).prefetch(buffer_size=10)
Rastgele veri artırmayı kullanma
Büyük bir görüntü veri kümeniz olmadığında, eğitim görüntülerine rastgele yatay çevirme veya küçük rastgele döndürmeler gibi rastgele ancak gerçekçi dönüşümler uygulayarak örnek çeşitliliğini yapay olarak tanıtmak iyi bir uygulamadır. Bu, fazla uydurmayı yavaşlatırken modeli eğitim verilerinin farklı yönlerine maruz bırakmaya yardımcı olur.
from tensorflow import keras
from tensorflow.keras import layers
data_augmentation = keras.Sequential(
[layers.RandomFlip("horizontal"), layers.RandomRotation(0.1),]
)
Çeşitli rastgele dönüşümlerden sonra ilk grubun ilk görüntüsünün nasıl göründüğünü görselleştirelim:
import numpy as np
for images, labels in train_ds.take(1):
plt.figure(figsize=(10, 10))
first_image = images[0]
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
augmented_image = data_augmentation(
tf.expand_dims(first_image, 0), training=True
)
plt.imshow(augmented_image[0].numpy().astype("int32"))
plt.title(int(labels[0]))
plt.axis("off")
2021-09-01 18:45:34.772284: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Bir model yapmak
Şimdi daha önce açıkladığımız planı takip eden bir model oluşturalım.
Bunu not et:
- Bir ekleme
Rescaling
(başlangıçta ölçek girdi değerlerine katman[0, 255]
aralığında)[-1, 1]
aralığında. - Biz eklemek
Dropout
regularization, sınıflandırma tabakasının önce katmanı. - Biz geçmek emin
training=False
o batchnorm istatistikleri biz ince ayar için baz modeli önündeki engeli sonra bile güncellenmiş alamadım bu yüzden, çıkarsama modunda çalışır böylece, baz modeli çağrılırken.
base_model = keras.applications.Xception(
weights="imagenet", # Load weights pre-trained on ImageNet.
input_shape=(150, 150, 3),
include_top=False,
) # Do not include the ImageNet classifier at the top.
# Freeze the base_model
base_model.trainable = False
# Create new model on top
inputs = keras.Input(shape=(150, 150, 3))
x = data_augmentation(inputs) # Apply random data augmentation
# Pre-trained Xception weights requires that input be scaled
# from (0, 255) to a range of (-1., +1.), the rescaling layer
# outputs: `(inputs * scale) + offset`
scale_layer = keras.layers.Rescaling(scale=1 / 127.5, offset=-1)
x = scale_layer(x)
# The base model contains batchnorm layers. We want to keep them in inference mode
# when we unfreeze the base model for fine-tuning, so we make sure that the
# base_model is running in inference mode here.
x = base_model(x, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dropout(0.2)(x) # Regularize with dropout
outputs = keras.layers.Dense(1)(x)
model = keras.Model(inputs, outputs)
model.summary()
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/xception/xception_weights_tf_dim_ordering_tf_kernels_notop.h5 83689472/83683744 [==============================] - 2s 0us/step 83697664/83683744 [==============================] - 2s 0us/step Model: "model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_5 (InputLayer) [(None, 150, 150, 3)] 0 _________________________________________________________________ sequential_3 (Sequential) (None, 150, 150, 3) 0 _________________________________________________________________ rescaling (Rescaling) (None, 150, 150, 3) 0 _________________________________________________________________ xception (Functional) (None, 5, 5, 2048) 20861480 _________________________________________________________________ global_average_pooling2d (Gl (None, 2048) 0 _________________________________________________________________ dropout (Dropout) (None, 2048) 0 _________________________________________________________________ dense_7 (Dense) (None, 1) 2049 ================================================================= Total params: 20,863,529 Trainable params: 2,049 Non-trainable params: 20,861,480 _________________________________________________________________
Üst katmanı eğitin
model.compile(
optimizer=keras.optimizers.Adam(),
loss=keras.losses.BinaryCrossentropy(from_logits=True),
metrics=[keras.metrics.BinaryAccuracy()],
)
epochs = 20
model.fit(train_ds, epochs=epochs, validation_data=validation_ds)
Epoch 1/20 151/291 [==============>...............] - ETA: 3s - loss: 0.1979 - binary_accuracy: 0.9096 Corrupt JPEG data: 65 extraneous bytes before marker 0xd9 268/291 [==========================>...] - ETA: 1s - loss: 0.1663 - binary_accuracy: 0.9269 Corrupt JPEG data: 239 extraneous bytes before marker 0xd9 282/291 [============================>.] - ETA: 0s - loss: 0.1628 - binary_accuracy: 0.9284 Corrupt JPEG data: 1153 extraneous bytes before marker 0xd9 Corrupt JPEG data: 228 extraneous bytes before marker 0xd9 291/291 [==============================] - ETA: 0s - loss: 0.1620 - binary_accuracy: 0.9286 Corrupt JPEG data: 2226 extraneous bytes before marker 0xd9 291/291 [==============================] - 29s 63ms/step - loss: 0.1620 - binary_accuracy: 0.9286 - val_loss: 0.0814 - val_binary_accuracy: 0.9686 Epoch 2/20 291/291 [==============================] - 8s 29ms/step - loss: 0.1178 - binary_accuracy: 0.9511 - val_loss: 0.0785 - val_binary_accuracy: 0.9695 Epoch 3/20 291/291 [==============================] - 9s 30ms/step - loss: 0.1121 - binary_accuracy: 0.9536 - val_loss: 0.0748 - val_binary_accuracy: 0.9712 Epoch 4/20 291/291 [==============================] - 9s 29ms/step - loss: 0.1082 - binary_accuracy: 0.9554 - val_loss: 0.0754 - val_binary_accuracy: 0.9703 Epoch 5/20 291/291 [==============================] - 8s 29ms/step - loss: 0.1034 - binary_accuracy: 0.9570 - val_loss: 0.0721 - val_binary_accuracy: 0.9725 Epoch 6/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0975 - binary_accuracy: 0.9602 - val_loss: 0.0748 - val_binary_accuracy: 0.9699 Epoch 7/20 291/291 [==============================] - 9s 29ms/step - loss: 0.0989 - binary_accuracy: 0.9595 - val_loss: 0.0732 - val_binary_accuracy: 0.9716 Epoch 8/20 291/291 [==============================] - 8s 29ms/step - loss: 0.1027 - binary_accuracy: 0.9566 - val_loss: 0.0787 - val_binary_accuracy: 0.9678 Epoch 9/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0959 - binary_accuracy: 0.9614 - val_loss: 0.0734 - val_binary_accuracy: 0.9729 Epoch 10/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0995 - binary_accuracy: 0.9588 - val_loss: 0.0717 - val_binary_accuracy: 0.9721 Epoch 11/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0957 - binary_accuracy: 0.9612 - val_loss: 0.0731 - val_binary_accuracy: 0.9725 Epoch 12/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0936 - binary_accuracy: 0.9622 - val_loss: 0.0751 - val_binary_accuracy: 0.9716 Epoch 13/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0965 - binary_accuracy: 0.9610 - val_loss: 0.0821 - val_binary_accuracy: 0.9695 Epoch 14/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0939 - binary_accuracy: 0.9618 - val_loss: 0.0742 - val_binary_accuracy: 0.9712 Epoch 15/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0974 - binary_accuracy: 0.9585 - val_loss: 0.0771 - val_binary_accuracy: 0.9712 Epoch 16/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0947 - binary_accuracy: 0.9621 - val_loss: 0.0823 - val_binary_accuracy: 0.9699 Epoch 17/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0947 - binary_accuracy: 0.9625 - val_loss: 0.0718 - val_binary_accuracy: 0.9708 Epoch 18/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0928 - binary_accuracy: 0.9616 - val_loss: 0.0738 - val_binary_accuracy: 0.9716 Epoch 19/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0922 - binary_accuracy: 0.9644 - val_loss: 0.0743 - val_binary_accuracy: 0.9716 Epoch 20/20 291/291 [==============================] - 8s 29ms/step - loss: 0.0885 - binary_accuracy: 0.9635 - val_loss: 0.0745 - val_binary_accuracy: 0.9695 <keras.callbacks.History at 0x7f849a3b2950>
Tüm modelde bir tur ince ayar yapın
Son olarak, temel modeli çözelim ve tüm modeli düşük bir öğrenme oranıyla uçtan uca eğitelim.
Baz modeli eğitilebilir hale rağmen biz öldükten sonra da önemlisi, yine çıkarım modunda çalışırken training=False
biz modeli inşa ettiğinde bunu çağrılırken. Bu, içindeki toplu normalleştirme katmanlarının toplu istatistiklerini güncellemeyeceği anlamına gelir. Yaparlarsa, model tarafından şimdiye kadar öğrenilen temsilleri alt üst edeceklerdi.
# Unfreeze the base_model. Note that it keeps running in inference mode
# since we passed `training=False` when calling it. This means that
# the batchnorm layers will not update their batch statistics.
# This prevents the batchnorm layers from undoing all the training
# we've done so far.
base_model.trainable = True
model.summary()
model.compile(
optimizer=keras.optimizers.Adam(1e-5), # Low learning rate
loss=keras.losses.BinaryCrossentropy(from_logits=True),
metrics=[keras.metrics.BinaryAccuracy()],
)
epochs = 10
model.fit(train_ds, epochs=epochs, validation_data=validation_ds)
Model: "model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_5 (InputLayer) [(None, 150, 150, 3)] 0 _________________________________________________________________ sequential_3 (Sequential) (None, 150, 150, 3) 0 _________________________________________________________________ rescaling (Rescaling) (None, 150, 150, 3) 0 _________________________________________________________________ xception (Functional) (None, 5, 5, 2048) 20861480 _________________________________________________________________ global_average_pooling2d (Gl (None, 2048) 0 _________________________________________________________________ dropout (Dropout) (None, 2048) 0 _________________________________________________________________ dense_7 (Dense) (None, 1) 2049 ================================================================= Total params: 20,863,529 Trainable params: 20,809,001 Non-trainable params: 54,528 _________________________________________________________________ Epoch 1/10 291/291 [==============================] - 43s 131ms/step - loss: 0.0802 - binary_accuracy: 0.9692 - val_loss: 0.0580 - val_binary_accuracy: 0.9764 Epoch 2/10 291/291 [==============================] - 37s 128ms/step - loss: 0.0542 - binary_accuracy: 0.9792 - val_loss: 0.0529 - val_binary_accuracy: 0.9764 Epoch 3/10 291/291 [==============================] - 37s 128ms/step - loss: 0.0400 - binary_accuracy: 0.9832 - val_loss: 0.0510 - val_binary_accuracy: 0.9798 Epoch 4/10 291/291 [==============================] - 37s 128ms/step - loss: 0.0313 - binary_accuracy: 0.9879 - val_loss: 0.0505 - val_binary_accuracy: 0.9819 Epoch 5/10 291/291 [==============================] - 37s 128ms/step - loss: 0.0272 - binary_accuracy: 0.9904 - val_loss: 0.0485 - val_binary_accuracy: 0.9807 Epoch 6/10 291/291 [==============================] - 37s 128ms/step - loss: 0.0284 - binary_accuracy: 0.9901 - val_loss: 0.0497 - val_binary_accuracy: 0.9824 Epoch 7/10 291/291 [==============================] - 37s 127ms/step - loss: 0.0198 - binary_accuracy: 0.9937 - val_loss: 0.0530 - val_binary_accuracy: 0.9802 Epoch 8/10 291/291 [==============================] - 37s 127ms/step - loss: 0.0173 - binary_accuracy: 0.9930 - val_loss: 0.0572 - val_binary_accuracy: 0.9819 Epoch 9/10 291/291 [==============================] - 37s 127ms/step - loss: 0.0113 - binary_accuracy: 0.9958 - val_loss: 0.0555 - val_binary_accuracy: 0.9837 Epoch 10/10 291/291 [==============================] - 37s 127ms/step - loss: 0.0091 - binary_accuracy: 0.9966 - val_loss: 0.0596 - val_binary_accuracy: 0.9832 <keras.callbacks.History at 0x7f83982d4cd0>
10 çağdan sonra, ince ayar bize burada güzel bir gelişme kazandırıyor.