اصنع خلطات وابدأ التجميع

1. قبل البدء

في هذا الدرس التطبيقي حول الترميز، ستتعرّف على الانحرافات وسبب قوتها في سيناريوهات الرؤية الحاسوبية.

في الدرس التطبيقي السابق حول الترميز، أنشأت "شبكة عصبية" (DNN) بسيطة لرؤية الكمبيوتر لعناصر الأزياء. وقد كان هذا التقييد محدودًا لأن عنصر الملابس هو العنصر الوحيد في الصورة، وكان يجب توسيطه.

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

المتطلبات الأساسية

يستند هذا الدرس التطبيقي إلى عمل مُكتمَل على دفعَين سابقَين، وهما قول "أهلاً بك في &أهلاً، عالميًا&تعلّم تكنولوجيا تعلُّم الآلة وإنشاء نموذج رؤية حاسوبي. يُرجى إكمال الدروس التطبيقية حول الترميز قبل المتابعة.

ما ستتعرّف عليه

  • ما هو الالتفافات
  • كيفية إنشاء خريطة الميزات
  • ما هو التجميع؟

العناصر التي سيتم إنشاؤها

  • خريطة ميزات لصورة

المتطلبات اللازمة

يمكنك العثور على الرمز لبقية الدرس التطبيقي حول الترميز قيد التشغيل في Colab.

ويجب أيضًا تثبيت TensorFlow والمكتبات التي ثبّتها في الدرس التطبيقي السابق.

2. ما هي التركيبات؟

الالتفاف هو فلتر يعمل على تمرير صورة ومعالجتها واستخراج الميزات المهمة.

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

إن عملية تعيين الميزات بسيطة من الناحية النظرية. ستفحص كل وحدة بكسل في الصورة ثم تنظر إلى وحدات البكسل المجاورة لها. يمكنك ضرب قيم تلك وحدات البكسل في القيم المكافئة في أحد الفلاتر.

مثلاً:

التفاف على الصورة

في هذه الحالة، يتم تحديد مصفوفة الالتفاف 3x3 أو الصورة kernel.

القيمة الحالية لوحدة البكسل هي 192. يمكنك حساب قيمة البكسل الجديد من خلال الاطّلاع على قيم الجيرة وضربها في القيم المحدّدة في الفلتر وضبط قيمة البكسل الجديد على المبلغ النهائي.

والآن حان وقت استكشاف كيفية عمل التركيبات من خلال إنشاء التفاف أساسي على صورة بتدرج رمادي ثنائي الأبعاد.

وستوضح ذلك من خلال صورة الصعود من SciPy. إنها صورة مُدمجة رائعة وتحتوي على العديد من الزوايا والخطوط.

3- بدء الترميز

ابدأ باستيراد بعض مكتبات Python وصورة الصعود:

import cv2
import numpy as np
from scipy import misc
i = misc.ascent()

وبعد ذلك، استخدِم مكتبة Pyplot matplotlib لرسم الصورة حتى تعرف كيف تبدو:

import matplotlib.pyplot as plt
plt.grid(False)
plt.gray()
plt.axis('off')
plt.imshow(i)
plt.show()

edb460dd5397f7f4.png

يمكنك أن ترى ذلك صورة لدَرَج. هناك العديد من الميزات التي يمكنك تجربتها وعزلها. على سبيل المثال، هناك خطوط رأسية قوية.

يتم تخزين الصورة كمصفوفة NumPy، حتى نتمكن من إنشاء الصورة المحوَّلة من خلال نسخ هذه المصفوفة فقط. ستحتفظ المتغيّران size_x وsize_y بأبعاد الصورة حتى تتمكن من تكرارها لاحقًا.

i_transformed = np.copy(i)
size_x = i_transformed.shape[0]
size_y = i_transformed.shape[1]

4. إنشاء مصفوفة الالتفاف

أولاً، أنشِئ مصفوفة الالتفاف (أو النواة) كمصفوفة 3x3:

# This filter detects edges nicely
# It creates a filter that only passes through sharp edges and straight lines. 
# Experiment with different values for fun effects.
#filter = [ [0, 1, 0], [1, -4, 1], [0, 1, 0]] 
# A couple more filters to try for fun!
filter = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1]]
#filter = [ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]
 # If all the digits in the filter don't add up to 0 or 1, you 
# should probably do a weight to get it to do so
# so, for example, if your weights are 1,1,1 1,2,1 1,1,1
# They add up to 10, so you would set a weight of .1 if you want to normalize them
weight  = 1

احسب الآن وحدات البكسل التي يتم إخراجها. كرِّر ما سبق على الصورة، مع ترك هامش بحجم 1 بكسل، وضرب كلّ من جيران وحدة البكسل الحالية في القيمة المحدّدة في الفلتر.

وهذا يعني أنّ وحدة pixel&#39 الحالية أعلى وحدة البكسل وعلى يسارها سيتم ضربها في العنصر أعلى اليسار في الفلتر. ثم اضرب النتيجة في الوزن وتأكّد من أن النتيجة في النطاق بين 0 و255.

أخيرًا، حمِّل القيمة الجديدة إلى الصورة التي تم تحويلها:

for x in range(1,size_x-1):
  for y in range(1,size_y-1):
      output_pixel = 0.0
      output_pixel = output_pixel + (i[x - 1, y-1] * filter[0][0])
      output_pixel = output_pixel + (i[x, y-1] * filter[0][1])
      output_pixel = output_pixel + (i[x + 1, y-1] * filter[0][2])
      output_pixel = output_pixel + (i[x-1, y] * filter[1][0])
      output_pixel = output_pixel + (i[x, y] * filter[1][1])
      output_pixel = output_pixel + (i[x+1, y] * filter[1][2])
      output_pixel = output_pixel + (i[x-1, y+1] * filter[2][0])
      output_pixel = output_pixel + (i[x, y+1] * filter[2][1])
      output_pixel = output_pixel + (i[x+1, y+1] * filter[2][2])
      output_pixel = output_pixel * weight
      if(output_pixel<0):
        output_pixel=0
      if(output_pixel>255):
        output_pixel=255
      i_transformed[x, y] = output_pixel

5. فحص النتائج

والآن، خطِّط الصورة لمعرفة تأثير تمرير الفلتر عليها:

# Plot the image. Note the size of the axes -- they are 512 by 512
plt.gray()
plt.grid(False)
plt.imshow(i_transformed)
#plt.axis('off')
plt.show()   

48ff667b2df812ad.png

يمكنك استخدام قيم الفلتر التالية وتأثيرها على الصورة.

إنّ استخدام [-1,0,1,-2,0,2,-1,0,1] يقدم لك مجموعة قوية جدًا من الخطوط الرأسية:

جارٍ رصد فلتر الخطوط الرأسية

إنّ استخدام [-1,-2,-1,0,0,0,1,2,1] يتيح لك الخطوط الأفقية:

رصد الخطوط الأفقية

تعرَّف على قيم مختلفة. جرِّب أيضًا فلاتر مختلفة الحجم، مثل 5×5 أو 7×7.

6- فهم ميزة تجميع البيانات

بعد أن تعرّفت على الميزات الأساسية للصورة، ماذا تفعل؟ كيف تستخدم خريطة الميزات الناتجة لتصنيف الصور؟

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

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

كرِّر الصورة في كل نقطة، وضَع في اعتبارك بكسل البكسل المتجاور وإلى اليمين وأسفله ويمينه. أضِف أكبر عدد من تلك العناصر (وبالتالي الحد الأقصى للتجميع) وحمِّله إلى الصورة الجديدة. وبالتالي، ستكون الصورة الجديدة رُبع حجم الصورة القديمة. أقصى حوض سباحة

7- كتابة رمز للتجميع

سيعرض الرمز التالي مجموعة (2 أو 2) مجمّعة. يمكنك تشغيله للاطّلاع على النتيجة.

سترى أنّ الصورة ستكون رُبع حجم الصورة الأصلية ولكنّها احتفظت بجميع الميزات.

new_x = int(size_x/2)
new_y = int(size_y/2)
newImage = np.zeros((new_x, new_y))
for x in range(0, size_x, 2):
  for y in range(0, size_y, 2):
    pixels = []
    pixels.append(i_transformed[x, y])
    pixels.append(i_transformed[x+1, y])
    pixels.append(i_transformed[x, y+1])
    pixels.append(i_transformed[x+1, y+1])
    pixels.sort(reverse=True)
    newImage[int(x/2),int(y/2)] = pixels[0]
 
# Plot the image. Note the size of the axes -- now 256 pixels instead of 512
plt.gray()
plt.grid(False)
plt.imshow(newImage)
#plt.axis('off')
plt.show()

1f5ebdafd1db2595.png

لاحظ المحاور في هذا الرسم البياني. أصبحت الصورة الآن 256x256، وربع حجمها الأصلي، وقد تم تحسين الميزات التي تم اكتشافها على الرغم من وجود بيانات أقل في الصورة الآن.

8- تهانينا

لقد أنشأت أول نموذج رؤية للكمبيوتر. للتعرّف على كيفية تحسين نماذج الرؤية الحاسوبية بصورةٍ أكبر، يُرجى المتابعة إلى إنشاء شبكات عصبونية التفافية (CNNs) لتحسين الرؤية الحاسوبية.