اذهب إلى المحتوى
  • 0

استخدام تابع تكلفة Loss Function غير معرَف custom loss في كيراس Keras 

Chollet ML

السؤال

Recommended Posts

  • 1

يمكن إنشاء دالة خسارة مخصصة عن طريق تعريف الدلة التي تريد استخدامها، بحيث يجب أن تأخذ هذه الدالة القيم الحقيقية والقيم المتوقعة ،وأن تعيد الدالة قيم الكلفة للبيانات الممررة. وأخيراً يكون بعد ذلك بإمكانك تمرير التابع الخاص بك في مرحلة الترجمة compile. ويجب أن تكون حريصاً في النقاط التالية: 
1. تأخذ دالة الخسارة وسيطتين فقط ، وهما القيمة المستهدفة (y_true) والقيمة المتوقعة (y_pred). لأنه من أجل قياس الخطأ في التنبؤ (الخسارة) نحتاج إلى هاتين القيمتين. يتم تمرير هذه الوسائط من النموذج نفسه في وقت ملاءمة البيانات. 2. يجب أن تستفيد دالة الخسارة من قيمة y_pred أثناء حساب الخسارة ، إذا لم تقم بذلك ، فستحصل على خطأ ولن يتم حساب ال Gradients.ا 4.  يكون البعد الأول للوسيطتين y_true و y_pred دائماً هو نفسه حجم الدفعة (حجم الباتش Batch_size). على سبيل المثال، إذا كنت تلائم البيانات بحجم دفعة 64، وكانت شبكتك العصبية تحتوي على 10خلايا إخراج، فستكون أبعاد y_pred  هي (64,10) . لأنه سيكون هناك 64 قيمة كخرج للنموذج، ولكل منها 10 قيم. (64 حجم الباتش ولدينا 10 خلايا في طبقة الخرج، هذا يعني أنه سيكون لدينا في كل مرة 64 عينة نحسب لها 10 نواتج وكل ناتج نقارنه بالقيمة الحقيقية وفق دالة التكلفة). 5. يجب أن تقوم دالة الخسارة دائماً بإرجاع متجه بطول batch_size. لأنه يتعين عليك إرجاع خسارة لكل نقطة بيانات أي لكل عينة.
يمكنك تعريفها بالشكل التالي:

def loss(y_true, y_pred):          
    # نكتب الدالة هنا ولاننسى أن تكون متعلقة بالقيم المتوقعة  
    return loss
# بعدها يمكننا تمريرها للنموذج بالشكل التالي
model.compile(
	loss=custom_loss,
	)

بشكل عام يفضل استخدام keras.backend أثناء بناء دالتك لتحنب حدوث أخطاء (يمكنك استخدام نمباي لامشكلة، لكن يفضل استخدام backend ). في المثال التالي سأقوم ببناء دالة تكلفة وأعطي وزن أيضاً للإخراج. فرضاً لدينا مهمة توقع والخرج هو قيمتين [x1, x2] ونريد إعطاء x2 أهمية أكبر عند حساب التكلفة:

from keras import backend
def custom_mse(y_true, y_pred):
	# حساب مربع الفرق بين القيم الحقيقية والمتوقعة
    loss = backend.square(y_pred - y_true)  # (batch_size, 2)   
    # ضرب النواتج بقيم الأوزان التي نريدها حيث هنا أعطينا أهمية أكبر للمخرج الثاني
    loss = loss * [0.3, 0.7]          # (batch_size, 2)              
    # حساب مجموع الأخطاء
    loss = backend.sum(loss, axis=1)        # (batch_size,)   
    return loss
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 1

هناك الكثير من loss functions المبنية بداخل keras بالفعل، ويمكنك استخدامها بسهولة كالتالي:

model = keras.models.Sequential()

model.add(Dense(100, input_shape=(1,), activation='relu'))
model.add(Dense(50, activation='relu'))
model.add(Dense(10, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam')

أما اذا اردت انشاء دالة خاصة بجد يجب اتباع بعد القواعد لضمان نجاحها ومنها:

  • يجب أن تراعي أن الدالة تاخذ فقط وسيطين فقط وهما القيم المستهدفة y_pred والقيمة الحقيقية وهي y_true وذلك لان الدالة ستقوم بعمل مقارنة بين القيم المتوقعة والقيم الحقيقية.
  • كذلك فان الدالة يجب ان تستخدم y_pred من اجل حساب الخطأ والتي تقوم على اساسه بعمل تعديلات على القيم التي تم تعلمها بالفعل.
  • في النهاية يمكنك تحويلها للشكل model.compile لجعلها اسهل في الاستخدام.
  • لكن: عليك أن تاخذ حذرك من الابعاد، سواء المدخلة او المخرجة وكذلك ابعاد المدخلات في كل طبقة تعلم.
  • كذلك يجب ان تراعي ان الدالة تقوم بارجاع متجة طوله يساوى batch_size.

المثال التالي يوضح الفرق بين الدوال المبنية مسبقا وبين الدالة التي تقوم بصناعتها:

هنا يوضح loss function من النوع الخطي، لاحظ ابعاد المدخلات في كل طبقة تعلم وبين الطبقة النهائية:

model = keras.models.Sequential()

model.add(Dense(50, input_shape=(5,), activation='relu'))
model.add(Dense(20, activation='relu'))
model.add(Dense(10, activation='relu'))

model.add(Dense(2, activation='linear'))

الكود التالي يكافؤ نفس الدالة المستخدمة مسبقا لكن تم كتابتها بشكل يدوي وهي تحقق نفس ما تحققه الدالة الجاهزة تماما، لاحظ كيف استخدمنا نفس الابعاد فيها:

import keras.backend as K

def custom_mse(y_true, y_pred):
 
    # calculating squared difference between target and predicted values 
    loss = K.square(y_pred - y_true)  # (batch_size, 2)
    
    # multiplying the values with weights along batch dimension
    loss = loss * [0.3, 0.7]          # (batch_size, 2)
                
    # summing both loss values along batch dimension 
    loss = K.sum(loss, axis=1)        # (batch_size,)
    
    return loss

لاحظ ان 2 تعبر عن شكل الخرج وهو 2 classes لذلك استخدمناها سواء كقيمة في الدالة المبنية مسبقا او في الدالة التي قمنا ببناءها

تم التعديل في بواسطة Ahmed Sharshar
رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...