تنفيذ الشبكة العصبية في بايثون. تطوير الشبكة العصبية في بايثون

21.05.2019

الشبكات العصبية الاصطناعية (ANN) هي نماذج رياضية، بالإضافة إلى تطبيقاتها البرمجية أو الأجهزة، المبنية على مبدأ تنظيم وعمل الشبكات العصبية البيولوجية - شبكات الخلايا العصبية للكائن الحي.

الشبكات العصبية الاصطناعية هي نظام من المعالجات البسيطة المتصلة والمتفاعلة (الخلايا العصبية الاصطناعية).

الشبكات العصبية ليست مبرمجة بالمعنى المعتاد للكلمة، بل يتم تدريبها. تعد القدرة على التعلم إحدى المزايا الرئيسية للشبكات العصبية مقارنة بالخوارزميات التقليدية. ويكيبيديا

الشبكات العصبية مستوحاة من أدمغتنا. تم اختراع نموذج الخلايا العصبية القياسي منذ أكثر من خمسين عامًا ويتكون من ثلاثة أجزاء رئيسية:

  • العاج (الأسنان)- مسؤول عن جمع الإشارات الواردة؛
  • سوما- المسؤول عن المعالجة الرئيسية وجمع الإشارات؛
  • محور عصبي- مسؤول عن نقل الإشارات إلى التشعبات الأخرى.

يمكن وصف عمل الخلية العصبية بشيء من هذا القبيل: تقوم التشعبات بجمع الإشارات الواردة من الخلايا العصبية الأخرى، ثم تقوم الخلايا العصبية بجمع وحساب الإشارات والبيانات، وأخيرًا، بناءً على نتيجة المعالجة، يمكنها "إخبار" المحاور بنقل الإشارات والبيانات. إشارة أبعد من ذلك. ويعتمد النقل كذلك على عدد من العوامل، ولكن يمكننا نمذجة هذا السلوك كدالة نقل تأخذ المدخلات وتعالجها وتعد المخرجات إذا تم استيفاء خصائص دالة النقل.

الخلية العصبية البيولوجية عبارة عن نظام معقد، لم يتم بناء النموذج الرياضي له بشكل كامل بعد. تم تقديم العديد من النماذج، والتي تتفاوت في التعقيد الحسابي والتشابه مع الخلايا العصبية الحقيقية. واحدة من أهمها هي الخلايا العصبية الرسمية (FN). على الرغم من بساطة الوظيفة الوظيفية، يمكن للشبكات المبنية من هذه الخلايا العصبية أن تشكل وظيفة عشوائية متعددة الأبعاد عند الإخراج (المصدر: Zaentsev I.V. الشبكات العصبية: النماذج الأساسية).

تتكون الخلية العصبية من أفعى موزونة وعنصر غير خطي. يتم تحديد عمل الخلايا العصبية من خلال الصيغ:

تحتوي الخلية العصبية على عدة إشارات إدخال سوإشارة إخراج واحدة خارج. معلمات الخلية العصبية التي تحدد عملها هي: ناقل الأوزان ثومستوى العتبة θ ونوع وظيفة التنشيط F.

تجذب الشبكات العصبية الانتباه بسبب القدرات التالية:

  • قادرون على حل المشاكل الصعبة لإضفاء الطابع الرسمي عليها؛
  • مبدأ التشغيل الموازي متأصل، وهو أمر مهم للغاية عند معالجة كميات كبيرة من البيانات؛
  • القدرة على التعلم والقدرة على التعميم.
  • التسامح مع الأخطاء.

تشمل الخصائص الرئيسية للشبكات العصبية ما يلي:

    القدرة على التعلم. الشبكات العصبية ليست مبرمجة، ولكن يتم تدريبها من خلال الأمثلة. بمجرد تقديم إشارات الإدخال (ربما مع المخرجات المطلوبة)، تقوم الشبكة بضبط معلماتها لتوفير الاستجابة المطلوبة.

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

    تماثل. تتم معالجة المعلومات الموجودة على الشبكة بالتوازي، مما يجعل من الممكن إجراء معالجة معقدة إلى حد ما للبيانات باستخدام عدد كبير من الأجهزة البسيطة.

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

خوارزمية لحل المشكلات باستخدام الإدراك الحسي متعدد الطبقات(المصدر: Zaentsev I.V. الشبكات العصبية: النماذج الأساسية)

لبناء إدراك متعدد الطبقات، تحتاج إلى تحديد المعلمات الخاصة به. في أغلب الأحيان، يتطلب اختيار قيم الأوزان والعتبات التدريب، أي. التغييرات خطوة بخطوة في معاملات الترجيح ومستويات العتبة.

خوارزمية الحل العامة:

  1. تحديد المعنى الذي يتم وضعه في مكونات متجه الإدخال س. يجب أن يحتوي متجه الإدخال على حالة رسمية للمشكلة، أي. جميع المعلومات اللازمة للحصول على إجابة.
  2. حدد متجه الإخراج ذبحيث تحتوي مكوناته على إجابة كاملة للمهمة.
  3. تحديد نوع اللاخطية في الخلايا العصبية (وظيفة التنشيط). في هذه الحالة، من المستحسن أن تأخذ في الاعتبار تفاصيل المهمة، لأن الاختيار الجيد سوف يقلل من وقت التدريب.
  4. حدد عدد الطبقات والخلايا العصبية في الطبقة.
  5. ضبط نطاق التغييرات في المدخلات والمخرجات والأوزان ومستويات العتبة، مع مراعاة مجموعة قيم وظيفة التنشيط المحددة.
  6. قم بتعيين القيم الأولية لمعاملات الترجيح ومستويات العتبة والمعلمات الإضافية (على سبيل المثال، ميل وظيفة التنشيط، إذا كان سيتم تعديله أثناء التدريب). لا ينبغي أن تكون القيم الأولية كبيرة حتى لا تتشبع الخلايا العصبية (في الجزء الأفقي من وظيفة التنشيط)، وإلا فإن التعلم سيكون بطيئا للغاية. لا ينبغي أن تكون القيم الأولية صغيرة جدًا بحيث لا تساوي مخرجات معظم الخلايا العصبية الصفر، وإلا فإن التعلم سيتباطأ أيضًا.
  7. إجراء التدريب، أي. حدد معلمات الشبكة حتى يتم حل المشكلة بأفضل طريقة. بمجرد اكتمال التدريب، تصبح الشبكة جاهزة لحل المشكلات من النوع الذي تم تدريبها عليه.
  8. إرسال شروط المشكلة إلى مدخلات الشبكة في شكل متجه س. حساب متجه الإخراج ذ، والتي سوف تعطي حلا رسميا للمشكلة.

المشاكل التي يتعين حلها

حل المشكلات باستخدام الشبكات العصبية ().

    تصنيف الصور. وتتمثل المهمة في الإشارة إلى عضوية صورة الإدخال (على سبيل المثال، إشارة كلام أو حرف مكتوب بخط اليد)، ممثلة بواسطة ناقل الميزة، في فئة واحدة أو أكثر محددة مسبقًا. تشمل التطبيقات البارزة التعرف على الحروف، والتعرف على الكلام، وتصنيف إشارات مخطط كهربية القلب، وتصنيف خلايا الدم.

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

    تقريب الوظيفة. لنفترض أن هناك عينة تدريب ((x1,y1), (x2,y2)..., (xn,yn)) (أزواج بيانات الإدخال والإخراج) التي تم إنشاؤها بواسطة دالة غير معروفة (x) تالفة بسبب الضوضاء. مشكلة التقريب هي إيجاد تقدير للدالة المجهولة (x). يعد تقريب الوظيفة ضروريًا في حل العديد من مشكلات النمذجة الهندسية والعلمية.

    التنبؤ / التنبؤ. دع العينات المنفصلة n (y(t1)، y(t2)...، y(tn)) تُعطى في لحظات متتالية من الزمن t1، t2،...، tn. المهمة هي التنبؤ بقيمة y(tn+1) في وقت ما في المستقبل tn+1. للتنبؤ/التنبؤ تأثير كبير على عملية صنع القرار في مجال الأعمال والعلوم والتكنولوجيا. يعد التنبؤ بأسعار سوق الأوراق المالية والتنبؤ بالطقس من التطبيقات النموذجية لتقنيات التنبؤ/التنبؤ.

    تحسين. يمكن اعتبار العديد من المشكلات في الرياضيات والإحصاء والهندسة والعلوم والطب والاقتصاد مشكلات تحسينية. تتمثل مهمة خوارزمية التحسين في إيجاد حل يرضي نظام القيود ويزيد أو يقلل الوظيفة الهدف. تعد مسألة البائع المتجول، التي تنتمي إلى فئة NP-Complete، مثالًا كلاسيكيًا لمشكلة التحسين.

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

    يتحكم. خذ بعين الاعتبار نظامًا ديناميكيًا محددًا بالمجموعة (u(t)، y(t))، حيث u(t) هو إجراء التحكم في الإدخال، وy(t) هو مخرجات النظام في الوقت t. في أنظمة التحكم ذات النموذج المرجعي، يكون هدف التحكم هو حساب إجراء الإدخال u(t) بحيث يتبع النظام المسار المطلوب الذي يمليه النموذج المرجعي. مثال على ذلك هو التحكم الأمثل في المحرك.

أنواع الهندسة المعمارية

بنية الشبكات العصبية- طريقة لتنظيم وربط العناصر الفردية للشبكة العصبية (الخلايا العصبية). تكمن الاختلافات المعمارية بين الخلايا العصبية نفسها بشكل أساسي في استخدام وظائف التنشيط (الاستثارة) المختلفة. بناءً على بنية الاتصالات، يمكن تقسيم الشبكات العصبية إلى فئتين: شبكات التغذية الأمامية والشبكات المتكررة.

ويبين الشكل أدناه تصنيف الشبكات العصبية الاصطناعية حسب بنيتها.

تصنيف مماثل، ولكن توسعت قليلا

شبكة توزيع الإشارة الأمامية (شبكة الإرسال الأمامية)- شبكة عصبية بدون ردود فعل (حلقات). في مثل هذه الشبكة، تكون معالجة المعلومات أحادية الاتجاه: يتم إرسال الإشارة من طبقة إلى أخرى في الاتجاه من طبقة الإدخال للشبكة العصبية إلى طبقة الإخراج. يتم ضمان إشارة الخرج (استجابة الشبكة) من خلال عدد محدد مسبقًا من الخطوات (يساوي عدد الطبقات). تتميز شبكات Feedforward بأنها سهلة التنفيذ ومدروسة جيدًا. لحل المشاكل المعقدة فإنها تتطلب عددا كبيرا من الخلايا العصبية.

جدول المقارنة متعدد الطبقات الإدراكيةو شبكات RBF

متعدد الطبقات المستقبلات شبكات RBF
حدود القرار هي تقاطع الطائرات الفائقة حدود القرار هي تقاطع الكرات الفوقية، والتي تحدد حدود الشكل الأكثر تعقيدًا
طوبولوجيا معقدة من الاتصالات بين الخلايا العصبية والطبقات شبكة عصبية بسيطة مكونة من طبقتين
خوارزمية التعلم المعقدة وبطيئة التقارب إجراء التعلم السريع: حل نظام المعادلات + التجميع
العمل على عينة تدريبية صغيرة مطلوب قدر كبير من بيانات التدريب للحصول على نتيجة مقبولة
عالمية التطبيق: التجميع، التقريب، التحكم، إلخ. عادةً ما يتم تقريب الوظيفة وتجميعها فقط

يتم التعبير عن قيمة المشتق بسهولة من خلال الوظيفة نفسها. تعمل الحسابات المشتقة السريعة على تسريع عملية التعلم.

منحنى غاوسي

يتم استخدامه في الحالات التي يجب أن تكون فيها استجابة الخلايا العصبية بحد أقصى لبعض قيمة NET المحددة.

وحدات بايثون للشبكات العصبية

مثال بسيط

كمثال، سأقدم شبكة عصبية بسيطة (simple perceptron)، والتي بعد التدريب سوف تكون قادرة على التعرف على الأجسام الطائرة، وليس كلها، ولكن فقط النورس:)، سيتم التعرف على كافة الصور المدخلة الأخرى جسم غامض.

# encoding=utf8 استيراد فئة عشوائية NN: def __init__(self, عتبة, حجم): """ تعيين المعلمات الأولية. """ self.threshold = عتبة self.size = size self.init_weight() def init_weight(self) : """ تهيئة مصفوفة الأوزان ببيانات عشوائية. """ self.weights = [ for j in xrange(self.size)] def check(self, Sample): """ اقرأ إشارة الخرج لعينة الصورة. إذا كانت قيمة vsum > self. فيمكننا أن نفترض أن العينة تحتوي على صورة طائر النورس """ vsum = 0 لـ i في xrange(self.size): لـ j في xrange(self.size): vsum += self. .weights[i][j] * Sample[i][j] if vsum > self.threshold: return True else: return False def learn(self, Sample): """ تدريب الشبكة العصبية. """ for i in xrange(self.size): for j in xrange(self.size): self.weights[i][j] += Sample[i][j] nn = NN(20, 6) # تدريب الشبكة العصبية. tsample1 = [ , , , , , , ] nn.teach(tsample1) tsample2 = [ , , , , , , ] nn.teach(tsample2) tsample3 = [ , , , , , , ] nn.teach(tsample3) tsample4 = [ , , , , , , ] nn.teach(tsample4) # دعونا نتحقق مما يمكن أن تفعله الشبكة العصبية. # دعنا ننقل صورة النورس التي تشبه تقريبًا تلك التي يعرفها الإدراك الحسي. wsample1 = [ , , , , , , ] print u"seagull" if nn.check(wsample1) else u"UFO" # إرسال صورة غير معروفة. wsample2 = [ , , , , , , ] print u"seagull" if nn.check(wsample2) else u"UFO" # سنرسل صورة طائر النورس، والتي تشبه تقريبًا الصورة التي يعرفها الإدراك الحسي. wsample3 = [ , , , , , , ] اطبع u"seagull" إذا nn.check(wsample3) وإلا u"UFO"

كيراسهي مكتبة شعبية للتعلم العميق ساهمت بشكل كبير في تسويق التعلم العميق. يعد Keras سهل الاستخدام ويسمح لك بإنشاء شبكات عصبية باستخدام بضعة أسطر فقط من كود Python.

في هذه المقالة، ستتعلم كيفية استخدام Keras لإنشاء شبكة عصبية تتنبأ بكيفية تقييم المستخدمين للمنتج بناءً على تقييماتهم، وتصنيفه إلى فئتين: إيجابي أو سلبي. تسمى هذه المهمة تحليل المشاعر (تحليل المشاعر)وسنقوم بحلها بمساعدة موقع مراجعة الأفلام IMDb. يمكن أيضًا تطبيق النموذج الذي سنبنيه لحل المشكلات الأخرى بعد إجراء تعديلات طفيفة.

يرجى ملاحظة أننا لن نخوض في التفاصيل حول Keras والتعلم العميق. يهدف هذا المنشور إلى تقديم مخطط تخطيطي لـ Keras وإدخال كيفية تنفيذه.

  • ما هو كيراس؟
  • ما هو تحليل المشاعر؟
  • مجموعة البيانات على موقع IMDB
  • استكشاف البيانات
  • إعداد البيانات
  • إنشاء النموذج والتدريب

ما هو كيراس؟

Keras هي مكتبة Python مفتوحة المصدر تسهل إنشاء الشبكات العصبية. المكتبة متوافقة مع Microsoft Cognitive Toolkit وTheano وMXNet. يعد Tensorflow وTheano من أطر عمل Python الرقمية الأكثر استخدامًا لتطوير خوارزميات التعلم العميق، لكن من الصعب جدًا استخدامها.


تقييم شعبية أطر التعلم الآلي في 7 فئات

من ناحية أخرى، توفر Keras طريقة بسيطة ومريحة لإنشاء نماذج التعلم العميق. قام منشئها، فرانسوا شوليه، بتطويرها من أجل تسريع وتبسيط عملية إنشاء الشبكات العصبية قدر الإمكان. لقد ركز على القابلية للتوسعة والنمطية والبساطة ودعم بايثون. يمكن استخدام Keras مع وحدة معالجة الرسومات (GPU) ووحدة المعالجة المركزية (CPU)؛ وهو يدعم كلاً من Python 2 وPython 3. وقد ساهم Keras من Google بشكل كبير في تسويق التعلم العميق والتعلم العميق، لأنه يحتوي على أحدث خوارزميات التعلم العميق التي لم يكن من الممكن الوصول إليها في السابق فحسب، بل كانت أيضًا غير قابلة للاستخدام.

ما هو تحليل المشاعر (تحليل المشاعر)؟

يمكن استخدام تحليل المشاعر لتحديد موقف الشخص (أي الحالة المزاجية) تجاه النص أو التفاعل أو الحدث. ولذلك فإن تحليل المشاعر ينتمي إلى مجال معالجة اللغة الطبيعية، حيث يجب فك رموز النص لاستخراج الشعور والوجدان منه.


مثال على مقياس تحليل المشاعر

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

مجموعة بيانات IMDb


تقييمات على موقع IMDb (الإنجليزية)

تتكون مجموعة بيانات IMDb من 50000 مراجعة للأفلام من المستخدمين، مصنفة على أنها إيجابية (1) وسلبية (0).

  • تتم معالجة المراجعات مسبقًا ويتم تشفير كل واحدة منها بسلسلة من فهارس الكلمات كأعداد صحيحة.
  • تتم فهرسة الكلمات في المراجعات حسب تكرار حدوثها الإجمالي في مجموعة البيانات. على سبيل المثال، يقوم العدد الصحيح "2" بترميز الكلمة الثانية الأكثر استخدامًا.
  • تنقسم المراجعات البالغ عددها 50000 إلى مجموعتين: 25000 للتدريب و25000 للاختبار.

تم إنشاء مجموعة البيانات من قبل باحثين في جامعة ستانفورد وتم تقديمها في ورقة بحثية عام 2011، حيث بلغت دقة التنبؤ المحققة 88.89٪. تم استخدام مجموعة البيانات أيضًا كجزء من مسابقة مجتمع Keggle "حقيبة الكلمات تلتقي بأكياس الفشار"في عام 2011.

استيراد التبعيات واسترجاع البيانات

لنبدأ باستيراد التبعيات اللازمة لمعالجة البيانات مسبقًا وبناء النموذج.

%matplotlib استيراد مضمّن، استيراد matplotlib matplotlib.pyplot كـ plt، استيراد numpy كـ np من keras.utils، استيراد to_categorical من keras، استيراد النماذج من طبقات استيراد keras

لنقم بتحميل مجموعة بيانات IMDb، المضمنة بالفعل في Keras. نظرًا لأننا لا نريد الحصول على بيانات تدريب واختبار بنسبة 50/50، فسنقوم بدمج هذه البيانات فورًا بعد تحميلها لتقسيمها لاحقًا بنسبة 80/20:

من keras.datasets استيراد imdb (بيانات التدريب، أهداف التدريب)، (testing_data، test_targets) = imdb.load_data(num_words=10000) data = np.concatenate((training_data, test_data)، axis=0) الأهداف = np.concatenate((training_targets ، test_targets)، المحور = 0)

استكشاف البيانات

دعونا ندرس مجموعة البيانات لدينا:

طباعة ("الفئات:"، np.unique(targets)) print("عدد الكلمات الفريدة:"، len(np.unique(np.hstack(data)))) الفئات: عدد الكلمات الفريدة: 9998 الطول = طباعة ("متوسط ​​طول المراجعة:"، np.mean(length)) print("الانحراف المعياري:"، round(np.std(length))) متوسط ​​طول المراجعة: 234.75892 الانحراف المعياري: 173.0

يمكنك أن ترى أن جميع البيانات تنقسم إلى فئتين: 0 أو 1، وهو ما يمثل مشاعر المراجعة. تحتوي مجموعة البيانات بأكملها على 9998 كلمة فريدة، ويبلغ متوسط ​​حجم المراجعة 234 كلمة مع انحراف معياري قدره 173.

دعونا نلقي نظرة على طريقة بسيطة للتعلم:

طباعة ("التسمية:"، الأهداف) التسمية: طباعة واحدة (بيانات)

هنا ترى المراجعة الأولى من مجموعة البيانات، والتي تم وضع علامة إيجابية عليها (1). الكود التالي يحول المؤشرات مرة أخرى إلى كلمات حتى نتمكن من قراءتها. يتم فيه استبدال كل كلمة غير معروفة بـ "#". ويتم ذلك باستخدام الوظيفة get_word_index().

Index = imdb.get_word_index()verse_index = dict([(value, key) for (key, value) in Index.items()]) decoded = " ".join() print(decoded) # كان هذا الفيلم مجرد اختيار رائع الموقع، المشهد، القصة، الاتجاه، الجميع يناسب حقًا الدور الذي لعبوه، ويمكنك فقط أن تتخيل وجودك هناك. روبرت # ممثل رائع والآن هو نفس المخرج # الأب جاء من نفس الجزيرة الاسكتلندية مثلي، لذلك أحببت حقيقة أنه كان هناك اتصال حقيقي بهذا الفيلم، كانت الملاحظات الذكية طوال الفيلم رائعة، لقد كانت رائعة جدًا لدرجة أنني اشتريت الفيلم بمجرد إصداره لـ # وأوصي به الجميع لمشاهدته وكان الصيد بالذباب مذهلًا حقًا بكيت على كان الأمر محزنًا للغاية في النهاية وأنت تعرف ما يقولونه إذا بكيت في فيلم ما، فلا بد أن هذا كان أمرًا جيدًا، وهذا بالتأكيد كان أيضًا # بالنسبة للولدين الصغيرين اللذين لعبا دور # نورمان وبول، فقد كانا مجرد أطفال رائعين في كثير من الأحيان أعتقد أنه تم استبعادهم من القائمة رقم # لأن النجوم الذين لعبوا دورهم جميعًا كبارًا يمثلون ملفًا شخصيًا كبيرًا للفيلم بأكمله ولكن هؤلاء الأطفال رائعون ويجب الإشادة بهم على ما فعلوه، ألا تعتقد أن القصة بأكملها كانت كذلك جميلة لأنها كانت حقيقية وكانت حياة شخص ما بعد كل ما شاركناه جميعًا

إعداد البيانات

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

Def Vectorize(التسلسلات، البعد = 10000): النتائج = np.zeros((len(التسلسلات)، البعد)) لـ i، التسلسل في التعداد(التسلسلات): النتائج = 1 إرجاع نتائج البيانات = Vectorize(البيانات) الأهداف = np. صفيف (الأهداف).astype ("float32")

دعونا نقسم مجموعة البيانات إلى مجموعات تدريب واختبار. ستتألف مجموعة التدريب من 40.000 مراجعة، وستتكون مجموعة الاختبار من 10.000 مراجعة.

Test_x = البيانات[:10000] test_y = الأهداف[:10000] Train_x = بيانات Train_y = الأهداف

إنشاء النموذج والتدريب

الآن يمكنك إنشاء شبكة عصبية بسيطة. لنبدأ بتحديد نوع النموذج الذي نريد إنشاءه. هناك نوعان من النماذج المتوفرة في Keras: واجهة برمجة التطبيقات التسلسلية والوظيفية.

ثم تحتاج إلى إضافة طبقات الإدخال والمخفية والمخرجات. لمنع التجهيز الزائد، سوف نستخدم استثناء بينهما ( "أوقع"). لاحظ أنه يجب عليك دائمًا استخدام معدل استبعاد يتراوح بين 20% و50%. تستخدم كل طبقة وظيفة "كثيف"لربط الطبقات مع بعضها البعض بشكل كامل. في الطبقات المخفية سوف نستخدم "ريلو"لأن هذا يؤدي دائمًا إلى نتائج مرضية. لا تخف من تجربة وظائف التنشيط الأخرى. في طبقة الإخراج، نستخدم دالة سينية تعمل على إعادة تطبيع القيم في النطاق من 0 إلى 1. لاحظ أننا قمنا بتعيين حجم عناصر مجموعة البيانات المدخلة على 10000 لأن حجم مراجعاتنا يصل إلى 10000 عدد صحيح. تقبل طبقة الإدخال العناصر بحجم 10000 وتخرج العناصر بحجم 50.

أخيرًا، اسمح لـ Keras بطباعة وصف مختصر للنموذج الذي أنشأناه للتو.

# الإدخال - نموذج الطبقة.add(layers.Dense(50,activation = "relu", input_shape=(10000,))) # مخفي - الطبقات model.add(layers.Dropout(0.3, Noise_shape=None,seed=None) ) model.add(layers.Dense(50,activation = "relu") model.add(layers.Dropout(0.2, Noise_shape=None,seed=None)) model.add(layers.Dense(50,activation = "relu ")) # نموذج إخراج الطبقة.add(layers.Dense(1,activation = "sigmoid"))model.summary() model.summary() _________________________________________________________________ الطبقة (النوع) شكل الإخراج Param # ======= ================================================================================================== === ======== كثيف_1 (كثيف) (لا يوجد، 50) 500050 _____________________________________ التسرب_1 (التسرب) (لا يوجد، 50) 0 _________________________________________________________________ كثيف_2 (كثيف) (لا يوجد، 50) 2550 ___________________________________________________ التسرب_2 (التسرب) (لا يوجد) ، 50) 0 ___________________________________________________ كثيفة_3 (كثيفة) (لا شيء، 50) 2550 _____________________________________ كثيفة_4 (كثيفة) (لا شيء، 1) 51 =============== =========================== إجمالي المعلمات: 505,201 معلمات قابلة للتدريب: 505,201 معلمات غير قابلة للتدريب: 0 _________________________________________________________________

الآن نحن بحاجة إلى تجميع نموذجنا، أي إعداده بشكل أساسي للتدريب. سوف نستخدم محسن "آدم". المُحسِّن عبارة عن خوارزمية تعمل على تغيير الأوزان والتحيزات أثناء التدريب. مثل وظائف الخسارةنحن نستخدم الإنتروبيا الثنائية (نظرًا لأننا نعمل مع التصنيف الثنائي)، والدقة كمقياس للتقييم.

Model.compile(المحسن = "آدم"، الخسارة = "binary_crossentropy"، المقاييس = ["الدقة"])

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

النتائج = model.fit(train_x, Train_y, epochs= 2, Batch_size = 500, validation_data = (test_x, test_y)) التدريب على 40000 عينة، والتحقق من صحة 10000 عينة Epoch 1/2 40000/40000 [======= =======================] - 5s 129us/step - الخسارة: 0.4051 - acc: 0.8212 - val_loss: 0.2635 - val_acc: 0.8945 Epoch 2/2 40000 /40000 [======================] - 4s 90us/step - الخسارة: 0.2122 - acc: 0.9190 - val_loss: 0.2598 - val_acc: 0.8950

دعونا نقيم أداء النموذج:

طباعة(np.mean(results.history["val_acc"])) 0.894750000536

عظيم! لقد حطم نموذجنا البسيط بالفعل الرقم القياسي للدقة في ورقة بحثية عام 2011المذكورة في بداية هذا المنصب. لا تتردد في تجربة معلمات الشبكة وعدد الطبقات.

رمز النموذج الكامل موضح أدناه:

استيراد numpy كـ np من keras.utils استيراد to_categorical من keras استيراد النماذج من keras استيراد الطبقات من keras.datasets استيراد imdb (training_data،training_targets)، (testing_data، test_targets) = imdb.load_data(num_words=10000) data = np.concatenate( (بيانات التدريب، بيانات الاختبار)، المحور = 0) الأهداف = np.concatenate((training_targets، test_targets)، المحور = 0) def Vectorize(التسلسلات، البعد = 10000): النتائج = np.zeros((len(التسلسلات)، البعد) ) بالنسبة إلى i، التسلسل في التعداد (التسلسلات): النتائج = 1 إرجاع نتائج البيانات = المتجهات (البيانات) الأهداف = np.array(targets).astype("float32") test_x = data[:10000] test_y = الأهداف[:10000 ] Train_x = data Train_y = Targets model =models.Sequential() # الإدخال - الطبقات model.add(layers.Dense(50,activation = "relu", input_shape=(10000,))) # مخفي - الطبقات model.add( Layers.Dropout(0.3, الضوضاء_الشكل=لا شيء, البذور=لا شيء)) model.add(layers.Dense(50, التنشيط = "relu")) model.add(layers.Dropout(0.2, Noise_shape=لا شيء, البذور=لا شيء) ) model.add(layers.Dense(50,activation = "relu")) # طبقة الإخراج model.add(layers.Dense(1,activation = "sigmoid")) model.summary() # تجميع النموذج النموذجي. ترجمة (المُحسِّن = "آدم"، الخسارة = "binary_crossentropy"، المقاييس = ["الدقة"]) النتائج = model.fit(train_x, Train_y, epochs= 2, Batch_size = 500, validation_data = (test_x, test_y)) طباعة( "دقة الاختبار:"، np.mean(results.history["val_acc"]))

نتائج

لقد تعلمت ما هو تحليل المشاعر ولماذا تعد Keras إحدى مكتبات التعلم العميق الأكثر شعبية.

لقد أنشأنا شبكة عصبية بسيطة مكونة من ست طبقات يمكنها حساب مشاعر مراجعي الأفلام بدقة تصل إلى 89%. يمكنك الآن استخدام هذا النموذج لتحليل المشاعر الثنائية في مصادر أخرى، ولكن للقيام بذلك سيتعين عليك جعل حجمها يساوي 10000 أو تغيير معلمات طبقة الإدخال.

يمكن تطبيق هذا النموذج (مع تعديلات طفيفة) على مشكلات التعلم الآلي الأخرى.

من المحتمل أن البعض منكم قد أخذ مؤخرًا دورات في جامعة ستانفورد، ولا سيما فئة ai وml-class، ومع ذلك، فإن مشاهدة العديد من محاضرات الفيديو والإجابة على أسئلة الاختبار وكتابة عشرات البرامج في Matlab / Octave شيء واحد، والبدء شيء آخر. باستخدام المعرفة المكتسبة في الممارسة العملية. ولكي لا تنتهي المعرفة التي تلقيتها من أندرو إنج في نفس الزاوية المظلمة من عقلي حيث ضاعت نظرية dft والنظرية النسبية الخاصة ومعادلة لاغرانج لأويلر، قررت عدم تكرار أخطاء المعهد، وبينما لا تزال المعرفة جديدة في ذاكرتي، ممارسة قدر الإمكان.

وعندها فقط وصل DDoS إلى موقعنا. كان من الممكن محاربته باستخدام أساليب الإدارة/البرمجة (grep/awk/etc) أو اللجوء إلى استخدام تقنيات التعلم الآلي.

مثال على بناء القاموس وناقل الميزات

لنفترض أننا ندرب شبكتنا العصبية بمثالين فقط: أحدهما جيد والآخر سيئ. ثم سنحاول تفعيله في تسجيل تجريبي.

الدخول من السجل "السيئ":
0.0.0.0 - - "POST /forum/index.php HTTP/1.1" 503 107 "http://www.mozilla-europe.org/" "-"

الدخول من السجل "الجيد":
0.0.0.0 - - "GET /forum/rss.php?topic=347425 HTTP/1.0" 200 1685 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9) Gecko/2008052906 Firefox/ 3.0"

القاموس الناتج:
["__UA___OS_U"، "__UA_EMPTY"، "__REQ___METHOD_POST"، "__REQ___HTTP_VER_HTTP/1.0"، "__REQ___URL___NETLOC_"، "__REQ___URL___PATH_/forum/rss.php"، "__REQ___URL___PATH_/forum/index.php"، "__REQ___URL___SCHEME _ "، "__REQ____HTTP_VER_HTTP/ 1.1 "،" __ua ___ Ver_firefox/3.0 "،" __refer___netloc_www.mozilla-europe.org "،" __ua___os_windows "،" __ua ___mozilla/5.0 "،"، __code_503"، "، __ua___os_os l"،"، __refer ___ path_/"، __refer___scheme_http ""، "__no_refer__"، "__REQ___METHOD_GET"، "__UA___OS_Windows NT 5.1"، "__UA____OS_rv:1.9"، "__REQ___URL___QS_topic"، "__UA___VER_Gecko/2008052906"]

دخول الاختبار:
0.0.0.0 - - "GET /forum/viewtopic.php?t=425550 HTTP/1.1" 502 107 "-" "BTWebClient/3000(25824)"

ناقلات الميزة:

لاحظ مدى "تناثر" ناقل الميزة - سيتم ملاحظة هذا السلوك لجميع الاستعلامات.

قسم مجموعة البيانات

من الممارسات الجيدة تقسيم مجموعة البيانات إلى عدة أجزاء، حيث قمت بتقسيمها إلى جزأين بنسبة 70/30:
  • عدة التدريبات. نستخدمها لتدريب شبكتنا العصبية.
  • مجموعة الاختبار. نستخدمها للتحقق من مدى جودة تدريب شبكتنا العصبية.
يرجع هذا التقسيم إلى حقيقة أن الشبكة العصبية التي بها أصغر خطأ في التدريب (خطأ في مجموعة التدريب) ستنتج ب ياخطأ أكبر في البيانات الجديدة، لأننا "أعدنا تدريب" الشبكة، وشحذناها في إطار مجموعة التدريب.
في المستقبل، إذا كان عليك اختيار الثوابت المثالية، فستحتاج مجموعة البيانات إلى تقسيمها إلى 3 أجزاء بنسبة 60/20/20: مجموعة التدريب ومجموعة الاختبار والتحقق المتقاطع. سيعمل هذا الأخير على تحديد المعلمات المثلى للشبكة العصبية (على سبيل المثال، WeightDecay).

الشبكة العصبية على وجه الخصوص

الآن بعد أن لم يعد لدينا أي سجلات نصية في أيدينا، ولكن فقط مصفوفات من ناقلات الميزات، يمكننا أن نبدأ في بناء الشبكة العصبية نفسها.

لنبدأ باختيار الهيكل. لقد اخترت شبكة مكونة من طبقة مخفية واحدة بحجم ضعف طبقة الإدخال. لماذا؟ الأمر بسيط: هذا ما تركه أندرو إنج في حال كنت لا تعرف من أين تبدأ. أعتقد أنه يمكنك اللعب بهذا في المستقبل من خلال رسم الرسوم البيانية للتدريب.
وظيفة التنشيط للطبقة المخفية هي السيني الذي طالت معاناته، ولطبقة الإخراج - Softmax. تم اختيار الأخير في حالة ضرورة القيام بذلك
تصنيف متعدد الطبقات مع فئات متنافية. على سبيل المثال، أرسل طلبات "جيدة" إلى الواجهة الخلفية، وطلبات "سيئة" إلى حظر جدار الحماية، وطلبات "رمادية" لحل اختبار التحقق.

تميل الشبكة العصبية إلى الانتقال إلى الحد الأدنى المحلي، لذلك في الكود الخاص بي أقوم ببناء عدة شبكات واختيار الشبكة التي تحتوي على أصغر خطأ في الاختبار (لاحظ أنه الخطأ في مجموعة الاختبار، وليس مجموعة التدريب).

تنصل

أنا لست لحام حقيقي. أعرف فقط عن التعلم الآلي ما تعلمته من فئة ml وai-class. لقد بدأت البرمجة باستخدام لغة بايثون مؤخرًا نسبيًا، وتمت كتابة الكود أدناه في حوالي 30 دقيقة (كان الوقت، كما تعلمون، ينفد) وتم بعد ذلك حفظه قليلاً في ملف.

كما أن هذا الرمز ليس مستقلاً بذاته. لا يزال يحتاج إلى تسخير السيناريو. على سبيل المثال، إذا قام عنوان IP بتقديم N طلبات سيئة خلال X دقيقة، فقم بحظره على جدار الحماية.

أداء

  • lfu_cache. تم نقله من ActiveState لتسريع معالجة الطلبات عالية التردد بشكل كبير. الجانب السلبي - زيادة استهلاك الذاكرة.
  • PyBrain، بالطبع، مكتوب بلغة python وبالتالي فهو ليس سريعًا جدًا، ومع ذلك، يمكنه استخدام وحدة arac المستندة إلى ATLAS إذا حددت Fast=True عند إنشاء الشبكة. يمكنك قراءة المزيد عن هذا في وثائق PyBrain.
  • التوازي. لقد قمت بتدريب شبكتي العصبية على خادم Nehalem "سميك" إلى حد ما، ومع ذلك، حتى هناك ظهرت عيوب التدريب أحادي الخيط. يمكنك التفكير في موضوع موازنة التدريب على الشبكات العصبية. الحل البسيط هو تدريب العديد من الشبكات العصبية بالتوازي واختيار الأفضل منهم، ولكن هذا سيخلق حملاً إضافيًا على الذاكرة، وهو أيضًا ليس جيدًا جدًا. ربما يكون من المنطقي إعادة كتابة كل شيء في لغة C، لأن الأساس النظري بأكمله في فئة ml تم مضغه.
  • استهلاك الذاكرة وعدد الميزات. كان التحسين الجيد للذاكرة هو الانتقال من صفائف Python القياسية إلى صفائف numpy. كما أن تقليل حجم القاموس و/أو استخدام PCA يمكن أن يساعد بشكل جيد للغاية، المزيد عن ذلك أدناه.

للمستقبل

  • حقول إضافية في السجل. يمكنك إضافة المزيد إلى السجل المدمج؛ ومن المفيد التفكير في الحقول التي ستساعد في تحديد الروبوتات. قد يكون من المنطقي أن نأخذ في الاعتبار الثماني بتات الأولى من عنوان IP، لأنه في مشروع الويب غير الدولي، من المرجح أن يكون المستخدمون الصينيون عبارة عن روبوتات.
  • برمجة
    • ترجمة

    ما هو المقال حول؟

    أنا شخصياً أتعلم بشكل أفضل باستخدام أكواد العمل الصغيرة التي يمكنني اللعب بها. في هذا البرنامج التعليمي، سوف نتعلم خوارزمية الانتشار العكسي باستخدام شبكة عصبية صغيرة تم تنفيذها في لغة بايثون كمثال.

    أعطني الرمز!

    X = np.array([ ,,, ]) y = np.array([]).T Syn0 = 2*np.random.random((3,4)) - 1 Syn1 = 2*np.random.random ((4,1)) - 1 لـ j في xrange(60000): l1 = 1/(1+np.exp(-(np.dot(X,syn0)))) l2 = 1/(1+np. exp(-(np.dot(l1,syn1)))) l2_delta = (y - l2)*(l2*(1-l2)) l1_delta = l2_delta.dot(syn1.T) * (l1 * (1-l1) )) Syn1 += l1.T.dot(l2_delta) Syn0 += X.T.dot(l1_delta)

    مضغوط جدا؟ دعونا نقسمها إلى أجزاء أبسط.

    الجزء 1: الشبكة العصبية للعبة الصغيرة

    تحاول الشبكة العصبية المدربة من خلال الانتشار العكسي استخدام بيانات الإدخال للتنبؤ ببيانات الإخراج.

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

    يقوم Backpropagation، في أبسط حالاته، بحساب إحصائيات مثل هذه لإنشاء نموذج. دعونا نحاول.

    الشبكة العصبية في طبقتين

    استيراد numpy كـ np # Sigmoid def Nonlin(x,deriv=False): if(deriv==True): return f(x)*(1-f(x)) return 1/(1+np.exp(-x) )) # مجموعة بيانات الإدخال X = np.array([ , , , ]) # بيانات الإخراج y = np.array([]).T # جعل الأرقام العشوائية أكثر تحديدًا np.random.seed(1) # تهيئة أوزان بطريقة عشوائية بمتوسط ​​0 Syn0 = 2*np.random.random((3,1)) - 1 لـ iter في xrange(10000): # الانتشار الأمامي l0 = X l1 = Nonlin(np.dot(l0,syn0 )) # كم كنا مخطئين؟ l1_error = y - l1 # اضرب هذا مع ميل السيني # بناءً على القيم الموجودة في l1 l1_delta = l1_error * Nonlin(l1,True) # !!! # تحديث الأوزان Syn0 += np.dot(l0.T,l1_delta) # !!! اطبع "الإخراج بعد التدريب:" اطبع l1

    الإخراج بعد التدريب: [[ 0.00966449] [ 0.00786506] [ 0.99358898] [ 0.99211957]]

    المتغيرات وأوصافها.






    "*" - الضرب حسب العناصر - يقوم متجهان من نفس الحجم بضرب القيم المقابلة، ويكون الإخراج متجهًا بنفس الحجم
    "-" - الطرح الحكيم للمتجهات
    x.dot(y) – إذا كان x وy متجهين، فسيكون الناتج عبارة عن منتج عددي. إذا كانت هذه مصفوفات، فإن النتيجة هي ضرب المصفوفات. إذا كانت المصفوفة واحدة منها فقط، فهي ضرب متجه ومصفوفة.

    • قارن l1 بعد التكرار الأول وبعد الأخير
    • انظر إلى وظيفة غير لين.
    • انظر كيف يتغير l1_error
    • سطر التحليل 36 - يتم جمع المكونات السرية الرئيسية هنا (تم وضع علامة !!!)
    • سطر التحليل 39 - الشبكة بأكملها تستعد بدقة لهذه العملية (تم وضع علامة !!!)

    دعونا نحلل الكود سطرا تلو الآخر

    استيراد numpy كـ np

    يستورد numpy، مكتبة الجبر الخطي. إدماننا الوحيد.

    تعريف غير لين (x، deriv = False):

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

    إذا (مشتق==صحيح):

    يمكن لهذه الوظيفة أيضًا إنتاج مشتق السيني (اشتقاق = صحيح). وهذه واحدة من خصائصه المفيدة. إذا كان مخرج الدالة متغيرًا خارجًا، فسيكون المشتق خارجًا * (1-out). فعال.

    X = np.array([، ...

    تهيئة مصفوفة بيانات الإدخال كمصفوفة numpy. كل سطر هو مثال للتدريب. الأعمدة هي عقد الإدخال. لقد حصلنا في النهاية على 3 عقد إدخال في الشبكة و4 أمثلة للتدريب.

    Y = np.array([]).T

    تهيئة بيانات الإخراج. ".T" - وظيفة النقل. بعد الترجمة، تحتوي المصفوفة y على 4 صفوف بعمود واحد. كما هو الحال مع بيانات الإدخال، كل صف هو مثال تدريبي، وكل عمود (واحد في حالتنا) هو عقدة إخراج. اتضح أن الشبكة بها 3 مدخلات ومخرج واحد.

    Np.random.seed(1)

    وبفضل هذا، سيكون التوزيع العشوائي هو نفسه في كل مرة. سيسمح لنا ذلك بمراقبة الشبكة بسهولة أكبر بعد إجراء تغييرات على الكود.

    Syn0 = 2*np.random.random((3,1)) – 1

    مصفوفة وزن الشبكة. Syn0 يعني "المشبك صفر". وبما أن لدينا طبقتين فقط، المدخلات والمخرجات، فإننا نحتاج إلى مصفوفة وزن واحدة تربط بينهما. البعد هو (3، 1)، حيث أن لدينا 3 مدخلات و 1 مخرج. بمعنى آخر، l0 له حجم 3 وl1 له حجم 1. وبما أننا نربط جميع العقد في l0 بجميع العقد في l1، فإننا بحاجة إلى مصفوفة البعد (3، 1).

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

    بالنسبة إلى iter في xrange(10000):

    هذا هو المكان الذي يبدأ فيه كود تدريب الشبكة الرئيسي. تتكرر حلقة التعليمات البرمجية عدة مرات وتعمل على تحسين الشبكة لمجموعة البيانات.

    الطبقة الأولى، l0، هي مجرد بيانات. X يحتوي على 4 أمثلة تدريبية. سنقوم بمعالجتها جميعًا مرة واحدة - وهذا ما يسمى التدريب الجماعي. في المجمل لدينا 4 أسطر مختلفة من l0، لكن يمكن اعتبارها مثالًا تدريبيًا واحدًا - في هذه المرحلة لا يهم (يمكنك تحميل 1000 أو 10000 منها دون أي تغييرات في الكود).

    L1 = غير لين (np.dot(l0,syn0))

    هذه هي خطوة التنبؤ. نترك الشبكة تحاول التنبؤ بالمخرجات بناءً على المدخلات. ثم سنرى كيف تفعل ذلك حتى نتمكن من تعديله للتحسين.

    هناك خطوتين في كل سطر. الأول يقوم بضرب المصفوفات لـ l0 وsyn0. والثاني يمرر الإخراج من خلال السيني. أبعادها هي كما يلي:

    (4 × 3) نقطة (3 × 1) = (4 × 1)

    تتطلب عمليات ضرب المصفوفة أن تكون الأبعاد واحدة في منتصف المعادلة. تحتوي المصفوفة النهائية على نفس عدد الصفوف الموجودة في المصفوفة الأولى، ونفس عدد الأعمدة الموجودة في المصفوفة الثانية.

    قمنا بتحميل 4 أمثلة تدريبية وحصلنا على 4 تخمينات (مصفوفة 4x1). يتوافق كل مخرج مع تخمين الشبكة لمدخل معين.

    L1_error = ص - l1

    وبما أن l1 يحتوي على تخمينات، فيمكننا مقارنة اختلافها مع الواقع عن طريق طرح l1 من الإجابة الصحيحة y. l1_error هو ناقل للأرقام الموجبة والسالبة التي تميز الشبكة "المفقود".

    وهنا العنصر السري. يجب تحليل هذا الخط قطعة قطعة.

    الجزء الأول: مشتق

    نونلين (l1، صحيح)

    يمثل L1 هذه النقاط الثلاث، وينتج الكود ميل الخطوط الموضحة أدناه. لاحظ أنه بالنسبة للقيم الكبيرة مثل x=2.0 (النقطة الخضراء) والقيم الصغيرة جدًا مثل x=-1.0 (أرجواني) فإن الخطوط لها ميل طفيف. أكبر زاوية عند النقطة x=0 (الأزرق). هذا يحدث فرقا كبيرا. لاحظ أيضًا أن جميع المشتقات تتراوح من 0 إلى 1.

    التعبير الكامل: مشتق مرجح بالخطأ

    L1_delta = l1_error * غير لين (l1، صحيح)

    رياضيا، هناك طرق أكثر دقة، ولكن في حالتنا هذه مناسبة أيضا. l1_error هي مصفوفة (4,1). تقوم Nonlin(l1,True) بإرجاع المصفوفة (4,1). هنا نضربهم عنصرًا بعنصر، وعند الإخراج نحصل أيضًا على المصفوفة (4,1)، l1_delta.

    ومن خلال ضرب المشتقات في الأخطاء، فإننا نحد من أخطاء التنبؤات التي يتم إجراؤها بثقة عالية. إذا كان ميل الخط صغيرًا، فإن الشبكة تحتوي إما على قيمة كبيرة جدًا أو صغيرة جدًا. إذا كان تخمين الشبكة قريبًا من الصفر (x=0, y=0.5)، فهي ليست واثقة بشكل خاص. نقوم بتحديث هذه التوقعات غير المؤكدة ونترك التنبؤات عالية الثقة بمفردها عن طريق ضربها بقيم قريبة من الصفر.

    Syn0 += np.dot(l0.T,l1_delta)

    نحن على استعداد لتحديث الشبكة. دعونا نلقي نظرة على مثال تدريبي واحد. فيه سنقوم بتحديث الأوزان. تحديث الوزن أقصى اليسار (9.5)

    تحديث الوزن = قيمة الإدخال * l1_delta

    بالنسبة للوزن في أقصى اليسار سيكون 1.0 * l1_delta. من المفترض أن يؤدي هذا إلى زيادة 9.5 قليلاً فقط. لماذا؟ لأن التنبؤ كان بالفعل واثقًا تمامًا، وكانت التوقعات صحيحة عمليًا. خطأ بسيط ومنحدر طفيف للخط يعني تحديثًا صغيرًا جدًا.

    ولكن بما أننا نقوم بتدريب جماعي، فإننا نكرر الخطوة المذكورة أعلاه لجميع أمثلة التدريب الأربعة. لذا فهي تبدو مشابهة جدًا للصورة أعلاه. إذن ماذا يفعل خطنا؟ يقوم بإحصاء تحديثات الوزن لكل وزن، لكل مثال تدريبي، ويلخصها ويحدث جميع الأوزان - كل ذلك في سطر واحد.

    بعد ملاحظة تحديث الشبكة، لنعد إلى بيانات التدريب لدينا. عندما يكون كل من المدخلات والمخرجات 1، فإننا نزيد الوزن بينهما. عندما يكون الإدخال 1 والإخراج 0، نقوم بتقليل الوزن.

    المدخلات والمخرجات 0 0 1 0 1 1 1 1 1 0 1 1 0 1 1 0

    لذلك في أمثلةنا التدريبية الأربعة أدناه، فإن وزن المدخل الأول بالنسبة إلى المخرجات إما أن يزيد أو يبقى ثابتًا، والوزنان الآخران سيزدادان وينقصان اعتمادًا على الأمثلة. يساهم هذا التأثير في التعلم الشبكي بناءً على الارتباطات بين بيانات الإدخال والإخراج.

    الجزء 2: مهمة أكثر صعوبة

    المدخلات والمخرجات 0 0 1 0 0 1 1 1 1 0 1 1 1 1 1 0

    دعونا نحاول التنبؤ ببيانات الإخراج بناءً على ثلاثة أعمدة لبيانات الإدخال. لا يرتبط أي من أعمدة الإدخال بنسبة 100% بالمخرجات. العمود الثالث غير متصل بأي شيء على الإطلاق، لأنه يحتوي على تلك الموجودة على طول الطريق. ومع ذلك، هنا يمكنك رؤية النمط - إذا كان أحد العمودين الأولين (ولكن ليس كلاهما في وقت واحد) يحتوي على 1، فستكون النتيجة أيضًا مساوية لـ 1.

    هذا تصميم غير خطي لأنه لا يوجد مراسلات مباشرة بين الأعمدة. تعتمد المطابقة على مجموعة من المدخلات والعمودين 1 و2.

    ومن المثير للاهتمام أن التعرف على الأنماط مهمة مشابهة جدًا. إذا كان لديك 100 صورة لدراجات وأنابيب بنفس الحجم، فإن وجود وحدات بكسل معينة في أماكن معينة لا يرتبط بشكل مباشر بوجود دراجة أو أنبوب في الصورة. إحصائيًا، قد يبدو لونها عشوائيًا. لكن بعض مجموعات البكسلات ليست عشوائية - تلك التي تشكل صورة دراجة (أو أنبوب).


    إستراتيجية

    لدمج وحدات البكسل في شيء يمكن أن يكون له توافق واحد لواحد مع المخرجات، تحتاج إلى إضافة طبقة أخرى. تجمع الطبقة الأولى بين المدخلات، بينما تقوم الثانية بتعيين تطابق للمخرجات باستخدام مخرجات الطبقة الأولى كمدخل. انتبه إلى الجدول.

    المدخلات (ل0) الأوزان المخفية (ل1) المخرجات (ل2) 0 0 1 0.1 0.2 0.5 0.2 0 0 1 1 0.2 0.6 0.7 0.1 1 1 0 1 0.3 0.2 0.3 0.9 1 1 1 1 0.2 0.1 0.3 0.8 0

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

    الشبكة العصبية في ثلاث طبقات

    استيراد numpy كـ np def Nonlin(x,deriv=False): if(deriv==True): return f(x)*(1-f(x)) return 1/(1+np.exp(-x)) X = np.array([, , , ]) y = np.array([, , , ]) np.random.seed(1) # تهيئة الأوزان بشكل عشوائي، في المتوسط ​​- 0 Syn0 = 2*np.random. عشوائي ((3,4)) - 1 Syn1 = 2*np.random.random((4,1)) - 1 لـ j في xrange(60000): # انتقل للأمام عبر الطبقات 0 و1 و2 l0 = X l1 = Nonlin(np.dot(l0,syn0)) l2 = Nonlin(np.dot(l1,syn1)) # ما مدى خطأنا بشأن القيمة المطلوبة؟ l2_error = y - l2 if (j% 10000) == 0: print "Error:" + str(np.mean(np.abs(l2_error))) # ما هي الطريقة التي يجب أن تتحرك بها؟ # إذا كنا واثقين من التنبؤ، فلن نحتاج إلى تغييره كثيرًا l2_delta = l2_error*nonlin(l2,deriv=True) # ما مدى تأثير قيم l1 على الأخطاء في l2؟ l1_error = l2_delta.dot(syn1.T) # في أي اتجاه يجب أن نتحرك للوصول إلى l1؟ # إذا كنا واثقين من التنبؤ، فلن نحتاج إلى تغييره كثيرًا l1_delta = l1_error * Nonlin(l1,deriv=True) Syn1 += l1.T.dot(l2_delta) Syn0 += l0.T.dot (l1_delta)

    خطأ: 0.496410031903 خطأ: 0.00858452565325 خطأ: 0.00578945986251 خطأ: 0.00462917677677 خطأ: 0.00395876528027 خطأ: 0.00351012256786

    المتغيرات وأوصافها

    X هي مصفوفة مجموعة بيانات الإدخال؛ سلاسل - أمثلة للتدريب
    y - مصفوفة مجموعة بيانات الإخراج؛ سلاسل - أمثلة للتدريب
    l0 - طبقة الشبكة الأولى المحددة بواسطة بيانات الإدخال
    l1 – الطبقة الثانية من الشبكة، أو الطبقة المخفية
    l2 هي الطبقة النهائية، هذه هي فرضيتنا. أثناء التدرب، يجب أن تقترب من الإجابة الصحيحة.
    Syn0 – الطبقة الأولى من الأوزان، Synapse 0، تجمع بين l0 وl1.
    Syn1 - الطبقة الثانية من الأوزان، Synapse 1، تجمع بين l1 وl2.
    l2_error – خطأ في الشبكة من الناحية الكمية
    l2_delta – خطأ في الشبكة، اعتمادًا على موثوقية التنبؤ. يكاد يكون مطابقًا للخطأ، باستثناء التوقعات الواثقة
    l1_error – من خلال وزن l2_delta مع الأوزان من Syn1، نحسب الخطأ في الطبقة الوسطى/المخفية
    l1_delta – أخطاء الشبكة من l1، والتي يتم قياسها حسب درجة ثقة التنبؤات. مطابق تقريبًا لـ l1_error، باستثناء التوقعات الواثقة

    يجب أن يكون الكود واضحًا إلى حد ما - فهو مجرد تطبيق سابق للشبكة، مكدس في طبقتين، واحدة فوق الأخرى. مخرجات الطبقة الأولى l1 هي مدخلات الطبقة الثانية. هناك شيء جديد فقط في السطر التالي.

    L1_error = l2_delta.dot(syn1.T)

    يستخدم الأخطاء المرجحة بثقة التنبؤات من l2 لحساب الخطأ لـ l1. يمكن القول أننا حصلنا على خطأ مرجح بالمساهمات - فنحن نحسب مقدار مساهمة القيم الموجودة في العقد l1 في الأخطاء الموجودة في l2. هذه الخطوة تسمى الانتشار العكسي. نقوم بعد ذلك بتحديث Syn0 باستخدام نفس الخوارزمية مثل الشبكة العصبية ذات الطبقتين.

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

    المادة مخصصة للأشخاص الذين ليسوا على دراية بلغات البرمجة.

    تحتاج أولاً إلى تثبيت بايثون. فأنت بحاجة إلى تثبيت بيئة مناسبة لكتابة البرامج في بايثون. البوابة مخصصة لهاتين الخطوتين.

    إذا تم تثبيت كل شيء وتكوينه، يمكنك البدء.

    المتغيرات

    عامل- مفهوم أساسي في أي لغة برمجة (وليس فيها فقط). أسهل طريقة للتفكير في المتغير هي كمربع به تسمية. يحتوي هذا الصندوق على شيء (رقم، مصفوفة، كائن، ...) ذو قيمة بالنسبة لنا.

    على سبيل المثال، نريد إنشاء متغير x الذي يجب أن يخزن القيمة 10. في بايثون، سيبدو رمز إنشاء هذا المتغير كما يلي:

    على اليسار نحن نعلنمتغير اسمه x وهذا يعادل وضع علامة اسم على الصندوق. بعد ذلك تأتي علامة التساوي والرقم 10. تلعب علامة التساوي دورًا غير عادي هنا. وهذا لا يعني أن "س يساوي 10". المساواة في هذه الحالة تضع الرقم 10 في المربع. وبعبارة أكثر دقة، نحن تعيينالمتغير x هو الرقم 10.

    الآن، في الكود أدناه يمكننا الوصول إلى هذا المتغير وكذلك تنفيذ إجراءات مختلفة معه.

    يمكنك ببساطة عرض قيمة هذا المتغير على الشاشة:

    X=10 طباعة(x)

    تمثل print(x) استدعاء دالة. وسوف ننظر فيها أبعد من ذلك. الشيء المهم الآن هو أن هذه الوظيفة تطبع على وحدة التحكم ما هو موجود بين الأقواس. بين القوسين لدينا x. في السابق، قمنا بتعيين x القيمة 10. وهذا هو ما تتم طباعة 10 في وحدة التحكم إذا قمت بتشغيل البرنامج أعلاه.

    يمكن إجراء العديد من العمليات البسيطة باستخدام المتغيرات التي تخزن الأرقام: الجمع والطرح والضرب والقسمة والأسي.

    X = 2 y = 3 # إضافة z = x + y print(z) # 5 # الفرق z = x - y print(z) # -1 # المنتج z = x * y print(z) # 6 # القسمة z = x / y print(z) # 0.66666... ​​​​# الأسي z = x ** y print(z) # 8

    في الكود أعلاه، نقوم أولاً بإنشاء متغيرين يحتويان على 2 و3. ثم نقوم بإنشاء متغير z الذي يخزن نتيجة العملية على x وy ويطبع النتائج على وحدة التحكم. يوضح هذا المثال بوضوح أن المتغير يمكنه تغيير قيمته أثناء تنفيذ البرنامج. لذلك، فإن المتغير z يغير قيمته بما يصل إلى 5 مرات.

    المهام

    في بعض الأحيان يصبح من الضروري تنفيذ نفس الإجراءات مرارا وتكرارا. على سبيل المثال، في مشروعنا غالبًا ما نحتاج إلى عرض 5 أسطر من النص.

    "هذا نص مهم للغاية!"
    "هذا النص لا يمكن قراءته"
    "الخطأ في السطر العلوي تم عن قصد"
    "مرحبا وداعا"
    "نهاية"

    سيبدو الكود الخاص بنا كما يلي:

    X = 10 y = x + 8 - 2 print("هذا نص مهم جدًا!") print("لا يمكن قراءة هذا النص") print("تم ارتكاب الخطأ في السطر العلوي عن قصد") print(" مرحبًا وداعًا") print ("النهاية") z = x + y print("هذا نص مهم جدًا!") print("لا يمكن قراءة هذا النص") print("حدث الخطأ في السطر العلوي" عن قصد") print("مرحبًا وداعًا") print("النهاية") test = z print("هذا نص مهم جدًا!") print("لا يمكن قراءة هذا النص") print("الخطأ في تم عمل السطر العلوي عن قصد") print("مرحبا وداعا") print("End")

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

    خاصة في الحالات التي تحتاج فيها إلى تنفيذ نفس الأوامر بشكل متكرر، يمكنك إنشاء وظائف بلغات البرمجة.

    وظيفة- كتلة منفصلة من التعليمات البرمجية يمكن استدعاؤها بالاسم.

    يتم تعريف الوظيفة باستخدام الكلمة الأساسية def. ويتبع ذلك اسم الدالة، ثم الأقواس والنقطتين. بعد ذلك، تحتاج إلى سرد الإجراءات التي سيتم تنفيذها عند استدعاء الوظيفة، مع وضع مسافة بادئة لها.

    Def print_5_lines(): print("هذا نص مهم جدًا!") print("لا يمكن قراءة هذا النص") print("حدث الخطأ في السطر العلوي عن قصد") print("مرحبًا وداعًا") طباعة ("النهاية")

    لقد قمنا الآن بتعريف الدالة print_5_lines(). الآن، إذا أردنا مرة أخرى في مشروعنا إدراج خمسة أسطر، فإننا ببساطة نسمي الدالة. سيتم تنفيذ جميع الإجراءات تلقائيًا.

    # حدد الوظيفة def print_5_lines(): print("هذا نص مهم جدًا!") print("لا يمكن قراءة هذا النص") print("الخطأ في السطر العلوي كان مقصودًا") print("مرحبًا وداعًا" ") print(" End") # رمز مشروعنا x = 10 y = x + 8 - 2 print_5_lines() z = x + y print_5_lines() test = z print_5_lines()

    مريحة، أليس كذلك؟ لقد قمنا بتحسين إمكانية قراءة الكود بشكل جدي. بالإضافة إلى ذلك، تعد الوظائف جيدة أيضًا لأنه إذا كنت تريد تغيير بعض الإجراءات، فأنت تحتاج فقط إلى تصحيح الوظيفة نفسها. سيعمل هذا التغيير في جميع الأماكن التي يتم استدعاء وظيفتك فيها. أي أنه يمكننا تصحيح الخطأ في السطر الثاني من النص الناتج ("لا" > "لا") في نص الوظيفة. سيتم استدعاء الخيار الصحيح تلقائيًا في جميع الأماكن في مشروعنا.

    وظائف مع المعلمات

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

    تسمى المتغيرات التي نمررها إلى الدالة الحجج.

    لنكتب دالة بسيطة تجمع رقمين محددين لها وترجع النتيجة.

    مجموع التعريف (أ، ب): النتيجة = نتيجة الإرجاع أ + ب

    يبدو السطر الأول تقريبًا مثل الوظائف العادية. ولكن بين القوسين يوجد الآن متغيران. هذا خياراتالمهام. تحتوي وظيفتنا على معلمتين (أي أنها تأخذ متغيرين).

    يمكن استخدام المعلمات داخل دالة تمامًا مثل المتغيرات العادية. في السطر الثاني، نقوم بإنشاء نتيجة متغيرة، وهي تساوي مجموع المعلمات a و b. في السطر الثالث نعيد قيمة المتغير الناتج.

    الآن، في مزيد من التعليمات البرمجية يمكننا أن نكتب شيئا من هذا القبيل:

    جديد = مجموع (2، 3) طباعة (جديد)

    نسمي الدالة sum ونمررها وسيطتين على التوالي: 2 و3. 2 تصبح قيمة المتغير a، و3 تصبح قيمة المتغير b. تقوم وظيفتنا بإرجاع قيمة (مجموع 2 و 3) ونستخدمها لإنشاء متغير جديد، جديد .

    يتذكر. في الكود أعلاه، الرقمان 2 و3 هما وسيطات الدالة sum. وفي دالة المجموع نفسها، يكون المتغيران a وb عبارة عن معلمات. بمعنى آخر، المتغيرات التي نمررها إلى دالة عند استدعائها تسمى وسيطات. ولكن داخل الدالة، تسمى هذه المتغيرات التي تم تمريرها المعلمات. في الواقع، هذان اسمان لنفس الشيء، لكن لا ينبغي الخلط بينهما.

    دعونا ننظر إلى مثال آخر. لنقم بإنشاء دالة مربعة (أ) تأخذ رقمًا واحدًا وتقوم بتربيعه:

    Def Square(a): قم بإرجاع a * a

    تتكون وظيفتنا من سطر واحد فقط. يقوم على الفور بإرجاع نتيجة ضرب المعلمة a بواسطة a .

    أعتقد أنك خمنت بالفعل أننا نقوم أيضًا بإخراج البيانات إلى وحدة التحكم باستخدام وظيفة. تسمى هذه الوظيفة print() وتقوم بطباعة الوسيطة التي تم تمريرها إليها إلى وحدة التحكم: رقم، سلسلة، متغير.

    المصفوفات

    إذا كان من الممكن اعتبار المتغير بمثابة صندوق يخزن شيئًا ما (وليس بالضرورة رقمًا)، فيمكن اعتبار المصفوفات بمثابة أرفف كتب. أنها تحتوي على عدة متغيرات في وقت واحد. فيما يلي مثال لمصفوفة مكونة من ثلاثة أرقام وسلسلة واحدة:

    صفيف =

    فيما يلي مثال عندما لا يحتوي المتغير على رقم، بل على كائن آخر. في هذه الحالة، يحتوي المتغير لدينا على مصفوفة. يتم ترقيم كل عنصر من عناصر المصفوفة. دعونا نحاول عرض بعض عناصر المصفوفة:

    صفيف = طباعة (صفيف)

    في وحدة التحكم سترى الرقم 89. لكن لماذا 89 وليس 1؟ المشكلة هي أنه في بايثون، كما هو الحال في العديد من لغات البرمجة الأخرى، يبدأ ترقيم المصفوفات من 0. لذلك، تعطينا المصفوفة ثانيةعنصر المصفوفة، وليس العنصر الأول. للاتصال بالرقم الأول، كان عليك كتابة array .

    حجم الصفيف

    في بعض الأحيان يكون من المفيد جدًا معرفة عدد العناصر في المصفوفة. يمكنك استخدام الدالة len() لهذا الغرض. سيتم حساب عدد العناصر وإرجاع عددها.

    صفيف = طباعة (لين (صفيف))

    ستعرض وحدة التحكم الرقم 4.

    الشروط والدورات

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

    بالإضافة إلى ذلك، غالبًا ما تكون هناك حاجة لتكرار نفس تسلسل الأوامر تقريبًا عدة مرات.

    في الحالة الأولى تساعد الظروف، وفي الحالة الثانية تساعد الدورات.

    شروط

    هناك حاجة إلى شروط لتنفيذ مجموعتين مختلفتين من الإجراءات اعتمادًا على ما إذا كانت العبارة التي يتم اختبارها صحيحة أم خاطئة.

    في بايثون، يمكن كتابة الشروط باستخدام if: ... else: ... build. دعونا نحصل على متغير x = 10. إذا كانت x أقل من 10، فإننا نريد قسمة x على 2. إذا كانت x أكبر من أو تساوي 10، فإننا نريد إنشاء متغير جديد آخر، يساوي مجموع x والرقم 100. هذا هو كيف سيبدو الرمز:

    س = 10 إذا (س< 10): x = x / 2 print(x) else: new = x + 100 print(new)

    بعد إنشاء المتغير x، نبدأ في كتابة شرطنا.

    يبدأ كل شيء بالكلمة الأساسية if (مترجمة من الإنجليزية بـ "if"). بين قوسين نشير إلى التعبير الذي سيتم التحقق منه. في هذه الحالة، نتحقق مما إذا كان المتغير x أقل بالفعل من 10. إذا كان أقل من 10 بالفعل، فنقسمه على 2 ونطبع النتيجة على وحدة التحكم.

    ثم تأتي الكلمة الأساسية else، وبعدها تبدأ مجموعة من الإجراءات التي سيتم تنفيذها إذا كان التعبير الموجود بين قوسين بعد if خطأ.

    إذا كان أكبر من أو يساوي 10، فإننا نقوم بإنشاء متغير جديد يساوي x + 100، ونخرجه أيضًا إلى وحدة التحكم.

    دورات

    هناك حاجة إلى حلقات لتكرار الإجراءات عدة مرات. لنفترض أننا نريد عرض جدول مربعات الأعداد الطبيعية العشرة الأولى. يمكن القيام به على هذا النحو.

    طباعة("المربع 1 هو" + str(1**2)) طباعة ("المربع 2 هو" + str(2**2)) طباعة ("المربع 3 هو" + str(3**2)) طباعة(" "المربع 4 هو" + str(4**2)) print("المربع 5 هو" + str(5**2)) print("المربع 6 هو" + str(6**2)) print("مربع 7 هو " + str(7**2)) print("مربع 8 هو " + str(8**2)) print("مربع 9 هو " + str(9**2)) print("مربع من 10 هو " + str(10**2))

    لا تتفاجأ من حقيقة أننا نضيف أسطرًا. "بداية السطر" + "النهاية" في بايثون تعني ببساطة سلاسل متسلسلة: "بداية نهاية السطر". بنفس الطريقة أعلاه، نضيف السلسلة النصية "مربع x يساوي" ونتيجة رفع الرقم إلى القوة الثانية، ويتم تحويلها باستخدام الدالة str(x**2).

    يبدو الرمز أعلاه زائداً عن الحاجة. ماذا لو أردنا طباعة مربعات أول 100 رقم؟ يؤلمنا الانسحاب..

    في مثل هذه الحالات توجد دورات. هناك نوعان من الحلقات في بايثون: while وfor. دعونا نتعامل معهم واحدا تلو الآخر.

    تكرر حلقة while الأوامر الضرورية طالما ظل الشرط صحيحًا.

    X = 1 بينما x<= 100: print("Квадрат числа " + str(x) + " равен " + str(x**2)) x = x + 1

    نقوم أولاً بإنشاء متغير وتخصيص الرقم 1 له ثم نقوم بإنشاء حلقة while والتحقق مما إذا كانت x أقل من (أو تساوي) 100. إذا كان أقل (أو يساوي) فإننا نقوم بإجراءين:

    1. إخراج المربع x
    2. زيادة × بمقدار 1

    بعد الأمر الثاني، يعود البرنامج إلى الحالة. إذا كان الشرط صحيحا مرة أخرى، فإننا نقوم بتنفيذ هذين الإجراءين مرة أخرى. وهكذا حتى تصبح x مساوية لـ 101. ثم سيعود الشرط خطأ ولن يتم تنفيذ الحلقة بعد الآن.

    تم تصميم حلقة for للتكرار عبر المصفوفات. لنكتب نفس المثال بمربعات أول مائة عدد طبيعي، ولكن من خلال حلقة for.

    بالنسبة لـ x في النطاق (1,101): print("مربع الرقم " + str(x) + " is " + str(x**2))

    دعونا ننظر إلى السطر الأول. نحن نستخدم الكلمة الأساسية لإنشاء حلقة. بعد ذلك، نحدد أننا نريد تكرار إجراءات معينة لجميع x في النطاق من 1 إلى 100. تقوم الدالة range(1,101) بإنشاء مصفوفة من 100 رقم، تبدأ بالرقم 1 وتنتهي بالرقم 100.

    فيما يلي مثال آخر للتكرار عبر مصفوفة باستخدام حلقة for:

    لأني في: طباعة (i * 2)

    يُخرج الكود أعلاه 4 أرقام: 2 و20 و200 و2000. هنا يمكنك أن ترى بوضوح كيف يأخذ كل عنصر من عناصر المصفوفة وينفذ مجموعة من الإجراءات. ثم يأخذ العنصر التالي ويكرر نفس مجموعة الإجراءات. وهكذا حتى نفاد العناصر الموجودة في المصفوفة.

    الطبقات والكائنات

    في الحياة الواقعية، نحن لا نتعامل مع المتغيرات أو الوظائف، بل مع الأشياء. قلم، سيارة، شخص، قطة، كلب، طائرة - أشياء. الآن لنبدأ بالنظر إلى القطة بالتفصيل.

    لديها بعض المعلمات. وتشمل هذه لون المعطف ولون العين ولقبها. ولكن هذا ليس كل شيء. بالإضافة إلى المعلمات، يمكن للقط القيام بإجراءات مختلفة: الخرخرة والهسهسة والخدش.

    لقد وصفنا للتو جميع القطط بشكل تخطيطي. مشابه وصف الخصائص والأفعالبعض الكائنات (على سبيل المثال، قطة) في بايثون تسمى فئة. الفئة هي ببساطة مجموعة من المتغيرات والوظائف التي تصف كائنًا ما.

    من المهم أن نفهم الفرق بين الفئة والكائن. فصل - مخطط، الذي يصف الكائن. الكائن هو لها تجسيد مادي. فئة القطة هي وصف لخصائصها وأفعالها. كائن القط هو القط الحقيقي نفسه. يمكن أن يكون هناك العديد من القطط الحقيقية المختلفة - العديد من كائنات القطط. ولكن هناك فئة واحدة فقط من القطط. مظاهرة جيدة هي الصورة أدناه:

    الطبقات

    لإنشاء فئة (مخطط قطتنا)، تحتاج إلى كتابة فئة الكلمة الأساسية ثم تحديد اسم هذه الفئة:

    فئة القط:

    بعد ذلك نحتاج إلى سرد تصرفات هذه الفئة (إجراءات القط). الإجراءات، كما قد تكون خمنت، هي وظائف محددة داخل الفصل الدراسي. عادةً ما تسمى هذه الوظائف داخل الفصل بالطرق.

    طريقة- دالة محددة داخل الفصل.

    لقد سبق أن وصفنا أساليب القطة لفظيًا أعلاه: الخرخرة، والهسهسة، والخدش. الآن دعونا نفعل ذلك في بايثون.

    # فئة القطة فئة القط: # Purr defpurr(self): print("Purrr!") # Hiss def hiss(self): print("Shhh!") # Scratch def scrabble(self): print("Scratch-scratch" "!")

    بكل بساطة! لقد أخذنا وحددنا ثلاث وظائف عادية، ولكن داخل الفصل فقط.

    من أجل التعامل مع المعلمة الذاتية غير المفهومة، دعونا نضيف طريقة أخرى لقطتنا. ستقوم هذه الطريقة باستدعاء الطرق الثلاث التي تم إنشاؤها بالفعل مرة واحدة.

    # فئة القطة فئة القط: # Purr defpurr(self): print("Purrr!") # Hiss def hiss(self): print("Shhh!") # Scratch def scrabble(self): print("Scratch-scratch" !") # الكل معًا def all_in_one(self): self.purr() self.hiss() self.scrabble()

    كما ترون، فإن المعلمة self، المطلوبة لأي عملية، تسمح لنا بالوصول إلى أساليب ومتغيرات الفئة نفسها! وبدون هذه الحجة، لن نكون قادرين على القيام بمثل هذه الإجراءات.

    لنقم الآن بتعيين خصائص قطتنا (لون الفراء، ولون العين، واللقب). كيف افعلها؟ في أي فئة يمكنك تحديد الدالة __init__(). يتم استدعاء هذه الوظيفة دائمًا عندما نقوم بإنشاء كائن حقيقي من فئتنا.

    في طريقة __init__() الموضحة أعلاه، قمنا بتعيين متغيرات القطة. كيف نفعل ذلك؟ أولاً، نقوم بتمرير 3 وسيطات لهذه الطريقة، وهي المسؤولة عن لون المعطف ولون العين واللقب. بعد ذلك، نستخدم المعلمة self لتعيين قطتنا فورًا على السمات الثلاث الموضحة أعلاه عند إنشاء كائن.

    ماذا يعني هذا الخط؟

    Self.wool_color = Wool_color

    على الجانب الأيسر، نقوم بإنشاء سمة لقطتنا تسمى Wool_color، ثم نقوم بتعيين هذه السمة القيمة الموجودة في معلمة Wool_color التي مررناها إلى الدالة __init__(). كما ترون، السطر أعلاه لا يختلف عن إنشاء المتغير العادي. تشير البادئة self فقط إلى أن هذا المتغير ينتمي إلى فئة Cat.

    يصف- متغير ينتمي إلى فئة.

    لذلك، قمنا بإنشاء فئة القطط الجاهزة. هنا هو الكود الخاص به:

    # فئة القطة فئة القط: # الإجراءات التي يجب تنفيذها عند إنشاء كائن "قطة" def __init__(self, Wool_color,eyes_color, name): self.wool_color = Wool_color self.eyes_color =eyes_color self.name = name # Purr defpurr( self): print("Purrr!") # Hiss def hiss(self): print("Shhh!") # Scratch def scrabble(self): print("Scratch-scratch!") # الكل معًا def all_in_one(self) : self.purr() self.hiss() self.scrabble()

    أشياء

    لقد أنشأنا مخطط القط. لنقم الآن بإنشاء كائن قطة حقيقي باستخدام هذا المخطط:

    My_cat = قطة("أسود"، "أخضر"، "زوسيا")

    في السطر أعلاه، قمنا بإنشاء متغير my_cat ثم قمنا بتعيين كائن من فئة Cat له. يبدو كل هذا بمثابة استدعاء لبعض الوظائف Cat(...) . في الواقع، هذا صحيح. باستخدام هذا الإدخال، نسمي الطريقة __init__()‎ لفئة Cat. تأخذ الدالة __init__() في فصلنا 4 وسائط: كائن الفئة الذاتية نفسه، والذي لا يحتاج إلى تحديد، بالإضافة إلى 3 وسائط أخرى مختلفة، والتي تصبح بعد ذلك سمات لقطتنا.

    لذا، باستخدام السطر أعلاه قمنا بإنشاء كائن قطة حقيقي. تتميز قطتنا بالصفات التالية: الفراء الأسود والعيون الخضراء واللقب زوسيا. لنطبع هذه السمات على وحدة التحكم:

    طباعة (my_cat.wool_color) طباعة (my_cat.eyes_color) طباعة (my_cat.name)

    أي أنه يمكننا الوصول إلى سمات الكائن عن طريق كتابة اسم الكائن ووضع نقطة والإشارة إلى اسم السمة المطلوبة.

    يمكن تغيير سمات القطة. على سبيل المثال، دعونا نغير اسم قطتنا:

    My_cat.name = "نيوشا"

    الآن، إذا قمت بعرض اسم القطة في وحدة التحكم مرة أخرى، فسوف ترى Nyusha بدلاً من Zosia.

    اسمحوا لي أن أذكرك أن فصل قطتنا يسمح لها بأداء إجراءات معينة. إذا قمنا بمداعبة Zosya/Nyusha، فسوف تبدأ بالخرخرة:

    My_cat.purr()

    سيؤدي تنفيذ هذا الأمر إلى طباعة النص "Purrr!" على وحدة التحكم. كما ترون، الوصول إلى أساليب الكائن هو بنفس سهولة الوصول إلى سماته.

    وحدات

    أي ملف بامتداد .py هو وحدة نمطية. حتى تلك التي تعمل فيها على هذه المقالة. ما هي الحاجة ل؟ للراحة. يقوم الكثير من الأشخاص بإنشاء ملفات ذات وظائف وفئات مفيدة. يقوم المبرمجون الآخرون بتوصيل وحدات الطرف الثالث هذه ويمكنهم استخدام جميع الوظائف والفئات المحددة فيها، وبالتالي تبسيط عملهم.

    على سبيل المثال، لا تحتاج إلى إضاعة الوقت في كتابة وظائفك الخاصة للعمل مع المصفوفات. يكفي توصيل الوحدة numpy واستخدام وظائفها وفئاتها.

    في الوقت الحالي، كتب مبرمجو بايثون الآخرون أكثر من 110.000 وحدة مختلفة. تتيح لك الوحدة numpy المذكورة أعلاه العمل بسرعة وسهولة مع المصفوفات والمصفوفات متعددة الأبعاد. توفر وحدة الرياضيات العديد من الطرق للتعامل مع الأرقام: جيب التمام، وجيب التمام، وتحويل الدرجات إلى راديان، وما إلى ذلك، وما إلى ذلك....

    تثبيت الوحدة

    يتم تثبيت Python مع مجموعة قياسية من الوحدات. تتضمن هذه المجموعة عددًا كبيرًا جدًا من الوحدات التي تتيح لك العمل مع الرياضيات وطلبات الويب وقراءة الملفات وكتابتها وتنفيذ الإجراءات الضرورية الأخرى.

    إذا كنت تريد استخدام وحدة نمطية غير مضمنة في المجموعة القياسية، فستحتاج إلى تثبيتها. لتثبيت الوحدة، افتح سطر الأوامر (Win + R، ثم أدخل "cmd" في الحقل الذي يظهر) وأدخل الأمر فيه:

    تثبيت النقطة [module_name]

    ستبدأ عملية تثبيت الوحدة. عند اكتماله، يمكنك استخدام الوحدة المثبتة في برنامجك بأمان.

    توصيل واستخدام الوحدة

    من السهل جدًا توصيل وحدة الطرف الثالث. ما عليك سوى كتابة سطر واحد قصير من التعليمات البرمجية:

    استيراد [module_name]

    على سبيل المثال، لاستيراد وحدة تسمح لك بالعمل مع الدوال الرياضية، تحتاج إلى كتابة ما يلي:

    استيراد الرياضيات

    كيفية الوصول إلى وظيفة الوحدة النمطية؟ تحتاج إلى كتابة اسم الوحدة، ثم وضع نقطة وكتابة اسم الوظيفة/الفئة. على سبيل المثال، تم إيجاد مضروب 10 على النحو التالي:

    عامل الرياضيات(10)

    وهذا يعني أننا لجأنا إلى دالة العامل (أ)، والتي تم تعريفها داخل وحدة الرياضيات. وهذا أمر مناسب، لأننا لا نحتاج إلى إضاعة الوقت وإنشاء دالة يدويًا تحسب مضروب الرقم. يمكنك توصيل الوحدة وتنفيذ الإجراء المطلوب على الفور.