المجلد الثاني

⚡ المحولات والتعلم العميق المتقدم

من الانتباه إلى النماذج التوليدية — رحلة في عمق الذكاء الاصطناعي

يغوص هذا المجلد في أعماق هندسة المحولات (Transformers) التي غيّرت مسار الذكاء الاصطناعي، ويغطي أحدث التطورات في الرؤية الحاسوبية والشبكات التوليدية والتعلم المعزز، مع أمثلة عملية بلغة PyTorch لكل مفهوم.

📅 الجمعة، 12 يونيو 2026 📄 8 فصول · 30+ مفهوم المستوى: متقدم 🐍 PyTorch · Transformers · OpenCV

🔮 آلية الانتباه (Attention)

الانتباه هو المفهوم الأكثر تأثيراً في深度学习 الحديث. قبل المحولات، كانت الشبكات العصبية تعالج التسلسلات خطوة بخطوة عبر RNNs أو LSTMs، مما يجعلها بطيئة ويصعب تدريبها على التسلسلات الطويلة. الانتباه غيّر هذا تماماً: أصبح بإمكان النموذج أن ينظر إلى كل الكلمات في وقت واحد ويقرر أيها الأكثر أهمية في كل خطوة.

💡 الفكرة الجوهرية: بدلاً من معالجة الكلمات تسلسلياً، يحسب الانتباه درجة ارتباط كل كلمة بكل كلمة أخرى — مما يخلق "خريطة علاقات" كاملة للتسلسل.

Scaled Dot-Product Attention

هذا هو النوع الأساسي من الانتباه المستخدم في المحولات. يعتمد على ثلاث مصفوفات: Q (Query — الاستعلام)، K (Key — المفتاح)، وV (Value — القيمة).

Attention(Q, K, V) = softmax( QKT / √dk ) V

الخطوات بالتفصيل:

  1. Query · Key: نضرب Q في منقول K لنحصل على أوزان الانتباه الأولية.
  2. Scaling (√dk): نقسم على جذر بُعد المفاتيح لمنع انفجار القيم.
  3. Softmax: نحول الأوزان إلى توزيع احتمالي (مجموعها = 1).
  4. Weighted Sum: نضرب الأوزان في V لنحصل على المخرجات النهائية.
PyTorch — Scaled Dot-Product Attention 📋
import torch import torch.nn as nn import torch.nn.functional as F class ScaledDotProductAttention(nn.Module): def __init__(self, d_k): super().__init__() self.d_k = d_k self.scale = d_k ** 0.5 def forward(self, Q, K, V, mask=None): # Q, K, V: (batch, seq_len, d_k) scores = torch.matmul(Q, K.transpose(-2, -1)) # (batch, seq, seq) scores = scores / self.scale # Scaling if mask is not None: scores = scores.masked_fill(mask == 0, float('-inf')) attn_weights = F.softmax(scores, dim=-1) # (batch, seq, seq) output = torch.matmul(attn_weights, V) # (batch, seq, d_k) return output, attn_weights

Multi-Head Attention

بدلاً من آلية انتباه واحدة، تستخدم المحولات رؤوس انتباه متعددة (Multi-Head). كل رأس يتعلم التركيز على جوانب مختلفة من العلاقات بين الكلمات. هذا يشبه وجود عدة "خبراء" ينظرون إلى نفس الجملة من زوايا مختلفة.

MultiHead(Q, K, V) = Concat(head1, …, headh) WO
headi = Attention(Q WiQ, K WiK, V WiV)
PyTorch — Multi-Head Attention 📋
class MultiHeadAttention(nn.Module): def __init__(self, d_model, num_heads): super().__init__() assert d_model % num_heads == 0 self.d_model = d_model self.num_heads = num_heads self.d_k = d_model // num_heads self.W_Q = nn.Linear(d_model, d_model) self.W_K = nn.Linear(d_model, d_model) self.W_V = nn.Linear(d_model, d_model) self.W_O = nn.Linear(d_model, d_model) def forward(self, Q, K, V, mask=None): batch_size = Q.size(0) # 1. Linear projections + reshape for heads Q = self.W_Q.forward(Q).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) K = self.W_K.forward(K).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) V = self.W_V.forward(V).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) # 2. Apply attention per head attn_output, attn_weights = scaled_dot_product_attention(Q, K, V, mask) # 3. Concatenate heads + final projection attn_output = attn_output.transpose(1, 2).contiguous() \ .view(batch_size, -1, self.d_model) output = self.W_O.forward(attn_output) return output

Self-Attention vs Cross-Attention

🔄 Self-Attention

Q, K, V كلها من نفس المصدر — كل كلمة تنظر إلى كل الكلمات الأخرى في نفس التسلسل.

  • المصدر: نفس التسلسل (X → Q, K, V)
  • الاستخدام: التشفير (BERT) وفك التشفير (GPT)
  • الغرض: فهم السياق الداخلي لكل كلمة
  • مثال: "القطة أكلت السمكة" — "هي" تفهم أنها تشير إلى "القطة"
🔁 Cross-Attention

Q من مصدر و K, V من مصدر آخر — التسلسل الهدف ينظر إلى التسلسل المصدر.

  • المصدر: Q من الهدف، K و V من المصدر
  • الاستخدام: الترجمة (Encoder-Decoder)
  • الغرض: الربط بين تسلسلين مختلفين
  • مثال: الترجمة: الجملة الإنجليزية ← الجملة العربية
🏆 لماذا الانتباه غير مسبوق؟
التوازي: يمكن معالجة كل الكلمات في وقت واحد (عكس RNN).
المدى البعيد: يمكن ربط كلمتين متباعدتين بسهولة (عكس CNN).
الشفافية: يمكن رؤية أوزان الانتباه ومعرفة ما "يركز عليه" النموذج.
المرونة: نفس الآلية تعمل للنص والصورة والصوت والفيديو.

🏗️ Transformer Architecture

في ورقة "Attention Is All You Need" (2017)، قدمت Google هندسة المحول (Transformer) التي تستخدم الانتباه فقط — بدون أي RNNs أو CNNs. هذه الهندسة أصبحت الأساس لجميع نماذج اللغة الكبيرة اليوم.

Output
Probabilities
Decoder
(GPT Style)
Linear + Softmax
Encoder
(BERT Style)
Add & Norm
Multi-Head
Attention
Feed Forward
(MLP)
Positional
Encoding
Input
Embedding
Input Tokens
🧱 هيكل المحول الأساسي — تكديس طبقات الانتباه والتغذية الأمامية مع التوصيلات المتبقية

Encoder (BERT — Bidirectional Encoder Representations from Transformers)

BERT (2018) من Google يستخدم فقط المشفّر (Encoder) من المحول. BERT ثنائي الاتجاه — كل كلمة ترى كل الكلمات الأخرى في كلا الاتجاهين.

🧠 خصائص BERT
  • ثنائي الاتجاه: كل كلمة تنظر إلى اليمين واليسار في نفس الوقت.
  • Masked Language Model (MLM): نخفي 15% من الكلمات ونتوقعها.
  • Next Sentence Prediction (NSP): هل الجملة B تلي A؟
  • الاستخدامات: تصنيف النصوص، الإجابة على الأسئلة، التعرف على الكيانات.
PyTorch — Encoder Layer (BERT-style) 📋
class TransformerEncoderLayer(nn.Module): def __init__(self, d_model, num_heads, d_ff, dropout=0.1): super().__init__() self.self_attn = MultiHeadAttention(d_model, num_heads) self.ff = nn.Sequential( nn.Linear(d_model, d_ff), nn.ReLU(), nn.Linear(d_ff, d_model) ) self.norm1 = nn.LayerNorm(d_model) self.norm2 = nn.LayerNorm(d_model) self.dropout = nn.Dropout(dropout) def forward(self, x, mask=None): # Self-attention + residual + norm attn_out = self.self_attn.forward(x, x, x, mask) x = self.norm1.forward(x + self.dropout.forward(attn_out)) # Feed-forward + residual + norm ff_out = self.ff.forward(x) x = self.norm2.forward(x + self.dropout.forward(ff_out)) return x # Stack multiple encoder layers class BERTEncoder(nn.Module): def __init__(self, vocab_size, d_model=768, num_layers=12, num_heads=12, d_ff=3072, max_len=512): super().__init__() self.embed = nn.Embedding(vocab_size, d_model) self.pos_embed = nn.Embedding(max_len, d_model) self.layers = nn.ModuleList([ TransformerEncoderLayer(d_model, num_heads, d_ff) for _ in range(num_layers) ]) def forward(self, token_ids, pos_ids, mask=None): x = self.embed.forward(token_ids) + self.pos_embed.forward(pos_ids) for layer in self.layers: x = layer.forward(x, mask) return x

Decoder (GPT — Generative Pre-trained Transformer)

GPT (2018) من OpenAI يستخدم فقط فك التشفير (Decoder). GPT أحادي الاتجاه (Causal) — كل كلمة ترى فقط الكلمات التي قبلها. هذا يجعله مثالياً لتوليد النصوص.

🛠️ خصائص GPT
  • أحادي الاتجاه (Causal): كل كلمة ترى فقط ما قبلها (سببية).
  • Autoregressive: توليد كلمة كلمة — كل كلمة جديدة تعتمد على السابقة.
  • Masked Self-Attention: قناع يمنع الرؤية إلى المستقبل.
  • الاستخدامات: توليد النصوص، chat، البرمجة، الإبداع.
PyTorch — Causal Self-Attention Mask (GPT-style) 📋
def create_causal_mask(seq_len): # Upper triangular mask: prevents attending to future tokens mask = torch.tril(torch.ones(seq_len, seq_len)) mask = mask.unsqueeze(0).unsqueeze(0) # (1, 1, seq, seq) return mask # 1 = attend, 0 = mask class CausalSelfAttention(nn.Module): def __init__(self, d_model, num_heads): super().__init__() self.attn = MultiHeadAttention(d_model, num_heads) def forward(self, x): seq_len = x.size(1) causal_mask = create_causal_mask(seq_len).to(x.device) return self.attn.forward(x, x, x, causal_mask) class GPTDecoderLayer(nn.Module): def __init__(self, d_model, num_heads, d_ff, dropout=0.1): super().__init__() self.self_attn = CausalSelfAttention(d_model, num_heads) self.ff = nn.Sequential( nn.Linear(d_model, d_ff), nn.GELU(), # GPT uses GELU not ReLU nn.Linear(d_ff, d_model) ) self.norm1 = nn.LayerNorm(d_model) self.norm2 = nn.LayerNorm(d_model) self.dropout = nn.Dropout(dropout) def forward(self, x): # Causal self-attention + residual x = x + self.dropout.forward(self.self_attn.forward(x)) x = self.norm1.forward(x) # FF + residual x = x + self.dropout.forward(self.ff.forward(x)) x = self.norm2.forward(x) return x

Encoder-Decoder (T5 — Text-to-Text Transfer Transformer)

T5 (2019) من Google يستخدم الهندسة الكاملة: مشفّر + مفكّك تشفير. كل مهمة NLP تُصاغ كمهمة نص إلى نص (Text-to-Text). هذا مثالي للترجمة والتلخيص.

📥 Encoder (BERT)
  • ثنائي الاتجاه (Bidirectional)
  • يفهم النص بالكامل
  • مثالي للفهم والتصنيف
  • يُنتج تمثيلاً غنياً
📤 Decoder (GPT)
  • أحادي الاتجاه (Causal)
  • يولّد النص تسلسلياً
  • مثالي للتوليد والإبداع
  • يستخدم masked attention

🔢 Positional Encoding

الانتباه ليس له مفهوم "ترتيب" — فهو يرى كل الكلمات كمجموعة غير مرتبة. لذلك نحتاج إلى إضافة معلومات عن موقع كل كلمة في التسلسل. هذه هي مهمة التشفير الموضعي (Positional Encoding).

PE(pos, 2i) = sin(pos / 100002i/d)
PE(pos, 2i+1) = cos(pos / 100002i/d)

لماذا الموجات الجيبية؟

PyTorch — Sinusoidal Positional Encoding 📋
class PositionalEncoding(nn.Module): def __init__(self, d_model, max_len=5000): super().__init__() pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) div_term = torch.exp(torch.arange(0, d_model, 2) * -(torch.log(10000.0) / d_model)) pe[:, 0::2] = torch.sin(position * div_term) # even indices pe[:, 1::2] = torch.cos(position * div_term) # odd indices pe = pe.unsqueeze(0) # (1, max_len, d_model) self.register_buffer('pe', pe) # not trainable def forward(self, x): # x: (batch, seq_len, d_model) return x + self.pe[:, :x.size(1)]

Layer Normalization & Residual Connections

🔗 Residual Connections (التوصيلات المتبقية)

الفكرة: x ← x + F(x) بدلاً من x ← F(x).

  • تسمح بتدفق التدرج عبر 100+ طبقة.
  • تمنع مشكلة اختفاء التدرج (Vanishing Gradient).
  • كل طبقة تتعلم "التصحيح" بدلاً من التعلم من الصفر.
📊 Layer Normalization

تطبّع عبر أبعاد الميزات (وليس batch).

  • تُحسّب المتوسط والانحراف لكل عينة.
  • تثبّت التدريب وتسرّعه.
  • ضرورية للمحولات (عكس BatchNorm في CNNs).
PyTorch — Pre-LN vs Post-LN (طرق تطبيع مختلفة) 📋
# Post-LN (original Transformer): Norm بعد الجمع x = LayerNorm(x + Attention(x)) # الأصل في ورقة 2017 # Pre-LN (GPT/BERT modern): Norm قبل الدخول x = x + Attention(LayerNorm(x)) # أكثر استقراراً في التدريب # RMSNorm (LLaMA): تبسيط LayerNorm class RMSNorm(nn.Module): def __init__(self, d_model, eps=1e-6): super().__init__() self.weight = nn.Parameter(torch.ones(d_model)) self.eps = eps def forward(self, x): # RMS = sqrt(mean(x^2) + eps) rms = torch.sqrt(torch.mean(x ** 2, dim=-1, keepdim=True) + self.eps) return x / rms * self.weight

🧩 Embeddings — تمثيل الكلمات والمفاهيم

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

Word Embeddings: Word2Vec & GloVe

📖 Word2Vec (Mikolov et al., 2013)

فكرة Word2Vec بسيطة وعميقة: "الكلمة تُعرف من جيرانها" (You shall know a word by the company it keeps).

  • CBOW (Continuous Bag of Words): توقع الكلمة من سياقها.
  • Skip-gram: توقع السياق من الكلمة — أفضل للكلمات النادرة.
📖 GloVe (Pennington et al., 2014)

يجمع GloVe بين مزايا Word2Vec والتحليل الإحصائي للمصفوفات التكرارية.

  • يستخدم إحصائيات الحدوث المشترك (Co-occurrence) على مستوى المجموعة الكاملة.
  • العلاقات الخطية: "ملك" - "رجل" + "امرأة" ≈ "ملكة".
PyTorch — Embedding Layer + Word2Vec Skip-gram مثال 📋
import torch import torch.nn as nn # طبقة تضمين أساسية (كل محول يستخدمها) vocab_size = 30000 d_model = 512 embed = nn.Embedding(vocab_size, d_model) # مثال: تحويل كلمات إلى متجهات token_ids = torch.tensor([[12, 45, 789, 3, 1024]]) # (batch=1, seq=5) embedded = embed.forward(token_ids) # (1, 5, 512) # ------------------------------------------------- # Word2Vec Skip-gram (نسخة مبسطة) class SkipGramModel(nn.Module): def __init__(self, vocab_size, emb_dim): super().__init__() self.center_emb = nn.Embedding(vocab_size, emb_dim) self.context_emb = nn.Embedding(vocab_size, emb_dim) def forward(self, center, context): # center: البُعد المركزي, context: كلمة السياق center_vec = self.center_emb.forward(center) context_vec = self.context_emb.forward(context) score = (center_vec * context_vec).sum(dim=-1) return score # تشابه الكلمات عبر cosine similarity def cosine_sim(word_embed, word1, word2): v1 = word_embed[word1] # نفترض word_embed مصفوفة (vocab, dim) v2 = word_embed[word2] return torch.cosine_similarity(v1.unsqueeze(0), v2.unsqueeze(0))

Subword Tokenization — BPE, WordPiece, SentencePiece

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

التقنية المبدأ المميزات يستخدمها
BPE (Byte-Pair Encoding) دمج أزواج الرموز الأكثر تكراراً بسيط، فعال، سريع GPT, GPT-2, LLaMA
WordPiece دمج بناءً على زيادة الاحتمالية أفضل رياضياً من BPE BERT, DistilBERT
SentencePiece يتعامل مع النص كسلسلة Unicode لا يحتاج مسافات مسبقة، يدعم كل اللغات T5, ALBERT, XLNet
✂️ "unbelievable" → ["un", "believe", "able"]
مثال على تجزئة Subword — كلمة unseen تُقسَّم إلى أجزاء مألوفة

Positional Embeddings: Learnable vs Sinusoidal

📐 Sinusoidal (ثابتة)

الأصل في ورقة المحول. موجات جيبية وجيب التمام.

  • غير قابلة للتعلم (fixed).
  • تتعمم على أطوال غير مرئية.
  • تستخدم في: Transformer الأصلي.
🎯 Learnable (قابلة للتعلم)

مصفوفة Embedding عادية يتم تعلمها مع التدريب.

  • قابلة للتعلم — يتكيف مع البيانات.
  • محدودة بأقصى طول رؤية في التدريب.
  • تستخدم في: BERT, GPT.
PyTorch — Learnable Positional Embeddings (مثل BERT) 📋
class BERTEmbeddings(nn.Module): def __init__(self, vocab_size, d_model=768, max_len=512, type_vocab_size=2): # sentence A/B super().__init__() self.word_emb = nn.Embedding(vocab_size, d_model) self.pos_emb = nn.Embedding(max_len, d_model) self.type_emb = nn.Embedding(type_vocab_size, d_model) self.layer_norm = nn.LayerNorm(d_model) self.dropout = nn.Dropout(0.1) def forward(self, input_ids, token_type_ids=None): seq_len = input_ids.size(1) pos_ids = torch.arange(seq_len, device=input_ids.device).unsqueeze(0) word_vec = self.word_emb.forward(input_ids) pos_vec = self.pos_emb.forward(pos_ids) if token_type_ids is None: token_type_ids = torch.zeros_like(input_ids) type_vec = self.type_emb.forward(token_type_ids) embeddings = word_vec + pos_vec + type_vec return self.dropout.forward(self.layer_norm.forward(embeddings))

👁️ CNN المتقدمة للرؤية الحاسوبية

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

Convolution & Pooling

الالتفاف (Convolution) هو عملية رياضية حيث نمرّر نواة (kernel) صغيرة على الصورة لاكتشاف الأنماط مثل الحواف والأشكال. التجميع (Pooling) يقلل أبعاد الصورة مع الاحتفاظ بالمعلومات المهمة.

PyTorch — Convolution + Pooling Layers 📋
import torch.nn as nn # 2D Convolution — الطبقة الأساسية conv = nn.Conv2d( in_channels=3, # RGB → 3 قنوات out_channels=64, # نريد 64 فلتراً مختلفاً kernel_size=3, # نواة 3×3 stride=1, # خطوة واحدة padding=1 # حشو للحفاظ على الحجم ) # Max Pooling — يقلل الأبعاد pool = nn.MaxPool2d(kernel_size=2, stride=2) # يخفض الطول والعرض للنصف # مثال تطبيقي كامل — كتلة CNN واحدة class ConvBlock(nn.Module): def __init__(self, in_c, out_c): super().__init__() self.conv = nn.Conv2d(in_c, out_c, 3, padding=1) self.bn = nn.BatchNorm2d(out_c) # تطبيع الدفعة self.relu = nn.ReLU(inplace=True) self.pool = nn.MaxPool2d(2) def forward(self, x): x = self.conv.forward(x) x = self.bn.forward(x) x = self.relu.forward(x) x = self.pool.forward(x) return x # طبقات متعددة: 3 → 64 → 128 → 256 model = nn.Sequential( ConvBlock(3, 64), ConvBlock(64, 128), ConvBlock(128, 256), )

ResNet & EfficientNet

ResNet — Residual Networks (Residual Connections)

ResNet (2015) حل مشكلة أساسية: كلما زادت طبقات الشبكة، يصبح التدريب أصعب (Degradation Problem). الحل: التوصيلات المتبقية (Skip Connections) التي تسمح للشبكة بتعلم الفرق (residual) بدلاً من التعلم الكامل.

PyTorch — Residual Block (ResNet) 📋
class ResidualBlock(nn.Module): def __init__(self, in_channels, out_channels, stride=1): super().__init__() self.conv1 = nn.Conv2d(in_channels, out_channels, 3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(out_channels) self.conv2 = nn.Conv2d(out_channels, out_channels, 3, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(out_channels) self.relu = nn.ReLU(inplace=True) # Skip connection: إذا تغير حجم القنوات، نعدل الأبعاد self.shortcut = nn.Sequential() if stride != 1 or in_channels != out_channels: self.shortcut = nn.Sequential( nn.Conv2d(in_channels, out_channels, 1, stride=stride, bias=False), nn.BatchNorm2d(out_channels) ) def forward(self, x): # المسار الرئيسي out = self.relu.forward(self.bn1.forward(self.conv1.forward(x))) out = self.bn2.forward(self.conv2.forward(out)) # المسار المختصر (Skip Connection) out += self.shortcut.forward(x) # ★ هذا هو الابتكار out = self.relu.forward(out) return out

EfficientNet — التوسع المتوازن

EfficientNet (2019) يطرح سؤالاً: كيف نوسع الشبكة CNN بشكل أفضل؟ الجواب: توسيع الأبعاد الثلاثة معاً — العمق (depth)، العرض (width)، ودقة الصورة (resolution) — بنسبة ثابتة.

⚖️ العرض (width) × العمق (depth) × الدقة (resolution)
مبدأ التوسع المركب (Compound Scaling) في EfficientNet

Vision Transformer (ViT) — المحول في الرؤية

Vision Transformer (ViT) من Google (2020) أثبت أن المحولات يمكنها منافسة CNNs في الرؤية الحاسوبية — بل وتفوقها. الفكرة: نقسّم الصورة إلى قطع صغيرة (patches) ونعالجها كتسلسل من الكلمات.

PyTorch — Vision Transformer (ViT) Patch Embedding 📋
class PatchEmbed(nn.Module): def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768): super().__init__() self.img_size = img_size self.patch_size = patch_size self.num_patches = (img_size // patch_size) ** 2 # Conv2d بحجم النواة = patch_size → كل نواة تلتقط patch self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) def forward(self, x): # x: (batch, 3, 224, 224) x = self.proj.forward(x) # (batch, 768, 14, 14) — 224/16=14 x = x.flatten(2) # (batch, 768, 196) x = x.transpose(1, 2) # (batch, 196, 768) ← "تسلسل" من 196 patch return x # مثال استخدام patch_embed = PatchEmbed(img_size=224, patch_size=16, embed_dim=768) x = torch.randn(2, 3, 224, 224) # batch=2, RGB patches = patch_embed.forward(x) # (2, 196, 768) print(patches.shape) # torch.Size([2, 196, 768]) ✓

🎨 الشبكات التوليدية — GANs, VAE, Diffusion

الشبكات التوليدية تهدف إلى تعلّم توزيع البيانات ثم توليد عينات جديدة منها. هذا الفصل يغطي أهم ثلاث عوائل من النماذج التوليدية التي غيّرت مجال الذكاء الاصطناعي.

GANs — Generative Adversarial Networks

GANs (Goodfellow et al., 2014) هي فكرة عبقريّة: نموذجان يتنافسان — المولّد (Generator) يحاول خلق صور واقعية، والمميّز (Discriminator) يحاول اكتشاف المزيّف. مع الوقت، يصبح المولّد ماهراً جداً لدرجة أنه يخدع المميّز.

🎯 ديناميكية GAN: مثل مزوّر لوحات (Generator) وخبير فني (Discriminator). المزوّّر يتحسن حتى يصعب على الخبير التفريق بين الحقيقي والمزوّر.
PyTorch — DCGAN (Deep Convolutional GAN) 📋
class Generator(nn.Module): # يحول ضوضاء عشوائية (latent vector) إلى صورة 64×64 def __init__(self, latent_dim=100): super().__init__() self.model = nn.Sequential( nn.ConvTranspose2d(latent_dim, 512, 4, 1, 0), # 4×4 nn.BatchNorm2d(512), nn.ReLU(inplace=True), nn.ConvTranspose2d(512, 256, 4, 2, 1), # 8×8 nn.BatchNorm2d(256), nn.ReLU(inplace=True), nn.ConvTranspose2d(256, 128, 4, 2, 1), # 16×16 nn.BatchNorm2d(128), nn.ReLU(inplace=True), nn.ConvTranspose2d(128, 64, 4, 2, 1), # 32×32 nn.BatchNorm2d(64), nn.ReLU(inplace=True), nn.ConvTranspose2d(64, 3, 4, 2, 1), # 64×64 nn.Tanh() # output in [-1, 1] ) def forward(self, z): # z: (batch, 100, 1, 1) return self.model.forward(z) class Discriminator(nn.Module): # يحاول التمييز بين الحقيقي والمزيّف def __init__(self): super().__init__() self.model = nn.Sequential( nn.Conv2d(3, 64, 4, 2, 1), # 32×32 nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(64, 128, 4, 2, 1), # 16×16 nn.BatchNorm2d(128), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(128, 256, 4, 2, 1), # 8×8 nn.BatchNorm2d(256), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(256, 1, 4, 1, 0), # 1×1 nn.Sigmoid() # احتمال: 0 = fake, 1 = real ) def forward(self, x): return self.model.forward(x).view(-1)

StyleGAN — تحكم في الأنماط

StyleGAN (2019) من NVIDIA يضيف تحكماً غير مسبوق في خصائص الصورة المولّدة — مثل العمر، الجنس، الإضاءة، والخلفية — بشكل منفصل.

Variational Autoencoders (VAE)

VAE هو نموذج توليدي يتعلم تمثيلاً مضغوطاً (latent space) للبيانات. الفكرة: نشفّر الصورة إلى توزيع احتمالي (متوسط + انحراف معياري) ثم نأخذ عينة منه ونفكّ التشفير.

PyTorch — Variational Autoencoder (VAE) 📋
class VAE(nn.Module): def __init__(self, latent_dim=128): super().__init__() # Encoder self.encoder = nn.Sequential( nn.Linear(784, 512), nn.ReLU(), nn.Linear(512, 256), nn.ReLU(), ) self.mu = nn.Linear(256, latent_dim) # متوسط self.log_var = nn.Linear(256, latent_dim) # log التباين # Decoder self.decoder = nn.Sequential( nn.Linear(latent_dim, 256), nn.ReLU(), nn.Linear(256, 512), nn.ReLU(), nn.Linear(512, 784), nn.Sigmoid() ) def reparameterize(self, mu, log_var): # ★ خدعة إعادة التقييس (Reparameterization Trick) std = torch.exp(log_var * 0.5) eps = torch.randn_like(std) return mu + eps * std def forward(self, x): h = self.encoder.forward(x) mu = self.mu.forward(h) log_var = self.log_var.forward(h) z = self.reparameterize(mu, log_var) # عينة من التوزيع recon = self.decoder.forward(z) return recon, mu, log_var # دالة الخسارة: إعادة البناء + تباعد KL def vae_loss(recon_x, x, mu, log_var): recon_loss = F.binary_cross_entropy(recon_x, x, reduction='sum') kl_loss = -0.5 * torch.sum(1 + log_var - mu ** 2 - log_var.exp()) return recon_loss + kl_loss

نماذج الانتشار (Diffusion Models)

نماذج الانتشار هي أحدث وأقوى تقنية توليد للصور — وهي ما تستخدمه Stable Diffusion وDALL·E 3 وMidjourney. الفكرة: نبدأ من صورة عشوائية (ضوضاء خالصة) ونزيل الضوضاء تدريجياً حتى نحصل على صورة نظيفة.

🔄 كيف تعمل نماذج الانتشار؟
  1. Forward Process (الانتشار الأمامي): نأخذ صورة حقيقية ونضيف ضوضاء تدريجياً على T خطوة حتى تصبح ضوضاء خالصة.
  2. Reverse Process (الانتشار العكسي): ندرّب شبكة عصبية (U-Net) على توقع الضوضاء المضافة وإزالتها خطوة بخطوة.
  3. التوليد: نبدأ من ضوضاء خالصة ونطبق الانتشار العكسي — نزيل الضوضاء تدريجياً حتى تظهر الصورة.
Forward: q(xt | xt-1) = 𝒩(xt; √(1-βt)·xt-1, βtI)

Reverse: pθ(xt-1 | xt) = 𝒩(xt-1; μθ(xt, t), Σθ(xt, t))
PyTorch — DDPM (Denoising Diffusion Probabilistic Models) — خطوة الانتشار العكسي 📋
import torch import torch.nn as nn import torch.nn.functional as F class SinusoidalPositionEmbeddings(nn.Module): # تضمين خطوة الوقت t — ضروري لمعرفة في أي خطوة نحن def __init__(self, dim): super().__init__() self.dim = dim def forward(self, t): half_dim = self.dim // 2 emb = torch.log(torch.tensor(10000.0)) / (half_dim - 1) emb = torch.exp(torch.arange(half_dim, device=t.device) * -emb) emb = t[:, None].float() * emb[None, :] emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=-1) return emb class DDPM(nn.Module): # نموذج DDPM بسيط (U-Net مبسط) def __init__(self, img_channels=3, T=1000): super().__init__() self.T = T # جدول الضوضاء (noise schedule) — من β_1 إلى β_T self.beta = torch.linspace(1e-4, 0.02, T) self.alpha = 1.0 - self.beta self.alpha_bar = torch.cumprod(self.alpha, dim=0) # U-Net مبسط (للتوضيح — النموذج الحقيقي أكبر بكثير) self.time_embed = SinusoidalPositionEmbeddings(256) self.input_proj = nn.Conv2d(img_channels, 64, 3, padding=1) self.mid_block = nn.Sequential( nn.Conv2d(64, 128, 3, padding=1), nn.ReLU(), nn.Conv2d(128, 64, 3, padding=1), nn.ReLU(), ) self.output_proj = nn.Conv2d(64, img_channels, 3, padding=1) def forward(self, x, t): # x: صورة (قد تكون فيها ضوضاء), t: خطوة الوقت t_emb = self.time_embed.forward(t) x = self.input_proj.forward(x) x = self.mid_block.forward(x + t_emb[:, :, None, None]) x = self.output_proj.forward(x) return x # توقع الضوضاء المضافة # دالة إضافة ضوضاء مباشرة (Forward Process) def add_noise(model, x0, t): # x0: الصورة الأصلية, t: خطوات الضوضاء alpha_bar_t = model.alpha_bar[t].view(-1, 1, 1, 1) noise = torch.randn_like(x0) x_t = torch.sqrt(alpha_bar_t) * x0 + torch.sqrt(1 - alpha_bar_t) * noise return x_t, noise # التدريب: توقع الضوضاء المضافة # loss = MSE(model(x_t, t), noise)

Stable Diffusion — الانتشار في الفضاء الكامن

Stable Diffusion يطبق الانتشار ليس على الصورة مباشرة (باهظة الثمن) بل على الفضاء الكامن (Latent Space) بعد ضغط الصورة بمشفّر (VAE). هذا يجعله أسرع بكثير ويحتاج ذاكرة أقل.

🧊 Pixel Space → 🧬 VAE Encoder → 🌌 Latent Space → 🌀 Diffusion → 🧬 VAE Decoder → 🖼️
Stable Diffusion: الانتشار في الفضاء الكامن — أسرع وأقل استهلاكاً للذاكرة

🤖 التعلم المعزز (Reinforcement Learning)

التعلم المعزز (RL) هو فرع من الذكاء الاصطناعي حيث يتعلم الوكيل (Agent) من خلال التفاعل مع البيئة — يجرب أفعالاً، ويحصل على مكافآت أو عقوبات، ويتعلم مع مرور الوقت ما هي أفضل الاستراتيجيات.

💡 الفكرة الأساسية: مثل تدريب كلب — عندما يفعل الشيء الصحيح، نعطيه مكافأة (reward). مع الوقت، يتعلم أي السلوكيات تؤدي إلى أكبر مكافأة.

MDP (Markov Decision Process) & Q-Learning

MDP هو الإطار الرياضي لـ RL. يتكون من:

Q-Learning هو خوارزمية تتعلم قيمة كل فعل في كل حالة:

Q(s, a) ← Q(s, a) + α [ R + γ · maxa' Q(s', a') — Q(s, a) ]
PyTorch — Q-Learning Table-based (مثال بسيط) 📋
import numpy as np class QLearningAgent: def __init__(self, n_states, n_actions, lr=0.1, gamma=0.99, eps=1.0): self.n_actions = n_actions self.lr = lr # معدل التعلم (α) self.gamma = gamma # عامل الخصم (γ) self.eps = eps # استكشاف vs استغلال self.Q = np.zeros((n_states, n_actions)) # جدول Q def choose_action(self, state): # ε-greedy: أحياناً نستكشف (عشوائي)، أحياناً نستغل (أفضل Q) if np.random() < self.eps: return np.random.randint(self.n_actions) # استكشاف return np.argmax(self.Q[state]) # استغلال def update(self, state, action, reward, next_state): # معادلة Bellman لتحديث Q best_next = np.max(self.Q[next_state]) td_target = reward + self.gamma * best_next td_error = td_target - self.Q[state, action] self.Q[state, action] += self.lr * td_error

Deep Q-Networks (DQN)

عندما تصبح الحالات كثيرة جداً (مثل البكسل في لعبة فيديو)، لا يمكننا استخدام جدول Q. الحل: شبكة عصبية (Deep Q-Network) تتعلم تقريب دالة Q.

🧠 DQN (Mnih et al., 2015) — DeepMind's Atari Breakthrough
  • Experience Replay: نخزّن التجارب السابقة ونتعلم منها مراراً — يمنع النسيان.
  • Target Network: شبكة هدف منفصلة تثبّت التدريب.
  • Epsilon Greedy: توازن بين الاستكشاف والاستغلال.
PyTorch — Deep Q-Network (DQN) 📋
class DQN(nn.Module): def __init__(self, n_observations, n_actions): super().__init__() self.net = nn.Sequential( nn.Linear(n_observations, 128), nn.ReLU(), nn.Linear(128, 128), nn.ReLU(), nn.Linear(128, n_actions) # Q-values لكل فعل ) def forward(self, x): return self.net.forward(x) # === Experience Replay Buffer === from collections import deque import random class ReplayBuffer: def __init__(self, capacity=10000): self.buffer = deque(maxlen=capacity) def push(self, state, action, reward, next_state, done): self.buffer.append((state, action, reward, next_state, done)) def sample(self, batch_size): return random.sample(self.buffer, batch_size) def __len__(self): return len(self.buffer) # === DQN Training Loop (مبسّطة) === def train_dqn_step(policy_net, target_net, buffer, optimizer, batch_size=128, gamma=0.99): if len(buffer) < batch_size: return batch = buffer.sample(batch_size) states, actions, rewards, next_states, dones = zip(*batch) states = torch.tensor(states, dtype=torch.float) actions = torch.tensor(actions, dtype=torch.long).unsqueeze(1) rewards = torch.tensor(rewards, dtype=torch.float) next_states = torch.tensor(next_states, dtype=torch.float) dones = torch.tensor(dones, dtype=torch.float) # Q(s, a) الحالية current_q = policy_net.forward(states).gather(1, actions).squeeze() # Q(s', a') القصوى من الشبكة الهدف next_q = target_net.forward(next_states).max(1)[0] expected_q = rewards + gamma * next_q * (1 - dones) loss = F.mse_loss(current_q, expected_q) optimizer.zero_grad() loss.backward() optimizer.step()

Policy Gradients & PPO

Policy Gradients — التعلم المباشر للسياسة

بدلاً من تعلّم قيم Q (غير مباشر)، تتعلم طرق تدرّج السياسة (Policy Gradients) السياسة مباشرة: π(a|s) — احتمال اختيار الفعل a في الحالة s.

∇J(θ) = E[ ∇log πθ(a|s) · Gt ]
حيث Gt = Σ γk Rt+k+1 (العائد التراكمي)

PPO — Proximal Policy Optimization

PPO (Schulman et al., 2017) هو أشهر خوارزمية RL حالياً (يستخدمها ChatGPT للتدريب). يحل مشكلة عدم الاستقرار في طرق تدرّج السياسة عن طريق قصّ (clipping) التحديثات لمنع التغييرات الكبيرة جداً.

PyTorch — PPO Clip Loss (الجزء الأساسي) 📋
def ppo_clip_loss( log_probs_current, # log π_θ(a|s) — السياسة الحالية log_probs_old, # log π_{old}(a|s) — السياسة القديمة advantages, # ميزة كل فعل (advantage) eps_clip=0.2 # نطاق القص ): # نسبة الاحتمالات: r(θ) = π_θ / π_old ratios = torch.exp(log_probs_current - log_probs_old) # الخسارة غير المقصوصة surr1 = ratios * advantages # الخسارة المقصوصة — ★ ابتكار PPO surr2 = torch.clamp(ratios, 1.0 - eps_clip, 1.0 + eps_clip) * advantages # نأخذ min(...) — نختار الأكثر تحفظاً loss = -torch.min(surr1, surr2).mean() return loss # مكونات خسارة PPO الكاملة: # 1. خسارة السياسة (PPO Clip) — أعلاه # 2. خسارة القيمة (Value Loss) — MSE بين قيمة الحالة والعائد # 3. خسارة الإنتروبيا (Entropy Bonus) — تشجيع الاستكشاف # total_loss = policy_loss + c1 * value_loss — c2 * entropy
📊 RL Agent: State → Policy π(a|s) → Action → Environment → Reward + Next State
حلقة التفاعل الأساسية في التعلم المعزز — Agent interacts with Environment

🖼️ المحولات في الرؤية — ViT, Swin, DETR

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

Vision Transformer (ViT) & Swin Transformer

ViT — Vision Transformer (راجع القسم 4.3)

كما رأينا في القسم 4.3، ViT يقسم الصورة إلى patches ويدخلها إلى محول قياسي. ما يميّز ViT هو بساطته — نفس هندسة المحول تعمل للصور بدون أي تعديلات كبيرة.

📊 أداء ViT
  • على ImageNet (1.3M صورة): دقة 88.6% (منافس لـ EfficientNet).
  • على JFT-300M (300M صورة): دقة 90.45% — يتفوق على أفضل CNNs.
  • الدرس: المحولات تحتاج بيانات كثيرة لتعميم جيد.

Swin Transformer — المحول الهرمي

Swin Transformer (2021) من Microsoft يحل مشكلة في ViT: الحسابات ثقيلة (N² لكل طبقة). Swin يطبق الانتباه في نوافذ محلية (Windows) بدلاً of عالمي، ثم يدمج المعلومات عبر النوافذ.

🟦 ViT (Global Attention)
  • انتباه عالمي — كل patch يرى كل الـ patches.
  • O(N² · d) — ثقيل حسابياً N=196 (224px).
  • حجم ثابت للـ patches.
  • يكافح مع الصور عالية الدقة.
🟦 Swin (Hierarchical + Window Attention)
  • انتباه محلي (7×7 نافذة) + انتباه متحول (Shifted).
  • O(N · M² · d) — أخف بكثير M=49.
  • هرمي: يبني ميزات متعددة المقاييس (مثل CNN).
  • يتعامل مع الدقة العالية بكفاءة.
PyTorch — Swin Transformer Block (مبسّط) 📋
class SwinTransformerBlock(nn.Module): def __init__(self, dim, num_heads, window_size=7): super().__init__() self.dim = dim self.window_size = window_size self.num_heads = num_heads self.norm1 = nn.LayerNorm(dim) self.attn = WindowAttention(dim, num_heads, window_size) self.norm2 = nn.LayerNorm(dim) self.mlp = nn.Sequential( nn.Linear(dim, 4 * dim), nn.GELU(), nn.Linear(4 * dim, dim) ) def forward(self, x): # Split into windows, apply attention, merge back shortcut = x x = self.norm1.forward(x) x = window_partition(x, self.window_size) # → windows x = self.attn.forward(x) x = window_reverse(x, self.window_size) # → merge x = shortcut + x # residual # MLP block x = x + self.mlp.forward(self.norm2.forward(x)) return x # Patch Merging (Swin's downsampling — مثل Pooling في CNN) class PatchMerging(nn.Module): def __init__(self, dim): super().__init__() self.norm = nn.LayerNorm(4 * dim) self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) def forward(self, x, H, W): # يدمج كل 2×2 من الـ patches → يقلص H,W للنصف ويضاعف dim B, L, C = x.shape x = x.view(B, H, W, C) # يأخذ الركن العلوي الأيسر من كل 2×2 x0 = x[:, 0::2, 0::2, :] x1 = x[:, 0::2, 1::2, :] x2 = x[:, 1::2, 0::2, :] x3 = x[:, 1::2, 1::2, :] x = torch.cat([x0, x1, x2, x3], -1) # (B, H/2, W/2, 4*C) x = self.norm.forward(x) x = self.reduction.forward(x) return x.view(B, -1, 2*C)

DETR — Detection Transformer

DETR (Detection Transformer, 2020) من Facebook AI يغيّر طريقة اكتشاف الأشياء بالكامل. بدلاً من أنظمة الكشف المعقدة (مثل YOLO وFaster R-CNN التي تحتاج الكثير من المكونات)، DETR يستخدم محول واحد فقط.

🎯 كيف يعمل DETR؟
  1. CNN Backbone: يستخرج ميزات من الصورة (مثل ResNet).
  2. Transformer Encoder: يعالج ميزات الصورة بفهم السياق الكامل.
  3. Transformer Decoder: يستخدم عدداً ثابتاً من "object queries" (استعلامات كائن) لاكتشاف الأشياء — كل query يتعلم البحث عن شيء معين.
  4. Bipartite Matching: يطابق التوقعات مع الحقيقة الأرضية (باستخدام Hungarian Algorithm).
PyTorch — DETR (مبسّط — المكونات الأساسية) 📋
class DETR(nn.Module): def __init__(self, num_classes=80, num_queries=100, d_model=256): super().__init__() # CNN backbone (مثال: ResNet-50) self.backbone = nn.Sequential( nn.Conv2d(3, 64, 7, 2, 3), nn.ReLU(), nn.Conv2d(64, d_model, 3, 2, 1), nn.ReLU(), ) # Transformer Encoder encoder_layer = nn.TransformerEncoderLayer(d_model, nhead=8) self.encoder = nn.TransformerEncoder(encoder_layer, num_layers=6) # Object queries (قابلة للتعلم — تبحث عن الكائنات) self.query_embed = nn.Embedding(num_queries, d_model) # Transformer Decoder decoder_layer = nn.TransformerDecoderLayer(d_model, nhead=8) self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=6) # رؤوس التنبؤ: الفئة والمربع المحيط self.class_head = nn.Linear(d_model, num_classes + 1) # +1 for no-object self.bbox_head = nn.Sequential( nn.Linear(d_model, d_model), nn.ReLU(), nn.Linear(d_model, 4) # [x, y, w, h] ) def forward(self, x): # 1. CNN extracts features features = self.backbone.forward(x) # (B, d, H', W') B, D, H, W = features.shape features = features.flatten(2).permute(2, 0, 1) # (H*W, B, D) # 2. Transformer Encoder memory = self.encoder.forward(features) # 3. Queries + Decoder queries = self.query_embed.forward(torch.arange(queries.shape[0])) queries = queries.unsqueeze(1).repeat(1, B, 1) # (num_q, B, D) output = self.decoder.forward(queries, memory) # 4. Predict classes & boxes class_logits = self.class_head.forward(output) # (num_q, B, num_classes+1) bboxes = self.bbox_head.forward(output).sigmoid() # (num_q, B, 4) return class_logits, bboxes

🎵 المحولات في الصوت — AST, Whisper

بعد نجاح المحولات في النص والصور، كان الصوت هو المجال التالي. هذا الفصل يغطي أهم تطبيقين للمحولات في معالجة الصوت: AST لتصنيف الصوت، وWhisper للتعرف على الكلام.

AST — Audio Spectrogram Transformer

AST (Gong et al., 2021) هو أول محول يُطبّق مباشرة على الصوت — بدون CNNs. الفكرة: نحول الصوت إلى طيف (Spectrogram) ثم نعامله كصورة! نطبّق نفس فكرة ViT — تقسيم الطيف إلى patches.

🎵 Audio Wave → 🎛️ Spectrogram → 🧩 Patches → 🔄 Transformer → 🏷️ Classification
سير عمل AST: من الموجة الصوتية إلى الطيف إلى المحول إلى التصنيف
🔊 كيف يعمل AST خطوة بخطوة
  1. استخراج الطيف: نحول الصوت الخام إلى Mel-Spectrogram (تردد × الزمن) باستخدام STFT (Short-Time Fourier Transform).
  2. تقسيم إلى Patches: نقطع الطيف إلى patches صغيرة (مثل 16×16).
  3. خطي + Positional: نحول كل patch إلى متجه ونضيف التشفير الموضعي.
  4. محول قياسي: نمرر التسلسل عبر محول مثل BERT.
  5. CLS Token: نستخدم [CLS] token للتصنيف النهائي.
PyTorch — Audio Spectrogram Transformer (AST) مبسّط 📋
import torchaudio import torchaudio.functional as F_audio class AudioPreprocessor: # يحول الصوت الخام إلى Mel-Spectrogram def __init__(self, sample_rate=16000, n_mels=128, n_fft=1024, hop_length=512): self.mel_spec = torchaudio.transforms.MelSpectrogram( sample_rate=sample_rate, n_mels=n_mels, n_fft=n_fft, hop_length=hop_length ) def __call__(self, waveform): # waveform: (1, samples) → mel: (128, time_frames) mel = self.mel_spec.forward(waveform) mel = torchaudio.amplitude_to_DB(mel, multiplier=10, amin=1e-10, top_db=80.0) return mel # (n_mels, time) class ASTModel(nn.Module): def __init__(self, n_mels=128, patch_size=16, embed_dim=768, num_classes=527): # AudioSet classes super().__init__() self.patch_embed = nn.Conv2d(1, embed_dim, kernel_size=patch_size, stride=patch_size) num_patches = (n_mels // patch_size) * (100 // patch_size) self.cls_token = nn.Parameter(torch.randn(1, 1, embed_dim)) self.pos_embed = nn.Parameter(torch.randn(1, num_patches + 1, embed_dim)) self.dropout = nn.Dropout(0.1) # Transformer encoder (مثل ViT) encoder_layer = nn.TransformerEncoderLayer(embed_dim, nhead=12) self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=12) self.mlp_head = nn.Sequential( nn.LayerNorm(embed_dim), nn.Linear(embed_dim, num_classes) ) def forward(self, mel_spec): # mel_spec: (B, 1, n_mels, T) x = self.patch_embed.forward(mel_spec) # (B, D, H', W') x = x.flatten(2).transpose(1, 2) # (B, num_patches, D) # Add CLS token + positional embeddings cls_token = self.cls_token.expand(x.size(0), -1, -1) x = torch.cat([cls_token, x], dim=1) x = x + self.pos_embed[:, :x.size(1), :] x = self.dropout.forward(x) x = self.transformer.forward(x.transpose(0, 1)).transpose(0, 1) cls_out = x[:, 0, :] # CLS token return self.mlp_head.forward(cls_out)

Whisper — التعرف على الكلام متعدد اللغات

Whisper (OpenAI, 2022) هو نموذج تعرف على الكلام متعدد اللغات يستخدم هندسة Encoder-Decoder من المحولات. ما يجعله فريداً: درّب على 680,000 ساعة من البيانات متعددة اللغات ويدعم 99 لغة.

🌍 لماذا Whisper ثوري؟
  • متعدد اللغات: 99 لغة — العربية، الصينية، الإنجليزية، وغيرها.
  • يكتب باللغة الأصلية: يكتب النص العربي بالعربية مباشرة.
  • مقاوم للضوضاء: يعمل بشكل جيد في البيئات الصاخبة.
  • مهام متعددة: تعرف على الكلام، ترجمة، تحديد اللغة.
  • مفتوح المصدر: يمكن تشغيله محلياً (أحجام: tiny→large).
Python — استخدام Whisper مع transformers 🤗 📋
# تثبيت المكتبات: # pip install openai-whisper torch # أو استخدام transformers 🤗 import whisper # تحميل النموذج (tiny, base, small, medium, large) model = whisper.load_model("base") # ~1GB للـ base # نسخ صوت عربي result = model.transcribe("audio_arabic.mp3") print(result["text"]) # "مرحباً بكم في درس الذكاء الاصطناعي" # تحديد اللغة تلقائياً print(result["language"]) # 'ar' # === استخدام HuggingFace Transformers === from transformers import WhisperProcessor, WhisperForConditionalGeneration processor = WhisperProcessor.from_pretrained("openai/whisper-small") model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-small") # معالجة الصوت inputs = processor(librosa.load("speech.mp3")[0], sampling_rate=16000, return_tensors="pt") # توليد النص generated_ids = model.generate(inputs.input_features) transcription = processor.batch_decode(generated_ids, skip_special_tokens=True) print(transcription[0])

هندسة Whisper (Encoder-Decoder مع المحولات)

Text Output
"مرحباً"
Decoder (GPT-style)
Autoregressive
Cross-Attention
Q from Decoder, K,V from Encoder
Encoder (BERT-style)
Bidirectional
Conv + Sinusoidal PE
Mel-Spectrogram → Features
🎤 Audio Input
(Mel-Spectrogram)
🧱 هندسة Whisper: Encoder-Decoder مع محولات — مثل T5 ولكن للصوت
🧪 تجربة عملية — تشغيل Whisper على صوت عربي:
whisper audio.mp3 --model small --language Arabic
# النتيجة: "بسم الله الرحمن الرحيم، الحمد لله رب العالمين"

📊 مقارنة شاملة: المحولات في النص والصورة والصوت

المجال المُدخل طريقة التقسيم أشهر نموذج الهندسة
📝 النص Token IDs Subword (BPE/WordPiece) GPT-4, BERT, T5 Encoder / Decoder / Both
🖼️ الصورة Image Patches 16×16 patches ViT, Swin, DETR Encoder (معظم)
🎵 الصوت Mel-Spectrogram Patches + Time frames AST, Whisper Encoder / Encoder-Decoder
🎬 الفيديو Frame Patches + Time Spatial + Temporal VideoMAE, TimeSformer Encoder