Нейронные сети: улучшаем bpnn.py


В своей предыдущей статье я дал краткое описание нейронных сетей и привел вариант реализации нейронной сети на python посредством библиотеки bpnn.py. Сегодня мы продолжим работу с этой библиотекой.

Чем мне нравится библиотека bpnn.py, так это ее наглядность (как впрочем и большинство python-кода) и небольшой размер. Но как раз из-за компактности имеется у этого модуля и недостаток: реализованы только минимальный набор операций с нейронными сетями — создание, обучение и выдача выходного сигнала в ответ на входной.

Для того что бы обучить нейронную сеть (если конечно речь идет не об обучении нейронной сети операции XOR) зачастую требуется очень много машинного времени, особенно если обучающее множество велико (или велики размеры нейронной сети). К тому же восстановить нейронную сеть, просто повторив обучение на обучающем множестве, может не получиться, так как в начале обучения весовые коэффициенты принимают случайные значения и обучение изначально пойдет «не в ту сторону». Поэтому библиотеке просто необходима возможность сохранения нейронной сети файл и извлечение ее из файла. Написанием этого функционала я и займусь.

Вначале напишем процедуру сохранения нейронной сети. Что именно сохранять? Параметрами, определяющими нейронную сеть, являются ее размеры и весовые коэффициенты. Что бы определить какие именно переменные нам нужны, взглянем на процедуру инициализации нейронной сети в модуле bpnn.py. Размеры нейронной сети задаются переменными ni, nh и no — количество нейронов во входном, скрытом и выходном слоях. Весовые коэффициенты расположены в матрицах wi (размером ni*nh) и wo (размером nh*no). Напишем процедуру класса NN сохранения этих параметров в файл:

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

Теперь напишем процедуру загрузки нейронной сети из файла: сначала считываем размеры нейронной сети в переменные ni, nh и no, а потом две матрицы размером ni*nh и nh*no.

def load(self, fname):
	# открываем файл для чтения
	f = open(fname, "r")
	# считываем содержимое файла в переменную line, и закрываем файл
	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])

Улучшенную библиотеку bpnn.py можно скачать отсюда.

, ,



  1. #1 by Александр on 12 Май 2011 - 16:07

    Что-то ты перемудрил ;)

    def save(nn, filename):
    ‘сохраняет обученную нейросеть на диск’
    import pickle
    f = open(‘net.net’, ‘wb’)
    pickle.dump(nn, f, 1)
    f.close()

    def load(filename):
    ‘загружает обученную нейросеть с диска’
    import pickle
    f = open(‘net.net’, ‘rb’)
    n = pickle.load(f)
    f.close()
    return n

(никто не узнает)