عامر ابراهيم نشر 19 سبتمبر 2021 أرسل تقرير نشر 19 سبتمبر 2021 لدي نموذج مدرب قمت بحفظه سابقاً: model.save('my_model.h5') وأريد الآن تحميله لكن أريد استبدال طبقة الدخل فيه (input layer). النموذج بامتداد h5. فهل هذا ممكن؟ 2 اقتباس
1 Ali Haidar Ahmad نشر 19 سبتمبر 2021 أرسل تقرير نشر 19 سبتمبر 2021 نعم ممكن. عندما نقوم بحفظ النموذج من خلال: model.save('my_model.h5') يتم حفظ معماريته (هيكليته) مما يسمح لنا بإنشاء النموذج. ويتم حفظ أوزان النموذج المدربة و ال loss وال optimizer (وحالته أيضاً) مما يمكننا من استكمال التدريب لاحقاً. وبالتالي عند تحميل النموذج: load_model('my_model.h5') يمكننا الحصول على معماريته وأوزانه من خلال: model.summary() # ملخص بطبقات النموذج وأوزانه model.get_weights() # (قيم الأوزان) أوزان النموذج ثم يمكنك القيام بحذف طبقة الدخل من خلال الدالة pop حيث نمرر لها رقم الطبقة المراد حذفها ثم إضافة الطبقة الجديدة التي تريدها: model.layers.pop(0) # حذف الطبقة الأولى # تعريف طبقة الدخل الجديدة وتعديل النموذج Input = Input(batch_shape=(0,300,300,3)) # مثلاً # الخرج الجديد newOutputs = model(Input) newModel = Model(Input, newOutputs) # عرض هيكلية النموذج بعد التعديل newModel.summary() أو كحل ثاني وجدته لك لكنني غير مقتنع تماماً به (سيتجاهل حالة الأوبتيمايزر ودالة التكلفة لذا إن كانت غايتك هي تدريب النموذج من حيث توقف فلن ينجح الأمر. لذا فهذا الحل يصلح معك فقط إن أردت استخدام الأوزان السابقة): يمكنك استخراج تكوين النموذج السابق (هيكليته) ثم تعديله بالشكل الذي تريده في نموذج جديد ثم نسخ الأوزان إليه. مثلاً: # استخراج تكوين النموذج config = model.get_config() # نسخ التكوين input_layer_name = config['layers'][0]['name'] config['layers'][0] = { 'name': 'new_input', 'class_name': 'InputLayer', 'config': { 'batch_input_shape': (None, 300, 300), 'dtype': 'float32', 'sparse': False, 'name': 'new_input' }, 'inbound_nodes': [] } config['layers'][1]['inbound_nodes'] = [[['new_input', 0, 0, {}]]] config['input_layers'] = [['new_input', 0, 0]] # النموذج الجديد model = model.__class__.from_config(model_config, custom_objects={}) # نسخ الأوزان weights = [layer.get_weights() for layer in model.layers[1:]] for layer, weight in zip(new_model.layers[1:], weights): layer.set_weights(weight) اقتباس
1 Ahmed Sharshar نشر 20 سبتمبر 2021 أرسل تقرير نشر 20 سبتمبر 2021 دعنا نشرحها في هيئة خطوات بسيطة: تقوم باستخراج معلومات النموذج الذي تم تحميله: model_config = model.get_config() تبديل الطبقة التي تريد تغييرها: input_layer_name = model_config['layers'][0]['name'] model_config['layers'][0] = { 'name': 'new_input', 'class_name': 'InputLayer', 'config': { 'batch_input_shape': (None, 300, 300), 'dtype': 'float32', 'sparse': False, 'name': 'new_input' }, 'inbound_nodes': [] } model_config['layers'][1]['inbound_nodes'] = [[['new_input', 0, 0, {}]]] model_config['input_layers'] = [['new_input', 0, 0]] ثم تقوم بانشاء النموذج الجديد: new_model = model.__class__.from_config(model_config, custom_objects={}) ثم نسخ الأوزان من النموذج القديم للجديد: # iterate over all the layers that we want to get weights from weights = [layer.get_weights() for layer in model.layers[1:]] for layer, weight in zip(new_model.layers[1:], weights): layer.set_weights(weight) بعد ذلك اضافة الطبقات التي تريد: from kerassurgeon.operations import delete_layer, insert_layer model = delete_layer(model, layer_1) # insert new_layer_1 before layer_2 in a model model = insert_layer(model, layer_2, new_layer_3) الكود التالي يمثل كذلك طريقة مختلفة وسهلة لفعل ما تريد: import keras import numpy as np def get_model(): old_input_shape = (20, 20, 3) model = keras.models.Sequential() model.add(keras.layers.Conv2D(9, (3, 3), padding="same", input_shape=old_input_shape)) model.add(keras.layers.MaxPooling2D((2, 2))) model.add(keras.layers.Flatten()) model.add(keras.layers.Dense(1, activation="sigmoid")) model.compile(loss='binary_crossentropy', optimizer=keras.optimizers.Adam(lr=0.0001), metrics=['acc'], ) model.summary() return model def change_model(model, new_input_shape=(None, 40, 40, 3)): # تغيير شكل الدخل لاول طبقة model._layers[1].batch_input_shape = new_input_shape #استبدال وتعديل الطبقات التي تريد model._layers[2].pool_size = (8, 8) model._layers[2].strides = (8, 8) # اعادة بناء شكل النموذج new_model = keras.models.model_from_json(model.to_json()) new_model.summary() # نسخ الأوزان for layer in new_model.layers: try: layer.set_weights(model.get_layer(name=layer.name).get_weights()) except: print("Could not transfer weights for layer {}".format(layer.name)) # تجربة النموذج الجديد X = np.random.rand(10, 40, 40, 3) y_pred = new_model.predict(X) print(y_pred) return new_model if __name__ == '__main__': model = get_model() new_model = change_model(model) اقتباس
السؤال
عامر ابراهيم
لدي نموذج مدرب قمت بحفظه سابقاً:
وأريد الآن تحميله لكن أريد استبدال طبقة الدخل فيه (input layer). النموذج بامتداد h5. فهل هذا ممكن؟
2 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.