В этом примере показано, как обучить нейронную сеть с информацией о физике (PINN) численному вычислению решения уравнения Бургера с использованием алгоритма BFGS (LBFGS) с ограниченной памятью.
Уравнение Бургера - дифференциальное уравнение в частных производных (PDE), возникающее в различных областях прикладной математики. В частности, механика жидкости, нелинейная акустика, газодинамика и транспортные потоки.
Учитывая вычислительную область 0,1], этот пример использует нейронную сеть, информированную о физике (PINN) [1], и обучает многослойную перцептронную нейронную сеть, которая принимает , t) в качестве входных данных, -1,1] - пространственная переменная, t∈[0,1] - временная переменная, и (x, t), где u - решение B
с sin (øx) в качестве начального x = -и u (x = 1, t) = 0 в качестве граничных условий.
Вместо обучения сети с использованием trainNetwork функцию или использование пользовательского цикла обучения, который обновляет параметры с помощью sgdmupdate или подобные функции, этот пример оценивает обучаемые параметры с помощью fmincon (требуется Toolbox™ оптимизации). fmincon функция находит минимум ограниченных нелинейных многомерных функций.
Пример обучает модель, применяя то, что при вводе ) выходной сигнал сети t) удовлетворяет уравнению Бургера, граничным условиям и начальному условию. Для обучения модели exmaple использует алгоритм с ограниченной памятью BFGS (LBFGS), который является методом квази-Ньютона, который аппроксимирует алгоритм Бройдена-Флетчера-Гольдфарба-Шанно.
Обучение этой модели не требует предварительного сбора данных. Данные можно генерировать с помощью определения PDE и ограничений.
Обучение модели требует набора данных точек коллокации, которые обеспечивают граничные условия, обеспечивают исходные условия и выполняют уравнение Бургера.
Выберите 25 равноудаленных точек времени для выполнения каждого граничного условия t) = = 1, t) = 0.
numBoundaryConditionPoints = [25 25]; x0BC1 = -1*ones(1,numBoundaryConditionPoints(1)); x0BC2 = ones(1,numBoundaryConditionPoints(2)); t0BC1 = linspace(0,1,numBoundaryConditionPoints(1)); t0BC2 = linspace(0,1,numBoundaryConditionPoints(2)); u0BC1 = zeros(1,numBoundaryConditionPoints(1)); u0BC2 = zeros(1,numBoundaryConditionPoints(2));
Выберите 50 равноотстоящих пространственных точек для выполнения начального условия sin (øx).
numInitialConditionPoints = 50; x0IC = linspace(-1,1,numInitialConditionPoints); t0IC = zeros(1,numInitialConditionPoints); u0IC = -sin(pi*x0IC);
Сгруппируйте данные для начальных и граничных условий.
X0 = [x0IC x0BC1 x0BC2]; T0 = [t0IC t0BC1 t0BC2]; U0 = [u0IC u0BC1 u0BC2];
Выберите 10000 точек, чтобы принудительно использовать выходные данные сети для выполнения уравнения Бургера.
numInternalCollocationPoints = 10000; pointSet = sobolset(2); points = net(pointSet,numInternalCollocationPoints); dataX = 2*points(:,1)-1; dataT = points(:,2);
Создайте хранилище данных массива, содержащее данные обучения.
ds = arrayDatastore([dataX dataT]);
Определите многослойную перцептронную архитектуру с 9 полностью связанными операциями с 20 скрытыми нейронами. Первая операция полного соединения имеет два входных канала, соответствующих входам и t. Последняя операция полного соединения имеет один выход t).
Определите параметры для каждой операции и включите их в структуру. Использовать формат parameters.OperationName_ParameterName где parameters - структура, OperationName - имя операции (например, «fc1») и ParameterName - имя параметра (например, «Веса»).
Алгоритм в этом примере требует, чтобы обучаемые параметры находились на первом уровне структуры, поэтому не используйте вложенные структуры на этом этапе. fmincon функция требует, чтобы обучаемый был двойным.
Укажите количество слоев и количество нейронов для каждого слоя.
numLayers = 9; numNeurons = 20;
Инициализируйте параметры для первой операции полного подключения. Первая операция полного подключения имеет два входных канала.
parameters = struct; sz = [numNeurons 2]; parameters.fc1_Weights = initializeHe(sz,2,'double'); parameters.fc1_Bias = initializeZeros([numNeurons 1],'double');
Инициализируйте параметры для каждой из оставшихся промежуточных операций полного подключения.
for layerNumber=2:numLayers-1 name = "fc"+layerNumber; sz = [numNeurons numNeurons]; numIn = numNeurons; parameters.(name + "_Weights") = initializeHe(sz,numIn,'double'); parameters.(name + "_Bias") = initializeZeros([numNeurons 1],'double'); end
Инициализируйте параметры для конечной операции полного подключения. Конечная операция полного подключения имеет один выходной канал.
sz = [1 numNeurons]; numIn = numNeurons; parameters.("fc" + numLayers + "_Weights") = initializeHe(sz,numIn,'double'); parameters.("fc" + numLayers + "_Bias") = initializeZeros([1 1],'double');
Просмотрите параметры сети.
parameters
parameters = struct with fields:
fc1_Weights: [20×2 dlarray]
fc1_Bias: [20×1 dlarray]
fc2_Weights: [20×20 dlarray]
fc2_Bias: [20×1 dlarray]
fc3_Weights: [20×20 dlarray]
fc3_Bias: [20×1 dlarray]
fc4_Weights: [20×20 dlarray]
fc4_Bias: [20×1 dlarray]
fc5_Weights: [20×20 dlarray]
fc5_Bias: [20×1 dlarray]
fc6_Weights: [20×20 dlarray]
fc6_Bias: [20×1 dlarray]
fc7_Weights: [20×20 dlarray]
fc7_Bias: [20×1 dlarray]
fc8_Weights: [20×20 dlarray]
fc8_Bias: [20×1 dlarray]
fc9_Weights: [1×20 dlarray]
fc9_Bias: [1×1 dlarray]
Создание функции model, перечисленных в разделе «Функция модели» в конце примера, который вычисляет выходные данные модели глубокого обучения. Функция model принимает в качестве входных данных параметры модели и сетевые входные данные и возвращает выходные данные модели.
Создание функции modelGradients, перечисленных в разделе «Функция градиентов модели» в конце примера, который принимает в качестве входных данных параметры модели, входные данные сети и начальные и граничные условия, и возвращает градиенты потерь по отношению к обучаемым параметрам и соответствующим потерям.
fmincon Целевая функцияСоздание функции objectiveFunction, перечисленные в fmincon Целевая функция (Objective Function) в разделе примера, возвращающем потери и градиенты модели. Функция objectiveFunction принимает в качестве входных, вектор обучаемых параметров, сетевые входы, начальные условия, имена и размеры обучаемых параметров и возвращает потери, которые должны быть минимизированы fmincon функция и градиенты потерь относительно обучаемых параметров.
Укажите параметры оптимизации:
Оптимизация с помощью fmincon optmizer с алгоритмом LBFGS не более 7500 итераций и оценок функций.
Оценка с учетом допуска оптимальности 1e-5.
Предоставьте градиенты алгоритму.
options = optimoptions('fmincon', ... 'HessianApproximation','lbfgs', ... 'MaxIterations',7500, ... 'MaxFunctionEvaluations',7500, ... 'OptimalityTolerance',1e-5, ... 'SpecifyObjectiveGradient',true);
fminconОбучение сети с помощью fmincon функция.
fmincon функция требует указания обучаемых параметров в качестве вектора. Преобразование параметров в вектор с помощью paramsStructToVector (присоединена к этому примеру как вспомогательный файл). Для обратного преобразования в структуру параметров также верните имена и размеры параметров.
[parametersV,parameterNames,parameterSizes] = parameterStructToVector(parameters); parametersV = extractdata(parametersV);
Преобразование данных обучения в dlarray объекты с форматом 'CB' (канал, партия).
dlX = dlarray(dataX','CB'); dlT = dlarray(dataT','CB'); dlX0 = dlarray(X0,'CB'); dlT0 = dlarray(T0,'CB'); dlU0 = dlarray(U0,'CB');
Создайте дескриптор функции с одним входом, определяющим целевую функцию.
objFun = @(parameters) objectiveFunction(parameters,dlX,dlT,dlX0,dlT0,dlU0,parameterNames,parameterSizes);
Обновление обучаемых параметров с помощью fmincon функция. В зависимости от количества итераций выполнение может занять некоторое время. Чтобы включить подробный подробный вывод, установите 'Display' параметр оптимизации для 'iter-detailed'.
parametersV = fmincon(objFun,parametersV,[],[],[],[],[],[],[],options);
Solver stopped prematurely. fmincon stopped because it exceeded the function evaluation limit, options.MaxFunctionEvaluations = 7.500000e+03.
Для прогнозирования преобразуйте вектор параметров в структуру с помощью parameterVectorToStruct (присоединена к этому примеру как вспомогательный файл).
parameters = parameterVectorToStruct(parametersV,parameterNames,parameterSizes);
Для значений при 0,25, 0,5, 0,75 и 1 сравните предсказанные значения модели глубокого обучения с истинными решениями уравнения Бургера, используя относительную ошибку l2.
Задайте целевое время для тестирования модели в. Для каждого случая вычислите решение в 1001 равноотстоящих точках в диапазоне [-1,1].
tTest = [0.25 0.5 0.75 1]; numPredictions = 1001; XTest = linspace(-1,1,numPredictions);
Протестируйте модель.
figure for i=1:numel(tTest) t = tTest(i); TTest = t*ones(1,numPredictions); % Make predictions. dlXTest = dlarray(XTest,'CB'); dlTTest = dlarray(TTest,'CB'); dlUPred = model(parameters,dlXTest,dlTTest); % Calcualte true values. UTest = solveBurgers(XTest,t,0.01/pi); % Calculate error. err = norm(extractdata(dlUPred) - UTest) / norm(UTest); % Plot predictions. subplot(2,2,i) plot(XTest,extractdata(dlUPred),'-','LineWidth',2); ylim([-1.1, 1.1]) % Plot true values. hold on plot(XTest, UTest, '--','LineWidth',2) hold off title("t = " + t + ", Error = " + gather(err)); end subplot(2,2,2) legend('Predicted','True')

Графики показывают, насколько близки прогнозы к истинным значениям.
solveBurgers функция возвращает истинное решение уравнения Бургера в моменты времени t как указано в [2].
function U = solveBurgers(X,t,nu) % Define functions. f = @(y) exp(-cos(pi*y)/(2*pi*nu)); g = @(y) exp(-(y.^2)/(4*nu*t)); % Initialize solutions. U = zeros(size(X)); % Loop over x values. for i = 1:numel(X) x = X(i); % Calculate the solutions using the integral function. The boundary % conditions in x = -1 and x = 1 are known, so leave 0 as they are % given by initialization of U. if abs(x) ~= 1 fun = @(eta) sin(pi*(x-eta)) .* f(x-eta) .* g(eta); uxt = -integral(fun,-inf,inf); fun = @(eta) f(x-eta) .* g(eta); U(i) = uxt / integral(fun,-inf,inf); end end end
fmincon Целевая функция objectiveFunction функция определяет целевую функцию, используемую алгоритмом LBFGS.
Это objectiveFunction функция принимает в качестве входных данных вектор обучаемых параметров parametersV, сетевые входы, dlX и dlT, начальные и граничные условия dlX0, dlT0, и dlU0и имена и размеры обучаемых параметров parameterNames и parameterSizes, соответственно, и возвращает потери, которые должны быть минимизированы fmincon функция loss и вектор, содержащий градиенты потерь относительно обучаемых параметров gradientsV.
function [loss,gradientsV] = objectiveFunction(parametersV,dlX,dlT,dlX0,dlT0,dlU0,parameterNames,parameterSizes) % Convert parameters to structure of dlarray objects. parametersV = dlarray(parametersV); parameters = parameterVectorToStruct(parametersV,parameterNames,parameterSizes); % Evaluate model gradients and loss. [gradients,loss] = dlfeval(@modelGradients,parameters,dlX,dlT,dlX0,dlT0,dlU0); % Return loss and gradients for fmincon. gradientsV = parameterStructToVector(gradients); gradientsV = extractdata(gradientsV); loss = extractdata(loss); end
Модель обучают, вводя на вход ), что выход сети t) удовлетворяет уравнению Бургера, граничным условиям и начальному условию. В частности, потери, подлежащие минимизации, зависят от двух величин:
MSEu,
где | 2 ) -ui | 2.
Здесь 1Nu соответствуют точкам коллокации на границе вычислительной области и учитывают как границу, так и начальное i = 1Nf - точки во внутренней части области.
Вычисление требует производных выходных данных модели.
Функция modelGradients принимает в качестве входных, параметры модели parameters, сетевые входы dlX и dlT, начальные и граничные условия dlX0, dlT0, и dlU0и возвращает градиенты потерь относительно обучаемых параметров и соответствующих потерь.
function [gradients,loss] = modelGradients(parameters,dlX,dlT,dlX0,dlT0,dlU0) % Make predictions with the initial conditions. U = model(parameters,dlX,dlT); % Calculate derivatives with respect to X and T. gradientsU = dlgradient(sum(U,'all'),{dlX,dlT},'EnableHigherDerivatives',true); Ux = gradientsU{1}; Ut = gradientsU{2}; % Calculate second-order derivatives with respect to X. Uxx = dlgradient(sum(Ux,'all'),dlX,'EnableHigherDerivatives',true); % Calculate lossF. Enforce Burger's equation. f = Ut + U.*Ux - (0.01./pi).*Uxx; zeroTarget = zeros(size(f), 'like', f); lossF = mse(f, zeroTarget); % Calculate lossU. Enforce initial and boundary conditions. dlU0Pred = model(parameters,dlX0,dlT0); lossU = mse(dlU0Pred, dlU0); % Combine losses. loss = lossF + lossU; % Calculate gradients with respect to the learnable parameters. gradients = dlgradient(loss,parameters); end
Модель, обученная в этом примере, состоит из серии операций полного соединения с операцией tanh между каждой.
Функция модели принимает в качестве входных параметры модели parameters и сетевые входы dlX и dlTи возвращает выходные данные модели dlU.
function dlU = model(parameters,dlX,dlT) dlXT = [dlX;dlT]; numLayers = numel(fieldnames(parameters))/2; % First fully connect operation. weights = parameters.fc1_Weights; bias = parameters.fc1_Bias; dlU = fullyconnect(dlXT,weights,bias); % tanh and fully connect operations for remaining layers. for i=2:numLayers name = "fc" + i; dlU = tanh(dlU); weights = parameters.(name + "_Weights"); bias = parameters.(name + "_Bias"); dlU = fullyconnect(dlU, weights, bias); end end
Мазиар Райсси, Париж Пердикарис, и Джордж Эм Карниадакис, физика информированного глубокого обучения (часть I): управляемые данными решения нелинейных дифференциальных уравнений в частных производных https://arxiv.org/abs/1711.10561
C. Basdevant, M. Deville, P. Haldenwang, J. Lacroix, J. Ouazzani, R. Peiret, P. Orlandi, A. Patera, Спектральные и конечные дифференциальные решения уравнения Бургерса, Computers & Fluids 14 (1986) 23-41.
dlarray | dlfeval | dlgradient