علاقة غير خطية لحل مشكلة XOR

تشرح هذه المقالة استخدام الشبكات العصبية غير الخطية لحل مشكلة XOR ، وطريقة تهيئة المعلمة ، وسبب استخدام CrossEntropy بدلاً من MSE في مشاكل التصنيف.


أولاً ، الحل الطبيعي لعلاقة XOR

استيراد numpy كـ np

استيراد matplotlib.pyplot كـ PLT

x_data = np.array ([[1،0،0] ،

               [1،0،1] ،

               [1،1،0] ،

               [1،1،1]])

y_data = np.array ([[0]،

               [1] ،

               [1] ،

               [0]])

# تهيئة الوزن ، نطاق القيمة هو -1 ~ 1

v = (np.random.random ([3،4]) - 0.5) * 2

w = (np.random.random ([4،1]) - 0.5) * 2

lr = 0.11

def السيني (x):

    إرجاع 1 / (1 + np.exp (-x))

def d_sigmoid (x):

    إرجاع x * (1-x)

تحديث def ():

    x_data العالمية ، y_data ، w ، v ، lr ، L1 ، L2 ، L2_new

    L1 = السيني (np.dot (x_data ، v)) # الناتج 4 * 4 مصفوفة الطبقة المخفية

    L2 = السيني (np.dot (L1، w)) # الإخراج الفعلي للطبقة الناتجة 4 * 1

    # احسب خطأ طبقة الإخراج والطبقة المخفية ، ثم ابحث عن مقدار التحديث

    #

    L2_delta = (L2-y_data) # y_data 4 * 1 مصفوفة

    L1_delta = L2_delta.dot (wT) * d_sigmoid (L1)

    # قم بتحديث الأوزان من طبقة الإدخال إلى الطبقة المخفية والأوزان من الطبقة المخفية إلى طبقة الإخراج

    w_c = lr * L1.T.dot (L2_delta)

    v_c = lr * x_data.T.dot (L1_delta)

    ث = w-w_c

    ت = ت- v_c

L2_new = softmax (L2)

def cross_entropy_error (y، t):

    return -np.sum (t * np.log (y) + (1-t) * np.log (1-y))

def softmax (x):

    exp_x = np.exp (x)

    sum_exp_x = np.sum (exp_x)

    y = exp_x / sum_exp_x

    العودة ذ



إذا __name __ == '__ main__':

    لأني في النطاق (1000):

        update () #Update weights \

        إذا كان i٪ 10 == 0:

            مبعثر plt (i، np.mean (خطأ متقاطع (L2_new، y_data)))

    plt.title ("منحنى الخطأ")

    plt.xlabel ("التكرار")

    plt.ylabel ("خطأ")

    plt.show ()

    طباعة (L2)

    طباعة (cross_entropy_error (L2_new ، y_data))

صورة

دعنا نتحدث عن بيانات الإدخال x أولاً: العمود الأول هو عنصر التحيز مضبوط دائمًا على 1 ، وآخر عمودين هما x1 ، x2 على التوالي. و y هو الناتج المقابل لـ x1 ، x2 ، أي تسمية نتيجة علاقة XOR. lr هو معدل التعلم المحدد. يتم حساب الخسارة عن طريق الانتروبيا المتقاطعة. أخيرًا ، يتم الحصول على نتيجة التنبؤ أسفل الرقم ، وليس من الصعب رؤية أن نتيجة التنبؤ لا تزال قريبة جدًا من الملصق .


2. استخدم علاقة خطية لحل مشكلة XOR

استيراد numpy كـ np

استيراد matplotlib.pyplot كـ PLT


x_data = np.array ([[1،0،0] ،

               [1،0،1] ،

               [1،1،0] ،

               [1،1،1]])

y_data = np.array ([[0]،

               [1] ،

               [1] ،

               [0]])

# تهيئة الوزن ، نطاق القيمة هو -1 ~ 1

v = (np.random.random ([3،4]) - 0.5) * 2

w = (np.random.random ([4،1]) - 0.5) * 2

lr = 0.11

تحديث def ():

    x_data العالمية ، y_data ، w ، v ، lr ، L1 ، L2 ، L2_new

    L1 = np.dot (x_data، v) # مصفوفة الإخراج 4 * 4 للطبقة المخفية

    L2 = np.dot (L1، w) # الناتج الفعلي لطبقة المخرجات 4 * 1

    # احسب خطأ طبقة الإخراج والطبقة المخفية ، ثم ابحث عن مقدار التحديث

    #

    L2_delta = (L2-y_data) # y_data 4 * 1 مصفوفة

    L1_delta = L2_delta.dot (وزن)

    # قم بتحديث الأوزان من طبقة الإدخال إلى الطبقة المخفية والأوزان من الطبقة المخفية إلى طبقة الإخراج

    w_c = lr * L1.T.dot (L2_delta)

    v_c = lr * x_data.T.dot (L1_delta)

    ث = w-w_c

    ت = ت- v_c

    L2_new = softmax (L2)

def cross_entropy_error (y، t):

    return -np.sum (t * np.log (y) + (1-t) * np.log (1-y))

def softmax (x):

    exp_x = np.exp (x)

    sum_exp_x = np.sum (exp_x)

    y = exp_x / sum_exp_x

    العودة ذ

إذا __name __ == '__ main__':

    لأني في النطاق (300):

        update () #update weights

        إذا كان i٪ 10 == 0:

            مبعثر plt (i، np.mean (خطأ متقاطع (L2_new، y_data)))

    plt.title ("منحنى الخطأ")

    plt.xlabel ("التكرار")

    plt.ylabel ("خطأ")

    plt.show ()

    طباعة (L2)

print ("حجم الخطأ النهائي هو:"، cross_entropy_error (L2_new، y_data))

صورة
ليس من الصعب رؤية أن مشكلة XOR لا يمكن حلها باستخدام علاقة خطية .

3. استخدم MSE كدالة خسارة لحل مشكلة XOR

استيراد numpy كـ np

استيراد matplotlib.pyplot كـ PLT

x_data = np.array ([[1،0،0] ،

               [1،0،1] ،

               [1،1،0] ،

               [1،1،1]])

y_data = np.array ([[0]،

               [1] ،

               [1] ،

               [0]])

# تهيئة الوزن ، نطاق القيمة هو -1 ~ 1

v = (np.random.random ([3،4]) - 0.5) * 2

w = (np.random.random ([4،1]) - 0.5) * 2

lr = 0.11

def السيني (x):

    إرجاع 1 / (1 + np.exp (-x))

def d_sigmoid (x):

    إرجاع x * (1-x)

تحديث def ():

    x_data العالمية ، y_data ، w ، v ، lr ، L1 ، L2 ، L2_new

    L1 = السيني (np.dot (x_data ، v)) # الناتج 4 * 4 مصفوفة الطبقة المخفية

    L2 = السيني (np.dot (L1، w)) # الإخراج الفعلي للطبقة الناتجة 4 * 1

    #

    L2_delta = (L2-y_data) * d_sigmoid (L2) # y_data 4 * 1 مصفوفة

    L1_delta = L2_delta.dot (wT) * d_sigmoid (L1)

    # قم بتحديث الأوزان من طبقة الإدخال إلى الطبقة المخفية والأوزان من الطبقة المخفية إلى طبقة الإخراج

    w_c = lr * L1.T.dot (L2_delta)

    v_c = lr * x_data.T.dot (L1_delta)

    ث = w-w_c

    ت = ت- v_c

    L2_new = softmax (L2)

def softmax (x):

    exp_x = np.exp (x)

    sum_exp_x = np.sum (exp_x)

    y = exp_x / sum_exp_x

    العودة ذ

إذا __name __ == '__ main__':

    لأني في النطاق (1000):

        update () #Update weights \

        إذا كان i٪ 10 == 0:

            مبعثر plt (i، np.mean ((y_data-L2) ** 2) / 2)

    plt.title ("منحنى الخطأ")

    plt.xlabel ("التكرار")

    plt.ylabel ("خطأ")

    plt.show ()

    طباعة (L2)

طباعة (np.mean (((y_data-L2) ** 2) / 2))

صورة

ليس من الصعب أن نرى أن استخدام MSE لا يمكن أن يحل مشكلة XOR ، فما السبب؟

من الناحية النظرية ، سيكون من الممكن استخدام دالة الخسارة التربيعية لمشاكل التصنيف أيضًا ، ولكنها غير مناسبة. أولاً ، إن تقليل دالة الخسارة التربيعية إلى أدنى حد يكافئ أساسًا تقدير الاحتمال الأقصى في ظل افتراض أن الخطأ يتبع توزيعًا غاوسيًا ، في حين أن معظم مشاكل التصنيف ليس لها توزيع غاوسي. علاوة على ذلك ، في التطبيقات العملية ، يمكن أن يؤدي الانتروبيا المتقاطعة ، جنبًا إلى جنب مع وظيفة تنشيط Softmax ، إلى زيادة قيمة الخسارة ، وكلما زاد حجم المشتق ، وصغر قيمة الخسارة ، كلما كان المشتق أصغر ، والذي يمكنه تسريع معدل التعلم . ومع ذلك ، إذا تم استخدام دالة الخسارة التربيعية ، فكلما زادت الخسارة ، كان المشتق أصغر ، ويكون معدل التعلم بطيئًا للغاية. انظر إلى الصورة أدناه لترى المشكلة.

صورة

انظر إلى الرسم البياني للنتيجة الأول أعلاه والرسم البياني لنتيجة الفصل الثالث:

صورةصورة

إذا تم استخدام MSE كحساب الخسارة ، إذا كان التدرج صغيرًا جدًا ، فمن المستحيل معرفة ما إذا كان قريبًا من الهدف أو بعيدًا عن الهدف.
باستخدام الانتروبيا المتقاطعة كوظيفة خسارة ، في البداية ، سينخفض ​​الخطأ بشكل كبير. والسبب هو أن المشتق الجزئي لخطأ الانتروبيا المتقاطع إلى المعلمة w كبير جدًا في البداية ، وسيتم تحديث المعلمة بشكل كبير ، لذلك سينخفض ​​الخطأ بشكل أسرع.
يمكن أن ترى خسارة MSE أن الخطأ يتغير بلطف شديد ، مما يؤكد أيضًا خريطة الفضاء ثلاثية الأبعاد أعلاه ، وأن تحويل الخطأ بطيء جدًا.
رابعا ، مشكلة الوزن التهيئة
1. وظيفة عشوائية np
       np . هناك معلمتان أو أكثر. تتبع الأرقام العشوائية الموجودة فيه توزيعًا عاديًا قياسيًا بمتوسط ​​0 وانحراف معياري قدره 1.
       np.random.rand (d0، d1، ...، dn) : وظيفة المعلمة هي نفسها np.random.randn. يتم توزيع الرقم العشوائي بشكل موحد من 0 إلى 1 ، وقيمة العينة العشوائية هي [0 ، 1) ، والتي لا يمكن أن تكون 1.
np . _ الافتراضي هو np.int. إرجاع مصفوفة عدد صحيح عشوائي ، نطاق القيمة [منخفض ، مرتفع) ، ولا يمكن الحصول على عالية. عندما لا يتم ملء قيمة عالية ، يكون نطاق الأرقام العشوائي الافتراضي هو [0 ، منخفض).
2. تهيئة الأوزان
من أجل ضمان الفرق بين المدخلات والمخرجات ، يمكن أن يكون النموذج مستقرًا ويتقارب بسرعة

صورة


من أجل وصف الاختلاف ، فكر في التباين. يمثل كل من D (x) و Var (x) التباين.
معادلة التباين المطبقة على ناتج متغيرين عشوائيين:

صورة

للانتشار الأمامي ، فقط من خلال التأكد من أن تباينات قيم التنشيط لجميع الطبقات متساوية تقريبًا ، يمكن الحفاظ على سلاسة معلومات عينات التدريب التي تمر عبر الشبكة العصبية.
بالنسبة للانتشار العكسي ، تحافظ تدرجات كل طبقة على تباين تقريبي ، والذي يسمح أيضًا للمعلومات بالتدفق بسلاسة في الاتجاه المعاكس لتحديث الأوزان.
من المفترض أن الأوزان والتنشيطات والمخرجات المرجحة ومخرجات الشبكة الأولية والتدرجات مستقلة عن بعضها البعض.
بافتراض أن قيم التنشيط والأوزان موزعة بشكل موحد بمتوسط ​​0 ، فإن المصطلحين الأخيرين لمنتج المتغيرين العشوائيين المذكورين أعلاه هما 0.
من أجل جعل تباين الناتج الموزون z مساويًا تقريبًا لتباين قيم التنشيط في التمرير الأمامي ، يوصى باستخدام وظيفة التنشيط tanh () لأنها تحتوي على tanh (x) ≈ x في الأصل .
بعد ذلك ، ضع في اعتبارك الناتج الموزون للوحدة jth للطبقة Lth:

صورة

من أجل جعل الفرق بين مساحة العينة ومساحة الفئة ليس كبيرًا ، يجب جعل التباين بينهما متساويًا قدر الإمكان ، أي:  صورة

ثم تحتاجصورة

في backpropagation ، نفس الشيء

بحاجة إلىصورة

خذ المتوسط ​​التوافقي لهذين الرقمين:صورة

صورة

(أ ، ب) هو نطاق الأوزان الأولية.

في هذا المثال ، عدد الخلايا العصبية في الطبقة المخفية هو 4 ، لذلك يمكن ضبط نطاق تهيئة الوزن تقريبًا على (-1،1).