החייאת מונוכרום: צביעת תמונות בלמידה עמוקה

גווני הספיה והגרדיאנטים האפורים של תצלומים ישנים טומנים בחובם קסם ייחודי, לוכדים רגעים קפואים בזמן. עם זאת, לעתים קרובות חסרה להם המיידיות התוססת של הסצנה המקורית. דמיינו שאתם מפיחים את גווני החיים בחזרה לתוך הזיכרונות היקרים הללו, הופכים דיוקן שחור-לבן דהוי לחלון החושף את עולמו של המצולם בצבע מלא. תהליך טרנספורמטיבי זה, המכונה צביעת תמונות (image colorization), ריתק אמנים והיסטוריונים במשך זמן רב. כיום, מונע על ידי התקדמות בבינה מלאכותית, במיוחד בלמידה עמוקה, צביעה אוטומטית משיגה תוצאות שהיו פעם נחלת המדע הבדיוני.

הוספת צבע לתמונה בגווני אפור מציבה אתגר מרתק. כמות משמעותית של מידע – נתוני הצבע המקוריים – אובדת מטבעה כאשר תמונה מוצגת במונוכרום. כיצד אלגוריתם יכול לדעת את צבעו האמיתי של פרח, שמלה או השמיים מערכי בהירות בלבד? התשובה טמונה ברמזים העדינים המוטמעים בתמונה בגווני אפור עצמה: טקסטורות, צורות, הקשר, והאינטראקציה בין אור וצל. בעוד שזיהוי הצבע המקורי המדויק עשוי להיות בלתי אפשרי (האם הוורד ההוא היה באמת ארגמן, או אולי גוון של ורוד?), המטרה עוברת ליצירת צביעה סבירה ומשכנעת מבחינה אסתטית. המטרה היא לייצר תמונה שצופה אנושי ימצא כאמינה, ואולי אף בלתי ניתנת להבחנה מתצלום צבעוני מקורי.

מודלים של למידה עמוקה מצטיינים בחשיפת דפוסים מורכבים ויחסים סטטיסטיים בתוך מערכי נתונים עצומים. על ידי אימון מודלים אלה על מיליוני תמונות, תוך השוואת גרסאות בגווני אפור למקבילותיהן הצבעוניות המקוריות, אלגוריתמים לומדים לקשר טקסטורות ומבנים ספציפיים לצבעים סבירים. הם לומדים שדשא הוא בדרך כלל ירוק, שמיים הם לעתים קרובות כחולים, וטקסטורות מסוימות מתאימות לגרעיני עץ או לבד. זה דומה לניחוש מושכל, אך כזה המבוסס על אנציקלופדיה חזותית עצומה. האלגוריתם אינו ‘יודע’ את הצבע האמיתי במובן האנושי, אך הוא יכול לבצע חיזויים סבירים ביותר בהתבסס על מתאמים נלמדים.

שפת הצבע: CIELab ורשתות נוירונים

כדי להתמודד עם צביעה באופן חישובי, אנו זקוקים לדרך מתאימה לייצג צבע. בעוד ש-RGB (אדום, ירוק, כחול) נפוץ לתצוגות, הוא מערבב מידע על בהירות (luminance) וצבעוניות (chrominance). מערכת מועילה יותר למשימה זו היא מרחב הצבע CIELab. מודל זה מפריד באלגנטיות את הצבע לשלושה רכיבים נפרדים:

  • L (Lightness): ערוץ זה מייצג את המידע בגווני אפור, הנע משחור טהור ללבן טהור. זהו למעשה נתון הקלט שכבר יש לנו בתמונה בשחור-לבן.
  • a: ערוץ זה מקודד את הספקטרום מירוק (ערכים שליליים) לאדום (ערכים חיוביים).
  • b: ערוץ זה מקודד את הספקטרום מכחול (ערכים שליליים) לצהוב (ערכים חיוביים).

היופי של CIELab טמון בהפרדה זו. מודל הלמידה העמוקה שלנו יכול להתמקד בחיזוי שני ערוצי הצבעוניות (‘a’ ו-‘b’) בהתבסס אך ורק על ערוץ הבהירות (‘L’) הקלט. המשימה המרכזית הופכת להיות: בהינתן המידע בגווני אפור (L), מהם ערכי ‘a’ ו-‘b’ הסבירים ביותר המתאימים לכל פיקסל?

ניסיונות מוקדמים השתמשו לעתים קרובות ברשתות נוירונים קונבולוציוניות (CNNs) – סוג של ארכיטקטורת למידה עמוקה המיומנת במיוחד בעיבוד נתונים דמויי רשת כגון תמונות. רשתות אלו אומנו על מערכי נתונים גדולים של תמונות (כמו ImageNet) כדי לחזות ישירות את ערכי ‘a’ ו-‘b’ עבור כל פיקסל, תוך התייחסות לכך כבעיית רגרסיה (חיזוי ערכים רציפים). עם זאת, הופיעה מלכודת נפוצה: הצביעות שהתקבלו נראו לעתים קרובות דהויות או עמומות. מדוע? קחו בחשבון אובייקט כמו תפוח. הוא יכול להיות באופן סביר אדום, ירוק, או אפילו צהוב. אם הרשת מנסה למצע את האפשרויות הללו במהלך הרגרסיה, היא עשויה להתפשר על פשרה חומה ומשעממת במקום צבע ספציפי ותוסס. אפקט המיצוע הזה על פני מספר צבעים סבירים נטה לשטוף את התוצאות.

שינוי פרדיגמה: צביעה כסיווג

כדי להתגבר על בעיית הדעיכה ולהפיק צבעים חיים ומציאותיים יותר, גישה מתוחכמת יותר ממסגרת מחדש את הבעיה. במקום להתייחס לחיזוי צבע כרגרסיה, הוא נתפס כמשימת סיווג.

הנה השינוי הרעיוני:

  1. מרחב צבע מקוונטט (Quantized Color Space): הספקטרום הרציף של ערכי ‘a’ ו-‘b’ האפשריים מחולק לקבוצה מוגדרת מראש של ‘סלים’ (bins) או קטגוריות צבע מייצגות. חשבו על זה כצמצום פלטה עצומה לקבוצה ניתנת לניהול, אך מקיפה, של אפשרויות צבע מובחנות בתוך מישור ‘a’-‘b’.
  2. חיזוי הסתברויות: עבור כל פיקסל בתמונת הקלט בגווני אפור, ה-CNN אינו חוזה ערך ‘a’ ו-‘b’ יחיד. במקום זאת, הוא מוציא התפלגות הסתברות על פני סלי הצבע המקוונטטים. הוא בעצם אומר, ‘עבור פיקסל זה, יש סיכוי של 70% שהוא שייך ל’סל אדום עז #5’, סיכוי של 20% שהוא ‘סל אדום חיוור #2’, סיכוי של 5% שהוא ‘סל חום #12’,’ וכן הלאה.
  3. טיפול בעמימות: גישה הסתברותית זו מטפלת מטבעה בעמימות צבע. אם אובייקט יכול להיות במספר צבעים (כמו התפוח), הרשת יכולה להקצות הסתברויות משמעותיות למספר סלי צבע שונים, המשקפים אי-ודאות זו מבלי לפנות לממוצע תפל.
  4. פענוח לצבע חי: השלב האחרון כולל תרגום התפלגות ההסתברות הזו בחזרה לצבע יחיד וספציפי עבור כל פיקסל. גישה נאיבית עשויה להיות פשוט לבחור את סל הצבע עם ההסתברות הגבוהה ביותר (השכיח). עם זאת, כדי לעודד חיות ולהימנע מבעיית הדעיכה, משתמשים בטכניקות כמו חישוב הממוצע המחושל (annealed mean) של ההתפלגות. שיטה זו נותנת משקל רב יותר לחיזויים פחות סבירים אך צבעוניים יותר (רוויה גבוהה יותר), ובכך ‘שוברת שוויון’ לטובת חיות תוך כיבוד ההתפלגות החזויה הכוללת.

מסגרת סיווג זו, בשילוב עם תכנון קפדני של פונקציית ההפסד (המדד המשמש להערכת ביצועי המודל במהלך האימון) במיוחד עבור צביעה, מאפשרת למודל ללמוד את הקשר המורכב בין מאפיינים בגווני אפור לבין התפלגות הצבעים הסבירים. התוצאה היא תמונות שאינן רק צבועות באופן סביר אלא גם בעלות עושר ומשיכה חזותית שלעתים קרובות חסרים בשיטות מבוססות רגרסיה מוקדמות יותר.

הצצה מתחת למכסה המנוע: זרימת עבודה מעשית בלמידה עמוקה

בעוד שאימון CNN מתוחכם כזה מאפס הוא משימה מונומנטלית הדורשת משאבי חישוב עצומים ומערכי נתונים נרחבים, מינוף מודלים מאומנים מראש הופך טכנולוגיה זו לנגישה. בואו נעבור על השלבים הרעיוניים הכרוכים בשימוש במודל למידה עמוקה מאומן מראש (במיוחד כזה שנבנה באמצעות מסגרת Caffe, כמו בדוגמה המקורית) לצביעת תמונות, המיושם באמצעות Python וספריות נפוצות.

1. הרכבת ערכת הכלים:

הבסיס כולל בדרך כלל Python, שפת תכנות רב-תכליתית פופולרית במדעי הנתונים ובינה מלאכותית. ספריות מפתח ממלאות תפקידים חיוניים:

  • NumPy: חיונית לפעולות נומריות יעילות, במיוחד טיפול במערכים רב-ממדיים המייצגים תמונות.
  • OpenCV (cv2): ספרייה חזקה למשימות ראייה ממוחשבת. היא מספקת פונקציות לקריאה, כתיבה, עיבוד והצגה של תמונות, ובאופן מכריע, כוללת מודול רשת נוירונים עמוקה (DNN) המסוגל לטעון ולהריץ מודלים שאומנו במסגרות שונות כמו Caffe, TensorFlow ו-PyTorch.
  • Argparse: ספריית Python סטנדרטית ליצירת ממשקי שורת פקודה ידידותיים למשתמש, המאפשרת למשתמשים לציין בקלות פרמטרי קלט כמו נתיב קובץ התמונה.
  • OS: משמשת לאינטראקציות בסיסיות עם מערכת ההפעלה, כמו בניית נתיבי קבצים באופן שעובד על פני מערכות שונות (Windows, macOS, Linux).

2. רכישת האינטליגנציה המאומנת מראש:

במקום לבנות את הרשת הנוירונית לבנה אחר לבנה, אנו משתמשים בקבצים המייצגים רשת שכבר אומנה לצביעה. אלה כוללים בדרך כלל:

  • קובץ ארכיטקטורת המודל (.prototxt עבור Caffe): קובץ זה מגדיר את מבנה הרשת הנוירונית – השכבות, סוגיהן, החיבורים והפרמטרים שלהן. זהו התרשים של המודל.
  • קובץ משקלים מאומנים(.caffemodel עבור Caffe): קובץ זה מכיל את המשקלים המספריים שנלמדו על ידי הרשת במהלך תהליך האימון הנרחב שלה. משקלים אלה מכילים את ה’ידע’ שהמודל רכש לגבי מיפוי מאפיינים בגווני אפור להסתברויות צבע. זוהי האינטליגנציה המזוקקת.
  • נתוני קוונטיזציית צבע (קובץ .npy): קובץ NumPy זה מאחסן בדרך כלל את נקודות המרכז של סלי הצבע המקוונטטים ששימשו בגישת הסיווג שתוארה קודם לכן. הוא משמש כפלטת הייחוס להסתברויות הצבע החזויות.

קבצים אלה מייצגים את שיאם של שבועות או חודשים פוטנציאליים של אימון על חומרה חזקה.

3. טעינת מנוע הצביעה:

עם הקבצים הדרושים ממוקמים, מודול ה-DNN של OpenCV מספק את המנגנון לטעינת הרשת המאומנת מראש לזיכרון. הפונקציה cv2.dnn.readNetFromCaffe (או מקבילות עבור מסגרות אחרות) מקבלת את קבצי הארכיטקטורה והמשקלים כקלט ומאתחלת את הרשת, מה שהופך אותה למוכנה להסקה (inference) (תהליך ביצוע חיזויים על נתונים חדשים). נקודות קוונטיזציית הצבע מקובץ ה-.npy נטענות גם הן, בדרך כלל באמצעות NumPy.

4. כוונון עדין של רכיבי רשת (במידת הצורך):

לפעמים, שכבות ספציפיות בתוך הרשת המאומנת מראש זקוקות להתאמות קלות לפני ההסקה. בהקשר של מודל הצביעה מבוסס הסיווג שנדון:

  • התאמת שכבת הפלט: השכבה הסופית האחראית על פלט חיזויי ערוצי ‘a’ ו-‘b’ (למשל, בשם class8_ab במודל הייחוס) עשויה להזדקק לטעינה מפורשת עם מרכזי סלי הצבע מקובץ ה-.npy. זה מבטיח שהסתברויות הפלט של הרשת ימופו כראוי לפלטת הצבעים המוגדרת מראש. הנקודות מעוצבות מחדש לעתים קרובות ומומרות לסוג הנתונים המתאים (למשל, float32) לפני שהן מוקצות ל-‘blobs’ של השכבה (המונח של Caffe למכלי נתונים).
  • איזון מחדש של צבעים: שכבה אחרת (למשל, conv8_313_rh) עשויה להיות מותאמת כדי להשפיע על האיזון בין צבעים שונים בפלט, פוטנציאלית להגביר את הרוויה או לתקן הטיות שנלמדו במהלך האימון. זה כרוך לעתים קרובות בהגדרת ה-blobs של השכבה לערכים נלמדים ספציפיים (כמו הערך 2.606 המוזכר בקוד המקורי, שכנראה נגזר אמפירית או במהלך האימון).

שלבים אלה מתאימים את המודל הגנרי המאומן מראש לניואנסים הספציפיים של משימת הצביעה באמצעות גישת הסיווג.

5. הכנת תמונת הקלט:

תמונת הקלט בגווני אפור צריכה לעבור מספר שלבי עיבוד מקדים לפני שהיא מוזנת לרשת הנוירונית:

  • טעינה: התמונה נקראת מנתיב הקובץ שצוין באמצעות cv2.imread. גם אם היא בגווני אפור, OpenCV עשויה לטעון אותה כברירת מחדל כתמונת BGR תלת-ערוצית, תוך שכפול ערך האפור על פני הערוצים.
  • נורמליזציה: ערכי הפיקסלים, שבדרך כלל נעים בין 0 ל-255, מותאמים לטווח קטן יותר, לעתים קרובות 0.0 עד 1.0, על ידי חלוקה ב-255.0. נורמליזציה זו מסייעת לייצב את תהליך הלמידה וההסקה של הרשת.
  • המרת מרחב צבע: התמונה מומרת ממרחב הצבע BGR ברירת המחדל למרחב הצבע CIELab באמצעות cv2.cvtColor. זה חיוני לבידוד ערוץ הבהירות (L).
  • שינוי גודל: רוב ה-CNNs המאומנים מראש מצפים לתמונות קלט בגודל קבוע (למשל, 224x224 פיקסלים, תקן נפוץ המושפע ממערכי נתונים כמו ImageNet). תמונת ה-LAB משנה את גודלה בהתאם באמצעות cv2.resize. סטנדרטיזציה זו מבטיחה תאימות לארכיטקטורת הרשת.
  • בידוד ומרכוז ערוץ L: ערוץ הבהירות (L) מופק מתמונת ה-LAB ששונתה בגודלה. לעתים קרובות, ערכיו (בדרך כלל 0-100 ב-LAB) מרוכזים סביב אפס על ידי הפחתת ערך ממוצע (למשל, 50). מרכוז זה הוא נוהג נפוץ נוסף שיכול לשפר את ביצועי הרשת.

ערוץ L שעבר עיבוד קפדני זה מוכן כעת להצגה לרשת.

6. שלב ההסקה: חיזוי צבע:

כאן קורה הקסם:

  • יצירת Blob: ערוץ L המעובד (כעת מערך דו-ממדי) מומר ל-‘blob’, פורמט מערך 4-ממדי הצפוי על ידי מודול ה-DNN (cv2.dnn.blobFromImage). פורמט זה כולל בדרך כלל ממדים לגודל אצווה, ערוצים, גובה ורוחב.
  • מעבר קדימה (Forward Pass): ה-blob מוגדר כקלט לרשת הטעונה באמצעות net.setInput. לאחר מכן, נקראת המתודה net.forward(). זה מפעיל את החישוב: נתוני הקלט זורמים דרך שכבות הרשת, עוברים טרנספורמציות המוכתבות על ידי המשקלים הנלמדים, ובסופו של דבר מייצרים את הפלט החזוי. עבור מודל הצביעה שלנו, הפלט מייצג את ערוצי ‘a’ ו-‘b’ החזויים (או ליתר דיוק, את התפלגויות ההסתברות על פני סלי הצבע).
  • עיצוב מחדש של הפלט: הפלט הגולמי מהרשת צריך להיות מעוצב מחדש ומשוחלף בחזרה לפורמט מרחבי דו-ממדי המתאים לערוצי ‘a’ ו-‘b’.

הרשת יצרה כעת את הניחוש הטוב ביותר שלה למידע הצבע בהתבסס על תמונת הקלט בגווני אפור.

7. שחזור התמונה הצבעונית:

השלב הסופי כולל שילוב מידע הצבע החזוי עם נתוני התמונה המקוריים:

  • שינוי גודל ערוצים חזויים: ערוצי ‘a’ ו-‘b’ החזויים (שגודלם כרגע 224x224, תואם לקלט הרשת) צריכים לשנות את גודלם בחזרה לממדים המקוריים של תמונת הקלט באמצעות cv2.resize. זה מבטיח שמידע הצבע יתיישר כראוי עם מבנה התמונה המקורי.
  • חילוץ בהירות מקורית: באופן מכריע, ערוץ הבהירות (L) מופק מתמונת ה-LAB המקורית, בגודל מלא (שנוצרה במהלך העיבוד המקדים לפני שינוי הגודל). שימוש בערוץ L המקורי משמר את הפרטים המקוריים ואת מבנה הבהירות של התמונה, שהיו נפגעים אילו נעשה שימוש בערוץ L ששונה בגודלו.
  • שרשור: ערוץ L המקורי משולב (משרשר) עם ערוצי ‘a’ ו-‘b’ החזויים ששונה גודלם, לאורך ציר ערוץ הצבע. זה מרכיב מחדש תמונת LAB מלאה, כעת עם צבע חזוי.
  • המרת חזרה לפורמט תצוגה: תמונת ה-LAB המתקבלת מומרת בחזרה למרחב הצבע BGR באמצעות cv2.cvtColor, שכן זהו הפורמט הסטנדרטי הצפוי על ידי רוב פונקציות תצוגת התמונות (כמו cv2.imshow).
  • חיתוך והתאמת קנה מידה: ערכי הפיקסלים בתמונת ה-BGR, הנמצאים כעת בטווח המנורמל (ככל הנראה 0.0 עד 1.0), נחתכים כדי להבטיח שהם יישארו בטווח חוקי זה (ערכים יכולים לעתים לחרוג מעט מהגבולות עקב תהליך החיזוי). לאחר מכן, הם מותאמים בחזרה לטווח השלם הסטנדרטי 0-255 הנדרש לתצוגה או לשמירה כקובץ תמונה סטנדרטי.

8. הדמיה:

לבסוף, ניתן להשתמש בפונקציות כמו cv2.imshow כדי להציג את התמונה המקורית בגווני אפור לצד מקבילתה הצבועה החדשה, מה שמאפשר השוואה חזותית מיידית.

ביצוע התהליך:

בדרך כלל, סקריפט המיישם שלבים אלה יופעל משורת הפקודה. באמצעות הגדרת argparse, המשתמש יספק את הנתיב לתמונת הקלט בגווני אפור כארגומנט (למשל, python colorize_image.py --image my_photo.jpg). הסקריפט יבצע אז את שלבי הטעינה, העיבוד המקדים, ההסקה והשחזור, ובסופו של דבר יציג או ישמור את התוצאה הצבועה.

זרימת עבודה זו, הממנפת מודלים מאומנים מראש וספריות חזקות, הופכת את התיאוריה המורכבת של צביעה בלמידה עמוקה לכלי מעשי המסוגל להוסיף צבע חי וסביר לתמונות מונוכרום, ובכך מגשרת ביעילות על הפער בין עבר להווה.