नमस्ते, इस उदाहरण में मैं यह दिखाना चाहता हूं कि आप पैटर्न पहचान के लिए हॉपफील्ड नेटवर्क कैसे लागू कर सकते हैं।
मैंने खुद, कई दिनों की तरह, कार्यक्रम प्रशिक्षण, एआई और तंत्रिका नेटवर्क में रुचि लेने का फैसला किया। सौभाग्य से, नेटवर्क पर कई विश्लेषण और उदाहरण हैं, लेकिन वे सभी फ़ंक्शन फ़ार्मुलों की एक बहुतायत के साथ काम करते हैं और यदि आप गणित में कुशल नहीं हैं (मेरे जैसे), तो मैं गोलांग (जीओ) भाषा का उपयोग करके हॉपफील्ड नेटवर्क का एक सरल उदाहरण प्रदर्शित करने का प्रयास करूंगा।
गणितीय नेटवर्क विवरण -
हॉपफील्ड नेटवर्कवास्तव में हॉपफील्ड नेटवर्क क्यों?
एक त्वरित और अधिक या कम स्पष्ट उदाहरण, यदि आप एआई की दुनिया में "सरल" और "समझने योग्य" जैसे शब्दों के साथ काम कर सकते हैं।
इस उदाहरण में, हम 20x20 पिक्सेल मापने वाले एक काले और सफेद चित्र से छवियों को पहचानने की कोशिश करेंगे।
आइए उन चरणों को समझने की कोशिश करें जिन्हें हमें अपना वांछित परिणाम प्राप्त करने से पहले पूरा करना है:
- छवि को वेक्टर में बदलें
- वैक्टर को मैट्रेस में बदलें
- मेट्रिसेस को जोड़ो और एक एकल मैट्रिक्स (डब्ल्यू) प्राप्त करें
- शून्य एकल मैट्रिक्स तिरछे
- इनपुट छवि के वेक्टर द्वारा मैट्रिक्स डब्ल्यू को गुणा करें
- इस नेटवर्क के लिए सक्रियण फ़ंक्शन के माध्यम से प्राप्त वेक्टर पास करें (F)
- नए वेक्टर को चरण 5 पर रखें और तब तक ऑपरेशन जारी रखें जब तक हमें नेटवर्क की एक स्थिर स्थिति नहीं मिलती (हम आउटपुट पर समान वेक्टर प्राप्त करेंगे)।
एक विस्तृत विवरण के साथ कोड पर चलते हैं। सभी पुस्तकालयों की जरूरत है:
package main import ( "github.com/oelmekki/matrix" "fmt" "os" "log" "image" "math" "image/color" "image/png" _ "image/jpeg" )
हम 3 तत्वों (नमूनों की संख्या) के वैक्टर की एक सरणी बनाते हैं, छवियों को वैक्टर में परिवर्तित करते हैं और सरणी में नमूने जोड़ते हैं। 'Y' वेक्टर वह छवि है जिसे हम पहचानना चाहते हैं।
vectorArrays := [3][]float64{} x1 := getVectorFromImage("Images/.jpg") x2 := getVectorFromImage("Images/.jpg") x3 := getVectorFromImage("Images/.jpg") y := getVectorFromImage("Images/Income.jpg")
मेट्रिसेस की एक सरणी बनाएँ, सभी वैक्टर को मेट्रिसेस में बदलें और उन्हें मेट्रिसेस की सरणी में जोड़ें। हम मैट्रिक्स डब्ल्यू का एक रिक्त बनाते हैं और सभी मैट्रिसेस को समेटना शुरू करते हैं, परिणाम डब्ल्यू में डालते हैं।
matrixArray := [len(vectorArrays)]matrix.Matrix{} for i, vInArray := range vectorArrays { matrixArray[i] = vectorToMatrix(vInArray, vInArray) } W := matrix.Matrix{} for i, matrixInArray := range matrixArray { if i == 0 { W = matrixInArray continue } W, _ = W.Add(matrixInArray) }
मैट्रिक्स को तिरछे शून्य करें।
for i := 0; i < W.Rows(); i++ { W.SetAt(i, i, 0) }
हम आउटपुट वेक्टर का एक रिक्त बनाते हैं, वाई वेक्टर द्वारा मैट्रिक्स को गुणा करते हैं, परिणाम को वेक्टर एस में डालते हैं, और इसे गुणा से वापस प्रतिस्थापित करते हैं।
S := make([]float64, 400) for II := 0; II < 100; II++ { if II == 0 { S, _ = W.VectorMultiply(y) for i, element := range S {
सिग्मोड () फ़ंक्शन के बारे में अधिक।
यह सक्रियण फ़ंक्शन एफ है और इसके संचालन का सिद्धांत (हमारे उदाहरण में) आउटपुट वेक्टर में डेटा को परिवर्तित करना और उन्हें 1 या -1 में लाना है।
चूंकि हम द्विध्रुवी नेटवर्क के साथ काम करते हैं, इसलिए डेटा केवल 1 और -1 हो सकता है।
छवि को RGB से 1 और -1 तक कम किया जाना चाहिए, जहां 3 (सशर्त पिक्सेल चमक) द्वारा विभाजित सभी बिंदुओं का योग काला या सफेद होना चाहिए। चूंकि R = 255, G = 255, B = 255 सफेद है, और R = 0, G = 0, B = 0 काला है। मैंने 150 की दहलीज चुनी, ताकि 150 से अधिक या बराबर सफेद (1) होगा जो सभी काले (-1) से कम है, जहां -1 में काले और 1 के बीच का विकल्प सशर्त हो सकता है, हम सभी को काले और सफेद को कम करना है। मूल्यों से। सफेद भी हो सकता है -1, और काला 1, इस मामले में यह कोई फर्क नहीं पड़ता। यह भी विचार करने योग्य है कि हम एक सममित मैट्रिक्स के साथ काम कर रहे हैं और छवियों को समभुज होना चाहिए।
छवि को वेक्टर में बदलने के लिए, आपको एक मैट्रिक्स के रूप में छवि का प्रतिनिधित्व करने की आवश्यकता है जिसे हमने क्षैतिज रूप से काट दिया है और पिछली परत के अंत में प्रत्येक कट परत (और हम उनमें से 20) को जोड़ देंगे और एक वेक्टर 400 (20x20) लंबा हो जाएगा।
उदाहरण में, मैं स्थिरता के लिए आउटपुट वेक्टर की जांच नहीं करता हूं, लेकिन बस 100 बार चक्र से गुजरता हूं, और अंत में मैं जांचता हूं कि हमारा कौन सा नमूना कैसा दिखता है। नेटवर्क या तो अनुमान लगाता है या एक ही समय में तथाकथित चिमेरा या वह क्या देख सकता है की एक मुक्त व्याख्या दे रहा है। यह मैं छवि को बचाने के लिए परिणाम है।
चूंकि हम तुल्यकालिक हॉपफील्ड नेटवर्क मोड का उपयोग करते हैं, इसलिए परिणाम कमजोर होगा। बेशक, आप एसिंक्रोनस का उपयोग कर सकते हैं, जिसमें अधिक समय और संसाधन लगेगा, लेकिन परिणाम बहुत बेहतर होगा।
कार्य उदाहरण:
इनपुट छवि -

जवाब है

पूरा कोडपैकेज मुख्य
package main import ( "github.com/oelmekki/matrix" "fmt" "os" "log" "image" "math" "image/color" "image/png" _ "image/jpeg" ) func vectorToMatrix(v1 []float64, v2 []float64) (matrix.Matrix) { m := matrix.GenerateMatrix(len(v1), len(v2)) for i, elem := range v1 { for i2, elem2 := range v1 { m.SetAt(i, i2, elem2*elem) } } return m } func sigmod(v float64) (float64) { if v >= 0 { return 1 } else { return -1 } } func getVectorFromImage(path string) ([] float64) { reader, err := os.Open(path) if err != nil { log.Fatal(err) } defer reader.Close() m, _, err := image.Decode(reader) if err != nil { log.Fatal(err) } v := make([]float64, 400) vectorIteration := 0 for x := 0; x < 20; x++ { for y := 0; y < 20; y++ { r, g, b, _ := m.At(x, y).RGBA() normalVal := float64(r+g+b) / 3 / 257 if normalVal >= 150 { v[vectorIteration] = 1 } else { v[vectorIteration] = -1 } vectorIteration ++ } } return v } func main() { fmt.Println("Memory size ~ ", int(400/(2*math.Log2(400))), " objects") fmt.Println("1 - ") fmt.Println("2 - ") fmt.Println("3 - ") fmt.Println("-----Start------") vectorArrays := [3][]float64{} x1 := getVectorFromImage("Images/.jpg") x2 := getVectorFromImage("Images/.jpg") x3 := getVectorFromImage("Images/.jpg") y := getVectorFromImage("Images/Income.jpg") vectorArrays[0] = x1 vectorArrays[1] = x2 vectorArrays[2] = x3 matrixArray := [len(vectorArrays)]matrix.Matrix{} for i, vInArray := range vectorArrays { matrixArray[i] = vectorToMatrix(vInArray, vInArray) } W := matrix.Matrix{} for i, matrixInArray := range matrixArray { if i == 0 { W = matrixInArray continue } W, _ = W.Add(matrixInArray) } for i := 0; i < W.Rows(); i++ { W.SetAt(i, i, 0) } S := make([]float64, 400) for II := 0; II < 100; II++ { if II == 0 { S, _ = W.VectorMultiply(y) for i, element := range S { S[i] = sigmod(element) } continue } else { S, _ = W.VectorMultiply(S) for i, element := range S { S[i] = sigmod(element) } } } ar := [3]int{1, 1, 1} for vectorI, v := range vectorArrays { for i, elem := range v { if elem != S[i] { ar[vectorI] = 0 break } } } for i, el := range ar { if el == 1 { fmt.Println("Looks like", i+1) } } img := image.NewRGBA(image.Rect(0, 0, 20, 20)) xx := 0 yy := 0 for i := 0; i < 400; i++ { if i%20 == 0 { yy++ xx = 0 } else { xx++ } if S[i] == -1 { img.Set(xx, yy, color.RGBA{0, 0, 0, 255}) } else { img.Set(xx, yy, color.RGBA{255, 255, 255, 255}) } } f, _ := os.OpenFile("Images/out.png", os.O_WRONLY|os.O_CREATE, 0600) png.Encode(f, img) f.Close() var str string fmt.Scanln(&str) }