![]() | ![]() | ![]() | ![]() |
ভূমিকা
একটি কেরাস মডেলটিতে একাধিক উপাদান রয়েছে:
- আর্কিটেকচার বা কনফিগারেশন যা মডেলটিতে কী স্তর রয়েছে এবং কীভাবে তারা সংযুক্ত রয়েছে তা নির্দিষ্ট করে।
- ওজনের মানগুলির একটি সেট ("মডেলের রাজ্য")।
- একটি অপ্টিমাইজার (মডেল সংকলন দ্বারা সংজ্ঞায়িত)।
- ক্ষতির এবং
add_loss()
একটি সেট (মডেলটি সংকলন করে অথবাadd_loss()
বাadd_metric()
কল করে সংজ্ঞায়িত)।
কেরাস এপিআই এই সমস্ত টুকরোগুলি একবারে ডিস্কে সংরক্ষণ করতে বা এগুলিকে কেবল নির্বাচিতভাবে সংরক্ষণ করতে সক্ষম করে:
- টেনসরফ্লো সেভডমোডেল ফর্ম্যাটে (বা পুরানো কেরাস এইচ 5 ফর্ম্যাটে) একক সংরক্ষণাগারে সমস্ত কিছু সংরক্ষণ করা। এটি স্ট্যান্ডার্ড অনুশীলন।
- কেবলমাত্র 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()
করা হয়) বলা হয়) - অপ্টিমাইজার এবং এর রাজ্য, যদি কোনও হয় (এটি আপনাকে যেখানে রেখেছিল সেখানে প্রশিক্ষণ পুনরায় আরম্ভ করতে সক্ষম করে)
এপিআই
-
model.save()
বাtf.keras.models.save_model()
-
tf.keras.models.load_model()
পুরো মডেলটিকে ডিস্কে সংরক্ষণ করতে আপনি দুটি ফর্ম্যাট ব্যবহার করতে পারেন: টেনসরফ্লো সেভডমোডেল ফর্ম্যাট এবং পুরানো কেরাস এইচ 5 ফর্ম্যাট । প্রস্তাবিত বিন্যাসটি সেভডমডেল। আপনি যখন model.save()
ব্যবহার model.save()
তখন এটি ডিফল্ট।
আপনি এই দ্বারা H5 ফর্ম্যাটে স্যুইচ করতে পারেন:
-
save()
করারsave()
save_format='h5'
পাসsave_format='h5'
। -
save()
করারsave()
.h5
বা.keras
শেষ হয় এমন একটি ফাইল নাম পাস করা।
সেভডমোডেল ফর্ম্যাট
স্যাভডমোডেল হ'ল আরও বিস্তৃত সেভ ফর্ম্যাট যা মডেল আর্কিটেকচার, ওজন এবং কল ফাংশনের ট্রেসড টেনসরফ্লো সাবগ্রাফগুলি সংরক্ষণ করে। এটি কেরাসকে উভয় বিল্ট-ইন স্তরগুলির পাশাপাশি কাস্টম অবজেক্টগুলিকে পুনরুদ্ধার করতে সক্ষম করে।
উদাহরণ:
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.9237 INFO:tensorflow:Assets written to: my_model/assets 4/4 [==============================] - 0s 1ms/step - loss: 0.7730 <tensorflow.python.keras.callbacks.History at 0x7fd0a032a390>
সেভডমডেলে যা থাকে
model.save('my_model')
কল করা নিম্নলিখিতগুলির সাথে my_model
নামে একটি ফোল্ডার তৈরি করে:
ls my_model
assets saved_model.pb variables
মডেল আর্কিটেকচার এবং প্রশিক্ষণ কনফিগারেশন (অপ্টিমাইজার, লোকসান এবং মেট্রিক সহ) saved_model.pb
সংরক্ষণ করা হয়। ওজনগুলি variables/
ডিরেক্টরিতে সংরক্ষণ করা হয়।
সেভডমোডেল ফর্ম্যাট সম্পর্কিত বিশদ তথ্যের জন্য স্যাভডমোডেল গাইড ( ডিস্কে স্যাভডমোডেল ফর্ম্যাট ) দেখুন ।
কীভাবে সেভডমডেল কাস্টম অবজেক্টগুলি পরিচালনা করে
মডেল এবং এর স্তরগুলি সংরক্ষণ করার সময়, সেভডমোডেল ফর্ম্যাটটি শ্রেণীর নাম, কল ফাংশন , ক্ষয় এবং ওজন (এবং প্রয়োগ করা হলে কনফিগারেশন) সঞ্চয় করে। কল ফাংশনটি মডেল / স্তরের গণনা গ্রাফকে সংজ্ঞায়িত করে।
মডেল / লেয়ার কনফিগারটির অনুপস্থিতিতে, কল ফাংশনটি এমন মডেল তৈরি করতে ব্যবহৃত হয় যা বিদ্যমান মডেলের মতো বিদ্যমান যা প্রশিক্ষণ, মূল্যায়ন এবং অনুমানের জন্য ব্যবহার করা যেতে পারে।
তবুও, কাস্টম মডেল বা স্তর শ্রেণীর লেখার সময় 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 0x7fd0a035bcf8> Model Loaded with custom objects: <__main__.CustomModel object at 0x7fd1455d04e0> Model loaded without the custom object class: <tensorflow.python.keras.saving.saved_model.load.CustomModel object at 0x7fd14553af98>
কনফিগার এবং CustomModel
ক্লাসটি ব্যবহার করে প্রথম লোড হওয়া মডেলটি লোড হয়। দ্বিতীয় মডেলটি গতিশীলভাবে মডেল শ্রেণি তৈরি করে লোড করা হয় যা মূল মডেলের মতো কাজ করে।
সেভডমডেল কনফিগার করা হচ্ছে
নিউ TensoFlow 2.4 মধ্যে যুক্তি save_traces
যোগ করা হয়েছে model.save
, যা আপনি টগল SavedModel ফাংশন হদিশ করতে পারবেন। মূল শ্রেণীর সংজ্ঞা ছাড়াই save_traces=False
কাস্টম অবজেক্টগুলি পুনরায় লোড করার অনুমতি দেওয়ার জন্য কার্যগুলি সংরক্ষণ করা হয়, সুতরাং যখন save_traces=False
, সমস্ত কাস্টম অবজেক্ট অবশ্যই get_config
/ from_config
পদ্ধতিতে সংজ্ঞায়িত get_config
উচিত। লোড করার সময়, কাস্টম অবজেক্টগুলি অবশ্যই custom_objects
আর্গুমেন্টে পাস করতে হবে। save_traces=False
সেভডমডেল এবং সময় সাশ্রয় করে ডিস্কের স্থান হ্রাস করে।
কেরাস এইচ 5 ফর্ম্যাট
কেরাস এছাড়াও মডেলটির আর্কিটেকচার, ওজন মান এবং compile()
তথ্য সমন্বিত একটি একক এইচডিএফ 5 ফাইল সংরক্ষণ করতে সহায়তা করে। এটি সেভডমডেলের হালকা ওজনের বিকল্প।
উদাহরণ:
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.0153 4/4 [==============================] - 0s 1ms/step - loss: 0.9104 <tensorflow.python.keras.callbacks.History at 0x7fd1455c66a0>
সীমাবদ্ধতা
সেভডমোডেল বিন্যাসের তুলনায়, দুটি জিনিস রয়েছে যা এইচ 5 ফাইলে অন্তর্ভুক্ত হয় না:
-
model.add_loss()
এবংmodel.add_metric()
এর মাধ্যমে যুক্ত হওয়া বাহ্যিক ক্ষতি এবং মেট্রিকগুলি সংরক্ষণ করা হয়নি (সেভডমডেলের বিপরীতে)। যদি আপনার মডেলটিতে এমন ক্ষয় ও মেট্রিক থাকে এবং আপনি প্রশিক্ষণ পুনরায় শুরু করতে চান, মডেলটি লোড করার পরে আপনাকে এই ক্ষয়গুলি নিজের হাতে ফিরিয়ে আনতে হবে। লক্ষ্য করুন এর মাধ্যমে স্তর ভিতরে তৈরি লোকসান / মেট্রিক্স প্রযোজ্য নয়self.add_loss()
&self.add_metric()
। যতক্ষণ স্তরটি লোড হয়ে যায় ততক্ষণ এই ক্ষতিগুলি এবং মেট্রিকগুলি রাখা হয়, যেহেতু তারা স্তরটিরcall
পদ্ধতির অংশ। - কাস্টম স্তরগুলির মতো কাস্টম অবজেক্টগুলির গণনার গ্রাফ সংরক্ষণ করা ফাইলটিতে অন্তর্ভুক্ত নয়। লোডিংয়ের সময়, কেরাসকে মডেলটি পুনর্গঠন করার জন্য এই বিষয়গুলির পাইথন ক্লাস / ফাংশনে অ্যাক্সেসের প্রয়োজন হবে। কাস্টম অবজেক্ট দেখুন।
আর্কিটেকচার সংরক্ষণ করা
মডেলের কনফিগারেশন (বা আর্কিটেকচার) মডেলটিতে কী স্তর রয়েছে তা এবং এই স্তরগুলি কীভাবে সংযুক্ত রয়েছে তা নির্দিষ্ট করে। আপনার যদি কোনও মডেলের কনফিগারেশন থাকে, তবে ওজন এবং কোনও সংকলনের তথ্য না দিয়ে মডেলটি সতেজ আরম্ভের রাষ্ট্র দিয়ে তৈরি করা যেতে পারে।
* দ্রষ্টব্য এটি কেবলমাত্র কার্যকরী বা সিক্যুয়ালিয়াল এপিআইএস সাবক্ল্যাসড মডেল নয় ব্যবহার করে সংজ্ঞায়িত মডেলগুলিতে প্রযোজ্য।
সিক্যুয়ালিয়াল মডেল বা ক্রিয়ামূলক এপিআই মডেলের কনফিগারেশন
এই ধরণের মডেলগুলি স্তরগুলির স্পষ্ট গ্রাফ হয়: তাদের কনফিগারেশনটি সর্বদা কাঠামোগত আকারে উপলভ্য।
এপিআই
-
get_config()
এবংfrom_config()
-
tf.keras.models.model_to_json()
এবংtf.keras.models.model_from_json()
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)
কাস্টম অবজেক্টস
মডেল এবং স্তর
__init__
মডেল এবং স্তরগুলির আর্কিটেকচারটি __init__
এবং call
পদ্ধতিতে সংজ্ঞায়িত হয়। এগুলিকে পাইথন বাইটকোড হিসাবে বিবেচনা করা হয়, যা জেএসওএন-সামঞ্জস্যপূর্ণ কনফিগারেশনে সিরিয়ালাইজ করা যায় না - আপনি বাইটকোডকে সিরিয়ালাইজ করার চেষ্টা করতে পারেন (যেমন pickle
মাধ্যমে) তবে এটি সম্পূর্ণ অনিরাপদ এবং এর অর্থ আপনার মডেলটি অন্য কোনও সিস্টেমে লোড করা যায় না।
কাস্টম-সংজ্ঞায়িত স্তরগুলি বা একটি get_config
মডেল সহ কোনও মডেল সংরক্ষণ / লোড করার জন্য, আপনাকে get_config
ও বিকল্পভাবে from_config
পদ্ধতিতে ওভাররাইট করা উচিত। অতিরিক্তভাবে, আপনার কাস্টম অবজেক্টটি নিবন্ধভুক্ত করা উচিত যাতে কেরাস এ সম্পর্কে অবগত থাকে।
কাস্টম ফাংশন
কাস্টম-সংজ্ঞায়িত ফাংশন (যেমন অ্যাক্টিভেশন হ্রাস বা প্রারম্ভিককরণ) এর জন্য get_config
পদ্ধতির প্রয়োজন নেই। ফাংশনটির নামটি যতক্ষণ না এটি একটি কাস্টম অবজেক্ট হিসাবে নিবন্ধিত থাকে ততক্ষণ লোড করার জন্য যথেষ্ট।
শুধুমাত্র টেনসরফ্লো গ্রাফ লোড হচ্ছে
কেরাস দ্বারা উত্পাদিত টেনসরফ্লো গ্রাফটি লোড করা সম্ভব। আপনি যদি এটি করেন তবে আপনাকে কোনও 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()
INFO:tensorflow:Assets written to: my_model/assets
মনে রাখবেন যে এই পদ্ধতিতে বেশ কয়েকটি ত্রুটি রয়েছে:
- সন্ধানের কারণে, আপনার ব্যবহৃত কাস্টম অবজেক্টগুলিতে সর্বদা অ্যাক্সেস থাকা উচিত। আপনি এমন একটি মডেল উত্পাদন করতে চান না যা আপনি পুনরায় তৈরি করতে পারবেন না।
-
tf.saved_model.load
বস্তুটি ফিরে এসেছে কোনও কেরাস মডেল নয়। সুতরাং এটি ব্যবহার করা সহজ নয়। উদাহরণস্বরূপ, আপনার কাছে.predict()
বা।.fit()
অ্যাক্সেস থাকবে না
এমনকি যদি এর ব্যবহারকে নিরুৎসাহিত করা হয় তবে আপনি যদি কোনও কঠোর স্থানে থাকেন তবে এটি আপনাকে সহায়তা করতে পারে, উদাহরণস্বরূপ, আপনি যদি নিজের কাস্টম অবজেক্টের কোডটি হারিয়ে ফেলে থাকেন বা tf.keras.models.load_model()
দিয়ে মডেলটি লোড করার ক্ষেত্রে সমস্যা রয়েছে।
আপনি পৃষ্ঠায় আরও জানতে পারেন tf.saved_model.load
সম্পর্কে
কনফিগার পদ্ধতিগুলি সংজ্ঞায়িত করা হচ্ছে
বিশেষ উল্লেখ:
-
get_config
কেরাস আর্কিটেকচার- এবং মডেল-সেভিং এপিআইয়ের সাথে সামঞ্জস্যপূর্ণ হওয়ার জন্য একটি JSON- সিরিয়ালাইজযোগ্যget_config
ফিরিয়ে আনতে হবে। -
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} }
কেরাস সমস্ত বিল্ট-ইন লেয়ার, মডেল, অপ্টিমাইজার এবং মেট্রিক ক্লাসের একটি মাস্টার তালিকা রাখে, যা from_config
কল করার জন্য সঠিক ক্লাসটি সন্ধান করতে ব্যবহৃত হয়। যদি শ্রেণিটি খুঁজে পাওয়া যায় না, তবে একটি ত্রুটি উত্থাপিত হয় ( Value Error: Unknown layer
)। এই তালিকায় কাস্টম ক্লাস নিবন্ধ করার কয়েকটি উপায় রয়েছে:
- লোডিং ফাংশনে
custom_objects
আর্গুমেন্ট সেট করা। ("কনফিগার পদ্ধতিগুলি সংজ্ঞায়িত করা হচ্ছে" উপরের অংশে উদাহরণটি দেখুন) -
tf.keras.utils.custom_object_scope
বাtf.keras.utils.CustomObjectScope
-
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()
মাধ্যমে tf.keras.models.clone_model()
মডেলের মেমরি tf.keras.models.clone_model()
। এটি কনফিগার করার পরে তার কনফিগার থেকে মডেলটি পুনরায় তৈরি করার সমতুল্য (যাতে এটি সংকলনের তথ্য বা স্তর ওজনের মান সংরক্ষণ করে না)।
উদাহরণ:
with keras.utils.custom_object_scope(custom_objects):
new_model = keras.models.clone_model(model)
কেবলমাত্র মডেলের ওজনের মানগুলি সংরক্ষণ এবং লোড করা
আপনি কেবলমাত্র কোনও মডেলের ওজন সংরক্ষণ এবং লোড করতে বেছে নিতে পারেন। এটি কার্যকর হতে পারে যদি:
- আপনার কেবলমাত্র অনুমানের জন্য মডেল প্রয়োজন: এক্ষেত্রে আপনার প্রশিক্ষণ পুনরায় আরম্ভ করার দরকার হবে না, তাই আপনার সংকলনের তথ্য বা অপ্টিমাইজারের অবস্থার প্রয়োজন নেই।
- আপনি স্থানান্তর শেখাচ্ছেন: এক্ষেত্রে আপনি একটি নতুন মডেলকে পূর্বের মডেলটির অবস্থা পুনঃব্যবহার করে প্রশিক্ষণ দেবেন, সুতরাং আপনার পূর্ববর্তী মডেলের সংকলন তথ্যের প্রয়োজন হবে না।
মেমরির ওজন স্থানান্তরের জন্য এপিআই
get_weights
এবং set_weights
ব্যবহার করে ওজন বিভিন্ন বস্তুর মধ্যে অনুলিপি করা যেতে পারে:
-
tf.keras.layers.Layer.get_weights()
: অদ্ভুত অ্যারেগুলির তালিকা ফিরিয়ে দেয়। -
tf.keras.layers.Layer.set_weights()
: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())
ওজনকে ডিস্কে বাঁচাতে এবং এগুলি আবার লোড করার জন্য এপিআইগুলি
নিম্নলিখিত ফর্ম্যাটগুলিতে model.save_weights
কল করে model.save_weights
ডিস্কে সংরক্ষণ করা যায়:
- টেনসরফ্লো চেকপয়েন্ট
- এইচডিএফ 5
model.save_weights
ডিফল্ট ফর্ম্যাটটি model.save_weights
চেকপয়েন্ট। সংরক্ষণের ফর্ম্যাটটি নির্দিষ্ট করার জন্য দুটি উপায় রয়েছে:
-
save_format
আর্গুমেন্ট:save_format="tf"
বাsave_format="h5"
এ মান সেট করুন। -
path
আর্গুমেন্ট: যদি পথটি.h5
বা.hdf5
দিয়ে শেষ হয় তবে HDF5 ফর্ম্যাটটি ব্যবহার করা হবে। অন্যান্য প্রত্যয়গুলিsave_format
সেট না করা হলেsave_format
চেকপয়েন্টে ফলাফল দেয়।
মেমোরি নম্পি অ্যারে হিসাবে ওজন পুনরুদ্ধার করার একটি বিকল্প রয়েছে। প্রতিটি এপিআই এর বিভিন্ন উপকারিতা রয়েছে যা নীচে বিস্তারিত রয়েছে।
টিএফ চেকপয়েন্ট ফর্ম্যাট
উদাহরণ:
# 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 0x7fd0a065f128>
ফর্ম্যাট বিশদ
টেনসরফ্লো চেকপয়েন্ট ফর্ম্যাটটি অবজেক্ট বৈশিষ্ট্যের নাম ব্যবহার করে ওজনগুলি সংরক্ষণ করে এবং পুনরুদ্ধার করে। উদাহরণস্বরূপ, 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 0x7fd144b20b38>
সাধারণত বিল্ডিং মডেলগুলির জন্য একই এপিআইতে লেগে থাকার পরামর্শ দেওয়া হয়। আপনি যদি সিক্যুয়াল এবং ফাংশনাল, বা ফাংশনাল এবং সাবক্ল্যাসড ইত্যাদির মধ্যে স্যুইচ করেন তবে সর্বদা প্রাক-প্রশিক্ষিত মডেলটি পুনর্নির্মাণ করুন এবং সেই মডেলটিতে প্রাক-প্রশিক্ষিত ওজন লোড করুন।
পরবর্তী প্রশ্নটি হল, যদি মডেল আর্কিটেকচারগুলি একেবারে আলাদা হয় তবে কীভাবে ওজনগুলি বিভিন্ন মডেলগুলিতে সংরক্ষণ এবং লোড করা যায়? সমাধানটি হ'ল স্তর / ভেরিয়েবলগুলি সংরক্ষণ এবং পুনরুদ্ধার করার জন্য 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.6/site-packages/tensorflow/python/keras/engine/base_layer.py:2281: 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 0x7fd1455c6cc0>
এইচডিএফ 5 ফর্ম্যাট
এইচডিএফ 5 ফর্ম্যাটে স্তরের নাম দ্বারা গ্রুপযুক্ত ওজন রয়েছে। layer.weights
প্রশিক্ষণযোগ্য layer.weights
প্রশিক্ষণযোগ্য অযোগ্য ওজনের তালিকার ( layer.weights
সমান) সাথে layer.weights
। সুতরাং, কোনও মডেল যদি এইচডিএফ 5 চেকপয়েন্ট ব্যবহার করতে পারে তবে তার যদি চেকপয়েন্টে সংরক্ষণের মতো একই স্তর এবং প্রশিক্ষণযোগ্য স্থিতি থাকে।
উদাহরণ:
# 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
স্থানান্তর শিখন উদাহরণ
এইচডিএফ 5 থেকে পূর্বনির্ধারিত ওজন লোড করার সময়, ওজনকে আসল চেকপয়েন্টেড মডেলটিতে লোড করার পরামর্শ দেওয়া হয় এবং তারপরে কাঙ্ক্ষিত ওজন / স্তরগুলিকে একটি নতুন মডেলের মধ্যে আনতে হবে।
উদাহরণ:
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 _________________________________________________________________