מבוא לנוירוף

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. עֲצָבוֹן

ה עֲצָבוֹן בכיתה יש ארבע תכונות עיקריות:

  1. כניסה קלט: קשרים משוקללים בין נוירונים
  2. inputFunction: מפרט משקולות ו סכומים וקטוריים מוחל על נתוני חיבור נכנסים
  3. transferFunction: מפרט משקולות ו סכומים וקטוריים מוחל על נתונים יוצאים

  4. תְפוּקָה: ערך הפלט הנובע מהיישום של transferFunctions ו inputFunctions ל inputConnection

יחד ארבע התכונות העיקריות הללו קובעות את ההתנהגות:

פלט = transferFunction (inputFunction (inputConnections));

3.2. שִׁכבָה

שכבות הם בעצם קבוצות של נוירונים כאלה שכל אחד מהם נוירונ בתוך ה שִׁכבָה קשור (בדרך כלל) רק עם נוירונים בקודמות ובעקבותיה שכבות.

שכבותלכן העבירו מידע ביניהם דרך הפונקציות המשוקללות הקיימות על שלהם נוירונים.

נוירונים ניתן להוסיף לשכבות:

שכבת שכבה = שכבה חדשה (); layer.addNeuron (n);

3.3. רשת נוירונים

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

את כל רשתות עצביות מורכבים מ שכבות אשר בדרך כלל מאורגנים בטריכוטומיה:

  1. שכבות קלט
  2. שכבות נסתרות
  3. שכבות פלט

אם אנו משתמשים בבנאי תת-מחלקה של רשת נוירונים (כמו פרספטרון), נוכל להעביר את שִׁכבָהs, מספר עֲצָבוֹןs לכל אחד שִׁכבָה, והמדד שלהם בשיטה פשוטה זו:

NeuralNetwork ann = Perceptron חדש (2, 4, 1);

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

NeuralNetwork ann = NeuralNetwork חדש (); שכבת שכבה = שכבה חדשה (); ann.addLayer (0, שכבה); ann.setInputNeurons (layer.getNeurons ()); 

הטיעון הראשון מציין את האינדקס של שִׁכבָה בתוך ה רשת נוירונים; הטיעון השני מציין את שִׁכבָה את עצמה. שכבות שנוסף ידנית צריך להיות מחובר באמצעות ConnectionFactory מעמד:

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 ());

זכרו שכוחו וכוחו של א רשת נוירונים תלויים במידה רבה ב:

  1. מספר ה שכבות בתוך ה רשת נוירונים
  2. מספר ה נוירונים בכל אחד שִׁכבָה (וה פונקציות משוקללות ביניהם), ו
  3. האפקטיביות של אלגוריתמי ההדרכה / הדיוק של DataSet

3.4. אימון שלנו רשת נוירונים

רשתות עצביות מאומנים באמצעות DataSet ו LearningRule שיעורים.

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

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);

LearningRule מציין את הדרך DataSet נלמד או מאומן על ידי רשת נוירונים. מחלקות משנה של LearningRule לִכלוֹל BackPropagation ו פיקוח לימוד.

NeuralNetwork ann = NeuralNetwork חדש (); // ... BackPropagation backPropagation = חדש BackPropagation (); backPropagation.setMaxIterations (1000); ann.learn (ds, backPropagation);

4. לשים את הכל ביחד

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

4.1. שכבות

נרכיב את שלנו רשת נוירונים על ידי שילוב של ארבע שכבות. המטרה שלנו היא לבנות (2, 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. הַדְרָכָה

למטרות אימון, בואו להרכיב א DataSet על ידי ציון גודל הקלט וגם וקטור הפלט המתקבל:

int inputSize = 2; int outputSize = 1; DataSet ds = DataSet חדש (inputSize, outputSize);

אנו מוסיפים שורה אלמנטרית לשלנו DataSet שמירה על אילוצי הקלט והפלט שהוגדרו לעיל - מטרתנו בדוגמה זו היא ללמד את הרשת שלנו לבצע פעולות XOR בסיסיות (בלעדיות או):

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);

לאחר מכן, בואו נכשיר את שלנו רשת נוירונים עם המובנה BackPropogation LearningRule:

BackPropagation backPropagation = חדש BackPropagation (); backPropagation.setMaxIterations (1000); ann.learn (ds, backPropagation); 

4.4. בדיקה

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

ann.setInput (0, 1); ann.calculate (); כפול [] networkOutputOne = ann.getOutput (); 

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

במקרה זה, עבור פעולות לוגיות, 0 ו- 1 מושלמים לעבודה. התפוקה תהיה:

בדיקה: 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. מסקנה

סקרנו זה עתה את המושגים והשיעורים הבסיסיים בהם השתמש Neuroph.

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


$config[zx-auto] not found$config[zx-overlay] not found