Теоретическое введение#
Многослойный перцептрон#
Для начала очень кратко напомним общий принцип работы нейронной сети (многослойного перцептрона, multilayer perceptron или MLP). Перцептрон выглядит следующим образом:
Размерность входных и выходных данных может быть произвольной и зависит от задачи. Числа из входного слоя \(x_{i}\) умножаются на веса w (разные для разных рёбер) и их сумма подаётся на вход нейрону из 1 скрытого слоя, в котором к этой сумме применяется так называемая функция активация. Далее это продолжается - нейроны 2 скрытого слоя соединены рёбрами с нейронами 1 скрытого слоя с некоторыми весами, снова проводим вышеописанную операцию, и так пока не дойдём до выходного слоя.
Формально, результат от одного слоя к другому преобразуется по формуле
Здесь \(x_{i}\) - значение, соответствующее i-му нейрону на первом слое, \(y_{j}\) - j-му нейрону на втором слое, f - функция активации (вообще говоря, может быть разной для разных нейронов), \(w_{ij}\) - вес, соответствующий ребру, соединяющему i-й нейрон первого слоя и j-й нейрон второго слоя.
Само обучение нейронной сети происходит с помощью обратного распространения ошибки или backpropagation. Если у нас есть тренировочная выборка, то мы можем (произвольно выбрав веса), получить некоторый результат, вычислить погрешность (например, по MSE), а далее подправлять веса после каждого обучающего примера - с помощью стохастического градиентного спуска пытаться найти оптимальные веса, дающие минимум ошибки.
Аккуратно расписав, можно получить формулу вычисляющую градиент весов более раннего слоя через градиенты более позднего слоя, таким образом и получаем обратное распространение ошибки - вычислив ошибку в слое перед выходом, двигаясь по слоям к входу обновляем все веса.
Применение перцептрона для решения дифференциальных уравнений#
Теперь опишем метод, который можно применить для решения задачи Коши и краевой задачи для ОДУ и УРЧП. Для более глубокого понимания можно ознакомиться с оригинальной статьей 1997 года Artificial Neural Networks for Solving Ordinary and Partial Differential Equations.
Зададим дифференциальное уравнение в самой общей форме
Необходимо также задать граничные условия, пока не уточняем, в каком виде (будем делать это для конкретных примеров).
Возьмём пробное решение в виде
Здесь \(N(x ; \theta)\) - выход нейронной сети, \(B(x)\) - функция, удовлетворяющая граничным условиям и не имеющая настраиваемых параметров (она остаётся неизменной по ходу обучения нейронной сети), \(F(x, N(x ; \theta))\) - функция, удовлетворяющая нулевым граничным условиям - таким образом \(\hat{f}\) удовлетворяет граничным условиям.
Возьмём обучающую выборку размера \(M\) - точки \(x_{1}, x_{2}, \ldots, x_{M}\) из интервала, на котором нас интересует решение дифференциального уравнения, и зададим функцию потерь следующим образом:
Нетрудно догадаться, что задать ошибку как обычно в виде \( \frac{1}{M} \sum_{j=1}^{M} (f(x_{j})-\hat{f}(x_{j}))^{2}\) невозможно, ведь мы не знаем сами значения функции \(f\), нам известно только то, что \(f\) удовлетворяет заданному дифференциальному уравнению. Минимизируя функцию потерь \(J(\theta) \rightarrow 0\) мы надеемся получить решение, максимально близкое к истинному.
Следует отметить, что из выражения для функции потерь видно, что линейная функция активации и ReLU не подходят, так как их вторые производные обращаются в ноль, поэтому следует использовать сигмоиду или гиперболический тангенс. Однако, чтобы не ограничивать диапазон выходных данных (область значений сигмоиды и \(tanh\) ограничены), на последнем слое используем обычную линейную функцию.