Սկիզբ » Ուսումնական նյութեր » Ծրագրավորում » Ալգորիթմներ » Նեյրոնային ցանցերի ուսուցումը backpropagation ալգորիթմի միջոցով։ Մաս 4, իրականացում python֊ով։

Նեյրոնային ցանցերի ուսուցումը backpropagation ալգորիթմի միջոցով։ Մաս 4, իրականացում python֊ով։

| Մայիս 13, 2016 | Մեկնաբանված չէ |

Այս մասում կներկայացնենք սիմվոլների ճանաչումը backpropagation ալգորիթմի միջոցով։ Կոդը կգրենք python լեզվով, քանի որ այն կոմպակտ է և թույլ է տալիս իրականացնել արագ լուծումներ։

Ինչպես նշվել է նախորդ մասերում, ցանցի ելքերին պետք է նախապես տրվեն որոշակի արժեքներ, որոնց հետ պետք է համեմատվեն ցանցի փաստացի ելքերը, այդ իմաստով յուրաքանչյուր սիմվոլ կներկայացնենք 5×6 մատրիցի տեսքով։

Screenshot from 2016-05-13 14-21-39Վերը բերված նկարում պատկերված է “A” տառի մատրիցը։ Քանի որ ունենք 5×6 չափանի մատրից, ապա մուտքային շերտում պետք է ունենանք 30 հատ նեյրոն։ Նույն տրամաբանությամբ ելքային շերտում մեզ անհրաժեշտ են 26 հատ նեյրոններ, որը լատինատառ այբուբենի չափն է։ Թաքնված շերտի նեյրոնների քանակությունը որոշող խիստ կանոն գոյություն չունի և հիմնականում այն որոշվում է էմպիրիկ եղանակով՝ այնպես որ դրանց քանակությունը լինի մուտքային և ելքային շերտի նեյրոնների քանակության ինտերվալում գտնվող մի մեծություն։ Մենք այն կընդունենք հավասար 28 ֊ի։

Ելքային շերտում ունենք 26 հատ նեյրոն, որոնցից յուրաքանչյուրը պատասխանատու է մեկ առանձին վերցրած սիմվոլի ճանաչման համար, դա նշանակում է, որ եթե մուտքին տվել ենք “A” տառը, ապա 26 չափանի ելքային վեկտորում 1 արժեք պետք է ունենա դրա առաջին տարրը՝

Screenshot from 2016-05-13 14-38-21

“C”֊ի համար, որը 3֊րդ տառն է, ցանցի ելքերը նմանապես պետք է ունենան հետևյալ արժեքները՝

Screenshot from 2016-05-13 14-42-02

Ծուլության սկզբունքից ելնելով` կոդը կգրենք միայն 2 սիմվոլի ճանաչման համար` “A” և “C” 😀

import Tkinter as tk
import Image,ImageDraw
import numpy as np
import cv2
import tkFont
import pdb

class ImageGenerator:
    def __init__(self, output, parent, posx, posy, *kwargs):
        self.output = output
	np.random.seed(1)
	self.weights0_init = 2 * np.random.random((30, 28)) - 1
	self.weights1_init = 2 * np.random.random((28, 26)) - 1
	patterns = np.array([[0, 0, 1, 0, 0,  0, 0, 1, 0, 0,  0, 1, 0, 1, 0,  1, 1, 1, 1, 1,  1, 0, 0, 0, 1,  1, 0, 0, 0, 1],
		      [0, 1, 1, 1, 1,  1, 0, 0, 0, 0,  1, 0, 0, 0, 0,  1, 0, 0, 0, 0,  1, 0, 0, 0, 0,  0, 1, 1, 1, 1]])
	weights0, weights1 = back_prop(patterns, self.output, self.weights0_init, self.weights1_init)
        self.weights0 = weights0
        self.weights1 = weights1
        self.parent = parent
        self.posx = posx
        self.posy = posy
        self.sizex = 200
        self.sizey = 200
        self.b1 = "up"
        self.xold = None
        self.yold = None
        self.char_map = {'0':'A', '2':'C'}
        self.drawing_area=tk.Canvas(self.parent,width=self.sizex,height=self.sizey)
        self.drawing_area.place(x=self.posx,y=self.posy)
        self.drawing_area.bind("", self.motion)
        self.drawing_area.bind("", self.b1down)
        self.drawing_area.bind("", self.b1up)
        self.button=tk.Button(self.parent,text="Recognize",width=10,bg='white',command=self.save)
        self.button.place(x=self.sizex/11,y=self.sizey+20)
        self.button1=tk.Button(self.parent,text="Clear!",width=10,bg='white',command=self.clear)
        self.button1.place(x=(self.sizex/11)+120,y=self.sizey+20)
	self.label = tk.Label(self.parent, text="Brainy thinks it is:")
	self.label.place(x=250, y=10)
	self.customFont = tkFont.Font(family="Helvetica", size=36)
        self.out_text = tk.Text(self.parent, height=5, width=8, font=self.customFont)
        self.out_text.place(x=250, y=50)
        self.image=Image.new("RGB",(200,200),(255,255,255))
        self.draw=ImageDraw.Draw(self.image)

    def save(self):
        filename = "temp.png"
        self.image.save(filename)
        im_gray = cv2.imread(filename, 0)
        (thresh, im_bw) = cv2.threshold(im_gray, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
	r = 6.0 / im_bw.shape[1]
	dim = (5, int(im_bw.shape[0] * r))
	resized = cv2.resize(im_bw, dim, interpolation = cv2.INTER_AREA)
        out_array = []
        for row_ind in xrange(len(resized)):
          for pixel_ind in xrange(len(resized[row_ind])):
              if resized[row_ind][pixel_ind] < 255:
                 resized[row_ind][pixel_ind] = 1
              else:
                 resized[row_ind][pixel_ind] = 0
        for row in resized:
            out_array.extend(row)
        out_array = np.array(out_array)
        char_ind = predict(out_array, self.weights0, self.weights1)
        self.out_text.delete('1.0', tk.END)
        self.out_text.insert(tk.END, self.char_map[str(char_ind)])

    def clear(self):
        self.drawing_area.delete("all")
        self.image=Image.new("RGB",(200,200),(255,255,255))
        self.draw=ImageDraw.Draw(self.image)

    def b1down(self,event):
        self.b1 = "down"

    def b1up(self,event):
        self.b1 = "up"
        self.xold = None
        self.yold = None

    def motion(self,event):
        if self.b1 == "down":
            if self.xold is not None and self.yold is not None:
                event.widget.create_line(self.xold,self.yold,event.x,event.y,smooth='true',width=1,fill='blue')
                self.draw.line(((self.xold,self.yold),(event.x,event.y)),(0,128,0),width=2)

        self.xold = event.x
        self.yold = event.y

def sigmoid(inp, differential=False):
	if(differential == True):
	    return inp * (1 - inp)
	return 1/(1 + np.exp(-inp))

def predict(input_mat, weights0, weights1):
    layer1 = sigmoid(np.dot(input_mat, weights0))
    layer2 = sigmoid(np.dot(layer1, weights1))
    print layer2
    return np.argmax(layer2)

def back_prop(input_mat, output, weights0, weights1):
    for j in xrange(100000):
	layer0 = input_mat
	layer1 = sigmoid(np.dot(layer0, weights0))
	layer2 = sigmoid(np.dot(layer1, weights1))
	layer2_error = output - layer2
        if (j% 10000) == 0:
            print "Error:" + str(np.mean(np.abs(layer2_error)))
        layer2_delta = layer2_error * sigmoid(layer2, differential=True)
        layer1_error = layer2_delta.dot(weights1.T)
        layer1_delta = layer1_error * sigmoid(layer1, differential=True)
        weights1 += layer1.T.dot(layer2_delta)
        weights0 += layer0.T.dot(layer1_delta)
    return weights0, weights1

if __name__ == "__main__":
    root=tk.Tk()
    root.wm_geometry("%dx%d+%d+%d" % (400, 400, 10, 10))
    root.config(bg='white')
    root.title("BrainY")
    output = np.array([[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
                      [0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]])
    ImageGenerator(output, root, 10, 10)
    root.mainloop()

Մնացած սիմվոլներն էլ ճանաչելու համար ուղղակի պետք է “ImageGenerator” դասի patterns փոփոխականի մեջ ավելացնել համապատասխան սիմվոլի մատրիցը,  self.char_map փոփոխականում՝ դրան համապատասխանող բանալու արժեքը, ինչպես output ֊ում ավելացնել ելքերի արժեքները՝ համապատասխան սիմվոլին;

Բերված կոդում ունենք 100000 իտերացիա, այդ թիվը ընտրվել է էմպիրիկ եղանակով՝ չնայած կարելի է այն ընտրել ըստ ելքային սխալի տոկոսի փոքրացման։

Նշենք նաև, որ պատկերի վրա կիրառվել են այնպիսի ձևափոխություններ, ինչպիսիք են դրա բացում/փակումը, չափերի փոքրացումը, շեմային ձևափոխությունը, բինարիզացիան և քանի որ դրանք կապ չունեն ցանցերի ալգորիթմների հետ, ապա այդ գործողությունները կատարելու նպատակով օգտագործվել OpenCv֊ն։ Օգտագործվել է նաև numpy գրադարանը, որն ունի մատրիցների հետ աշխատելու շատ հարմար ֆունկցիոնալություն։

Սկզբում նկարում ենք սիմվոլը պատուհանի համապատասխան դաշտում, հետո ծրագիրը վերցնում է այն և շեմային ձևափոխության միջոցով բինարիզացնում է, դրանից հետո փոխում ենք պատկերի չափերը, որն անհրաժեշտ է կատարել այն 5×6 չափի բերելու նպատակով։ Փոքրացնելուց հետո ստանում ենք դրան համապատասխան փիքսել մափը և նայում ենք․ եթե փիքսելի արժեքը փոքր է 255 ֊ից, ապա այդտեղ ունենք հոծ փիքսել և մատրիցում դրա արժեքը դնում ենք 1, հակառակ դեպքում ՝ 0։ Ստացված մատրիցը տալիս ենք train եղած ցանցի predict ֆունկցիային, որն էլ անմիջականորեն ճանաչում է մուտքի սիմվոլը։

 

BrainY2

Ավելի լուրջ պատկերներ ճանաչելու համար օգտագործվում են convolutional neural network֊ներ, որոնց հետ դեռ նոր եմ ծանոթանում և եթե գրված պրոյեկտ լինի դրա արդյունքում՝ կներկայացնեմ։

Նեյրոնային ցանցերի ուսուցումը backpropagation ալգորիթմի միջոցով։ Մաս 4, իրականացում python֊ով։, 10.0 out of 10 based on 3 ratings

Նշագրեր: , ,

Բաժին: Ալգորիթմներ, Ծրագրավորում

Կիսվել , տարածել , պահպանել

VN:F [1.9.20_1166]
Rating: 10.0/10 (3 votes cast)

Մեկնաբանեք

Կհաստատվեն միայն մեսրոպատառ հայերենով գրած մեկնաբանությունները

229