Meezo ML نشر 21 يوليو 2021 أرسل تقرير نشر 21 يوليو 2021 أقوم ببناء نموذج للتوقع لكن الدقة تكون سيئة جداً عندما استخدم أحد توابع التنشيط مثل sigmoid أو tanh، لكن عندما استخدم تابع التنشيط relu يعطي نتيجة جيدة؟ أريد تفسير؟ اقتباس
2 Ali Haidar Ahmad نشر 22 يوليو 2021 أرسل تقرير نشر 22 يوليو 2021 هذا خطأ شائع يقع فيه المبتدئين، وهو استخدام توابع التنشيط في آخر طبقة من طبقات نماذج التوقع، يجب أن تتذكر دوماً أن مسائل التوقع Regression تكون فيها قيم الخرج قيم مستمرة أي قيم غير محدودة بمجال معين أي ليست كما في ال classifications حيث يكون فيها الخرج قيم متقطعة أي قيم معينة. لذلك لايجب استخدام أحد توابع التنشيط معها ولاسيما توابع التنشيط اللوجستية مثل التابع السيني sigmoid أو حتى tanh. لأن هذين التابعين خرجهما يكون بين ال 0 وال 1 (بالنسبة للسيني) و من 1 لل -1 (بالنسبة لل tanh). وبالتالي إذا استخدمت أحدهما في آخر طبقة سيكون خرج نموذجك قيماً محصورة بمجال محدد وهذا خاطئ لأنه في أي مهمة توقع ولتكن مهمة توقع أسعار المنازل مثلاً، يجب أن يكون الخرج قيماً تنتمي إلى مجال غير محدود (قيم مستمرة) أما إذا استخدمت التابع السيني مثلاً سيكون خرج النموذج من أجل أي عينة قيمة محصورة بالمجال من 0 ل 1 والقيمة الحقيقية قد تكون 100 أو 50 أو 77 أو أو.. وبالتالي سيكون مقدار الخطأ في التوقع كبير جداً. لذا يجب ضبط تابع التنشيط في آخر طبقة على None دوماً. حسناً أنت تتساءل لماذا تابع ال relu يعطيك نتائج جيدة، وهذا صحيح فبالفعل قد يعطيك نتائج جيدة وفي بعض الأحيان قد يعطيك نتائج أفضل من عدم استخدام تابع تنشيط أي None كالمثال التالي، حيث سنستخدم relu والخطأ المطلق mae=2.2152: from keras.datasets import boston_housing (train_data, train_targets), (test_data, test_targets) =boston_housing.load_data() mean = train_data.mean(axis=0) train_data -= mean std = train_data.std(axis=0) train_data /= std test_data -= mean test_data /= std from keras import models from keras import layers model = models.Sequential() model.add(layers.Dense(64, activation='relu', input_shape=(train_data.shape[1],))) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(1, activation='relu')) model.compile(optimizer='rmsprop', loss='mse', metrics=['mae']) history = model.fit(train_data, train_targets,epochs=7, batch_size=1, verbose=1) ------------------------------------------------- Epoch 1/7 404/404 [==============================] - 1s 967us/step - loss: 338.1444 - mae: 15.1877 Epoch 2/7 404/404 [==============================] - 0s 1ms/step - loss: 21.6941 - mae: 3.1332 Epoch 3/7 404/404 [==============================] - 0s 1ms/step - loss: 17.6999 - mae: 2.8479 Epoch 4/7 404/404 [==============================] - 0s 947us/step - loss: 13.1258 - mae: 2.4018 Epoch 5/7 404/404 [==============================] - 0s 970us/step - loss: 15.7603 - mae: 2.6360 Epoch 6/7 404/404 [==============================] - 0s 1ms/step - loss: 12.1877 - mae: 2.3640 Epoch 7/7 404/404 [==============================] - 0s 965us/step - loss: 9.7259 - mae: 2.2152 أما بدونه mae: 2.3221: from keras.datasets import boston_housing (train_data, train_targets), (test_data, test_targets) =boston_housing.load_data() mean = train_data.mean(axis=0) train_data -= mean std = train_data.std(axis=0) train_data /= std test_data -= mean test_data /= std from keras import models from keras import layers model = models.Sequential() model.add(layers.Dense(64, activation='relu', input_shape=(train_data.shape[1],))) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(1, activation=None)) model.compile(optimizer='rmsprop', loss='mse', metrics=['mae']) history = model.fit(train_data, train_targets,epochs=7, batch_size=1, verbose=1) ----------------------------------------------- Epoch 1/7 404/404 [==============================] - 1s 1ms/step - loss: 280.0789 - mae: 13.5154 Epoch 2/7 404/404 [==============================] - 0s 1ms/step - loss: 19.4468 - mae: 3.0621 Epoch 3/7 404/404 [==============================] - 0s 1ms/step - loss: 17.4921 - mae: 2.9243 Epoch 4/7 404/404 [==============================] - 0s 1ms/step - loss: 14.3356 - mae: 2.6068 Epoch 5/7 404/404 [==============================] - 0s 1ms/step - loss: 12.1125 - mae: 2.4581 Epoch 6/7 404/404 [==============================] - 0s 952us/step - loss: 16.5646 - mae: 2.5852 Epoch 7/7 404/404 [==============================] - 0s 1ms/step - loss: 12.4237 - mae: 2.3221 حسناً كما تلاحظ فإن النتيجة أفضل مع relu، والسبب في أن التابع relu هو تابع خطي خرجه من الشكل: max(x, 0) بحيث من أجل دخل x>0 سيكون خرجه هو x نفسها (أي لاتغيير أي كأننا لم نستخدم تابع تنشيط أي None ) ومن أجل دخل أصغر من الصفر يكون الخرج 0، هذا يعني أنه يسلك سلوك None من أجل الجزء الموجب وكما نعلم فإن أسعار المنازل هي دوماً موجبة وبالتالي استخدام relu سيكون مكافئاً ل None ولكن أفضل لأنه في حالة توقع النموذج قيمة سالبة للنموذج سوف يقصرها على 0 أي إذا توقع -5 سوف يجعلها 0 بسبب تابع ال relu ولهذا السبب كان استخدامه يعطي نتيجة أفضل، لكن هذا لايعني أن استخدامه صحيح وخصوصاً إذا كانت القيم السالبة ضمن مجال التوقع، وأيضاً استخدامه قد يضلل نموذجك قليلاً في الوصول للقيم الصغرى الشاملة لذا أنا أفضل عدم استخدامه. 2 اقتباس
السؤال
Meezo ML
أقوم ببناء نموذج للتوقع لكن الدقة تكون سيئة جداً عندما استخدم أحد توابع التنشيط مثل sigmoid أو tanh، لكن عندما استخدم تابع التنشيط relu يعطي نتيجة جيدة؟ أريد تفسير؟
1 جواب على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.