מבוא לנוירוף
1. הקדמה
מאמר זה בוחן את Neuroph - ספריית קוד פתוח ליצירת רשתות עצביות ושימוש בלמידת מכונה.
במאמר נסתכל על מושגי הליבה וכמה דוגמאות כיצד להרכיב את הכל.
2. נוירוף
אנו יכולים לתקשר עם Neuroph באמצעות:
- כלי מבוסס GUI
- ספריית Java
שתי הגישות נשענות על היררכיית מעמדות בסיסית הבונה רשתות עצביות מלאכותיות מתוך שכבות של נוירונים.
אנו נתמקד בצד הפרוגרמטי אך נתייחס למספר שיעורים משותפים מהגישה מבוססת ה- GUI של Neuroph כדי לעזור להבהיר מה אנו עושים.
למידע נוסף על הגישה המבוססת על ממשק משתמש, עיין בתיעוד Neuroph.
2.1. תלות
אם עליך להשתמש ב- Neuroph, עלינו להוסיף את ערך Maven הבא:
org.beykery neuroph 2.92
ניתן למצוא את הגרסה האחרונה ב- Maven Central.
3. שיעורי מפתח ומושגים
לכל אבני הבניין הרעיוניות הבסיסיות המשמשות יש שיעורי Java תואמים.
נוירונים מחוברים ל שכבות אשר מקובצים לאחר מכן ל רשתות עצביות. רשתות עצביות מאומנים לאחר מכן באמצעות LearningRules ו מערכי נתונים.
3.1. עֲצָבוֹן
ה עֲצָבוֹן בכיתה יש ארבע תכונות עיקריות:
- כניסה קלט: קשרים משוקללים בין נוירונים
- inputFunction: מפרט משקולות ו סכומים וקטוריים מוחל על נתוני חיבור נכנסים
- transferFunction: מפרט משקולות ו סכומים וקטוריים מוחל על נתונים יוצאים
- תְפוּקָה: ערך הפלט הנובע מהיישום של transferFunctions ו inputFunctions ל inputConnection
יחד ארבע התכונות העיקריות הללו קובעות את ההתנהגות:
פלט = transferFunction (inputFunction (inputConnections));
3.2. שִׁכבָה
שכבות הם בעצם קבוצות של נוירונים כאלה שכל אחד מהם נוירונ בתוך ה שִׁכבָה קשור (בדרך כלל) רק עם נוירונים בקודמות ובעקבותיה שכבות.
שכבותלכן העבירו מידע ביניהם דרך הפונקציות המשוקללות הקיימות על שלהם נוירונים.
נוירונים ניתן להוסיף לשכבות: מעמד העל ברמה העליונה רשת נוירונים מחולק לכמה סוגים מוכרים של רשתות עצביות מלאכותיות כולל רשתות עצביות קונבולוציות (תת-מחלקה רשת התפתחות), רשתות עצביות של הופפילד (מחלקה משנה) הופפילד), ורשתות עצביות פרספטרון רב שכבתיות (תת מחלקה רב שכבתי פרפרפטרון). את כל רשתות עצביות מורכבים מ שכבות אשר בדרך כלל מאורגנים בטריכוטומיה: אם אנו משתמשים בבנאי תת-מחלקה של רשת נוירונים (כמו פרספטרון), נוכל להעביר את שִׁכבָהs, מספר עֲצָבוֹןs לכל אחד שִׁכבָה, והמדד שלהם בשיטה פשוטה זו: לפעמים נרצה לעשות זאת באופן ידני (וזה טוב לראות מה קורה מתחת למכסה המנוע). הפעולה הבסיסית להוסיף א שִׁכבָה אל א רשת נוירונים מושגת כך: הטיעון הראשון מציין את האינדקס של שִׁכבָה בתוך ה רשת נוירונים; הטיעון השני מציין את שִׁכבָה את עצמה. שכבות שנוסף ידנית צריך להיות מחובר באמצעות ConnectionFactory מעמד: הראשון והאחרון שִׁכבָה צריך להיות מחובר גם: זכרו שכוחו וכוחו של א רשת נוירונים תלויים במידה רבה ב: רשתות עצביות מאומנים באמצעות DataSet ו LearningRule שיעורים. DataSet משמש לייצוג ולספקת המידע שנלמד או משמש לאימון רשת נוירונים. מערכי נתונים מאופיינים שלהם גודל קלט, גודל יציאה, ושורות (DataSetRow). LearningRule מציין את הדרך DataSet נלמד או מאומן על ידי רשת נוירונים. מחלקות משנה של LearningRule לִכלוֹל BackPropagation ו פיקוח לימוד. עכשיו בואו נרכיב את אבני הבניין האלה לדוגמא אמיתית. נתחיל ב שילוב של כמה שכבות יחד למוכר שכבת קלט, שכבה נסתרת, ו שכבת פלט תבנית מודגמים על ידי מרבית ארכיטקטורות הרשת העצבית. נרכיב את שלנו רשת נוירונים על ידי שילוב של ארבע שכבות. המטרה שלנו היא לבנות (2, 4, 4, 1) רשת נוירונים. בואו נגדיר תחילה את שכבת הקלט שלנו: לאחר מכן אנו מיישמים שכבה נסתרת אחת: ושכבה נסתרת שתיים: לבסוף, אנו מגדירים את שכבת הפלט שלנו: לאחר מכן נוכל לחבר אותם לא רשת נוירונים: למטרות אימון, בואו להרכיב א DataSet על ידי ציון גודל הקלט וגם וקטור הפלט המתקבל: אנו מוסיפים שורה אלמנטרית לשלנו DataSet שמירה על אילוצי הקלט והפלט שהוגדרו לעיל - מטרתנו בדוגמה זו היא ללמד את הרשת שלנו לבצע פעולות XOR בסיסיות (בלעדיות או): לאחר מכן, בואו נכשיר את שלנו רשת נוירונים עם המובנה BackPropogation LearningRule: עכשיו שלנו רשת נוירונים מאומן בוא נבדוק את זה. עבור כל זוג ערכים לוגיים המועברים אל שלנו DataSet כ DataSetRow, אנו מבצעים את סוג הבדיקה הבא: דבר חשוב לזכור הוא רשתות עצביות רק פלט ערך במרווח הכלול של 0 ו- 1. כדי להפיק ערך אחר, עלינו לנרמל ו לנרמל הנתונים שלנו. במקרה זה, עבור פעולות לוגיות, 0 ו- 1 מושלמים לעבודה. התפוקה תהיה: אנו רואים כי שלנו רשת נוירונים מנבא בהצלחה את התשובה הנכונה! סקרנו זה עתה את המושגים והשיעורים הבסיסיים בהם השתמש Neuroph. מידע נוסף על ספרייה זו זמין כאן, ואת דוגמאות הקוד המשמשות במאמר זה ניתן למצוא באתר GitHub.שכבת שכבה = שכבה חדשה (); layer.addNeuron (n);
3.3. רשת נוירונים
NeuralNetwork ann = Perceptron חדש (2, 4, 1);
NeuralNetwork ann = NeuralNetwork חדש (); שכבת שכבה = שכבה חדשה (); ann.addLayer (0, שכבה); ann.setInputNeurons (layer.getNeurons ());
ann.addLayer (0, inputLayer); ann.addLayer (1, hiddenLayerOne); ConnectionFactory.fullConnect (ann.getLayerAt (0), ann.getLayerAt (1));
ConnectionFactory.fullConnect (ann.getLayerAt (0), ann.getLayerAt (ann.getLayersCount () - 1), שקר); ann.setOutputNeurons (ann.getLayerAt (ann.getLayersCount () - 1) .getNeurons ());
3.4. אימון שלנו רשת נוירונים
int inputSize = 2; int outputSize = 1; DataSet ds = DataSet חדש (inputSize, outputSize); DataSetRow rOne = DataSetRow חדש (כפול חדש [] {0, 0}, כפול חדש [] {0}); ds.addRow (rOne); DataSetRow rTwo = DataSetRow חדש (כפול חדש [] {1, 1}, כפול חדש [] {0}); ds.addRow (rTwo);
NeuralNetwork ann = NeuralNetwork חדש (); // ... BackPropagation backPropagation = חדש BackPropagation (); backPropagation.setMaxIterations (1000); ann.learn (ds, backPropagation);
4. לשים את הכל ביחד
4.1. שכבות
שכבת inputLayer = שכבה חדשה (); inputLayer.addNeuron (נוירון חדש ()); inputLayer.addNeuron (נוירון חדש ());
Layer hiddenLayerOne = שכבה חדשה (); hiddenLayerOne.addNeuron (נוירון חדש ()); hiddenLayerOne.addNeuron (נוירון חדש ()); hiddenLayerOne.addNeuron (נוירון חדש ()); hiddenLayerOne.addNeuron (נוירון חדש ());
Layer hiddenLayerTwo = שכבה חדשה (); hiddenLayerTwo.addNeuron (נוירון חדש ()); hiddenLayerTwo.addNeuron (נוירון חדש ()); hiddenLayerTwo.addNeuron (נוירון חדש ()); hiddenLayerTwo.addNeuron (נוירון חדש ());
שכבת פלט שכבה = שכבה חדשה (); outputLayer.addNeuron (נוירון חדש ());
4.2. רשת נוירונים
NeuralNetwork ann = NeuralNetwork חדש (); ann.addLayer (0, inputLayer); ann.addLayer (1, hiddenLayerOne); ConnectionFactory.fullConnect (ann.getLayerAt (0), ann.getLayerAt (1)); ann.addLayer (2, hiddenLayerTwo); ConnectionFactory.fullConnect (ann.getLayerAt (1), ann.getLayerAt (2)); ann.addLayer (3, outputLayer); ConnectionFactory.fullConnect (ann.getLayerAt (2), ann.getLayerAt (3)); ConnectionFactory.fullConnect (ann.getLayerAt (0), ann.getLayerAt (ann.getLayersCount () - 1), שקר); ann.setInputNeurons (inputLayer.getNeurons ()); ann.setOutputNeurons (outputLayer.getNeurons ());
4.3. הַדְרָכָה
int inputSize = 2; int outputSize = 1; DataSet ds = DataSet חדש (inputSize, outputSize);
DataSetRow rOne = DataSetRow חדש (כפול חדש [] {0, 1}, כפול חדש [] {1}); ds.addRow (rOne); DataSetRow rTwo = DataSetRow חדש (כפול חדש [] {1, 1}, כפול חדש [] {0}); ds.addRow (rTwo); DataSetRow rThree = DataSetRow חדש (כפול חדש [] {0, 0}, כפול חדש [] {0}); ds.addRow (rThree); DataSetRow rFour = DataSetRow חדש (כפול חדש [] {1, 0}, כפול חדש [] {1}); ds.addRow (rFour);
BackPropagation backPropagation = חדש BackPropagation (); backPropagation.setMaxIterations (1000); ann.learn (ds, backPropagation);
4.4. בדיקה
ann.setInput (0, 1); ann.calculate (); כפול [] networkOutputOne = ann.getOutput ();
בדיקה: 1, 0 צפויה: 1.0 תוצאה: 1.0 בדיקה: 0, 1 צפויה: 1.0 תוצאה: 1.0 בדיקה: 1, 1 צפויה: 0.0 תוצאה: 0.0 בדיקה: 0, 0 צפויה: 0.0 תוצאה: 0.0
5. מסקנה