ניתוח מחירי פולקאדות 13 בספטמבר

רשת עצבית מתפתחת-יישום PyTorch במערך הנתונים CIFAR-10

צומת המקור: 1866263

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

מבוא

סיפר ​​10 | רשתות עצביות מתפתלות
                                    תמונה 1

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

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

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

רשתות עצביות מתפתלות
תמונה 2

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

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

ייבוא ​​ספריית PyTorch 

יבוא numpy כמו np ייבוא ​​פנדות כמו pd
ייבוא ​​לפיד יבוא לפיד.נ. פונקציונלי כמו F ממערכות נתונים של יבוא לפיד, הופך מיבוא לפיד nn יבוא matplotlib.pyplot כמו יבוא plt numpy כמו np יבוא ים כמו sns #מתוך tqdm.notebook יבוא tqdm מ tqdm יבוא tqdm

בשלב זה אנו מייבאים את הספריות הנדרשות. אנו יכולים לראות שאנחנו משתמשים ב- NumPy לפעולות מספריות ופנדות לפעולות מסגרות נתונים. ספריית הלפידים משמשת לייבוא ​​Pytorch.

ל- Pytorch יש רכיב nn המשמש להפשטת פעולות ולפונקציות של למידת מכונה. זה מיובא כ- F. הספרייה לפיד משמש כדי שנוכל לייבא את מערך הנתונים CIFAR-10. לספרייה זו מערכי נתוני תמונות רבים והיא נמצאת בשימוש נרחב למחקר. ניתן לייבא את הטרנספורמציות כך שנוכל לשנות את גודל התמונה לגודל שווה לכל התמונות. ה- tqdm משמש כדי שנוכל לעקוב אחר ההתקדמות במהלך האימון ומשמש להדמיה.

קרא את מערך הנתונים הנדרש

trainData = pd.read_csv ('cifar-10/trainLabels.csv') trainData.head ()

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

ניתוח הנתונים עם PyTorch

הדפס ("מספר הנקודות:", trainData.shape [0]) הדפס ("מספר התכונות:", trainData.shape [1]) הדפס ("תכונות:", trainData.columns.values) הדפס ("מספר ערכים ייחודיים ") עבור col ב trainData: print (col,": ", len (trainData [col] .unique ())) plt.figure (figsize = (12,8))

פלט:

מספר נקודות: 50000 מספר תכונות: 2 תכונות: ['id' 'label'] מספר מזהה ערכים ייחודיים: 50000 label: 10

בשלב זה אנו מנתחים את מערך הנתונים ורואים שלנתוני הרכבות שלנו יש כ- 50000 שורות עם המזהה והתווית המשויכת אליהם. יש בסך הכל 10 שיעורים כמו בשם CIFAR-10.

קבלת ערכת האימות באמצעות PyTorch

מאת torch.utils.data ייבוא ​​random_split val_size = 5000 train_size = len (dataset) - val_size train_ds, val_ds = random_split (dataset, [train_size, val_size]) len (train_ds), len (val_ds)

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

(45000, 5000)
מאת torch.utils.data.dataloader יבוא DataLoader batch_size = 64 train_dl = DataLoader (train_ds, batch_size, shuffle = True, num_workers = 4, pin_memory = True) val_dl = DataLoader (val_ds, batch_size, num_workers = 4, pin_memory = True)

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

הגדרת הפונקציות הנדרשות

@torch.no_grad () דיוק def (יציאות, תוויות): _, preds = לפיד.מקס (יציאות, dim = 1) החזר לפיד.טנסור (torch.sum (preds == labels) .item () / len (preds )) class ImageClassificationBase (nn.Module): def training_step (עצמי, אצווה): תמונות, תוויות = batch out = self (תמונות) # צור אובדן תחזיות = F.cross_entropy (out, labels) # חשב הפסד accu = דיוק (בחוץ) , תוויות) אובדן החזרה, accu def validation_step (עצמי, אצווה): תמונות, תוויות = אצווה החוצה = עצמית (תמונות) # צור אובדן תחזיות = F.cross_entropy (החוצה, תוויות) # חישוב הפסד acc = דיוק (החוצה, תוויות) # חשב החזר דיוק {'הפסד': loss.detach (), 'דיוק': acc} def validation_epoch_end (עצמי, יציאות): batch_losses = [x ['הפסד'] עבור x ביציאות] epoch_loss = לפיד.סטאק (batch_losses ) .mean () # לשלב הפסדים batch_accs = [x ['דיוק'] עבור x ביציאות] epoch_acc = torch.stack (batch_accs) .mean () # שלב דיוק מדויק להחזיר {'הפסד': epoch_loss.item (), ' דיוק ': epoch_acc.item ()} def epoch_end (עצמי, תקופה, תוצאה): pr int ("תקופה:", תקופה + 1) הדפס (f'Train דיוק: {result ["train_accuracy"]*100: .2f}% דיוק אימות: {result ["דיוק"]*100: .2f}% ' ) print (f'Train Loss: {result ["train_loss"]:. 4f} אובדן אימות: {result ["Loss"] :. 4f} ')

כפי שאנו יכולים לראות כאן השתמשנו ביישום בכיתה של ImageClassification ונדרש פרמטר אחד שהוא nn.Module. בתוך מחלקה זו, אנו יכולים ליישם את הפונקציות השונות או שלבים שונים כמו הדרכה, אימות וכו '. הפונקציות כאן הן יישומי פייתון פשוטים.

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

יישום מודול רשת עצבית מתפתחת

class Cifar10CnnModel (ImageClassificationBase): def __init __ (self): super () .__ init __ () self.network = nn.Sequential (nn.Conv2d (3, 32, kernel_size = 3, padding = 1), nn.ReLU (), nn.Conv2d (32, 64, kernel_size = 3, stride = 1, padding = 1), nn.ReLU (), nn.MaxPool2d (2, 2), # פלט: 64 x 16 x 16 nn.BatchNorm2d (64) , nn.Conv2d (64, 128, kernel_size = 3, stride = 1, padding = 1), nn.ReLU (), nn.Conv2d (128, 128, kernel_size = 3, סטרייד = 1, ריפוד = 1), nn .ReLU (), nn.MaxPool2d (2, 2), # פלט: 128 x 8 x 8 nn.BatchNorm2d (128), nn.Conv2d (128, 256, kernel_size = 3, סטרייד = 1, ריפוד = 1), nn.ReLU (), nn.Conv2d (256, 256, kernel_size = 3, stride = 1, padding = 1), nn.ReLU (), nn.MaxPool2d (2, 2), פלט #: 256 x 4 x 4 nn.BatchNorm2d (256), nn.Flatten (), nn.Linear (256*4*4, 1024), nn.ReLU (), nn.Linear (1024, 512), nn.ReLU (), nn.Linear (512, 10)) def קדימה (self, xb): return self.network (xb)

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

32 הוא הגודל של ערוץ הפלט הראשוני וכאשר נלך על שכבת ה- conv2d הבאה, יהיה לנו 32 זה כערוץ הקלט ו- 64 כערוץ הפלט.

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

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

הרכבת הדגם

@torch.no_grad () def evalu (model, data_loader): model.eval () outputs = [model.validation_step (batch) for batch in data_loader] return model.validation_epoch_end (outputs) def fit (model, train_loader, val_loader, epochs = 10, learning_rate = 0.001): best_valid = אין היסטוריה = [] אופטימיזציה = torch.optim.Adam (model.parameters (), learning_rate, weight_decay = 0.0005) לתקופה בטווח (תקופות): # שלב שלב אימון. ) train_losses = [] train_accuracy = [] עבור אצווה ב- tqdm (train_loader): loss, accu = model.training_step (batch) train_losses.append (loss) train_accuracy.append (accu) loss.backward () optimizer.step () אופטימיזציה .zero_grad () # תוצאה שלב אימות = הערכה (דגם, val_loader) תוצאה ['train_loss'] = לפיד.סטאק (train_losses) .mean (). item () תוצאה ['train_accuracy'] = לפיד.סטאק (רכבת_דיוק). mean (). item () model.epoch_end (תקופה, תוצאה) אם (best_valid == None או best_valid
היסטוריה = התאמה (דגם, train_dl, val_dl)

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

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

מתווה את התוצאות

בשלב זה נדמיין את הדיוק מול כל תקופה. אנו יכולים להבחין שככל שהתקופה גדלה הדיוק של המערכת ממשיך לגדול ובאופן דומה האובדן ממשיך לרדת. הקו האדום כאן מציין את התקדמות נתוני האימון וכחול לאימות. אנו יכולים לראות כי הייתה התאמה יתרה בתוצאותינו מכיוון שנתוני האימון עולים על תוצאות האימות באופן דומה ובמקרה של אובדן. לאחר 10 עידן נראה כי נתוני הרכבות עוקפים דיוק של 90% אך אובדן של כ- 0.5. נתוני הבדיקה מגיעים סביב 81% וההפסדים הם קרוב ל -0.2.

def plot_accuracies (היסטוריה): Validation_accuracies = [x ['דיוק'] עבור x בהיסטוריה] Training_Accuracies = [x ['train_accuracy'] עבור x בהיסטוריה] plt.plot (Training_Acuracies, '-rx') plot plt (Validation_accuracies , '-bx') plt.xlabel ('תקופה') plt.ylabel ('דיוק') plt.legend (['אימון', 'אימות']) plt.title ('דיוק מול מספר עידן') ; דיוק עלילה (היסטוריה)
עלילות דיוק
def plot_losses (היסטוריה): train_losses = [x.get ('train_loss') עבור x בהיסטוריה] val_losses = [x ['אובדן'] עבור x בהיסטוריה] plt.plot (train_losses, '-bx') plt.plot (val_losses, '-rx') plt.xlabel ('עידן') plt.ylabel ('הפסד') plt.legend (['אימון', 'אימות']) plt.title ('הפסד לעומת מספר עידן' '); עלילות_היסטוריה (היסטוריה)

test_dataset = ImageFolder (data_dir+'/test', transform = ToTensor ()) test_loader = DeviceDataLoader (DataLoader (test_dataset, batch_size), device) result = evalu (final_model, test_loader) print (f'Test Test: {result ["דיוק" ]*100: .2f}%')
דיוק הבדיקה: 81.07%

אנו יכולים לראות כי בסופו של דבר אנו מגיעים לדיוק של 81.07%.

סיכום:

תמונה: https: //unsplash.com/photos/5L0R8ZqPZHk

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

מקור תמונה

  1. Image 1: https://becominghuman.ai/cifar-10-image-classification-fd2ace47c5e8
  2. תמונה 2: https://www.analyticsvidhya.com/blog/2021/05/convolutional-neural-networks-cnn/

אתה מוזמן ליצור איתי קשר ב:

  1.  לינקדין: https://www.linkedin.com/in/siddharth-m-426a9614a/
  2.  Github: https://github.com/Siddharth1698

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

מקור: https://www.analyticsvidhya.com/blog/2021/09/convolutional-neural-network-pytorch-implementation-on-cifar10-dataset/

בול זמן:

עוד מ אנליטיקה וידיה