تخطَّ إلى المحتوى
1/30الفصل 1 من 30

الـ Perceptron من الصفر: ما الذي يحسبه العصبون؟

ابنِ perceptron ببايثون خالص، شاهده يفشل مع XOR، وافهم لماذا يَعِد مبرهان التقارب بالنجاح دون أن يضمن أنك ستراه.

في هذه الصفحة

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

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

الطريقة الأخرى هي موضوع هذه الدورة. أنت لا تكتب القاعدة. بل تكتب شكل القاعدة — قالبًا فيه فراغات — وتدع الأمثلة تقرر ما الذي يوضع في تلك الفراغات. هذا القلب في الاتجاه هو جوهر تعلم الآلة، وفي هذا الفصل يكون القالب أصغر ما يمكن أن يكون عليه قالب: رقمان وعتبة.

في النهاية ستكون قد كتبت perceptron في نحو عشرين سطرًا من Python، ورأيته ينجح، ورأيته يفشل، وفهمت الاثنين. الملف الذي تكتبه هنا ليس لعبة تُرمى في الفصل التالي: إنه أول commit في مستودع ينتهي، بعد تسعة وعشرين فصلًا من الآن، إلى agent لديه حلقة أدوات ونموذج أذونات.

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

اكتب قياسات قطعة واحدة كمتجه x=(x1,x2)\mathbf{x} = (x_1, x_2) — العرض والوزن. يحتفظ perceptron بمتجه أوزان w=(w1,w2)\mathbf{w} = (w_1, w_2) وانحياز bb. درجته هي

s(x)=wx+b=w1x1+w2x2+bs(\mathbf{x}) = \mathbf{w} \cdot \mathbf{x} + b = w_1 x_1 + w_2 x_2 + b

وإجابته هي إشارة تلك الدرجة: اقبل إذا كان s(x)0s(\mathbf{x}) \geq 0، وارفض خلاف ذلك.

هذا هو النموذج كله. كل ما سيعرفه perceptron يومًا عن المصنع يعيش في ثلاثة أرقام.

تستحق الهندسة التوقف عندها، لأنها الصورة التي ستظل صالحة خلال الفصول التسعة والعشرين التالية حتى عندما لا تعود المعادلات تتسع في سطر واحد. مجموعة النقاط التي يكون عندها s(x)=0s(\mathbf{x}) = 0 — حيث يكون perceptron غير حاسم تمامًا — هي خط مستقيم في المستوى. على أحد الجانبين تكون الدرجة موجبة وتُقبل كل القطع؛ وعلى الجانب الآخر تكون سالبة وتُرفض كل القطع. التعلم، بالنسبة إلى perceptron، يعني تحريك ذلك الخط.

حقيقتان عن ذلك الخط تتبعان مباشرة من الجبر، وكلتاهما ستهم لاحقًا:

  • w\mathbf{w} عمودي عليه. متجه الأوزان لا يقع بمحاذاة الحد، بل يشير عبره، نحو جهة القبول.
  • bb يزحزحه دون أن يديره. من دون انحياز سيُجبر الخط على المرور بنقطة الأصل، وهذا قيد عبثي لمصنع يقيس بالميليمترات والغرامات — سيعني أن قطعة عرضها صفر ووزنها صفر تقع تمامًا على السياج.

قاعدة التعلم، ولماذا لا تحتاج إلى تفاضل

رابط إلى القسم: قاعدة التعلم، ولماذا لا تحتاج إلى تفاضل

يبدأ perceptron وهو لا يعرف شيئًا: w=(0,0)\mathbf{w} = (0, 0) وb=0b = 0. كل درجة تساوي صفرًا، ولذلك يقبل كل شيء.

الآن اعرض عليه مثالًا واحدًا في كل مرة. وسم القطع المقبولة بـ y=+1y = +1 والمرفوضة بـ y=1y = -1. لكل مثال، اطرح سؤالًا واحدًا: هل خرجت الإشارة صحيحة؟ الطريقة المختصرة لكتابة هذا السؤال هي التحقق مما إذا كان ys(x)y \cdot s(\mathbf{x}) موجبًا — إذا اتفق الوسم والدرجة في الإشارة كان حاصل ضربهما موجبًا، وإذا اختلفا كان سالبًا.

إذا كانت الإجابة نعم، لا تغيّر شيئًا. إذا كانت لا، ادفع دفعة صغيرة:

ww+yx,bb+y\mathbf{w} \leftarrow \mathbf{w} + y\,\mathbf{x}, \qquad b \leftarrow b + y

هذه هي الخوارزمية كلها، ويستحق الأمر أن تفهم لماذا هذه هي الدفعة الصحيحة بدلًا من حفظها. لنفترض أن قطعة كان ينبغي قبولها (y=+1y = +1) لكن الدرجة خرجت سالبة. إضافة x\mathbf{x} إلى w\mathbf{w} تغيّر الدرجة على القطعة نفسها بمقدار

(w+x)xwx=xx=x2(\mathbf{w} + \mathbf{x}) \cdot \mathbf{x} - \mathbf{w} \cdot \mathbf{x} = \mathbf{x} \cdot \mathbf{x} = \lVert \mathbf{x} \rVert^2

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

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

الشيء الذي كنت سترغب في اشتقاقه هو الخطأ — عدد القطع المصنفة خطأ. لكن ذلك العدد يشبه درج السلم: يبقى ثابتًا عند 4 بينما تدفع الخط قليلًا، ثم يهبط إلى 3 في اللحظة التي يعبر فيها الخط نقطة. مشتقته صفر في كل مكان تقريبًا وغير معرفة عند الدرجات. لا يجد التفاضل ما يمسك به. تعمل قاعدة perceptron حول ذلك لأنها لا تطلب ميلًا أصلًا: تسأل فقط «صحيح أم خطأ؟»، وتتحرك في اتجاه يمكنها تبريره هندسيًا.

هذا حل حقيقي، وهو أيضًا طريق مسدود. في الفصل 2 سنريد loss تأتي من مكان ما بدلًا من أن تُختار، وفي الفصل 4 نموذجًا يذكر مدى تأكده، وفي الفصل 5 شيئًا له أكثر من طبقة واحدة — ولا يمكن الوصول إلى أي منها من قاعدة لا تعرف إلا «خطأ». استعادة ميل قابل للاستخدام هي ما يفرض الفصلين التاليين. لكن perceptron يستطيع أن يفعل شيئًا لا يستطيع أي من خلفائه فعله: أن يتعلم بلا تفاضل على الإطلاق.

Python خالص، من دون NumPy. قوائم وحلقة. سيصل NumPy في الفصل التالي، عندما لا تعود العمليات الحسابية تتسع في حلقة ترغب في قراءتها؛ إدخاله الآن سيخفي الحساب خلف مكتبة في اللحظة نفسها التي تريد فيها رؤيته.

perceptron.pyPYTHON
def score(w, b, x):
    return w[0] * x[0] + w[1] * x[1] + b


def predict(w, b, x):
    return 1 if score(w, b, x) >= 0 else -1


def train(data, epochs=200):
    """Returns (w, b, epoch_it_converged) — or None for the epoch if it never did."""
    w, b = [0.0, 0.0], 0.0
    for epoch in range(epochs):
        mistakes = 0
        for x, y in data:
            if y * score(w, b, x) <= 0:          
                w[0] += y * x[0]                 
                w[1] += y * x[1]                 
                b += y                           
                mistakes += 1
        if mistakes == 0:
            return w, b, epoch + 1
    return w, b, None

الأسطر الأربعة المظللة هي الخوارزمية. كل ما عدا ذلك أعمال تسجيل وترتيب.

وهذا هو السير، مع ثماني قطع قيسَت عليه — أربع شُحنت وأربع عادت:

belt.pyPYTHON
BELT = [
    ((18.0, 47.0), +1), ((19.5, 52.0), +1), ((20.2, 49.0), +1), ((21.0, 55.0), +1),
    ((24.0, 61.0), -1), ((25.5, 66.0), -1), ((23.0, 70.0), -1), ((26.0, 58.0), -1),
]

w, b, epoch = train(BELT, epochs=200)
print(epoch, w, b)

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

شغّله:

TEXT
None [-142.1, -13.0] 54.0

مئتا epoch، و454 تصحيحًا، ولم يتقارب. الأوزان كبيرة وإشارتها خاطئة. هناك شيء خطأ — إلا أن لا شيء خطأ، والسبب هو أكثر ما في هذا الفصل فائدة.

مبرهان التقارب، والرقم الذي يعطيك إياه فعليًا

رابط إلى القسم: مبرهان التقارب، والرقم الذي يعطيك إياه فعليًا

لدى perceptron ضمانة، أثبتها نوفيكوف عام 1962.1 إذا كان يمكن فصل البيانات بخط أصلًا، فإن الخوارزمية تجري على الأكثر

(Rγ)2\left(\frac{R}{\gamma}\right)^2

من التصحيحات قبل أن تتوقف عن إجراء أي تصحيح — حيث RR هو نصف قطر البيانات، أي طول أطول متجه مثال، وγ\gamma هو الهامش: المسافة من hyperplane الفاصل إلى أقرب نقطة في الفضاء المعزَّز حيث يكون الانحياز إحداثيًا ثالثًا. لهذا يغير توسيط البيانات هذا المقدار بينما لا تتغير المسافة بالميليمترات.

الضمانة غير مشروطة ولا تذكر epochs أو معدلات تعلم أو حظًا. لكنها أيضًا لا تذكر الوقت، وهذا الحذف هو لب المسألة.

ضع أرقامنا فيها. مقاسة مباشرة من القطع الثماني، مع طي الانحياز في صورة سمة ثابتة:

نصف القطر RRالهامش γ\gammaالحد (R/γ)2(R/\gamma)^2التصحيحات المنفذة فعليًا
ميليمترات وغرامات خام73.690.0452,633,55029,870
بعد طرح المتوسط12.820.9891681

لم يُخرق المبرهان قط. شغّل النسخة الخام مدة كافية وستتقارب فعلًا — عند epoch 11,976، بعد 29,870 تصحيحًا — داخل حدها البالغ 2,633,550 بارتياح، وهذه الفجوة نفسها هي المقصود: المبرهان يحدّ أسوأ الحالات، لا الحالة المعتادة. لقد احتاج ببساطة إلى epochs أكثر بستين مرة مما قد يصبر عليه أي شخص.

الصف الثاني هو القطع الثماني نفسها، والأسطر العشرون نفسها من الكود، مع إضافة ثلاثة أسطر لطرح متوسط العرض ومتوسط الوزن من كل قياس. هذا كل شيء. هذا هو التغيير كله. إنه يحرك سحابة النقاط بحيث تمتد حول نقطة الأصل بدلًا من أن تطفو عند (22, 57)، وأثر ذلك على الحد عامل قدره خمسة عشر ألفًا، لأن الحدين يتحسنان معًا: RR يهبط من 74 إلى 13 لأن النقاط لم تعد تُقاس من أصل بعيد، وγ\gamma يرتفع من 0.045 إلى 0.989 لأن الهامش يُقاس مقابل متجه أوزان لم يعد مضطرًا إلى حمل انحياز هائل للوصول إلى البيانات.

belt.py (centred)PYTHON
mean_w = sum(x[0] for x, _ in BELT) / len(BELT)   # 22.15
mean_g = sum(x[1] for x, _ in BELT) / len(BELT)   # 57.25
CENTRED = [(((x[0] - mean_w), (x[1] - mean_g)), y) for x, y in BELT]

w, b, epoch = train(CENTRED, epochs=200)
print(epoch, w, b)
TEXT
2 [-4.15, -10.25] 1.0

تقارب في epochين، بعدما صحح نفسه مرة واحدة بالضبط.

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

والآن الفشل الذي أنهى الحقبة الأولى من الشبكات العصبية، وهو يتسع في أربعة صفوف.

انسَ المصنع. خذ مدخلين، كل منهما إما 0 أو 1، واطلب أن تكون الإجابة +1+1 عندما يكون واحد منهما فقط مساويًا لـ 1:

x1x_1x2x_2yy
001-1
01+1+1
10+1+1
111-1

هذا هو XOR — أو الحصري. قبل أن تتابع القراءة، ارسم النقاط الأربع على الورق: ثلاث زوايا من مربع وحدوي والرابعة. علّم الزاويتين القطريتين (0,1)(0,1) و(1,0)(1,0) كمقبولتين، و(0,0)(0,0) و(1,1)(1,1) كمرفوضتين. الآن ارسم خطًا مستقيمًا واحدًا تكون النقطتان المقبولتان على جانب منه والنقطتان المرفوضتان على الجانب الآخر.

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

b<0,w2+b0,w1+b0,w1+w2+b<0b < 0, \qquad w_2 + b \geq 0, \qquad w_1 + b \geq 0, \qquad w_1 + w_2 + b < 0

اجمع المتراجحتين الوسطيتين: w1+w2+2b0w_1 + w_2 + 2b \geq 0، إذن w1+w22bw_1 + w_2 \geq -2b. تقول الأخيرة إن w1+w2<bw_1 + w_2 < -b. معًا: 2bw1+w2<b-2b \leq w_1 + w_2 < -b، وهذا يتطلب 2b<b-2b < -b، وهذا يتطلب b>0b > 0. وتقول المتراجحة الأولى إن b<0b < 0. لا يوجد bb كهذا، ولذلك لا توجد أوزان كهذه. لا يستطيع أي perceptron، بأي أرقام على الإطلاق، تصنيف XOR.

شغّله رغم ذلك، لأن مشاهدة خوارزمية تفشل أكثر قيمة من أن يُقال لك إنها ستفشل:

TEXT
     100 epochs -> converged=None  w=[0.0, 0.0] b=0.0  correct=2/4
   1,000 epochs -> converged=None  w=[0.0, 0.0] b=0.0  correct=2/4
 100,000 epochs -> converged=None  w=[0.0, 0.0] b=0.0  correct=2/4

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

في عام 1969 نشر مارفن مينسكي وسيمور بابرت Perceptrons، دراسة رياضية بحجم كتاب عما يستطيع هذا النموذج تمثيله وما لا يستطيع.2 نتيجة XOR هي أشهر ما يُقتبس منه، وغالبًا ما تُستخدم الاقتباسة كاتهام: أن الكتاب قتل أبحاث الشبكات العصبية خمسة عشر عامًا بدافع المنافسة أو الضغينة.

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

القصة الشائعة خاطئة تاريخيًا أيضًا. يناقش مينسكي وبابرت صراحة perceptrons متعددة الطبقات ويقولان إن مسألة قوتها مفتوحة — لقد اشتبها أن توسيع النظرية سيكون «عقيمًا»، وهذا تنبؤ لا برهان، وكان خاطئًا. ما كان مفقودًا عام 1969 لم يكن فكرة تكديس الطبقات؛ بل طريقة لتدريب كومة منها. لا تستطيع قاعدة perceptron فعل ذلك: فهي تحتاج إلى معرفة مقدار خطأ كل وحدة، وبالنسبة إلى وحدة مدفونة في الوسط لا يوجد وسم تُقارن به. بقيت تلك الفجوة مفتوحة حتى شاع backpropagation عام 1986،3 وإغلاقها هو ما يفعله الفصل 5.

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

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

ما زال هنا. الشكل — اضرب في الأوزان، اجمع، أضف انحيازًا، طبّق دالة غير خطية على الناتج — هو بالضبط شكل وحدة واحدة في كل شبكة عصبية في هذه الدورة، بما في ذلك الوحدات داخل كتلة transformer في الفصل 9. قاعدة التحديث عند الخطأ هي stochastic gradient descent متنكرة: إنها بالضبط ما تحصل عليه عند تطبيق طريقة الفصل 3 على دالة loss معينة. التدريب تدريجيًا — حفنة من الأمثلة في كل مرة بدل مجموعة البيانات كلها دفعة واحدة — لا يزال الطريقة التي تُدرَّب بها النماذج اليوم على كل نطاق. يقيس الفصل 3 أين يقع هذا التبادل فعليًا.

اختفى. العتبة نفسها: سيستبدلها الفصل 4 بدالة تُخرج احتمالًا بدلًا من حكم، لأن «ارفض» و«ارفض، لكن كان قريبًا» قطعتان مختلفتان من المعلومات، والإشارة ترمي الفرق بعيدًا. والطبقة الواحدة، سيستبدلها الفصل 5. والسمات المختارة يدويًا: اختار شخص ما العرض والوزن لهذا السير، وقد أدّى ذلك الاختيار عملًا أكثر مما أدته الخوارزمية. الفصل 8 هو المكان الذي يبدأ فيه النموذج اختيار سماته بنفسه.

تعثر perceptron في شيئين في الوقت نفسه، ويتبين أنهما الشيء نفسه.

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

لكن لا يمكنك تدريب كومة بقاعدة perceptron، لأنها لا تعرف إلا «خطأ»، ووحدة في وسط شبكة لا تملك وسمًا خاصًا بها تكون مخطئة بشأنه. لتدريب كومة، تحتاج إلى معرفة مدى الخطأ، وفي أي اتجاه، لكل وزن — تحتاج إلى ميل. ودالة خطأ perceptron، درج السلم، لا تملك واحدًا.

لذلك قبل الكومة لا بد من وجود دالة loss ذات مشتقة قابلة للاستخدام. وليست واحدة مختارة لأنها مريحة للاشتقاق أيضًا: بل واحدة تأتي من مكان ما، وتقول شيئًا صحيحًا عن البيانات، وينبع gradientها من ذلك المعنى بدل أن يُهندَس عكسيًا ليبدو مرتبًا.

هذا هو الفصل 2، ويبدأ بطرح سؤال لم يحتج perceptron إلى إجابته قط: ليس «هل هذه القطعة جيدة؟»، بل «ما مدى احتمال هذه القراءات، إذا كانت هذه هي الحقيقة؟»


من المفيد أيضًا أن تقرأ إلى جانب هذا الفصل: ورقة روزنبلات الأصلية، The Perceptron: A Probabilistic Model for Information Storage and Organization in the Brain (Psychological Review 65(6), 1958)، وهي أسهل قراءة مما توحي به سمعتها؛ وماكولوتش وبيتس، A Logical Calculus of the Ideas Immanent in Nervous Activity (Bulletin of Mathematical Biophysics 5, 1943)، الورقة التي نمذجت لأول مرة عصبونًا كعتبة فوق مجموع موزون؛ وقسم perceptron في A Course in Machine Learning لهال داومه الثالث، الذي يشتق التحديث نفسه مع تركيز مختلف؛ والفصلين 2 و3 من Mathematics for Machine Learning لديزنروث وفيصل وأونغ عن الجبر الخطي، إذا جعلك الصندوق أعلاه ترغب في أكثر مما قدمه.

  1. Novikoff, A. B. J. On convergence proofs for perceptrons. Proceedings of the Symposium on the Mathematical Theory of Automata, vol. 12, pp. 615–622 (Polytechnic Institute of Brooklyn, 1962). الصياغة والبرهان الأصليان لحدّ الأخطاء المستخدم أعلاه.

  2. Minsky, M. and Papert, S. Perceptrons: An Introduction to Computational Geometry (MIT Press, 1969; expanded edition 1988). نتيجة XOR أولية؛ أما النتائج الجوهرية فتتعلق بالمحمولات محدودة الرتبة والاتصال.

  3. Rumelhart, D. E., Hinton, G. E. and Williams, R. J. Learning representations by back-propagating errors. Nature 323, pp. 533–536 (1986).

هل أنت مستعد لتترك الاختيار لـ LIA؟

ابنِ بكل نماذج الذكاء الاصطناعي في مكان واحد — ابدأ مجانًا اليوم.