কেরাস মডেলগুলি সংরক্ষণ করুন এবং লোড করুন

সেভ করা পৃষ্ঠা গুছিয়ে রাখতে 'সংগ্রহ' ব্যবহার করুন আপনার পছন্দ অনুযায়ী কন্টেন্ট সেভ করুন ও সঠিক বিভাগে রাখুন।

TensorFlow.org এ দেখুন Google Colab-এ চালান GitHub-এ উৎস দেখুন নোটবুক ডাউনলোড করুন

ভূমিকা

একটি কেরাস মডেল একাধিক উপাদান নিয়ে গঠিত:

  • আর্কিটেকচার, বা কনফিগারেশন, যা নির্দিষ্ট করে যে মডেলটিতে কোন স্তর রয়েছে এবং তারা কীভাবে সংযুক্ত।
  • ওজন মানের একটি সেট ("মডেলের অবস্থা")।
  • একটি অপ্টিমাইজার (মডেল সংকলন দ্বারা সংজ্ঞায়িত)।
  • লোকসান এবং মেট্রিকস একটি সেট (মডেল সংকলন বা কল করে সংজ্ঞায়িত add_loss() বা add_metric() )।

কেরাস এপিআই এই সমস্ত টুকরোগুলিকে একবারে ডিস্কে সংরক্ষণ করা সম্ভব করে তোলে, বা শুধুমাত্র বেছে বেছে কিছু সংরক্ষণ করে:

  • TensorFlow SavedModel ফরম্যাটে (বা পুরোনো Keras H5 ফরম্যাটে) সবকিছু একটি একক সংরক্ষণাগারে সংরক্ষণ করা হচ্ছে। এটি আদর্শ অনুশীলন।
  • শুধুমাত্র আর্কিটেকচার / কনফিগারেশন সংরক্ষণ করা হচ্ছে, সাধারণত একটি JSON ফাইল হিসাবে।
  • শুধুমাত্র ওজন মান সংরক্ষণ. মডেল প্রশিক্ষণের সময় এটি সাধারণত ব্যবহৃত হয়।

আসুন এই বিকল্পগুলির প্রতিটির দিকে নজর দেওয়া যাক। আপনি কখন এক বা অন্যটি ব্যবহার করবেন এবং তারা কীভাবে কাজ করবে?

কিভাবে একটি মডেল সংরক্ষণ এবং লোড

এই নির্দেশিকাটি পড়ার জন্য যদি আপনার কাছে মাত্র 10 সেকেন্ড সময় থাকে তবে আপনার যা জানা দরকার তা এখানে।

একটি কেরাস মডেল সংরক্ষণ করা হচ্ছে:

model = ...  # Get model (Sequential, Functional Model, or Model subclass)
model.save('path/to/location')

মডেলটি আবার লোড হচ্ছে:

from tensorflow import keras
model = keras.models.load_model('path/to/location')

এখন, বিস্তারিত দেখুন.

সেটআপ

import numpy as np
import tensorflow as tf
from tensorflow import keras

সম্পূর্ণ মডেল সংরক্ষণ এবং লোড হচ্ছে

আপনি একটি একক আর্টিফ্যাক্টে একটি সম্পূর্ণ মডেল সংরক্ষণ করতে পারেন। এটি অন্তর্ভুক্ত করবে:

  • মডেলের আর্কিটেকচার/কনফিগারেশন
  • মডেলের ওজন মান (যা প্রশিক্ষণের সময় শেখা হয়েছিল)
  • মডেলের সংকলন তথ্য (যদি compile() বলা হতো)
  • অপ্টিমাইজার এবং তার অবস্থা, যদি থাকে (এটি আপনাকে প্রশিক্ষণ পুনরায় শুরু করতে সক্ষম করে যেখানে আপনি ছেড়েছিলেন)

এপিআই

TensorFlow SavedModel ফরম্যাট, এবং বয়স্ক Keras H5 বিন্যাস: দুটি ফরম্যাটের আপনি ডিস্কে একটি সম্পূর্ণ মডেল সংরক্ষণ করতে ব্যবহার করতে পারেন। প্রস্তাবিত বিন্যাস হল SavedModel. যখন আপনি ব্যবহার এটা ডিফল্ট model.save()

আপনি এর মাধ্যমে H5 ফর্ম্যাটে স্যুইচ করতে পারেন:

  • পাসিং save_format='h5' থেকে save()
  • একটি ফাইল পাশ প্রান্ত যে .h5 বা .keras করার save()

সংরক্ষিত মডেল বিন্যাস

SavedModel হল আরও ব্যাপক সেভ ফরম্যাট যা মডেল আর্কিটেকচার, ওজন এবং কল ফাংশনের ট্রেস করা টেনসরফ্লো সাবগ্রাফ সংরক্ষণ করে। এটি কেরাসকে বিল্ট-ইন স্তরের পাশাপাশি কাস্টম অবজেক্ট উভয়ই পুনরুদ্ধার করতে সক্ষম করে।

উদাহরণ:

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 ধারণ করে কি

কলিং model.save('my_model') নামে একটি ফোল্ডার তৈরি করে my_model নিম্নলিখিত ধারণকারী:

ls my_model
assets  keras_metadata.pb  saved_model.pb  variables

মডেল স্থাপত্য, এবং প্রশিক্ষণ কনফিগারেশন (অপটিমাইজার, লোকসান, এবং মেট্রিকস সহ) সংরক্ষণ করা হয় saved_model.pb । ওজন সংরক্ষিত হয় variables/ ডিরেক্টরি।

SavedModel বিন্যাস বিস্তারিত তথ্যের জন্য, দেখুন SavedModel গাইড (ডিস্কে SavedModel ফরম্যাট)

কিভাবে SavedModel কাস্টম অবজেক্ট পরিচালনা করে

যখন মডেল এবং তার স্তর SavedModel বিন্যাস দোকানে বর্গ নাম, কল ফাংশন, লোকসান, এবং ওজন সংরক্ষণ (এবং কনফিগ, যদি বাস্তবায়িত)। কল ফাংশন মডেল/স্তরের গণনা গ্রাফ সংজ্ঞায়িত করে।

মডেল/লেয়ার কনফিগারেশনের অনুপস্থিতিতে, কল ফাংশনটি এমন একটি মডেল তৈরি করতে ব্যবহৃত হয় যা আসল মডেলের মতো বিদ্যমান যা প্রশিক্ষণ, মূল্যায়ন এবং অনুমানের জন্য ব্যবহার করা যেতে পারে।

তা সত্ত্বেও, এটা সবসময় সংজ্ঞায়িত করতে একটি ভাল অনুশীলন get_config এবং from_config যখন একটি কাস্টম মডেল বা স্তর বর্গ লেখার পদ্ধতি। এটি আপনাকে প্রয়োজনে পরে সহজেই গণনা আপডেট করতে দেয়। সম্পর্কে বিভাগটি দেখুন কাস্টম বস্তু আরও তথ্যের জন্য।

উদাহরণ:

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>

প্রথমবার লোড মডেল কনফিগ এবং ব্যবহার লোড হয় CustomModel বর্গ। দ্বিতীয় মডেলটি গতিশীলভাবে মডেল ক্লাস তৈরি করে লোড করা হয় যা আসল মডেলের মতো কাজ করে।

সংরক্ষিত মডেল কনফিগার করা হচ্ছে

নিউ TensoFlow 2.4 মধ্যে যুক্তি save_traces যোগ করা হয়েছে model.save , যা আপনি টগল SavedModel ফাংশন হদিশ করতে পারবেন। কার্যাবলী মূল শ্রেণী definitons ছাড়া পুনরায় লোড কাস্টম বস্তু Keras করার অনুমতি সংরক্ষিত হয়, তাই যখন save_traces=False , সব কাস্টম বস্তু সংজ্ঞায়িত নিশ্চয়ই get_config / from_config পদ্ধতি। যখন লোড, কাস্টম বস্তু প্রেরণ করা আবশ্যক custom_objects যুক্তি। save_traces=False ডিস্ক SavedModel এবং সংরক্ষণ সময় ব্যবহৃত স্থান হ্রাস করা হয়।

Keras H5 বিন্যাস

Keras এছাড়াও মডেলের স্থাপত্য, ওজন ভ্যালু ও সমন্বিত একটি একক HDF5 ফাইলটি সংরক্ষণ সমর্থন compile() তথ্য। এটি SavedModel-এর একটি হালকা-ওজন বিকল্প।

উদাহরণ:

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>

সীমাবদ্ধতা

SavedModel বিন্যাসের তুলনায়, দুটি জিনিস রয়েছে যা H5 ফাইলে অন্তর্ভুক্ত করা হয় না:

  • এক্সটার্নাল লোকসান & মেট্রিক্স মাধ্যমে যোগ model.add_loss() & model.add_metric() (SavedModel অসদৃশ) সংরক্ষিত হয় না। যদি আপনার মডেলে এই ধরনের ক্ষতি এবং মেট্রিক্স থাকে এবং আপনি প্রশিক্ষণ পুনরায় শুরু করতে চান, তাহলে মডেলটি লোড করার পরে আপনাকে এই ক্ষতিগুলি আবার যোগ করতে হবে। লক্ষ্য করুন এর মাধ্যমে স্তর ভিতরে তৈরি লোকসান / মেট্রিক্স প্রযোজ্য নয় self.add_loss() & self.add_metric() । যতদিন স্তর লোড পরার হিসাবে, এই ক্ষতি ও বৈশিষ্ট্যের মান রাখা হয়, যেহেতু তারা অংশ call স্তর পদ্ধতি।
  • কাস্টম এর গণনার গ্রাফ যেমন বস্তু হিসেবে কাস্টম স্তর সংরক্ষিত ফাইলে অন্তর্ভুক্ত করা হয় না। লোড করার সময়, মডেলটিকে পুনর্গঠন করার জন্য কেরাসের এই বস্তুর পাইথন ক্লাস/ফাংশনগুলিতে অ্যাক্সেসের প্রয়োজন হবে। দেখুন কাস্টম বস্তু

স্থাপত্য সংরক্ষণ

মডেলের কনফিগারেশন (বা আর্কিটেকচার) মডেলটিতে কোন স্তর রয়েছে এবং এই স্তরগুলি কীভাবে সংযুক্ত করা হয়েছে তা নির্দিষ্ট করে। যদি আপনার কাছে একটি মডেলের কনফিগারেশন থাকে, তাহলে মডেলটিকে ওজনের জন্য একটি নতুন আরম্ভ করা অবস্থায় তৈরি করা যেতে পারে এবং কোনো সংকলন তথ্য নেই।

*মনে রাখবেন যে এটি শুধুমাত্র কার্যকরী বা অনুক্রমিক apis ব্যবহার করে সংজ্ঞায়িত মডেলগুলির ক্ষেত্রে প্রযোজ্য নয় উপশ্রেণীর মডেলগুলি।

একটি অনুক্রমিক মডেল বা কার্যকরী API মডেলের কনফিগারেশন

এই ধরণের মডেলগুলি স্তরগুলির সুস্পষ্ট গ্রাফ: তাদের কনফিগারেশন সর্বদা একটি কাঠামোগত আকারে উপলব্ধ।

এপিআই

get_config() এবং from_config()

কলিং config = model.get_config() মডেল কনফিগারেশন সম্বলিত একটি পাইথন অভি ফিরে আসবে। একই মডেল তারপর মাধ্যমে পুনর্নির্মিত করা যেতে পারে Sequential.from_config(config) (ক জন্য Sequential মডেল) বা Model.from_config(config) (ক ক্রিয়াগত এপিআই মডেল জন্য)।

একই ওয়ার্কফ্লো যেকোনো সিরিয়ালাইজেবল লেয়ারের জন্যও কাজ করে।

স্তর উদাহরণ:

layer = keras.layers.Dense(3, activation="relu")
layer_config = layer.get_config()
new_layer = keras.layers.Dense.from_config(layer_config)

অনুক্রমিক মডেল উদাহরণ:

model = keras.Sequential([keras.Input((32,)), keras.layers.Dense(1)])
config = model.get_config()
new_model = keras.Sequential.from_config(config)

কার্যকরী মডেল উদাহরণ:

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() এবং tf.keras.models.model_from_json()

এই অনুরূপ get_config / from_config ছাড়া এটি একটি JSON স্ট্রিংকে, যা মূল মডেল বর্গ ছাড়া লোড করা যাবে মধ্যে মডেল সক্রিয়। এটি মডেলগুলির জন্যও নির্দিষ্ট, এটি স্তরগুলির জন্য নয়৷

উদাহরণ:

model = keras.Sequential([keras.Input((32,)), keras.layers.Dense(1)])
json_config = model.to_json()
new_model = keras.models.model_from_json(json_config)

কাস্টম অবজেক্ট

মডেল এবং স্তর

Subclassed মডেল এবং স্তর স্থাপত্য পদ্ধতিতে সংজ্ঞায়িত করা হয় __init__ এবং call । তারা পাইথন বাইটকোড, যা একটি JSON- সামঞ্জস্যপূর্ণ কনফিগ মধ্যে ধারাবাহিকভাবে করা যাবে না বলে মনে করা হয় - আপনি বাইটকোড serializing চেষ্টা করে দেখতে পারেন (যেমন মাধ্যমে pickle ), কিন্তু এটি সম্পূর্ণ অনিরাপদ এবং আপনার মডেল একটি ভিন্ন সিস্টেমে লোড করা যাবে না মানে।

অর্ডার রক্ষা / কাস্টম সংজ্ঞায়িত স্তর সঙ্গে একটি মডেল, অথবা একটি subclassed মডেল লোড জন্য, আপনাকে ওভাররাইট উচিত get_config এবং ঐচ্ছিকরূপে from_config পদ্ধতি। অতিরিক্তভাবে, আপনার কাস্টম অবজেক্ট রেজিস্টার ব্যবহার করা উচিত যাতে কেরাস এটি সম্পর্কে সচেতন হয়।

কাস্টম ফাংশন

কাস্টম সংজ্ঞায়িত ফাংশন (যেমন অ্যাক্টিভেশন ক্ষতি বা আরম্ভের) একটি প্রয়োজন হবে না get_config পদ্ধতি। ফাংশনের নামটি লোড করার জন্য যথেষ্ট যতক্ষণ এটি একটি কাস্টম অবজেক্ট হিসাবে নিবন্ধিত থাকে৷

শুধুমাত্র TensorFlow গ্রাফ লোড করা হচ্ছে

কেরাস দ্বারা উত্পন্ন টেনসরফ্লো গ্রাফ লোড করা সম্ভব। যদি আপনি তা করেন, আপনি যে কোনো প্রদান করতে হবে না custom_objects । আপনি এই মত এটি করতে পারেন:

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

মনে রাখবেন যে এই পদ্ধতির বেশ কয়েকটি ত্রুটি রয়েছে:

  • ট্রেসেবিলিটি কারণে, আপনার সর্বদা ব্যবহার করা কাস্টম অবজেক্টগুলিতে অ্যাক্সেস থাকা উচিত। আপনি এমন একটি মডেল তৈরি করতে চান না যা আপনি পুনরায় তৈরি করতে পারবেন না।
  • বস্তু দ্বারা ফিরে tf.saved_model.load একটি Keras মডেল নয়। তাই এটি ব্যবহার করা সহজ নয়। উদাহরণস্বরূপ, যদি আপনি অ্যাক্সেস থাকবে না .predict() বা .fit()

এমনকি যদি তার ব্যবহার নিরুৎসাহিত করা হয়, এটা যদি আপনি উদাহরণস্বরূপ একটা সংকুচিত স্পট মধ্যে আছেন, সাহায্য করতে পারেন, যদি আপনি আপনার কাস্টম বস্তুর কোড হারিয়ে অথবা সঙ্গে মডেল লোড বিষয় আছে tf.keras.models.load_model()

আপনি আরো বিস্তারিত জানতে পারেন সম্পর্কে পৃষ্ঠা tf.saved_model.load

কনফিগার পদ্ধতি সংজ্ঞায়িত করা

স্পেসিফিকেশন:

  • get_config অনুক্রমে একটি JSON- serializable অভিধান আসতে architecture- এবং মডেল সংরক্ষণ API গুলি Keras সঙ্গে সামঞ্জস্যপূর্ণ হতে হবে।
  • from_config(config) ( classmethod ) যে কনফিগ থেকে তৈরি করা হয় একটি নতুন লেয়ার বা মডেল বস্তুর ফেরত পাঠাবেন। ডিফল্ট বাস্তবায়ন আয় cls(**config)

উদাহরণ:

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}
)

কাস্টম অবজেক্ট নিবন্ধন

কেরাস কোন ক্লাস কনফিগার তৈরি করেছে তার একটি নোট রাখে। উপরোক্ত উদাহরণে থেকে, tf.keras.layers.serialize কাস্টম স্তর একটি ধারাবাহিকভাবে ফর্ম উত্পন্ন:

{'class_name': 'CustomLayer', 'config': {'a': 2} }

Keras ওস্তাদ তালিকা রাখে সব বিল্ট-ইন স্তর, মডেল, অপটিমাইজার এবং মেট্রিক ক্লাস, যা কলে সঠিক বর্গ এটি ব্যবহার করা হয় from_config । বর্গ পাওয়া যাবে না, তাহলে একটি ত্রুটি উত্থাপিত হয় ( Value Error: Unknown layer )। এই তালিকায় কাস্টম ক্লাস নিবন্ধন করার কয়েকটি উপায় রয়েছে:

  1. সেট custom_objects লোড ফাংশনে যুক্তি। ("কনফিগার পদ্ধতি সংজ্ঞায়িত করা" উপরের বিভাগে উদাহরণ দেখুন)
  2. tf.keras.utils.custom_object_scope বা tf.keras.utils.CustomObjectScope
  3. tf.keras.utils.register_keras_serializable

কাস্টম স্তর এবং ফাংশন উদাহরণ

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)

ইন-মেমরি মডেল ক্লোনিং

এছাড়াও আপনি এর মাধ্যমে একটি মডেল ইন-মেমোরি ক্লোনিং করতে পারি না tf.keras.models.clone_model() । এটি কনফিগারেশন পাওয়ার সমতুল্য তারপর তার কনফিগারেশন থেকে মডেলটি পুনরায় তৈরি করা (তাই এটি সংকলন তথ্য বা স্তর ওজনের মান সংরক্ষণ করে না)।

উদাহরণ:

with keras.utils.custom_object_scope(custom_objects):
    new_model = keras.models.clone_model(model)

শুধুমাত্র মডেলের ওজনের মান সংরক্ষণ এবং লোড করা হচ্ছে

আপনি শুধুমাত্র একটি মডেলের ওজন সংরক্ষণ এবং লোড করতে বেছে নিতে পারেন। এটি দরকারী হতে পারে যদি:

  • অনুমানের জন্য আপনার শুধুমাত্র মডেল প্রয়োজন: এই ক্ষেত্রে আপনাকে প্রশিক্ষণ পুনরায় আরম্ভ করতে হবে না, তাই আপনার সংকলন তথ্য বা অপ্টিমাইজার অবস্থার প্রয়োজন নেই।
  • আপনি ট্রান্সফার লার্নিং করছেন: এই ক্ষেত্রে আপনি একটি নতুন মডেলকে প্রশিক্ষণ দেবেন যা পূর্বের মডেলের অবস্থা পুনঃব্যবহার করে, তাই আপনার পূর্বের মডেলের সংকলন তথ্যের প্রয়োজন নেই।

ইন-মেমরি ওজন স্থানান্তর জন্য APIs

ওজন ব্যবহার করে বিভিন্ন বস্তুর মধ্যে অনুলিপি করা যায় get_weights এবং set_weights :

নীচের উদাহরণ.

মেমরিতে এক স্তর থেকে অন্য স্তরে ওজন স্থানান্তর করা

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())

মেমরিতে একটি সামঞ্জস্যপূর্ণ আর্কিটেকচার সহ এক মডেল থেকে অন্য মডেলে ওজন স্থানান্তর করা

# 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())

রাষ্ট্রহীন স্তরের ক্ষেত্রে

যেহেতু স্টেটলেস লেয়ারগুলি ওজনের ক্রম বা সংখ্যা পরিবর্তন করে না, তাই অতিরিক্ত/অনুপস্থিত স্টেটলেস লেয়ার থাকলেও মডেলগুলিতে সামঞ্জস্যপূর্ণ আর্কিটেকচার থাকতে পারে।

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())

ডিস্কে ওজন সংরক্ষণ এবং সেগুলি আবার লোড করার জন্য API

ওজন কল করে ডিস্কে সংরক্ষণ করা যাবে model.save_weights নিম্নলিখিত বিন্যাসে:

  • টেনসরফ্লো চেকপয়েন্ট
  • HDF5

ডিফল্ট বিন্যাস model.save_weights TensorFlow চেকপয়েন্ট হয়। সংরক্ষণ বিন্যাস নির্দিষ্ট করার দুটি উপায় আছে:

  1. save_format যুক্তি: সেট মান save_format="tf" বা save_format="h5"
  2. path যুক্তি: যদি সঙ্গে পাথ প্রান্ত .h5 বা .hdf5 , তারপর HDF5 বিন্যাস ব্যবহার করা হয়। অন্যান্য প্রত্যয় একটি TensorFlow চেকপয়েন্ট পরিণাম ডেকে আনবে যদি না save_format সেট করা হয়।

ইন-মেমরি নম্পি অ্যারে হিসাবে ওজন পুনরুদ্ধার করার একটি বিকল্পও রয়েছে। প্রতিটি API এর সুবিধা এবং অসুবিধা রয়েছে যা নীচে বিশদ বিবরণ দেওয়া হয়েছে।

TF চেকপয়েন্ট বিন্যাস

উদাহরণ:

# 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>

বিন্যাস বিবরণ

টেনসরফ্লো চেকপয়েন্ট ফরম্যাট অবজেক্ট অ্যাট্রিবিউটের নাম ব্যবহার করে ওজন সংরক্ষণ ও পুনরুদ্ধার করে। উদাহরণস্বরূপ, বিবেচনা tf.keras.layers.Dense স্তর। : লেয়ার দুটি ওজন ধারণ dense.kernel এবং dense.bias । লেয়ার এ সংরক্ষিত থাকে, তখন tf ফরম্যাট, ফলে চেকপয়েন্ট কী রয়েছে "kernel" এবং "bias" এবং তাদের সংশ্লিষ্ট ওজন মান। আরও তথ্যের জন্য দেখুন "লোড হচ্ছে বলবিজ্ঞান" মেমরি চেকপয়েন্ট গাইডে

উল্লেখ্য পরে নাম পিতা বা মাতা বস্তু, না পরিবর্তনশীল নামে ব্যবহৃত অ্যাট্রিবিউট / গ্রাফ প্রান্ত নামকরণ করা হয়। বিবেচনা করুন CustomLayer নীচে দেওয়া উদাহরণে। পরিবর্তনশীল CustomLayer.var সংরক্ষিত আছে "var" কী অংশ হিসেবে না "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}

ট্রান্সফার শেখার উদাহরণ

মূলত, যতক্ষণ না দুটি মডেলের একই আর্কিটেকচার থাকে, ততক্ষণ তারা একই চেকপয়েন্ট ভাগ করতে সক্ষম হয়।

উদাহরণ:

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>

সাধারণত মডেল তৈরির জন্য একই API এ লেগে থাকার পরামর্শ দেওয়া হয়। আপনি যদি অনুক্রমিক এবং কার্যকরী, বা কার্যকরী এবং উপশ্রেণি ইত্যাদির মধ্যে স্যুইচ করেন, তাহলে সর্বদা প্রাক-প্রশিক্ষিত মডেলটি পুনর্নির্মাণ করুন এবং সেই মডেলে প্রাক-প্রশিক্ষিত ওজন লোড করুন।

পরবর্তী প্রশ্ন হল, মডেলের আর্কিটেকচারগুলি সম্পূর্ণ ভিন্ন হলে কীভাবে ওজনগুলি বিভিন্ন মডেলে সংরক্ষণ এবং লোড করা যায়? সমাধান ব্যবহার করা tf.train.Checkpoint সংরক্ষণ করুন এবং সঠিক স্তর / ভেরিয়েবল পুনঃস্থাপন।

উদাহরণ:

# 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 বিন্যাস

HDF5 বিন্যাসে স্তরের নাম অনুসারে গোষ্ঠীবদ্ধ ওজন রয়েছে। ওজন তালিকা অ trainable ওজন (হিসাবে একই তালিকায় trainable ওজন তালিকা concatenating দ্বারা আদেশ হয় layer.weights )। এইভাবে, একটি মডেল একটি hdf5 চেকপয়েন্ট ব্যবহার করতে পারে যদি এটির চেকপয়েন্টে সংরক্ষিত একই স্তর এবং প্রশিক্ষণযোগ্য স্থিতি থাকে।

উদাহরণ:

# 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")

লক্ষ্য করুন পরিবর্তন layer.trainable একটি ভিন্ন হতে পারে layer.weights ক্রম যখন মডেল নেস্টেড স্তর রয়েছে।

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

ট্রান্সফার শেখার উদাহরণ

HDF5 থেকে পূর্ব-প্রশিক্ষিত ওজন লোড করার সময়, মূল চেকপয়েন্টেড মডেলে ওজন লোড করার পরামর্শ দেওয়া হয় এবং তারপরে পছন্দসই ওজন/স্তরগুলিকে একটি নতুন মডেলে বের করার পরামর্শ দেওয়া হয়।

উদাহরণ:

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
_________________________________________________________________