في هذا المنشور أريد أن أتحدث عن الأنماط التي يمكن أن تجدها الشبكات العصبية. تركز العديد من أدلة المبتدئين على أسلوب كتابة التعليمات البرمجية للشبكات العصبية ، في حين أن أسئلة "المنطق" (ما يمكن أن الشبكات العصبية؟ أي بنيات هي الأنسب لأية مهام ولماذا؟) غالبا ما تبقى على الهامش. آمل أن يساعد منشوري المبتدئين على فهم قدرات الشبكات العصبية بشكل أفضل. للقيام بذلك ، سنحاول معرفة كيفية تعاملهم مع بعض المهام النموذجية. سيتم توفير نموذج التعليمات البرمجية في بيثون باستخدام مكتبة keras.
المهمة 1. لنبدأ مع واحد بسيط. نحن نبني شبكة عصبية تقارب الجيب.
import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, np.pi, n) y = np.sin(X) return X, y n = 40 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(6, input_dim=1, activation='relu')) model.add(Dense(4, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mean_squared_error']) model.fit(X, y, epochs=1000, batch_size=4) X_test = np.linspace(start=0, stop=np.pi, num=500) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Sinus approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show()
نحصل على الرسم البياني التالي:

كما ترون ، تعاملت الشبكة العصبية بنجاح مع مهمة تقريب وظيفة بسيطة.
المهمة 2. لنرى كيف ستتعامل الشبكة العصبية مع مهمة أكثر تعقيدًا. سنقوم بإدخال قيم x موزعة بشكل موحد على الفاصل الزمني [0 ، 1] ، وسيتم تعيين y عشوائيًا: بالنسبة إلى x <0.6 ، ستكون y عبارة عن متغير عشوائي يأخذ القيمة 0 باحتمال 0.75 و 1 باحتمال 0.25 (أي ، قيمة عشوائية ذات الحدين مع ع = 0.25). بالنسبة إلى x> 0.6 ، سيكون y متغيرًا عشوائيًا يأخذ القيمة 0 مع الاحتمال 0.3 والقيمة 1 مع الاحتمال 0.7. كدالة محسّنة ، نأخذ الخطأ القياسي.
import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, 1, n) y0 = np.random.binomial(size=n, n=1, p=0.25) y1 = np.random.binomial(size=n, n=1, p=0.7) y = np.where(X < 0.6, y0, y1) return X, y n_inputs = 1 n_hidden1 = 100 n_hidden2 = 50 n_outputs = 1 n = 2000 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(n_hidden1, input_dim=1, activation='relu')) model.add(Dense(n_hidden2, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy']) model.fit(X, y, epochs=200, batch_size=100) X_test = np.linspace(start=0, stop=1, num=100) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Binomial distribution approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show()
نحصل على الرسم البياني التالي لشبكة عصبية دالة تقريبية:

كما ترون ، الشبكة العصبية تقارب التوقع الرياضي لمتغيرنا العشوائي y. لذلك ، يمكن للشبكات العصبية (من حيث المبدأ) تقريب متوسط قيم المتغيرات العشوائية التي تعتمد على المعلمات. على سبيل المثال ، يمكننا أن نتوقع منهم حل المشكلة التالية: الأشخاص الذين يصل دخلهم إلى 1000 دولار هم في المتوسط غير راضين ، والأشخاص الذين يزيد دخلهم عن 1000 دولار في المتوسط سعداء ؛ يجب على المرء أن يتعلم التنبؤ "بمستوى السعادة" حسب الدخل. سوف تكون الشبكة العصبية قادرة على العثور على اعتماد متوسط مستوى السعادة على الدخل ، على الرغم من حقيقة أن الأشخاص الذين لديهم أي مستوى دخل يكونون سعداء وغير سعداء.
المشكلة 3. الآن ننتقل إلى التنبؤ بالتسلسلات. سننظر في تتابعات 0 و 1 المعرّفة في القاعدة التالية: 10 أعضاء تساوي 0 أو 1 ، والحادي عشر تساوي 1 إذا كانت المدة السابقة تساوي 0 ، وتساوي 0 أو 1 إذا كان الحد السابق هو 1. سنقوم بإنشاء تسلسلات طولها 11 (10 إدخال أعضاء التسلسل وواحد ، والأخير ، ونحن نتوقع) وتدريبهم على شبكتنا العصبية المتكررة. وبعد التدريب ، دعونا نتحقق من كيفية تعاملها مع التنبؤ بالتسلسلات الجديدة (الطول 11 أيضًا).
import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense def get_X_y(m, n): X = np.random.binomial(size=(m,n), n=1, p=0.5) y0 = np.ones(m) y1 = np.random.binomial(size=m, n=1, p=0.5) y = np.where(X[:, n-1]==0, y0, y1) X = np.reshape(X, (X.shape[0], X.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=50)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000, 10) model.fit(X_train, y_train, epochs = 20, batch_size = 32) m_test = 12 n_test = 10 X_test, y_test = get_X_y(m_test, n_test) y_predicted = model.predict(X_test) for i in range(m_test): print("x_last=", X_test[i, n_test-1, 0], "y_predicted=", y_predicted[i, 0])
دعونا نرى ما تنبئ به شبكتنا العصبية على التسلسلات المختبرة (ستكون نتائجك مختلفة ، حيث توجد العشوائية هنا في اختيار التسلسلات وفي تدريب الشبكة العصبية).
كما ترون ، إذا كان العضو قبل الأخير من التسلسل هو 0 ، فإن الشبكة العصبية تتنبأ بقيمة قريبة من 1 ، وإذا كانت 1 ، فستكون القيمة قريبة من 0.5. هذا قريب من التوقعات المثلى. مثال مماثل من "الحياة" يمكن أن يبدو كالتالي: "إذا ذهبت إلى السينما اليوم ، فعندئذ سأتناول غدًا في مطعم ؛ إذا كنت ذاهب إلى المسرح اليوم ، فعندئذ سأتناول غدًا في أي مكان ". كما رأينا ، يمكن لشبكة عصبية التقاط أنماط من هذا النوع والتنبؤ برحلة إلى مطعم بالذهاب إلى السينما (والذهاب إلى المسرح للتنبؤ "بشيء ما").
المهمة 4. نحن تعقيد مهمة الشبكة العصبية. اجعل كل شيء كما في المثال السابق ، سيتم تحديد العضو الحادي عشر فقط من التسلسل ، ليس بواسطة السابق ، ولكن بواسطة العضو الثاني في التسلسل (وفقًا لنفس القاعدة). لن نعطي الرمز هنا ، لأنه لا يختلف عملياً عن الكود السابق. أوضحت تجربتي أن الشبكة العصبية لا تزال تجد نمطًا ، لكن لمزيد من الوقت (اضطررت إلى استخدام 100 عصر بدلاً من 20 للتدريب).
وبالتالي ، يمكن للشبكات العصبية (مرة أخرى ، من حيث المبدأ ، التوضيح) التقاط التبعيات طويلة الأجل إلى حد ما (في "مثال حياتنا" ، يمكنهم التقاط أنماط مثل "أذهب إلى مطعم اليوم إذا كنت في فيلم قبل أسبوع").
المهمة 5. لنرى كيف تستخدم الشبكة العصبية المعلومات المتاحة للتنبؤ.
للقيام بذلك ، سنجري تدريبات على متواليات الطول 4. في المجموع ، سيكون لدينا 3 متواليات مختلفة محتملة بالتساوي:
0, 0, 1, 1
0, 1, 0, 1
0, 1, 1, 0
وبالتالي ، بعد الجمع الأولي بين 0 و 0 ، نلتقي دائمًا بوحدتين ، وبعد الجمع بين 0 ، 1 من المحتمل أن نلتقي 0 أو 1 ، لكننا نعرف الرقم الأخير بالتأكيد. سنطلب الآن من شبكتنا العصبية إرجاع التتابعات عن طريق تعيين return_sequences = True. كتسلسلات متوقعة ، نأخذ نفس التسلسلات الخاصة بنا خطوة بخطوة ويكملها صفر على اليمين. الآن يمكننا أن نفترض بالفعل ما سيحدث: في الخطوة الأولى ، ستنتج الشبكة العصبية عددًا قريبًا من 2/3 (نظرًا لاحتمال 2/3 المصطلح الثاني هو 1) ، ومن أجل مجموعة من 0 ، ستنتج رقمين قريبين من وحدة ، ولكن بالنسبة إلى 0 ، 1 أولاً ، ستعطى عددًا قريبًا من 0.5 ، ثم تعطى رقمًا قريبًا من 0 أو 1 ، وهذا يتوقف على ما إذا كنا قد حصلنا على التسلسل 0 أو 1 أو 0 أو 0 ، 1 ، 1. في نهاية الشبكة العصبية ستنتج دائمًا رقمًا قريبًا من 0. التحقق من الكود التالي يوضح أن افتراضاتنا صحيحة.
import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense import random def get_X_y(n): X = np.zeros((n, 4)) z = np.array([random.randint(0, 2) for i in range(n)]) X[z == 0, :] = [0, 0, 1, 1] X[z == 1, :] = [0, 1, 0, 1] X[z == 2, :] = [0, 1, 1, 0] y = np.zeros((n, 4)) y[:, :3] = X[:, 1:] X = np.reshape(X, (X.shape[0], X.shape[1], 1)) y = np.reshape(y, (y.shape[0], y.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=20, return_sequences=True)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000) model.fit(X_train, y_train, epochs = 100, batch_size = 32) X_test = np.zeros((3, 4)) X_test[0, :] = [0, 0, 1, 1] X_test[1, :] = [0, 1, 0, 1] X_test[2, :] = [0, 1, 1, 0] X_test = np.reshape(X_test, (3, 4, 1)) y_predicted = model.predict(X_test) print(y_predicted)
من هذا المثال ، نرى أن الشبكة العصبية يمكنها تغيير التنبؤ ديناميكيًا وفقًا للمعلومات الواردة. سنفعل نفس الشيء ، في محاولة للتنبؤ بتسلسل معين: عندما تسمح لنا المعلومات المتاحة بتقدير احتمالات النتائج في الخطوة التالية ، فإننا نتوقع استنادًا إلى هذه المعلومات ؛ ولكن عندما نكتشف معلومات إضافية في الخطوة التالية ، فإننا نغير التوقعات اعتمادًا عليها.
لذلك ، إذا رأينا أن هناك شخصًا قادم إلينا من الظلام ، فحينئذٍ نقول "هذا شخص ، لا نعرف بمزيد من التفاصيل" ؛ عندما نبدأ في التمييز بين الشعر الطويل في الظلام ، نقول "ربما هذه امرأة". لكن إذا اعتبرنا بعد ذلك أن الشخص مصاب بشارب ، فإننا نقول أنه من المحتمل أن يكون رجلاً (وإن كان بشعر طويل). كما رأينا ، تعمل الشبكة العصبية بشكل مشابه ، باستخدام المعلومات المتوفرة حاليًا للتنبؤ.
لذلك ، نظرنا في أمثلة بسيطة عن كيفية عمل الشبكات العصبية والأنماط التي يمكن أن تجدها. بشكل عام ، رأينا أن الشبكات العصبية غالبًا ما تتصرف "بشكل معقول" ، مما يجعل التنبؤات قريبة من تلك التي قد يقوم بها الشخص. على الرغم من أنه تجدر الإشارة إلى أنه من أجل التقاط أنماط بسيطة ، فإنها تحتاج إلى بيانات أكثر بكثير من الناس.