Пишу нейронную сеть на Python с несколькими скрытыми слоями, и не знаю, как организовать правильное хранение весов
Написал нейросеть по книжке, теперь хочу сделать ее более универсальной, с регулируемым кол-вом скрытых слоев, но не могу правильно организовать хранение весов и сигналов между слоями
import scipy.special
import numpy as np
class neural_Network:
#инициализация
def __init__(self, innodes, hiddenodes, outnodes, learningrate):
#задаем кол-во узлов во входном, скрытых и выходном слоях
self.inodes = innodes
self.hnodes = hiddenodes
self.onodes = outnodes
#Что-то подобное для хранения самих весов
self.hnodes_count = len(self.hnodes)
self.wih = [] * self.hnodes_count
#Создаем матрицы весов
for i in range(self.hnodes_count):
if i == 0:
self.wih[i] = np.random.normal(0.0, pow(self.hnodes[i], -0.5),(self.hnodes[i], self.inodes))
else:
self.wih[i] = np.random.normal(0.0, pow(self.hnodes[i], -0.5),(self.hnodes[i], self.hnodes[i-1]))
self.who = np.random.normal(0.0, pow(self.onodes, -0.5),(self.onodes, self.hnodes[-1]))
#print(self.wih)
#print(self.who)
#кэфф. обучения
self.lr = learningrate
#обучение
def train(self, inputs_list, targets_list):
#преобразуем полученные данные в двумерные массивы
inputs = np.array(inputs_list, ndmin = 2).T
targets = np.array(targets_list, ndmin = 2).T
# так же как-то надо хранить сигналы со всех слоев
hidden_inputs = [] * self.hnodes_count
hidden_outputs = [] * self.hnodes_count
for i in range(self.hnodes_count):
if i == 0:
# рассчитываем входящие сигналы для первого скрытого слоя
hidden_inputs[i] = np.dot(self.wih[i], inputs)
# рассчитываем исходящие сигналы для первого скрытого слоя
hidden_outputs[i] = scipy.special.expit(hidden_inputs[i])
else:
# рассчитываем входящие сигналы для первого скрытого слоя
hidden_inputs[i] = np.dot(self.wih[i], hidden_outputs[i-1])
# рассчитываем исходящие сигналы для первого скрытого слоя
hidden_outputs[i] = scipy.special.expit(hidden_inputs[i])
# рассчитываем входящие сигналы для выходного слоя
final_inputs = np.dot (self.who, hidden_outputs[-1])
# рассчитываем исходящие сигналы для выходного слоя
final_outputs = scipy.special.expit(final_inputs)
#вычисляем ошибку
out_errors = final_outputs - targets
#распределяем ошибки по скрытому слою
hidden_errors = np.dot (self.who.T, out_errors)
#обновляем веса связей между узлами скрытого и выходного слоев
self.who += self.lr * np.dot ((final_outputs * (1 - final_outputs)), np.transpose(hidden_outputs))
#обновляем веса связей между узлами входного и скрытого слоев
self.wih += self.lr * np.dot ((final_inputs * (1 - final_inputs)), np.transpose(hidden_inputs))
pass
#опрос
def query(self, inputs_list):
#создаем двумерный массив входных зачений
inputs = np.array(inputs_list, ndmin = 2).T
hidden_inputs = [] * self.hnodes_count
hidden_outputs = [] * self.hnodes_count
for i in range(self.hnodes_count):
if i == 0:
# рассчитываем входящие сигналы для первого скрытого слоя
hidden_inputs[i] = np.dot(self.wih[i], inputs)
# рассчитываем исходящие сигналы для первого скрытого слоя
hidden_outputs[i] = scipy.special.expit(hidden_inputs[i])
else:
# рассчитываем входящие сигналы для первого скрытого слоя
hidden_inputs[i] = np.dot(self.wih[i], hidden_outputs[i-1])
# рассчитываем исходящие сигналы для первого скрытого слоя
hidden_outputs[i] = scipy.special.expit(hidden_inputs[i])
# рассчитываем входящие сигналы для выходного слоя
final_inputs = np.dot (self.who, hidden_outputs[-1])
# рассчитываем исходящие сигналы для выходного слоя
final_outputs = scipy.special.expit(final_inputs)
return(final_outputs)
pass
input_nodes = 3
hidde_nodes = [4, 5]
out_nodes = 5
learning_rate = 0.2
n = neural_Network(input_nodes, hidde_nodes, out_nodes, learning_rate)
print(n.query([1, 3, 7]))