الوحدة 2 — المرمّزات التلقائية والفضاء الكامن
قبل أن نبني نموذجًا يولّد صورًا، علينا أن نمرّ بشيء أبسط: نموذج يعيد بناء ما رآه. المرمّز التلقائي فكرة بسيطة على الورق، لكن ما يكشفه — أنّ الصور تعيش على متشعّب منخفض البعد داخل فضاء البكسلات الضخم — هو أساس كلّ ما يأتي بعده في هذه الدورة.
البنية: مرمّز، عنق، فكّ ترميز
المرمّز التلقائي شبكتان مركّبتان: مرمّز يضغط إلى تمثيل كامن صغير، وفكّ ترميز يحاول إعادة بناء من وحدها. تفصلهما طبقة تُدعى عنق الاختناق أبعادها أصغر كثيرًا من أبعاد المُدخَل، وهذه القيود هي التي تحمل التعلّم.
الخسارة أبسط ما يمكن: مسافة تربيعية بين المُدخَل والمُخرَج.
فما دام الطريق مرّ عبر بُعد ضيّق، فإنّ الشبكة مضطرّ ة إلى أن تختار ما تحفظ. الوجه المألوف يُختصر إلى بضع عشرات من القيم، وينبذ الباقي بوصفه إعادة توليد ممكنة. وهذا ما يُعطي فكرة الفضاء الكامن معناها التجريبي: كلّ نقطة فيه تُشفّر صورة كاملة.
بناء أوّل على MNIST
خيطنا الأحمر يبدأ من MNIST: الأرقام المكتوبة يدويًّا 28 في 28 بكسلًا. سنبني مرمّزًا تلقائيًّا كثيفًا يضغطها إلى فضاء كامن من 32 قيمة.
import torch
import torch.nn as nn
class AutoencodeurMNIST(nn.Module):
def __init__(self, dim_latente=32):
super().__init__()
self.encodeur = nn.Sequential(
nn.Flatten(), # (B, 1, 28, 28) -> (B, 784)
nn.Linear(784, 256), nn.ReLU(),
nn.Linear(256, dim_latente), # عنق الاختناق
)
self.decodeur = nn.Sequential(
nn.Linear(dim_latente, 256), nn.ReLU(),
nn.Linear(256, 784), nn.Sigmoid(), # بكسلات في [0, 1]
)
def forward(self, x):
z = self.encodeur(x)
x_reconstruit = self.decodeur(z).view(-1, 1, 28, 28)
return x_reconstruit, z
modele = AutoencodeurMNIST()
optimiseur = torch.optim.Adam(modele.parameters(), lr=1e-3)
critere = nn.MSELoss()
for x_lot, _ in chargeur_train: # التسمية تُهمَل تمامًا
x_reconstruit, _ = modele(x_lot)
perte = critere(x_reconstruit, x_lot)
optimiseur.zero_grad()
perte.backward()
optimiseur.step()
لاحظ نقطتين مهمّتين. الأولى أنّ التدريب دون تسميات: نستخدم البيانات نفسها هدفًا. وهذا ما يجعل المرمّز التلقائي جزءًا من التعلّم غير المُشرَف عليه، ويتيح استعماله على جبال من الصور غير المُصنَّفة. الثانية أنّ حجم الفضاء الكامن قرارٌ هندسيّ حاسم: 32 يعطي إعادة بناء واضحة على MNIST، أمّا 2 فيُنتج ضبابًا لكنّه يسمح بالرسم البصريّ، و1024 يجعل الشبكة تنسخ المُدخَل تقريبًا دون تعلّم شيء مفيد.
الاستيفاء في الفضاء الكامن: علامة على أنّ التعلّم نجح
مجرّد إعادة البناء لا يُخبرنا هل الفضاء الكامن مُنظَّم فعلًا. الاختبار المعتاد هو الاستيفاء الخطّي: نأخذ صورتين و، نمرّ بمرمّزنا فنحصل على و، ثمّ نُولّد سلسلة من الصور من نقاط حيث من 0 إلى 1.
إذا رأينا رقم 3 يتحوّل تدريجيًّا إلى رقم 8 مع صور وسيطة معقولة، فالفضاء الكامن قد التقط بنية دلاليّة. أمّا إذا رأينا رقم 3 ثمّ فوضى بصريّة ثمّ رقم 8 دون تدرّج، فالفضاء الكامن مُفَجَّر ولا يمكن الاعتماد عليه لأيّ توليد.
with torch.no_grad():
z_a = modele.encodeur(x_a.unsqueeze(0))
z_b = modele.encodeur(x_b.unsqueeze(0))
for t in torch.linspace(0, 1, steps=10):
z_t = (1 - t) * z_a + t * z_b
x_t = modele.decodeur(z_t).view(28, 28)
لماذا لا يولّد المرمّز البسيط جيّدًا
هنا الفكرة الجوهرية التي تُبرّر الوحدة التالية بكاملها. المرمّز التلقائي البسيط يتعلّم دالّة إعادة بناء ممتازة، لكنّه لا يتعلّم شيئًا عن توزيع النقاط في الفضاء الكامن.
إذا حاولنا أخذ عيّنة عن طريق ثمّ مرّرناها إلى فكّ الترميز، فالنتيجة كارثيّة في الغالب. لماذا؟ لأنّ ما تعلّمه فكّ الترميز صحيح فقط في المنطقة التي دُرِّبت فيها الشبكة، وهي منطقة صغيرة جدًّا من الفضاء الكامن تتشكّل من الصور التي أنتجها المرمّز. خارج هذه المنطقة، فكّ الترميز يُنتج فوضى: قد يكون توسيطك و خارج التوزيع الفعليّ، فتحصل على صور غير معقولة.
كثيرًا ما يُعرَّف المرمّز التلقائي بوصفه أوّل نموذج توليديّ، وهذا خطأ يُكلّف وقتًا. إعادة البناء لا تُساوي التوليد: الأولى تحتاج إلى حقيقيّة تُدخَل، والثانية تحتاج إلى نقطة جديدة في الفضاء الكامن دون مرور بأيّ . لا يوجد في المرمّز البسيط شيء يفرض على أن يتبع توزيعًا معلومًا. لهذا السبب بالضبط تأتي VAE في الوحدة التالية: لتُضيف قيدًا احتماليًّا يجعل التوليد ممكنًا.
استخدامات المرمّز التلقائي رغم ذلك
هذا العطب في التوليد لا يجعل المرمّز التلقائي عديم الفائدة. له استعمالات عمليّة يوميّة:
- ضغط البيانات المدروس: تعلّم تمثيل صغير يُحتفظ به بدل الصورة كاملة، مع إعادة البناء عند الحاجة. Stable Diffusion يستخدم مرمّزًا تلقائيًّا لضغط الصور بمعامل 8 قبل تشغيل الانتشار عليها، وهي مكسب ضخم في التكلفة الحسابيّة سنعود إليه في الوحدة 6.
- إزالة التشويش: يُدرَّب المرمّز على استقبال مشوَّشة وإعادة نظيفة. هذه هي فكرة المرمّز التلقائي المُشوَّش التي تُوسِّع بشكل جميل إلى نماذج الانتشار.
- كشف الشذوذ: مثال بعيد عن التوزيع سيُعاد بناؤه بشكل سيّئ، فارتفاع خسارة إعادة البناء علامة على شذوذ. مفيد على أعطال آلات صناعيّة أو معاملات بنكيّة غير معتادة.
- التهيئة المسبقة: تعلّم فضاء كامن على بيانات غير مُصنَّفة، ثمّ استعمال المرمّز نقطة انطلاق لمصنِّف يُدرَّب على العدد القليل من التسميات المتاحة.
في الخلاصة
- المرمّز التلقائي شبكتان مركّبتان بينهما عنق اختناق، خسارتهما إعادة البناء التربيعية، وتدريبهما لا يحتاج تسميات.
- الفضاء الكامن يكون مُنَظَّمًا إذا أعطى الاستيفاء بين صورتين سلسلة انتقاليّة معقولة؛ وإلّا فهو مُفَجَّر ولا يصلح للتوليد.
- المرمّز البسيط لا يُولّد لأنّ فكّ الترميز لم يُدرَّب إلّا في منطقة صغيرة م ن الفضاء الكامن؛ نقطة عشوائية من تعطي في العادة فوضى.
- استخداماته الحقيقية هي الضغط، إزالة التشويش، كشف الشذوذ والتهيئة المسبقة، وهو أساس ضغط الصور في Stable Diffusion.
الوحدة التالية تُضيف قطعة واحدة تُبدّل المرمّز التلقائي إلى نموذج توليديّ حقيقيّ: قيد احتماليّ على الفضاء الكامن يُتيح أخذ عيّنة معنى لها.