![]() | ![]() | ![]() | ![]() |
Tanıtım
Bir Keras modeli birden çok bileşenden oluşur:
- Modelin hangi katmanları içerdiğini ve bunların nasıl bağlanacağını belirten mimari veya konfigürasyon.
- Bir dizi ağırlık değeri ("modelin durumu").
- Bir optimize edici (modelin derlenmesiyle tanımlanır).
- Kayıpları ve metrik bir dizi (model derleme ya da arama tarafından tanımlanan
add_loss()
ya daadd_metric()
).
Keras API, tüm bu parçaları bir kerede diske kaydetmeyi veya yalnızca bazılarını seçerek kaydetmeyi mümkün kılar:
- Her şeyi TensorFlow SavedModel formatında (veya daha eski Keras H5 formatında) tek bir arşive kaydetme. Bu standart uygulamadır.
- Yalnızca mimariyi/yapılandırmayı, tipik olarak bir JSON dosyası olarak kaydetme.
- Yalnızca ağırlık değerlerinin kaydedilmesi. Bu genellikle modeli eğitirken kullanılır.
Bu seçeneklerin her birine bir göz atalım. Birini veya diğerini ne zaman kullanırsınız ve bunlar nasıl çalışır?
Bir model nasıl kaydedilir ve yüklenir
Bu kılavuzu okumak için yalnızca 10 saniyeniz varsa, bilmeniz gerekenler burada.
Keras modelini kaydetme:
model = ... # Get model (Sequential, Functional Model, or Model subclass)
model.save('path/to/location')
Modeli geri yükleme:
from tensorflow import keras
model = keras.models.load_model('path/to/location')
Şimdi ayrıntılara bakalım.
Kurmak
import numpy as np
import tensorflow as tf
from tensorflow import keras
Tüm model kaydetme ve yükleme
Tüm bir modeli tek bir esere kaydedebilirsiniz. Şunları içerecektir:
- Modelin mimarisi/yapılandırması
- Modelin ağırlık değerleri (eğitim sırasında öğrenilen)
- Modelin derleme bilgileri (eğer
compile()
denirdi) - Optimize edici ve varsa durumu (bu, eğitime kaldığınız yerden yeniden başlamanızı sağlar)
API'ler
-
model.save()
ya datf.keras.models.save_model()
-
tf.keras.models.load_model()
TensorFlow SavedModel biçimini ve daha eski Keras H5 biçimi: Eğer diske bütün bir modeli kaydetmek için kullanabileceğiniz iki biçimi vardır. Önerilen biçim SavedModel'dir. Kullanmak zaman varsayılan model.save()
.
H5 formatına şu şekilde geçebilirsiniz:
- Geçme
save_format='h5'
içinsave()
. - Bir dosya adı geçirerek uçları o
.h5
veya.keras
içinsave()
.
Kaydedilmiş Model biçimi
SavedModel, model mimarisini, ağırlıkları ve çağrı işlevlerinin izlenen Tensorflow alt grafiklerini kaydeden daha kapsamlı kaydetme biçimidir. Bu, Keras'ın hem yerleşik katmanları hem de özel nesneleri geri yüklemesini sağlar.
Örnek:
def get_model():
# Create a simple model.
inputs = keras.Input(shape=(32,))
outputs = keras.layers.Dense(1)(inputs)
model = keras.Model(inputs, outputs)
model.compile(optimizer="adam", loss="mean_squared_error")
return model
model = get_model()
# Train the model.
test_input = np.random.random((128, 32))
test_target = np.random.random((128, 1))
model.fit(test_input, test_target)
# Calling `save('my_model')` creates a SavedModel folder `my_model`.
model.save("my_model")
# It can be used to reconstruct the model identically.
reconstructed_model = keras.models.load_model("my_model")
# Let's check:
np.testing.assert_allclose(
model.predict(test_input), reconstructed_model.predict(test_input)
)
# The reconstructed model is already compiled and has retained the optimizer
# state, so training can resume:
reconstructed_model.fit(test_input, test_target)
4/4 [==============================] - 1s 2ms/step - loss: 0.5884 2021-08-25 17:49:05.320893: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them. INFO:tensorflow:Assets written to: my_model/assets 4/4 [==============================] - 0s 2ms/step - loss: 0.5197 <keras.callbacks.History at 0x7f99486ad490>
SavedModel'in içeriği
Arayan model.save('my_model')
adında bir klasör oluşturur my_model
aşağıdakileri içeren:
ls my_model
assets keras_metadata.pb saved_model.pb variables
Model mimari ve (iyileştirici, kayıp, ve metrik dahil) eğitim yapılandırma saklanır saved_model.pb
. Ağırlıklar kaydedilir variables/
dizinine.
SavedModel biçimi hakkında ayrıntılı bilgi için bkz SavedModel kılavuzu (diskte SavedModel biçimi) .
SavedModel özel nesneleri nasıl işler?
(Eğer uygulanırsa ve yapılandırma,) modelini ve katmanlarını, SavedModel biçim mağazaları sınıf adı, çağrı işlevi, kayıp, ve ağırlıklar kaydederken. Çağrı işlevi, modelin/katmanın hesaplama grafiğini tanımlar.
Model/katman yapılandırmasının yokluğunda, çağrı işlevi, orijinal model gibi eğitilebilen, değerlendirilebilen ve çıkarım için kullanılabilen bir model oluşturmak için kullanılır.
Yine de tanımlamak için iyi bir uygulamadır her zaman get_config
ve from_config
bir özel model veya katman sınıf yazarken yöntemleri. Bu, gerekirse daha sonra hesaplamayı kolayca güncellemenizi sağlar. Hakkında bölümüne bakınız Özel nesneler daha fazla bilgi için.
Örnek:
class CustomModel(keras.Model):
def __init__(self, hidden_units):
super(CustomModel, self).__init__()
self.hidden_units = hidden_units
self.dense_layers = [keras.layers.Dense(u) for u in hidden_units]
def call(self, inputs):
x = inputs
for layer in self.dense_layers:
x = layer(x)
return x
def get_config(self):
return {"hidden_units": self.hidden_units}
@classmethod
def from_config(cls, config):
return cls(**config)
model = CustomModel([16, 16, 10])
# Build the model by calling it
input_arr = tf.random.uniform((1, 5))
outputs = model(input_arr)
model.save("my_model")
# Option 1: Load with the custom_object argument.
loaded_1 = keras.models.load_model(
"my_model", custom_objects={"CustomModel": CustomModel}
)
# Option 2: Load without the CustomModel class.
# Delete the custom-defined model class to ensure that the loader does not have
# access to it.
del CustomModel
loaded_2 = keras.models.load_model("my_model")
np.testing.assert_allclose(loaded_1(input_arr), outputs)
np.testing.assert_allclose(loaded_2(input_arr), outputs)
print("Original model:", model)
print("Model Loaded with custom objects:", loaded_1)
print("Model loaded without the custom object class:", loaded_2)
INFO:tensorflow:Assets written to: my_model/assets WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually. WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually. Original model: <__main__.CustomModel object at 0x7f9949c86810> Model Loaded with custom objects: <__main__.CustomModel object at 0x7f99681f61d0> Model loaded without the custom object class: <keras.saving.saved_model.load.CustomModel object at 0x7f9aaceefd10>
İlk yüklenen modeli yapılandırma kullanılarak yüklenir CustomModel
sınıfı. İkinci model, orijinal model gibi davranan model sınıfı dinamik olarak oluşturularak yüklenir.
SavedModel'i Yapılandırma
Yeni TensoFlow 2.4'te argüman save_traces
eklendi model.save
SavedModel fonksiyonu izleme geçiş yapmanızı sağlar, hangi. Fonksiyonlar, bu nedenle zaman orijinal sınıf definitons olmadan yeniden yük özel nesnelere keras izin kaydedilir save_traces=False
, tüm özel nesneler tanımlanmış olmalı get_config
/ from_config
yöntemleri. Yüklerken, özel nesneler aktarılması gerekir custom_objects
argüman. save_traces=False
SavedModel ve zamandan tasarruf tarafından kullanılan disk alanını azaltır.
Keras H5 formatı
Keras ayrıca modelin mimarisi, ağırlıklar değerleri ve içeren tek HDF5 dosyasını tasarruf destekler compile()
bilgisini. SavedModel'e hafif bir alternatiftir.
Örnek:
model = get_model()
# Train the model.
test_input = np.random.random((128, 32))
test_target = np.random.random((128, 1))
model.fit(test_input, test_target)
# Calling `save('my_model.h5')` creates a h5 file `my_model.h5`.
model.save("my_h5_model.h5")
# It can be used to reconstruct the model identically.
reconstructed_model = keras.models.load_model("my_h5_model.h5")
# Let's check:
np.testing.assert_allclose(
model.predict(test_input), reconstructed_model.predict(test_input)
)
# The reconstructed model is already compiled and has retained the optimizer
# state, so training can resume:
reconstructed_model.fit(test_input, test_target)
4/4 [==============================] - 0s 1ms/step - loss: 1.6322 4/4 [==============================] - 0s 1ms/step - loss: 1.4790 <keras.callbacks.History at 0x7f9aacc0fd50>
sınırlamalar
SavedModel biçimiyle karşılaştırıldığında, H5 dosyasına dahil edilmeyen iki şey vardır:
- İle eklenmiş Dış kayıplar ve ölçümlerini
model.add_loss()
&model.add_metric()
(SavedModel aksine) kaydedilmez. Modelinizde bu tür kayıplar ve metrikler varsa ve eğitime devam etmek istiyorsanız, modeli yükledikten sonra bu kayıpları kendiniz eklemeniz gerekir. Not Bu yoluyla katmanları içinde oluşturulan kayıplar / ölçümlere geçerli olmadığınıself.add_loss()
&self.add_metric()
. Parçası oldukları çoktan katman yüklenen Olarak, bu kayıplar ve metrikler, tutulurcall
tabakasının yöntemle. - Özel tabakalar kaydedilen dosyanın dahil olarak özel hesaplama grafik nesneleri gibi. Yükleme sırasında, modeli yeniden yapılandırmak için Keras'ın bu nesnelerin Python sınıflarına/işlevlerine erişmesi gerekir. Bkz Özel nesneleri .
Mimariyi kaydetme
Modelin konfigürasyonu (veya mimarisi), modelin hangi katmanları içerdiğini ve bu katmanların nasıl bağlandığını belirtir*. Bir modelin konfigürasyonuna sahipseniz, model, ağırlıklar için yeni başlatılmış bir durumla ve derleme bilgisi olmadan oluşturulabilir.
*Bunun yalnızca işlevsel veya Sıralı api alt sınıflanmamış modeller kullanılarak tanımlanan modeller için geçerli olduğunu unutmayın.
Sıralı modelin veya İşlevsel API modelinin yapılandırılması
Bu tür modeller, açık katman grafikleridir: konfigürasyonları her zaman yapılandırılmış bir biçimde mevcuttur.
API'ler
-
get_config()
vefrom_config()
-
tf.keras.models.model_to_json()
vetf.keras.models.model_from_json()
get_config()
ve from_config()
Arayan config = model.get_config()
modelinin yapılandırmasını içeren bir Python dicti döndürür. Aynı model, daha sonra yoluyla yeniden olabilir Sequential.from_config(config)
, (a için Sequential
modeli) ya da Model.from_config(config)
(Fonksiyonel API modeli için).
Aynı iş akışı, herhangi bir seri hale getirilebilir katman için de çalışır.
Katman örneği:
layer = keras.layers.Dense(3, activation="relu")
layer_config = layer.get_config()
new_layer = keras.layers.Dense.from_config(layer_config)
Sıralı model örneği:
model = keras.Sequential([keras.Input((32,)), keras.layers.Dense(1)])
config = model.get_config()
new_model = keras.Sequential.from_config(config)
Fonksiyonel model örneği:
inputs = keras.Input((32,))
outputs = keras.layers.Dense(1)(inputs)
model = keras.Model(inputs, outputs)
config = model.get_config()
new_model = keras.Model.from_config(config)
to_json()
ve tf.keras.models.model_from_json()
Bu benzer get_config
/ from_config
o zaman orijinal modelin sınıfa olmadan yüklenebilir bir JSON dize içine modeli döner hariç. Ayrıca modellere özeldir, katmanlar için değildir.
Örnek:
model = keras.Sequential([keras.Input((32,)), keras.layers.Dense(1)])
json_config = model.to_json()
new_model = keras.models.model_from_json(json_config)
Özel nesneler
Modeller ve katmanlar
Sınıflandırma model ve katmanların mimarisi yöntemleri tanımlanmıştır __init__
ve call
. (Örneğin aracılığıyla size bayt kodu seri hale deneyebilirsiniz - Onlar JSON uyumlu yapılandırmada içine getirilemez Python bytecode, kabul edilir pickle
), ama tamamen güvensiz olduğunu ve model farklı bir sistem üzerinde yüklenemiyor demektir.
/ Kaydetme özel tanımlı katmanlar sahip bir model ya da bir sınıflandırma modeli yükleme amacıyla, üzerine yazmak gerekir get_config
ve isteğe bağlı from_config
yöntemleri. Ek olarak, Keras'ın bundan haberdar olması için özel nesneyi kaydettirmelisiniz.
Özel işlevler
Özel-tanımlı fonksiyonlar (örneğin aktivasyon kaybı ya da başlatma) bir gerek yoktur get_config
yöntemi. İşlev adı, özel bir nesne olarak kaydedildiği sürece yükleme için yeterlidir.
Yalnızca TensorFlow grafiğini yükleme
Keras tarafından oluşturulan TensorFlow grafiğini yüklemek mümkündür. Bunu, herhangi sağlamak gerekmez custom_objects
. Bunu şu şekilde yapabilirsiniz:
model.save("my_model")
tensorflow_graph = tf.saved_model.load("my_model")
x = np.random.uniform(size=(4, 32)).astype(np.float32)
predicted = tensorflow_graph(x).numpy()
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model. INFO:tensorflow:Assets written to: my_model/assets
Bu yöntemin birkaç dezavantajı olduğunu unutmayın:
- İzlenebilirlik nedenleriyle, kullanılan özel nesnelere her zaman erişiminiz olmalıdır. Yeniden yaratamayacağınız bir modeli üretime sokmak istemezsiniz.
- Tarafından döndürülen nesne
tf.saved_model.load
bir Keras model değildir. Yani kullanımı o kadar kolay değil. Örneğin, hiç erişemez.predict()
veya.fit()
Bunun kullanımı tavsiye edilmez bile, örneğin, sıkı bir noktada iseniz özel nesnelerin kod kaybetmiş veya modelin yükleme sorunları varsa, o size yardımcı olabilir tf.keras.models.load_model()
.
Sen daha öğrenebilirsiniz hakkında sayfa tf.saved_model.load
Yapılandırma yöntemlerini tanımlama
Özellikler:
-
get_config
Mimarlık ve model tasarrufu API'ler keras ile uyumlu olması için bir JSON serileştirilebilir sözlüğü dönmelidir. -
from_config(config)
(classmethod
) yapılandırma oluşturulur yeni bir katman ya da model nesne döndürmelidir. Varsayılan uygulama dönercls(**config)
.
Örnek:
class CustomLayer(keras.layers.Layer):
def __init__(self, a):
self.var = tf.Variable(a, name="var_a")
def call(self, inputs, training=False):
if training:
return inputs * self.var
else:
return inputs
def get_config(self):
return {"a": self.var.numpy()}
# There's actually no need to define `from_config` here, since returning
# `cls(**config)` is the default behavior.
@classmethod
def from_config(cls, config):
return cls(**config)
layer = CustomLayer(5)
layer.var.assign(2)
serialized_layer = keras.layers.serialize(layer)
new_layer = keras.layers.deserialize(
serialized_layer, custom_objects={"CustomLayer": CustomLayer}
)
Özel nesneyi kaydetme
Keras, yapılandırmayı hangi sınıfın oluşturduğunu not eder. Yukarıdaki örnekte, tf.keras.layers.serialize
özel tabakasının bir seri formunu oluşturur:
{'class_name': 'CustomLayer', 'config': {'a': 2} }
Keras bir ana liste tutar tüm yerleşik çağrı için doğru sınıfını bulmak için kullanılır katmanı modeli, optimize edici, ve metrik sınıflar, from_config
. Sınıf bulunamazsa, o zaman bir hata (yükseltilir Value Error: Unknown layer
). Bu listeye özel sınıfları kaydetmenin birkaç yolu vardır:
- Ayar
custom_objects
yükleme işlevi argüman. (yukarıdaki "Yapılandırma yöntemlerini tanımlama" bölümündeki örneğe bakın) -
tf.keras.utils.custom_object_scope
veyatf.keras.utils.CustomObjectScope
-
tf.keras.utils.register_keras_serializable
Özel katman ve işlev örneği
class CustomLayer(keras.layers.Layer):
def __init__(self, units=32, **kwargs):
super(CustomLayer, self).__init__(**kwargs)
self.units = units
def build(self, input_shape):
self.w = self.add_weight(
shape=(input_shape[-1], self.units),
initializer="random_normal",
trainable=True,
)
self.b = self.add_weight(
shape=(self.units,), initializer="random_normal", trainable=True
)
def call(self, inputs):
return tf.matmul(inputs, self.w) + self.b
def get_config(self):
config = super(CustomLayer, self).get_config()
config.update({"units": self.units})
return config
def custom_activation(x):
return tf.nn.tanh(x) ** 2
# Make a model with the CustomLayer and custom_activation
inputs = keras.Input((32,))
x = CustomLayer(32)(inputs)
outputs = keras.layers.Activation(custom_activation)(x)
model = keras.Model(inputs, outputs)
# Retrieve the config
config = model.get_config()
# At loading time, register the custom objects with a `custom_object_scope`:
custom_objects = {"CustomLayer": CustomLayer, "custom_activation": custom_activation}
with keras.utils.custom_object_scope(custom_objects):
new_model = keras.Model.from_config(config)
Bellek içi model klonlama
Ayrıca yoluyla bir modelin bellek içi klonlama yapabilirsiniz tf.keras.models.clone_model()
. Bu, yapılandırmayı alıp ardından modeli yapılandırmasından yeniden oluşturmaya eşdeğerdir (bu nedenle derleme bilgilerini veya katman ağırlık değerlerini korumaz).
Örnek:
with keras.utils.custom_object_scope(custom_objects):
new_model = keras.models.clone_model(model)
Yalnızca modelin ağırlık değerlerini kaydetme ve yükleme
Yalnızca bir modelin ağırlıklarını kaydetmeyi ve yüklemeyi seçebilirsiniz. Bu, aşağıdaki durumlarda yararlı olabilir:
- Modele yalnızca çıkarım için ihtiyacınız var: bu durumda eğitimi yeniden başlatmanız gerekmeyecek, bu nedenle derleme bilgilerine veya optimize edici durumuna ihtiyacınız yok.
- Transfer öğrenimi yapıyorsunuz: bu durumda, önceki bir modelin durumunu yeniden kullanarak yeni bir modeli eğitiyor olacaksınız, bu nedenle önceki modelin derleme bilgilerine ihtiyacınız yok.
Bellek içi ağırlık aktarımı için API'ler
Ağırlıklar kullanarak farklı nesneler arasında kopyalanabilir get_weights
ve set_weights
:
-
tf.keras.layers.Layer.get_weights()
: numpy diziler bir listesini döndürür. -
tf.keras.layers.Layer.set_weights()
: değerlere modeli ağırlıkları ayarlarweights
değişken.
Aşağıdaki örnekler.
Ağırlıkları bir katmandan diğerine bellekte aktarma
def create_layer():
layer = keras.layers.Dense(64, activation="relu", name="dense_2")
layer.build((None, 784))
return layer
layer_1 = create_layer()
layer_2 = create_layer()
# Copy weights from layer 1 to layer 2
layer_2.set_weights(layer_1.get_weights())
Ağırlıkları bir modelden başka bir modele uyumlu bir mimariye sahip bellekte aktarma
# Create a simple functional model
inputs = keras.Input(shape=(784,), name="digits")
x = keras.layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = keras.layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = keras.layers.Dense(10, name="predictions")(x)
functional_model = keras.Model(inputs=inputs, outputs=outputs, name="3_layer_mlp")
# Define a subclassed model with the same architecture
class SubclassedModel(keras.Model):
def __init__(self, output_dim, name=None):
super(SubclassedModel, self).__init__(name=name)
self.output_dim = output_dim
self.dense_1 = keras.layers.Dense(64, activation="relu", name="dense_1")
self.dense_2 = keras.layers.Dense(64, activation="relu", name="dense_2")
self.dense_3 = keras.layers.Dense(output_dim, name="predictions")
def call(self, inputs):
x = self.dense_1(inputs)
x = self.dense_2(x)
x = self.dense_3(x)
return x
def get_config(self):
return {"output_dim": self.output_dim, "name": self.name}
subclassed_model = SubclassedModel(10)
# Call the subclassed model once to create the weights.
subclassed_model(tf.ones((1, 784)))
# Copy weights from functional_model to subclassed_model.
subclassed_model.set_weights(functional_model.get_weights())
assert len(functional_model.weights) == len(subclassed_model.weights)
for a, b in zip(functional_model.weights, subclassed_model.weights):
np.testing.assert_allclose(a.numpy(), b.numpy())
Durumsuz katmanlar durumu
Durum bilgisi olmayan katmanlar ağırlıkların sırasını veya sayısını değiştirmediğinden, fazladan/eksik durumsuz katmanlar olsa bile modeller uyumlu mimarilere sahip olabilir.
inputs = keras.Input(shape=(784,), name="digits")
x = keras.layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = keras.layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = keras.layers.Dense(10, name="predictions")(x)
functional_model = keras.Model(inputs=inputs, outputs=outputs, name="3_layer_mlp")
inputs = keras.Input(shape=(784,), name="digits")
x = keras.layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = keras.layers.Dense(64, activation="relu", name="dense_2")(x)
# Add a dropout layer, which does not contain any weights.
x = keras.layers.Dropout(0.5)(x)
outputs = keras.layers.Dense(10, name="predictions")(x)
functional_model_with_dropout = keras.Model(
inputs=inputs, outputs=outputs, name="3_layer_mlp"
)
functional_model_with_dropout.set_weights(functional_model.get_weights())
Ağırlıkları diske kaydetmek ve geri yüklemek için API'ler
Ağırlıklar arayarak diske kaydedilebilir model.save_weights
aşağıdaki biçimlerde:
- TensorFlow Kontrol Noktası
- HDF5
İçin varsayılan biçim model.save_weights
TensorFlow kontrol noktası olduğunu. Kaydetme biçimini belirtmenin iki yolu vardır:
-
save_format
argümanı: Set değerisave_format="tf"
veyasave_format="h5"
. -
path
argümanı: ile yol uçları ise.h5
veya.hdf5
ardından HDF5 biçimi kullanılır. Sürece diğer ekleri bir TensorFlow kontrol noktasında yol açacaksave_format
ayarlanır.
Ağırlıkları bellek içi numpy dizileri olarak alma seçeneği de vardır. Her API'nin aşağıda ayrıntıları verilen artıları ve eksileri vardır.
TF Kontrol Noktası formatı
Örnek:
# Runnable example
sequential_model = keras.Sequential(
[
keras.Input(shape=(784,), name="digits"),
keras.layers.Dense(64, activation="relu", name="dense_1"),
keras.layers.Dense(64, activation="relu", name="dense_2"),
keras.layers.Dense(10, name="predictions"),
]
)
sequential_model.save_weights("ckpt")
load_status = sequential_model.load_weights("ckpt")
# `assert_consumed` can be used as validation that all variable values have been
# restored from the checkpoint. See `tf.train.Checkpoint.restore` for other
# methods in the Status object.
load_status.assert_consumed()
<tensorflow.python.training.tracking.util.CheckpointLoadStatus at 0x7f9aaca4ced0>
Biçim ayrıntıları
TensorFlow Checkpoint formatı, nesne öznitelik adlarını kullanarak ağırlıkları kaydeder ve geri yükler. Örneğin, düşünün tf.keras.layers.Dense
katmanı. : Tabakası iki ağırlıkları içeren dense.kernel
ve dense.bias
. Tabaka ile kaydedildiğinde tf
biçimi, ortaya çıkan denetim noktası tuşları içeriyor "kernel"
ve "bias"
ve bunlara karşılık gelen ağırlık değerleri. Daha fazla bilgi için bkz TF Checkpoint kılavuzunda "Yükleme mekaniği" .
Adı üst nesne, değişken olmayan adına kullanıldıktan sonra bu özellik / grafik kenar adlandırılır edin. Düşünün CustomLayer
aşağıdaki örnekte. Değişken CustomLayer.var
birlikte kaydedilir "var"
anahtar parçası olarak değil, "var_a"
.
class CustomLayer(keras.layers.Layer):
def __init__(self, a):
self.var = tf.Variable(a, name="var_a")
layer = CustomLayer(5)
layer_ckpt = tf.train.Checkpoint(layer=layer).save("custom_layer")
ckpt_reader = tf.train.load_checkpoint(layer_ckpt)
ckpt_reader.get_variable_to_dtype_map()
{'save_counter/.ATTRIBUTES/VARIABLE_VALUE': tf.int64, '_CHECKPOINTABLE_OBJECT_GRAPH': tf.string, 'layer/var/.ATTRIBUTES/VARIABLE_VALUE': tf.int32}
Transfer öğrenme örneği
Esasen, iki model aynı mimariye sahip olduğu sürece, aynı kontrol noktasını paylaşabilirler.
Örnek:
inputs = keras.Input(shape=(784,), name="digits")
x = keras.layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = keras.layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = keras.layers.Dense(10, name="predictions")(x)
functional_model = keras.Model(inputs=inputs, outputs=outputs, name="3_layer_mlp")
# Extract a portion of the functional model defined in the Setup section.
# The following lines produce a new model that excludes the final output
# layer of the functional model.
pretrained = keras.Model(
functional_model.inputs, functional_model.layers[-1].input, name="pretrained_model"
)
# Randomly assign "trained" weights.
for w in pretrained.weights:
w.assign(tf.random.normal(w.shape))
pretrained.save_weights("pretrained_ckpt")
pretrained.summary()
# Assume this is a separate program where only 'pretrained_ckpt' exists.
# Create a new functional model with a different output dimension.
inputs = keras.Input(shape=(784,), name="digits")
x = keras.layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = keras.layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = keras.layers.Dense(5, name="predictions")(x)
model = keras.Model(inputs=inputs, outputs=outputs, name="new_model")
# Load the weights from pretrained_ckpt into model.
model.load_weights("pretrained_ckpt")
# Check that all of the pretrained weights have been loaded.
for a, b in zip(pretrained.weights, model.weights):
np.testing.assert_allclose(a.numpy(), b.numpy())
print("\n", "-" * 50)
model.summary()
# Example 2: Sequential model
# Recreate the pretrained model, and load the saved weights.
inputs = keras.Input(shape=(784,), name="digits")
x = keras.layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = keras.layers.Dense(64, activation="relu", name="dense_2")(x)
pretrained_model = keras.Model(inputs=inputs, outputs=x, name="pretrained")
# Sequential example:
model = keras.Sequential([pretrained_model, keras.layers.Dense(5, name="predictions")])
model.summary()
pretrained_model.load_weights("pretrained_ckpt")
# Warning! Calling `model.load_weights('pretrained_ckpt')` won't throw an error,
# but will *not* work as expected. If you inspect the weights, you'll see that
# none of the weights will have loaded. `pretrained_model.load_weights()` is the
# correct method to call.
Model: "pretrained_model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= digits (InputLayer) [(None, 784)] 0 _________________________________________________________________ dense_1 (Dense) (None, 64) 50240 _________________________________________________________________ dense_2 (Dense) (None, 64) 4160 ================================================================= Total params: 54,400 Trainable params: 54,400 Non-trainable params: 0 _________________________________________________________________ -------------------------------------------------- Model: "new_model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= digits (InputLayer) [(None, 784)] 0 _________________________________________________________________ dense_1 (Dense) (None, 64) 50240 _________________________________________________________________ dense_2 (Dense) (None, 64) 4160 _________________________________________________________________ predictions (Dense) (None, 5) 325 ================================================================= Total params: 54,725 Trainable params: 54,725 Non-trainable params: 0 _________________________________________________________________ Model: "sequential_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= pretrained (Functional) (None, 64) 54400 _________________________________________________________________ predictions (Dense) (None, 5) 325 ================================================================= Total params: 54,725 Trainable params: 54,725 Non-trainable params: 0 _________________________________________________________________ <tensorflow.python.training.tracking.util.CheckpointLoadStatus at 0x7f9aaca76990>
Model oluşturmak için genellikle aynı API'ye bağlı kalmanız önerilir. Sıralı ve İşlevsel veya İşlevsel ve alt sınıflı vb. arasında geçiş yaparsanız, her zaman önceden eğitilmiş modeli yeniden oluşturun ve önceden eğitilmiş ağırlıkları bu modele yükleyin.
Bir sonraki soru, model mimarileri oldukça farklıysa ağırlıklar nasıl kaydedilebilir ve farklı modellere yüklenebilir? Solüsyon kullanmaktır tf.train.Checkpoint
kesin katmanlar / değişkenleri kaydetmek ve geri yüklemek için.
Örnek:
# Create a subclassed model that essentially uses functional_model's first
# and last layers.
# First, save the weights of functional_model's first and last dense layers.
first_dense = functional_model.layers[1]
last_dense = functional_model.layers[-1]
ckpt_path = tf.train.Checkpoint(
dense=first_dense, kernel=last_dense.kernel, bias=last_dense.bias
).save("ckpt")
# Define the subclassed model.
class ContrivedModel(keras.Model):
def __init__(self):
super(ContrivedModel, self).__init__()
self.first_dense = keras.layers.Dense(64)
self.kernel = self.add_variable("kernel", shape=(64, 10))
self.bias = self.add_variable("bias", shape=(10,))
def call(self, inputs):
x = self.first_dense(inputs)
return tf.matmul(x, self.kernel) + self.bias
model = ContrivedModel()
# Call model on inputs to create the variables of the dense layer.
_ = model(tf.ones((1, 784)))
# Create a Checkpoint with the same structure as before, and load the weights.
tf.train.Checkpoint(
dense=model.first_dense, kernel=model.kernel, bias=model.bias
).restore(ckpt_path).assert_consumed()
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/engine/base_layer.py:2223: UserWarning: `layer.add_variable` is deprecated and will be removed in a future version. Please use `layer.add_weight` method instead. warnings.warn('`layer.add_variable` is deprecated and ' <tensorflow.python.training.tracking.util.CheckpointLoadStatus at 0x7f9aaca6f390>
HDF5 formatı
HDF5 formatı, katman adlarına göre gruplandırılmış ağırlıklar içerir. Ağırlıklar olmayan eğitilebilen ağırlıkları (aynı listesine eğitilebilen ağırlıkların listesini birleştirerek sıralı listeleri layer.weights
). Bu nedenle, bir model, kontrol noktasında kaydedilenle aynı katmanlara ve eğitilebilir durumlara sahipse bir hdf5 kontrol noktası kullanabilir.
Örnek:
# Runnable example
sequential_model = keras.Sequential(
[
keras.Input(shape=(784,), name="digits"),
keras.layers.Dense(64, activation="relu", name="dense_1"),
keras.layers.Dense(64, activation="relu", name="dense_2"),
keras.layers.Dense(10, name="predictions"),
]
)
sequential_model.save_weights("weights.h5")
sequential_model.load_weights("weights.h5")
Değişen geldiğini hatırlatırız layer.trainable
farklı sonuçlanabilir layer.weights
modeli iç içe katmanları içerdiğinde sipariş.
class NestedDenseLayer(keras.layers.Layer):
def __init__(self, units, name=None):
super(NestedDenseLayer, self).__init__(name=name)
self.dense_1 = keras.layers.Dense(units, name="dense_1")
self.dense_2 = keras.layers.Dense(units, name="dense_2")
def call(self, inputs):
return self.dense_2(self.dense_1(inputs))
nested_model = keras.Sequential([keras.Input((784,)), NestedDenseLayer(10, "nested")])
variable_names = [v.name for v in nested_model.weights]
print("variables: {}".format(variable_names))
print("\nChanging trainable status of one of the nested layers...")
nested_model.get_layer("nested").dense_1.trainable = False
variable_names_2 = [v.name for v in nested_model.weights]
print("\nvariables: {}".format(variable_names_2))
print("variable ordering changed:", variable_names != variable_names_2)
variables: ['nested/dense_1/kernel:0', 'nested/dense_1/bias:0', 'nested/dense_2/kernel:0', 'nested/dense_2/bias:0'] Changing trainable status of one of the nested layers... variables: ['nested/dense_2/kernel:0', 'nested/dense_2/bias:0', 'nested/dense_1/kernel:0', 'nested/dense_1/bias:0'] variable ordering changed: True
Transfer öğrenme örneği
HDF5'ten önceden eğitilmiş ağırlıkları yüklerken, ağırlıkları orijinal kontrol noktası modele yüklemeniz ve ardından istenen ağırlıkları/katmanları yeni bir modele çıkarmanız önerilir.
Örnek:
def create_functional_model():
inputs = keras.Input(shape=(784,), name="digits")
x = keras.layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = keras.layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = keras.layers.Dense(10, name="predictions")(x)
return keras.Model(inputs=inputs, outputs=outputs, name="3_layer_mlp")
functional_model = create_functional_model()
functional_model.save_weights("pretrained_weights.h5")
# In a separate program:
pretrained_model = create_functional_model()
pretrained_model.load_weights("pretrained_weights.h5")
# Create a new model by extracting layers from the original model:
extracted_layers = pretrained_model.layers[:-1]
extracted_layers.append(keras.layers.Dense(5, name="dense_3"))
model = keras.Sequential(extracted_layers)
model.summary()
Model: "sequential_6" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_1 (Dense) (None, 64) 50240 _________________________________________________________________ dense_2 (Dense) (None, 64) 4160 _________________________________________________________________ dense_3 (Dense) (None, 5) 325 ================================================================= Total params: 54,725 Trainable params: 54,725 Non-trainable params: 0 _________________________________________________________________