Я успешно написал несколько нейронных сетей в прошлом. Я написал многослойный персептрон с полностью связанными слоями (любых размеров и количества) и обучил его backprop. Я сделал сверточную сеть и нашел ее градиенты с ручной/рассчитанной математикой. Сейчас я пытаюсь быть более общим. Я хочу написать обратное распространение для любого вычислительного графа в духе Theano.C++ Обратное распространение на графике; гетерогенные векторы?
Рассмотрим этот Python код:
from __future__ import division
from pylab import *
class Node(object):
def __init__(self):
self.children = []
self.parents = []
self.state = []
def forward_prop(self):
for child in self.children:
child.forward_prop()
class Static(Node):
def __init__(self, *shape):
super(Static, self).__init__()
state = zeros(shape)
class MatrixProduct(Node):
def __init__(self, w, x):
super(MatrixProduct, self).__init__()
self.w = w
self.x = x
self.state = [0]*len(x.state)
def forward_prop(self):
self.state = self.w.state.dot(self.x.state)
for child in self.children:
child.forward_prop()
class Doubler(Node):
def __init__(self):
super(Doubler, self).__init__()
def forward_prop(self):
self.state = [s*2 for s in self.state]
for child in self.children:
child.forward_prop()
a = Static()
a.state = array([2,3])
w = Static()
w.state = array([[1,2],[3,4]])
x = MatrixProduct(w, a)
a.children.append(x)
d = Doubler()
d.state.append(3)
x.children.append(d)
a.forward_prop()
print a.state
print d.state
я вижу, в основном, как порт, на C++. Моя проблема заключается в том, что я не могу понять, как обеспечить прямое распространение детей на C++. В Python это легко, потому что дети - это список потенциально гетерогенных типов, каждый из которых имеет собственное поведение forward_propagate. В C++, что мне делать?
Я чувствую, что ответ является наследованием, но если все они являются базовым классом, то он вызывает базовый класс вперед, а не дочерний.
Я стараюсь избегать избыточности. Узлы знают, какую операцию нужно сделать, чтобы превратить свои входы в выходы. Но они могут принимать входные данные разных типов, если они имеют одинаковую форму. IE, элемент ElementwiseVectorDoubler может принимать как входные данные и выводить на любой узел узел, который обрабатывает векторы. Может получить вход от матрицы умножить и т. Д. Но я не хочу иметь отдельные классы ElementwiseVectorDoubler для каждого конкретного типа ввода входного вектора 1d.
* «Если все они являются базовым классом, то он вызывает базовый класс вперед, а не дочерний». * - Вы слышали о виртуальных функциях? – UnholySheep
Да, но едва. Я расскажу об этом и попробую применить его. Благодаря! –
Для защиты от вопросов X/Y: вы делаете это как личное упражнение? Существует несколько хороших инфраструктур NN, которые могут значительно ускорить ваше время разработки - если сама модель является вашей фактической целью, а не образованием. – Prune