
مرحبا ، habrozhiteli! يضع الكتاب الأساس لمزيد من التمكن من تكنولوجيا التعلم العميق. ويبدأ مع وصف لأساسيات الشبكات العصبية ومن ثم يبحث بالتفصيل طبقات إضافية من الهندسة المعمارية.
تم كتابة هذا الكتاب خصيصًا بهدف توفير أدنى عتبة دخول ممكنة. لا تحتاج إلى معرفة الجبر الخطي والأساليب العددية والتحسينات المحدبة وحتى التعلم الآلي. سيتم توضيح كل ما هو مطلوب لفهم التعلم العميق كما تذهب.
نحن نقدم لك أن تتعرف على المقطع "ما هو إطار التعلم العميق؟"
الأدوات الجيدة تقلل من الأخطاء وتطور السرعة وتزيد من سرعة التنفيذ.إذا قرأت الكثير عن التعلم العميق ، فمن المحتمل أن تكون قد صادفتك إطارات معروفة مثل PyTorch و TensorFlow و Theano (تم الإعلان عنها مؤخرًا) و Keras و Lasagne و DyNet. في السنوات القليلة الماضية ، تطورت الأطر بسرعة كبيرة ، وعلى الرغم من حقيقة أن جميع هذه الأُطر يتم توزيعها بحرية ومفتوحة المصدر ، كل منها لديه روح المنافسة والصداقة الحميمة.
حتى الآن ، لقد تجنبت مناقشة أطر العمل ، لأنه أولاً وقبل كل شيء ، كان من المهم للغاية بالنسبة لك أن تفهم ما يجري وراء الكواليس ، وتنفيذ الخوارزميات يدويًا (باستخدام مكتبة NumPy فقط). ولكن الآن سنبدأ في استخدام مثل هذه الأُطُر ، لأن الشبكات التي سنقوم بتدريبها ، والشبكات التي تحتوي على ذاكرة قصيرة المدى (LSTM) طويلة التعقيد ، والرمز الذي ينفذها باستخدام NumPy يصعب قراءته واستخدامه وتصحيحه (التدرجات في هذا الرمز تم العثور عليها في كل مكان).
هذا هو التعقيد الذي تم تصميم أطر التعلم العميق لمعالجته. يمكن لإطار التعلم العميق أن يقلل بدرجة كبيرة من تعقيد الشفرة (وكذلك يقلل من عدد الأخطاء ويزيد من سرعة التطوير) ويزيد من سرعة تنفيذه ، خاصة إذا كنت تستخدم معالج رسومات (GPU) لتدريب الشبكة العصبية ، والتي يمكنها تسريع العملية بمقدار 10-100 مرة. لهذه الأسباب ، يتم استخدام الأطر في كل مكان تقريبًا في مجتمع البحث ، وسيصبح فهم ميزات عملهم مفيدًا في حياتك المهنية كمستخدم وباحث تعلم عميق.
لكننا لن نحصر أنفسنا في إطار أي إطار عمل معين ، لأن هذا سيمنعك من معرفة كيفية عمل جميع هذه النماذج المعقدة (مثل LSTM). بدلاً من ذلك ، سنقوم بإنشاء إطار عمل خفيف الوزن خاص بنا ، باتباع أحدث الاتجاهات في تطوير الأطر. باتباع هذا المسار ، ستعرف بالضبط ما تفعله الأُطر عندما يتم إنشاء أبنية معقدة بمساعدتهم. بالإضافة إلى ذلك ، فإن محاولة إنشاء إطار صغير خاص بك بمفردك سيساعدك على التبديل بسلاسة إلى استخدام أطر التعلم العميقة الحقيقية ، لأنك ستعرف بالفعل مبادئ تنظيم واجهة البرنامج (API) ووظائفها. كان هذا التمرين مفيدًا جدًا لي ، وقد اتضح أن المعرفة المكتسبة عند إنشاء إطار العمل الخاص بي كانت مفيدة للغاية عند تصحيح نماذج المشكلات.
كيف يبسط الإطار الكود؟ التحدث بشكل مجردة ، فإنه يلغي الحاجة إلى كتابة نفس الكود مرارا وتكرارا. على وجه التحديد ، تتمثل الميزة الأكثر ملاءمة لإطار التعلم العميق في دعم backpropagation التلقائي والتحسين التلقائي. يتيح لك ذلك كتابة رمز التوزيع المباشر فقط ، وسيهتم الإطار تلقائيًا بالتوزيع الخلفي وتصحيح الأوزان. تبسط معظم الأُطر الحديثة الشفرة التي تنفذ التوزيع المباشر من خلال تقديم واجهات عالية المستوى لتحديد الطبقات النموذجية ووظائف الفقد.
مقدمة إلى التنسور
التنسورات هي شكل تجريدي من المتجهات والمصفوفاتحتى هذه اللحظة ، كنا نستخدم المتجهات والمصفوفات باعتبارها الهياكل الرئيسية. اسمحوا لي أن أذكرك بأن المصفوفة هي قائمة من المتجهات ، وأن المتجه عبارة عن قائمة من الأعداد القياسية (أرقام مفردة). الموتر عبارة عن نموذج تجريدي لتمثيل قوائم الأرقام المتداخلة. المتجه عبارة عن موتر أحادي البعد. المصفوفة عبارة عن موتر ثنائي الأبعاد ، وتسمى الهياكل ذات عدد كبير من الأبعاد tensors n-dimensional. لذلك ، لنبدأ في إنشاء إطار تعلم عميق جديد عن طريق تحديد نوع أساسي ، والذي سنطلق عليه Tensor:
import numpy as np class Tensor (object): def __init__(self, data): self.data = np.array(data) def __add__(self, other): return Tensor(self.data + other.data) def __repr__(self): return str(self.data.__repr__()) def __str__(self): return str(self.data.__str__()) x = Tensor([1,2,3,4,5]) print(x) [1 2 3 4 5] y = x + x print(y) [2 4 6 8 10]
هذه هي النسخة الأولى من هيكل البيانات الأساسي لدينا. لاحظ أنه يخزن جميع المعلومات العددية في صفيف NumPy (self.data) ويدعم عملية توتر واحد (الجمع). لا تعد إضافة عمليات إضافية أمرًا صعبًا على الإطلاق ، ما عليك سوى إضافة وظائف إضافية مع الوظيفة المقابلة لفئة Tensor.
مقدمة لحساب التدرج الآلي (autograd)
في السابق ، أجرينا الانتشار الخلفي اليدوي. الآن لنجعلها تلقائية!في الفصل 4 ، قدمنا المشتقات. منذ ذلك الحين ، قمنا بحساب هذه المشتقات يدويًا في كل شبكة عصبية جديدة. واسمحوا لي أن أذكركم بأن هذا يتحقق من خلال الحركة العكسية عبر الشبكة العصبية: أولاً ، يتم حساب التدرج في إخراج الشبكة ، ثم يتم استخدام هذه النتيجة لحساب المشتق في المكون السابق ، وهكذا ، حتى يتم تحديد التدرجات الصحيحة لجميع الأوزان في الهيكل. يمكن أيضًا إضافة هذا المنطق لحساب التدرجات إلى فئة الموتر. يظهر التالي ما كان يدور في خلدي.
import numpy as np class Tensor (object): def __init__(self, data, creators=None, creation_op=None): self.data = np.array(data) self.creation_op = creation_op self.creators = creators self.grad = None def backward(self, grad): self.grad = grad if(self.creation_op == "add"): self.creators[0].backward(grad) self.creators[1].backward(grad) def __add__(self, other): return Tensor(self.data + other.data, creators=[self,other], creation_op="add") def __repr__(self): return str(self.data.__repr__()) def __str__(self): return str(self.data.__str__()) x = Tensor([1,2,3,4,5]) y = Tensor([2,2,2,2,2]) z = x + y z.backward(Tensor(np.array([1,1,1,1,1])))
هذه الطريقة تقدم اثنين من الابتكارات. أولاً ، يتلقى كل تينسور سمتين جديدتين. المنشئون عبارة عن قائمة بأي موانع تستخدم لإنشاء الموتر الحالي (الإعدادات الافتراضية إلى لا شيء). وهذا هو ، إذا تم الحصول على الموتر z من خلال إضافة التينسور الأخريين ، x و y ، فإن سمة منشئي التينور z سوف تحتوي على التينورز x و y. create_op هي سمة مصاحبة تخزن العمليات المستخدمة في عملية إنشاء هذا الموتر. بمعنى أن التعليمة z = x + y ستقوم بإنشاء رسم بياني حسابي بثلاث عقد (x و y و z) وحافتين (z -> x و z -> y). يتم توقيع كل حافة بواسطة العملية من create_op ، أي ، إضافة. سيساعد هذا الرسم البياني في تنظيم الانتشار العكسي المتدرج للتدرجات.
أول ابتكار في هذا التطبيق هو الإنشاء التلقائي للرسم البياني أثناء كل عملية رياضية. إذا أخذنا z ونجري عملية أخرى ، فسيستمر الرسم البياني في متغير مرجعي جديد z.
الابتكار الثاني في هذا الإصدار من فئة Tensor هو القدرة على استخدام الرسم البياني لحساب التدرجات. إذا قمت باستدعاء الأسلوب z.backward () ، فسوف يمر التدرج اللوني لـ x و y ، مع مراعاة الوظيفة التي تم إنشاؤها tensor z (add). كما هو موضح في المثال أعلاه ، فإننا نمرر متجه التدرج (np.array ([1،1،1،1،1]]) إلى z ، وهذا الشخص يطبقه على الوالدين. كما تتذكر على الأرجح من الفصل 4 ، فإن الانتشار الخلفي من خلال الجمع يعني تطبيق الانتشار الخلفي. في هذه الحالة ، لدينا تدرج واحد فقط لإضافته إلى x و y ، لذلك نقوم بنسخه من z إلى x و y:
print(x.grad) print(y.grad) print(z.creators) print(z.creation_op) [1 1 1 1 1] [1 1 1 1 1] [array([1, 2, 3, 4, 5]), array([2, 2, 2, 2, 2])] add
الميزة الأكثر وضوحًا لهذا الشكل من أشكال التدرج التلقائي هي أنها تعمل بشكل متكرر - يستدعي كل متجه طريقة .backward () لجميع الوالدين من قائمة self.creators:
»يمكن الاطلاع على مزيد من المعلومات حول الكتاب على
موقع الناشر»
المحتويات»
مقتطفاتخصم 25٪ على كوبون للمتجولين -
التعلم العميقعند دفع النسخة الورقية من الكتاب ، يتم إرسال كتاب إلكتروني عبر البريد الإلكتروني.