אל תשתמש ב-Flaten() - איגוד גלובלי עבור CNNs עם TensorFlow ו-Keras PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

אל תשתמש ב-Flaten() – איגוד גלובלי עבור CNNs עם TensorFlow ו-Keras

רוב המתרגלים, בזמן שהם לומדים לראשונה על ארכיטקטורות של רשתות עצביות קונבולוציונית (CNN) - לומדים שהיא מורכבת משלושה מקטעים בסיסיים:

  • שכבות התהפכות
  • איגום שכבות
  • שכבות מחוברות לחלוטין

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

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

model = keras.Sequential([
    
    keras.layers.MaxPooling2D((2, 2), strides=(2, 2), padding='same'),
    keras.layers.Flatten(),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(4096, activation='relu'), 
    keras.layers.Dropout(0.5),
    keras.layers.Dense(4096, activation='relu'),
    keras.layers.Dense(n_classes, activation='softmax')
])

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

model = keras.Sequential([
    
    keras.layers.GlobalAveragePooling2D(),
    keras.layers.Dense(n_classes, activation='softmax')
])

השטחה ב-CNN נמשכת כבר 7 שנים. שנים 7! ונראה שלא מספיק אנשים מדברים על ההשפעה המזיקה שיש לזה גם על חווית הלמידה שלך וגם על המשאבים החישוביים שבהם אתה משתמש.

איגוד ממוצע גלובלי עדיף בחשבונות רבים על פני שיטוח. אם אתה מייצר אבות ל-CNN קטן - השתמש ב-Global Pooling. אם אתה מלמד מישהו על CNNs - השתמש ב-Global Pooling. אם אתה עושה MVP - השתמש ב-Global Pooling. השתמש בשכבות רידוד למקרי שימוש אחרים שבהם יש צורך בפועל.

מקרה מבחן - שיטוח לעומת איגוד גלובלי

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

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

שים לב ששכבות צווארי בקבוק עבור רשתות כמו ResNets נחשבות בעשרות אלפי תכונות, לא רק 1536. בעת השטחה, אתה מענה את הרשת שלך כדי ללמוד מוקטורים בעלי צורה מוזרה בצורה מאוד לא יעילה. תארו לעצמכם תמונה דו-ממדית נחתכת לפרוסות בכל שורת פיקסל ולאחר מכן משורשרת לוקטור שטוח. שני הפיקסלים שהיו 2 פיקסלים זה מזה אנכית אינם feature_map_width פיקסלים משם אופקית! למרות שזה אולי לא משנה יותר מדי עבור אלגוריתם סיווג, המעדיף אינווריאציה מרחבית - זה אפילו לא יהיה טוב מבחינה רעיונית עבור יישומים אחרים של ראייה ממוחשבת.

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

model = keras.Sequential([
    keras.layers.Input(shape=(224, 224, 3)),
    keras.layers.Conv2D(32, (3, 3), activation='relu'),
    keras.layers.Conv2D(32, (3, 3), activation='relu'),
    keras.layers.MaxPooling2D((2, 2), (2, 2)),
    keras.layers.BatchNormalization(),
    keras.layers.Conv2D(64, (3, 3), activation='relu'),
    keras.layers.Conv2D(64, (3, 3), activation='relu'),
    keras.layers.MaxPooling2D((2, 2), (2, 2)),
    keras.layers.BatchNormalization(),
    keras.layers.Flatten(),
    keras.layers.Dropout(0.3),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dense(32, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])
model.summary()

איך נראה הסיכום?

...                                                              
 dense_6 (Dense)             (None, 10)                330       
                                                                 
=================================================================
Total params: 11,574,090
Trainable params: 11,573,898
Non-trainable params: 192
_________________________________________________________________

11.5 מיליון פרמטרים לרשת צעצועים - וצפו בפרמטרים מתפוצצים עם קלט גדול יותר. 11.5 מיליון פרמטרים. EfficientNets, אחת הרשתות עם הביצועים הטובים ביותר שתוכננה אי פעם עובדת בפרמטרים של ~6 מיליון, ואי אפשר להשוות אותה עם המודל הפשוט הזה מבחינת ביצועים בפועל ויכולת ללמוד מנתונים.

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

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

הנה רשת עם איגוד גלובלי:

model = keras.Sequential([
    keras.layers.Input(shape=(224, 224, 3)),
    keras.layers.Conv2D(32, (3, 3), activation='relu'),
    keras.layers.Conv2D(32, (3, 3), activation='relu'),
    keras.layers.MaxPooling2D((2, 2), (2, 2)),
    keras.layers.BatchNormalization(),
    keras.layers.Conv2D(64, (3, 3), activation='relu'),
    keras.layers.Conv2D(64, (3, 3), activation='relu'),
    keras.layers.MaxPooling2D((2, 2), (2, 2)),
    keras.layers.BatchNormalization(),
    keras.layers.GlobalAveragePooling2D(),
    keras.layers.Dropout(0.3),
    keras.layers.Dense(10, activation='softmax')
])

model.summary()

סיכום?

 dense_8 (Dense)             (None, 10)                650       
                                                                 
=================================================================
Total params: 66,602
Trainable params: 66,410
Non-trainable params: 192
_________________________________________________________________

הרבה יותר טוב! אם נעמיק עם המודל הזה, ספירת הפרמטרים תגדל, ואולי נוכל ללכוד דפוסים מורכבים יותר של נתונים עם השכבות החדשות. אם נעשה זאת בתמימות, יתעוררו אותן בעיות שקשורות ל-VGGNets.

הולך רחוק יותר - פרויקט יד מקצה לקצה

האופי הסקרן שלך גורם לך לרצות ללכת רחוק יותר? אנו ממליצים לבדוק את שלנו פרויקט מודרך: "רשתות עצביות מתהפכות - מעבר לארכיטקטורות בסיסיות".

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

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

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

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

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

סיכום

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

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

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

בול זמן:

עוד מ Stackabuse