وصلنا للمثال الثاني وهوا الشبكات العصبية، وبدون تفيكر الخلايا العصبية هي احد العوامل الاساسيه التي انشأت مفهوم "ألذكاء الاصطناعي".
في هذا الدرس سنقوم ببناء الخلية العصبية من الصفر حتى نجعلها تقوم بوظييفه معينه وليكن تخمين الارقام المكتوبة يدويا.
والتطبيقات للخلايا العصبية لا تقتصر على هذا فقط اليك بعض الامثلة.
معالجة الصور
تصنيف الصور: يمكننا ببناء نموذج لتصنيف الصور إلى فئات (على سبيل المثال، القطط و الكلاب، أو أنواع الزهور).
اكتشاف الكائنات: يمكن أن نستخدمها للتعرف على الاشياء في الصور أو مقاطع الفيديو.
في الطب: يمكننا تطوير نموزج يقوم بالتعرف على الاورام في صور الاشعة.
نقل الأسلوب: يمكن استخدامها ايضا لـ لنقل الأساليب الفنية بين الصور.
النصوص
تحليل المشاعر: تحديد المشاعر في اكلام (إيجابية أو سلبية أو محايدة).
ترجمة اللغة: نظام ترجمة آلية لا يترجم الكلام ترجمة حرفية.
تلخيص النصوص: يمكننا ايضا انشاء نموذج يقوم بعمل ملخصات موجزة للمستندات الطويلة.
الإجابة على الأسئلة: حتى يمكننا بتطوير أنظمة مثل ChatGPT من OpenAI للإجابة على استفسارات المستخدمين.
الكلام والصوت
التعرف على الكلام: يمكننا تحويل الكلام الصوتي الى كتابة نصية.
او العكس مثل تحويل النص إلى كلام: إنشاء نظام لتوليد الكلام من النص.
إنشاء الموسيقى: استخدام الشبكات العصبية لتأليف الموسيقى.
تصنيف الصوت: تصنيف المقاطع الصوتية إلى فئات (على سبيل المثال، اصوات طيور، أصوات سيارات).
الألعاب والمحاكاة
يمكنك ايضا عمل روبوتات تلعب الالعاب عوضا عنك: AI Game Bots ( و اعتقد اني سأقوم بعملها قريبا ).
في صناعة الالعاب: يمكننا عمل نموزج ايضا يقوم بإنشاء Assets للعبة الخاصة بك.
تحليل سلوك اللاعب الخصم: دراسة حركة لاعب معين والتنبؤ بما سيقوم به.
الرعاية الصحية والتكنولوجيا الحيوية
التنبؤ بالأمراض: إنشاء نماذج للكشف المبكر عن أمراض مثل مرض السكري أو السرطان أو أمراض القلب.
مراقبة المرضى: التنبؤ بحالة المريض بناءً على بعض البيانات.
التمويل والأعمال التجارية
الكشف عمليات الاحتيال المالي: بناء نماذج للكشف عن المعاملات الغريبة وغسل الاموال.
التنبؤ بسعر السهم: استخدم الشبكات العصبية للتنبؤ باتجاهات الأسهم.
التصنيف الائتماني او ما يعرف بـ Credit Scoring : توقع الجدارة الائتمانية باستخدام البيانات المالية.
التخصيص والتوصيات
أنظمة التوصية: اقترح أفلامًا أو موسيقى أو منتجات (مثل YouTube أو Amazon).
التسعير الديناميكي: تنفيذ استراتيجيات التسعير بناءً على سلوك المستخدم واتجاهات السوق.
الروبوتات وأنظمة التحكم
المركبات ذاتية القيادة: بناء نماذج للكشف عن الكائنات والاشياء المحيطة بالسيارة والتحكم فيها وجعل السيارات ذاتية القيادة.
الملاحة الروبوتية: تطوير أنظمة للكشف عن العوائق وتخطيط المسار.
الـ Generative Models
إنشاء أعمال فنية أو تصميمات أو حتى صور واقعية.
إنشاء الشعر أو القصص أو التعليمات البرمجية باستخدام نماذج اللغة.
عمل Deepfake: (للاستخدام الأخلاقي فقط) تبديل الوجوه في مقاطع الفيديو أو إنشاء صوت/فيديو واقعي.
التعليم والتدريب
منصات التعلم التكيفي: تخصيص المحتوى للطلاب.
تصحيح الامتحانات: أتمتة تصحيح المقالات والاختبارات.
المعلمون الافتراضيون: إنشاء أنظمة الذكاء الاصطناعي للتفاعل الفردي بين الطلاب.
التطبيقات البيئية والاجتماعية
المناخ: التنبؤ بالتغيرات والأنماط البيئية.
مراقبة الحياة البرية: استخدام الذكاء الاصطناعي لتتبع الحيوانات ومراقبتها.
التنبؤ بالكوارث: التنبؤ بالزلازل أو الفيضانات أو العواصف.
الأمن السيبراني
الـ Anomaly Detection : تحديد الأنماط غير العادية في حركة المرور على الشبكة.
الـ Phishing Detection : تصنيف رسائل البريد الإلكتروني ومواقع الويب على أنها آمنة أو ضارة.
اختبار قوة كلمة المرور: تقييم واقتراح كلمات مرور آمنة.
Neural Networksمفهوم الـ
من المرجع انك قمت بروئة مثل هذا النمط من قبل، لا تقلق الامر بسيط.
الشبكات العصبية هي نماذج حسابية مستوحاة من الدماغ البشري، وتستخدم على نطاق واسع في مجالات مختلفة ذكرت من قبل. وفيما يلي الأنواع الرئيسية للشبكات العصبية:
Feedforward Neural Networks (FNN)
Convolutional Neural Networks (CNN)
Recurrent Neural Networks (RNN)
Long Short-Term Memory Networks (LSTM)
Transformer Networks
الانواع لا تقتصر على تلك فقط لكن، هم الاكثر شيوعا..
حسنا، في البداية، ما هي الـ Neural Networks ؟ وكيف تعمل.
افضل تشبيه للـ Neural Networks برأيي وكيفية عملها هو الـ Function . لكن ما هي الـ Function ؟ ؟
في عالم البرمجة ... الـ Function هي داله، نعطيها مدخلات وتعطينا مخرجات.. حسب نوع ووظيفه الداله.. مثال:
def x(a, b):
y= a + b
return y
result = x(5, 2)
print(result)
وفي عالم الرياضيات هي مجرد ايضا داله لها مدخلات ولها مخرجات.
طريقة عمل الشبكات العصبية او الـ Neural Networks لاتختلف كثيرا عن ما رأيته قبل قليل...
هذاهو شكل ابسط مكون للـ Neural Networks وتسمى Perceptron وفي الواقع هي اشبه في شكلها وطريقة اتصالها وايضا عملها بالخلايا العصبية للإنسان..
من الخصائص الأساسية في الشبكات العصبية التي يجب أن تعرفها جيدًا هي أن كل إدخال (input) يحمل قيمة، وكل إدخال متصل بالخلية العصبية عبر اتصال معين (الذي يظهر باللون الأزرق في الصورة). هذا الاتصال يحمل أيضًا قيمة تسمى الوزن (weight)، بينما الخلية نفسها في مثالنا هي Perceptron وتحمل قيمة تُسمى الانحياز (bias)، التي تظهر في الصورة وتقدر بـ 0.6.
قد يسأل البعض: لماذا كل هذه القيم والأرقام؟
حسنًا، الموضوع بسيط للغاية.
لنفترض أنك ترغب في إصابة الدبابة البرتقالية على اليمين. في بداية اللعبة، عند المحاولة الأولى، يكون لديك موقع عشوائي، وكذلك اتجاه فوهة المدفع موجه بشكل عشوائي، بالإضافة إلى قوة الضربة العشوائية. لذلك، احتمالية إصابة الهدف ستكون منخفضة في البداية.
إذا اعتمدت على متغير واحد فقط، مثل قوة الضربة، فمن المحتمل أن تصيب الهدف بعد عدة محاولات. لكن ستظل دقة إصابتك منخفضة، وإذا تحرك الهدف، سيكون الوضع سيئًا.
لكن مع زيادة عدد المتغيرات التي يمكنك التحكم بها (مثل المسافة، الاتجاه، السرعة، وما إلى ذلك)، ستزداد دقة التعلم في كل مرة، وستتمكن من تعديل هذه المتغيرات بشكل تدريجي نحو الإصابة المثالية.
افترض أنك تحاول إصابة الدبابة البرتقالية الموجودة على اليمين. في بداية اللعبة، وبالضبط في المرة الأولى، يكون لديك موقع عشوائي، واتجاه فوهة المدفع موجه بشكل عشوائي أيضًا، بالإضافة إلى قوة ضربة عشوائية. لذلك، احتمالية إصابة الهدف ستكون ضئيلة.
إذا لم تكن لديك مجموعة متنوعة من المتغيرات التي يمكنك التحكم بها، فغالبًا ستصيب نفس المكان في كل مرة. لكن مع زيادة عدد المتغيرات التي يمكننا تعديلها، فإن التعلم من الأخطاء سيكون أفضل في كل محاولة، وستتمكن من توجيه المتغيرات نحو الهدف بدقة أكبر.
ملاحظة: إذا اعتمدنا على متغير واحد فقط، مثل قوة الضربة، فقد تصيب الهدف بعد عدة محاولات. لكن الدقة ستظل ضعيفة، وإذا تحرك الهدف، ستكون الإصابة صعبة جدًا.
كما هو الحال في النموذج الذي أمامنا، لدينا خلية واحدة فقط. لذلك، من الصعب أن نحصل على نتائج دقيقة للغاية، مثل 95% إلى 100% في كل مرة. لكن إذا كان لدينا العديد من الخلايا، سيكون لدينا مجموعة متنوعة من المتغيرات التي يمكننا التحكم بها (مثل الوزن و الانحياز).
لقد ذكرنا أن هذه الخلايا تشبه الخلايا العصبية في الدماغ البشري في كل شيء. الآن، دعونا نرى كيفية عملها بشكل عملي. لنأخذ أبسط مثال لدينا هنا وهو "تصنيف صورة".
في هذا المثال، المخرجات ستكون عبارة عن تصنيف، مثل "قطة" أو "كلب"، أو حتى قيم مثل 0 أو 1. لدينا خلية واحدة فقط، مما يعني أن النموذج سيكون محدودًا إلى حد ما في دقته. أما المدخلات فستكون صورة، وبما أن الصورة هي عبارة عن فن بكسل بحجم 8x8، فإن البكسل هو أصغر جزء في الصورة. وبالتالي، سيكون لدينا 8 * 8 = 64 مدخلًا للخلية.
كل بكسل في الصورة سيحتوي على قيمة تمثل اللون المميز لذلك البكسل. على سبيل المثال، إذا كانت الصورة تظهر قطة، فقد تحتوي على ألوان مثل الأسود، الرمادي، الوردي، الأبيض، والأخضر. المدخل الأول في هذه الحالة سيكون اللون الأبيض (أول جزء من الصورة) والذي سيحمل القيمة 1، يليه مباشرة اللون الأسود الذي سيحمل القيمة 0. كل لون في الصورة سيكون مميزًا حسب شدته الضوئية، ومن ثم يتم تعيين رقم يميز كل لون.
إذن، لدينا 64 رقمًا كمدخلات للخلية، ولكل مدخل 64 اتصالًا (connections) يقابله 64 وزنًا (weights). ولكن يبقى لدينا انحياز واحد (bias) لأن لدينا خلية واحدة فقط، كما ذكرنا.
MINST
بعد أن فهمنا آلية عمل الشبكات العصبية، دعونا نأخذ مثالًا عمليًا، وهو تخمين الأرقام المكتوبة يدويًا. سنقوم ببناء شبكة عصبية أمامية (Feedforward Neural Network) مكونة من خلية واحدة فقط في البداية، ثم بعد ذلك سنقوم بزيادة عدد الخلايا ونرى الفرق والتحسن الذي سيطرأ على الأداء.
سنستخدم إحدى أشهر المكتبات في الذكاء الاصطناعي وهي PyTorch لبناء النموذج. أولًا، دعونا نبدأ بتثبيت PyTorch:
pip install torch torchvision torchaudio
pip install torch torchvision torchaudio --index-url [URL]https://download.pytorch.org/whl/cu118[/URL]
import torch
print(torch.__version__)
print("CUDA available:", torch.cuda.is_available())
كما فعلنا في المثال السابق، أولًا نحتاج إلى البيانات التي سنقوم بتدريب النموذج عليها، ثم نقوم بتقسيمها إلى بيانات تدريب وبيانات لاختبار النموذج بعد التدريب. في هذه الحالة، سنستخدم مجموعة بيانات MNIST، وهي عبارة عن 70,000 صورة تمثل الأرقام من 0 إلى 9. إليكم شكل هذه البيانات:
لنبدأ بتجهيز المكتبات اللازمة ثم تحميلها. أولًا، سنحتاج إلى تثبيت مكتبة PyTorch بالإضافة إلى torchvision، التي تحتوي على مجموعة بيانات MNIST.
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
# Transform to flatten images and normalize them
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
# Download and load training and test data
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=False)
هنا سيقوم هذا الجزء من الكود بتحميل الـ Dataset تلقائيا على حاسوبك إذا لم تكن موجودة من قبل.
A single-layer perceptron is essentially a linear layer:
class SingleLayerPerceptron(nn.Module):
def __init__(self, input_size, num_classes):
super(SingleLayerPerceptron, self).__init__()
self.linear = nn.Linear(input_size, num_classes)
def forward(self, x):
return self.linear(x)
حجم الصور في مجموعة بيانات MNIST هو 28 بكسل × 28 بكسل. أما المخرجات فهي عبارة عن 10 احتمالات تمثل الأرقام من 0 إلى 9. كل صورة في هذه المجموعة يتم تصنيفها إلى واحدة من هذه الأرقام.
# Model parameters
input_size = 28 * 28 # Each MNIST image is 28x28 pixels
num_classes = 10 # 10 classes for digits 0-9
# Model, loss, and optimizer
model = SingleLayerPerceptron(input_size, num_classes)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
حجم الصور في مجموعة بيانات MNIST هو 28 بكسل × 28 بكسل. أما المخرجات فهي عبارة عن 10 احتمالات تمثل الأرقام من 0 إلى 9. كل صورة في هذه المجموعة يتم تصنيفها إلى واحدة من هذه الأرقام.
# Training the mode l
num_epochs = 100
for epoch in range(num_epochs):
model.train()
total_loss = 0
for images, labels in train_loader:
# Flatten images
images = images.view(-1, 28 * 28)
# Forward pass
outputs = model(images)
loss = criterion(outputs, labels)
# Backward pass and optimization
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch [{epoch + 1}/{num_epochs}], Loss: {total_loss / len(train_loader):.4f}")
وأخيرًا، نصل إلى مرحلة التدريب، التي تنقسم إلى جزئين. الجزء الأول هو عندما نقوم بتدريب النموذج وجعله يرى البيانات لأول مرة. لدينا أيضًا عدد الـ epochs، وهو عدد المرات التي نقوم فيها بتدريب النموذج، أو بمعنى آخر، عدد المرات التي نصحح فيها أخطاء النموذج خلال التدريب. كلما زاد هذا العدد، زادت دقة النموذج، ولكن إذا زاد العدد بشكل كبير، قد يؤدي ذلك إلى التعلم الزائد، حيث سيقوم النموذج بحفظ الصور بدلاً من فهم الأنماط (أي "حافظ مش فاهم").
الجزء الثاني من التدريب هو الـ Backpropagation، حيث نقوم بحساب الأخطاء التي ارتكبها النموذج أثناء التدريب. على سبيل المثال، عندما نقوم بتدريب النموذج للمرة الأولى، واكتشفنا أثناء مرحلة الاختبار أنه تعرف على الرقم 1 على أنه الرقم 4، سنقوم بتعديل الأوزان (weights) قليلاً لجعل النموذج أكثر دقة في المرة القادمة (تذكر مثال الدبابة).
تذكر أنه في حالتنا، لدينا خلية واحدة فقط، لذلك سيكون تأثير عملية الـ Backpropagation صغيرًا نسبيًا ولكن ملاحظًا.
# Evaluate the model
model.eval()
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
# Flatten images
images = images.view(-1, 28 * 28)
# Predictions
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print(f"Test Accuracy: {accuracy:.2f}%")
بعد ذلك، يأتي تقييم النموذج من حيث الدقة، وعدد مرات التخمين الصحيح و التخمين الخطأ. نقوم بحساب نسبة الدقة عن طريق مقارنة المخرجات التي تنبأ بها النموذج مع النتائج الفعلية. على سبيل المثال، إذا كانت الصورة التي دخلت للنموذج هي رقم 3، وكان النموذج قد توقع الرقم 3 أيضًا، فهذا يعتبر تخمينًا صحيحًا.
نسبة الدقة هي مقياس مهم لمعرفة مدى قدرة النموذج على التعميم والتعرف على الأنماط بشكل صحيح.
نلاحظ هنا أنه عند تدريب النموذج ثلاث مرات، ومع كل مرة كانت نسبة الخطأ تقل تدريجيًا حتى وصلنا إلى دقة تصل إلى 90.94%. الآن، سأعيد نفس التجربة ولكن مع عدد مرات تدريب أكبر لأرى كيف تؤثر هذه الزيادة في عدد الـ epochs على دقة النموذج.
ونلاحظ هنا أنه مع تدريب النموذج 15 مرة، ارتفعت الدقة إلى 92%. ولكن حتى مع زيادة عدد مرات التدريب، ستظل النسبة تقارب نفسها، وهذا بسبب قلة المتغيرات التي يمكن ضبطها (عدد الخلايا). فعند استخدام خلية واحدة فقط، تكون قدرة النموذج على التعلم والتحسن محدودة، حيث لا توجد مساحة كافية لزيادة التفاعل بين المتغيرات لتحقيق تحسن كبير في الدقة.
لكن إذا قمنا بزيادة عدد الخلايا بإضافة المزيد من الطبقات (layers)، يمكننا الوصول إلى دقة تقارب 99.67% أو أكثر. زيادة عدد الخلايا والطبقات يتيح للنموذج تعلم الأنماط بشكل أكثر تعقيدًا ويزيد من قدرته على التعميم والتعرف على التفاصيل الدقيقة في البيانات، مما يؤدي إلى تحسن كبير في الدقة.
وأخيرًا، بعد إتمام عملية التدريب، نقوم بحفظ النموذج لاستخدامه لاحقًا. سأقوم بإرفاق النموذج الخاص بي بحيث يمكنك تجربته.
Save the Model
# Save the model
torch.save(model.state_dict(), 'mnist_single_perceptron.pth')
print("Model saved as 'mnist_single_perceptron.pth'.")
وأخيرًا، بعد إتمام عملية التدريب، نقوم بحفظ النموذج لاستخدامه لاحقًا. سأقوم بإرفاق النموذج الخاص بي بحيث يمكنك تجربته وهذه صورة منه.
ونراكم في الدرس القادم