Форум сайта python.su
Объясните как обучить сеть, в каком формате скармливать информацию
Допустим я хочу научить распознавать символ на изображении, в каком формате мне изображение на вход сети дать и как на выходе ей результат правильный представить
pat = [ [[0,0], [0]], [[0,1], [1]], [[1,0], [1]], [[1,1], [0]] ]
import math import random import string random.seed(0) # calculate a random number where: a <= rand < b def rand(a, b): return (b-a)*random.random() + a # Make a matrix (we could use NumPy to speed this up) def makeMatrix(I, J, fill=0.0): m = [] for i in range(I): m.append([fill]*J) return m # our sigmoid function, tanh is a little nicer than the standard 1/(1+e^-x) def sigmoid(x): return math.tanh(x) # derivative of our sigmoid function, in terms of the output (i.e. y) def dsigmoid(y): return 1.0 - y**2 class NN: def __init__(self, ni, nh, no): # number of input, hidden, and output nodes self.ni = ni + 1 # +1 for bias node self.nh = nh self.no = no # activations for nodes self.ai = [1.0]*self.ni self.ah = [1.0]*self.nh self.ao = [1.0]*self.no # create weights self.wi = makeMatrix(self.ni, self.nh) self.wo = makeMatrix(self.nh, self.no) # set them to random vaules for i in range(self.ni): for j in range(self.nh): self.wi[i][j] = rand(-0.2, 0.2) for j in range(self.nh): for k in range(self.no): self.wo[j][k] = rand(-2.0, 2.0) # last change in weights for momentum self.ci = makeMatrix(self.ni, self.nh) self.co = makeMatrix(self.nh, self.no) def save(self, fname): f = open(fname, "w") f.write(str(self.ni)+";") f.write(str(self.nh)+";") f.write(str(self.no)+";") for i in xrange(self.ni): for j in xrange(self.nh): f.write(str(self.wi[i][j])+";") for i in xrange(self.nh): for j in xrange(self.no): f.write(str(self.wo[i][j])+";") f.close() def load(self, fname): f = open(fname, "r") line = f.read() f.close() arr = string.split(line, ";") self.ni, self.nh, self.no = int(arr[0]), int(arr[1]), int(arr[2]) self.wi = makeMatrix(self.ni, self.nh) self.wo = makeMatrix(self.nh, self.no) n = 2 for i in xrange(self.ni): for j in xrange(self.nh): n += 1 self.wi[i][j] = float(arr[n]) for i in xrange(self.nh): for j in xrange(self.no): n += 1 self.wo[i][j] = float(arr[n]) def update(self, inputs): if len(inputs) != self.ni-1: raise ValueError('wrong number of inputs') # input activations for i in range(self.ni-1): #self.ai[i] = sigmoid(inputs[i]) self.ai[i] = inputs[i] # hidden activations for j in range(self.nh): sum = 0.0 for i in range(self.ni): sum = sum + self.ai[i] * self.wi[i][j] self.ah[j] = sigmoid(sum) # output activations for k in range(self.no): sum = 0.0 for j in range(self.nh): sum = sum + self.ah[j] * self.wo[j][k] self.ao[k] = sigmoid(sum) return self.ao[:] def backPropagate(self, targets, N, M): if len(targets) != self.no: raise ValueError('wrong number of target values') # calculate error terms for output output_deltas = [0.0] * self.no for k in range(self.no): error = targets[k]-self.ao[k] output_deltas[k] = dsigmoid(self.ao[k]) * error # calculate error terms for hidden hidden_deltas = [0.0] * self.nh for j in range(self.nh): error = 0.0 for k in range(self.no): error = error + output_deltas[k]*self.wo[j][k] hidden_deltas[j] = dsigmoid(self.ah[j]) * error # update output weights for j in range(self.nh): for k in range(self.no): change = output_deltas[k]*self.ah[j] self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k] self.co[j][k] = change #print N*change, M*self.co[j][k] # update input weights for i in range(self.ni): for j in range(self.nh): change = hidden_deltas[j]*self.ai[i] self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j] self.ci[i][j] = change # calculate error error = 0.0 for k in range(len(targets)): error = error + 0.5*(targets[k]-self.ao[k])**2 return error def test(self, patterns): for p in patterns: print(p[0], '->', self.update(p[0])) def weights(self): print('Input weights:') for i in range(self.ni): print(self.wi[i]) print() print('Output weights:') for j in range(self.nh): print(self.wo[j]) def train(self, patterns, iterations=1000, N=0.5, M=0.1): # N: learning rate # M: momentum factor for i in range(iterations): error = 0.0 for p in patterns: inputs = p[0] targets = p[1] self.update(inputs) error = error + self.backPropagate(targets, N, M) if i % 100 == 0: print('error %-.5f' % error) def demo(): # Teach network XOR function pat = [ [[0,0], [0]], [[0,1], [1]], [[1,0], [1]], [[1,1], [0]] ] # create a network with two input, two hidden, and one output nodes n = NN(2, 2, 1) # train it with some patterns n.train(pat) # test it n.test(pat) n.save("z.txt") n.load("z.txt") n.test(pat) if __name__ == '__main__': demo()
Отредактировано sanodin (Авг. 20, 2013 07:20:28)
Офлайн
Подаю изображение 20x20 , черно-белое, цифры пока, процесс пошел
изображения сложил по отдельным директориям, чем больше изображений, тем лучше распознает сеть
from pybrain.tools.shortcuts import buildNetwork from pybrain.structure import TanhLayer from pybrain.datasets import SupervisedDataSet from PIL import Image import os from pybrain.supervised.trainers import BackpropTrainer import pickle ################################################## ds = SupervisedDataSet(400, 1) iconset = ['0','1','2','3','4','5','6','7','8','9'] imageset = [] #перебираем в папке изображения и преобразуем в массив пикселей #сам массив подаем в формате (1-0), 1-пиксели черного цвета, 0- белого #создаем сеть ds.addSample(sl,letter) for letter in iconset: for img in os.listdir('./iconset/%s/'%(letter)): temp = [] if img != "Thumbs.db": # windows check... im=(Image.open("./iconset/%s/%s"%(letter,img))) im = im.convert("P") im2 = Image.new("P",im.size,255) im = im.convert("P") temp = {} for x in range(im.size[1]): for y in range(im.size[0]): pix = im.getpixel((y,x)) temp[pix] = pix if pix == 0: # these are the numbers to get im2.putpixel((y,x),0) sl=[] for i in im2.getdata(): #print i if i==0: i=1 else: i=0 sl.append(i) ds.addSample(sl,letter) net = buildNetwork(400, 133, 1, bias=True, hiddenclass=TanhLayer) trainer = BackpropTrainer(net, ds) #print trainer.trainUntilConvergence() #тренеруем-обучаем trainer = BackpropTrainer(net, ds) for epoch in range(0, 10000): error = trainer.train() if error < 0.00006: break #преобразуем тестовое изображение def imag(): im = Image.open("2-2.png") im = im.convert("P") im2 = Image.new("P",im.size,255) im = im.convert("P") temp = {} for x in range(im.size[1]): for y in range(im.size[0]): pix = im.getpixel((y,x)) temp[pix] = pix if pix == 0: # these are the numbers to get im2.putpixel((y,x),0) sl=[] for i in im2.getdata(): #print i if i==0: i=1 else: i=0 sl.append(i) return sl #сохраняем обученную сеть fileObject = open('filename', 'w') pickle.dump(net, fileObject) fileObject.close() fileObject = open('filename','r') net = pickle.load(fileObject) #подаем на распознование массив пикселей, тестового изображения test= imag() print net.activate(test) ####################################################
Отредактировано sanodin (Авг. 23, 2013 06:15:36)
Офлайн
sanodin выложи папку с изображениями.
На хабре была подобная статья http://habrahabr.ru/post/143129/
Офлайн
Я пока еще не обучал сеть , все хочу на работе компьютер озадачить, на домашнем неохота гонять, говорят и по десять часов обучение проходит, завтра на работе с утра запущу…
а изображения сам рисовал в паинте, коряво, потом плюнул написал генератор, все вместе и по папкам разложил, не знаю скажется на результатах или нет…приложу архив, если что корявые удалите цифры
На хабре полно статей…с библиотекой FANN хотел поработать, но она под винду у меня не пошла…напильник мож и есть ,да руки не оттуда…
Отредактировано sanodin (Авг. 27, 2013 20:48:19)
Прикреплённый файлы:
iconset.zip (337,3 KБ)
Офлайн