Концепции обучения нейронной сети

Эта тема является частью рабочего процесса проекта, описанного в Рабочем процессе для Neural Network Design.

В этом разделе описываются два различных стиля обучения. При пошаговом обучении веса и смещения сети обновляются каждый раз, когда вход представляется в сеть. При пакетном обучении веса и смещения обновляются только после представления всех входов. Методы обучения обычно более эффективны в MATLAB® окружение, и они подчеркнуты в программном обеспечении Deep Learning Toolbox™, но есть некоторые приложения, где пошаговое обучение может быть полезно, так что парадигма также реализована.

Инкрементальное обучение с адаптацией

Инкрементальное обучение может применяться как к статическим, так и к динамическим сетям, хотя чаще используется с динамическими сетями, такими как адаптивные фильтры. Этот раздел иллюстрирует, как инкрементальное обучение выполняется как в статических, так и в динамических сетях.

Инкрементальное обучение статических сетей

Снова рассмотрим статическую сеть, используемую для первого примера. Вы хотите обучать его постепенно, чтобы веса и смещения обновлялись после представления каждого входа. В этом случае вы используете функцию adapt, и входы и цели представлены в виде последовательностей.

Предположим, что вы хотите обучить сеть создавать линейную функцию:

t=2p1+p2

Затем для предыдущих входов,

p1=[12],p2=[21],p3=[23],p4=[31]

целями будут

t1=[4],t2=[5],t3=[7],t4=[7]

Для инкрементного обучения вы представляете входы и цели как последовательности:

P = {[1;2] [2;1] [2;3] [3;1]};
T = {4 5 7 7};

Во-первых, настройте сеть с нулевыми начальными весами и смещениями. Кроме того, установите начальный темп обучения на нуле, чтобы показать эффект инкрементного обучения.

net = linearlayer(0,0);
net = configure(net,P,T);
net.IW{1,1} = [0 0];
net.b{1} = 0;

Напоминаем из Simulation with Concurrent Inputs in a Static Network, что для статической сети симуляция сети создает те же выходы, представлены ли входы как матрица параллельных векторов или как массив ячеек из последовательных векторов. Однако это не соответствует действительности при обучении сети. Когда вы используете adapt функция, если входы представлены как массив ячеек из последовательных векторов, то веса обновляются по мере представления каждого входного сигнала (инкрементный режим). Как показано в следующем разделе, если входы представлены как матрица параллельных векторов, то веса обновляются только после представления всех входов (пакетный режим).

Теперь вы готовы обучать сеть пошагово.

[net,a,e,pf] = adapt(net,P,T);

Выходы сети остаются нулевыми, потому что скорость обучения равна нулю, а веса не обновляются. Ошибки равны целям:

a = [0]    [0]    [0]    [0]
e = [4]    [5]    [7]    [7]

Если вы теперь установите скорость обучения равную 0,1, вы можете увидеть, как сеть скорректирована, когда каждый вход представлен:

net.inputWeights{1,1}.learnParam.lr = 0.1;
net.biases{1,1}.learnParam.lr = 0.1;
[net,a,e,pf] = adapt(net,P,T);
a = [0]    [2]    [6]    [5.8]
e = [4]    [3]    [1]    [1.2]

Первый выход такой же, как и с нулевой скоростью обучения, потому что обновление не производится до тех пор, пока не будет представлен первый вход. Второй выход отличается, потому что веса были обновлены. Веса продолжают изменяться при вычислении каждой ошибки. Если сеть способна, и скорость обучения установлена правильно, ошибка в конечном счете доводится до нуля.

Инкрементальное обучение с динамическими сетями

Можно также пошагово обучать динамические сети. На самом деле это была бы самая распространенная ситуация.

Чтобы обучать сеть постепенно, представьте входы и цели как элементы массивов ячеек. Вот начальный вход Pi и входы P и целевые T как элементы массивов ячеек.

Pi = {1};
P = {2 3 4};
T = {3 5 7};

Возьмите линейную сеть с одной задержкой на входе, как используется в предыдущем примере. Инициализируйте веса в нуле и установите скорость обучения равной 0,1.

net = linearlayer([0 1],0.1);
net = configure(net,P,T);
net.IW{1,1} = [0 0];
net.biasConnect = 0;

Вы хотите обучить сеть создавать токовый выход путем суммирования тока и предыдущих входов. Это та же входная последовательность, что и в предыдущем примере, за исключением того, что первый член в последовательности назначается в качестве начального условия задержки. Теперь можно последовательно обучать сеть, используя adapt.

[net,a,e,pf] = adapt(net,P,T,Pi);
a = [0] [2.4] [7.98]
e = [3] [2.6] [-0.98]

Первый выход равен нулю, потому что веса еще не были обновлены. Веса изменяются на каждом последующем временном шаге.

Пакетное обучение

Пакетное обучение, при котором веса и смещения обновляются только после представления всех входных параметров и целей, может применяться как к статическим, так и к динамическим сетям. Оба типа сетей рассматриваются в этом разделе.

Пакетное обучение со статическими сетями

Пакетное обучение может быть выполнено с помощью либо adapt или train, хотя train обычно является лучшей опцией, потому что он обычно имеет доступ к более эффективным алгоритмам настройки. Инкрементальное обучение обычно выполняется с adapt; пакетное обучение обычно выполняется с train.

Для пакетного обучения статической сети с adaptвекторы входа должны быть помещены в одну матрицу параллельных векторов.

P = [1 2 2 3; 2 1 3 1];
T = [4 5 7 7];

Начнем со статической сети, используемой в предыдущих примерах. Значение скорости обучения устанавливается равным 0,01.

net = linearlayer(0,0.01);
net = configure(net,P,T);
net.IW{1,1} = [0 0];
net.b{1} = 0;

Когда вы звоните adapt, оно вызывает trains (функция адаптации по умолчанию для линейной сети) и learnwh (функция обучения по умолчанию для весов и смещений). trains использует обучение Widrow-Hoff.

[net,a,e,pf] = adapt(net,P,T);
a = 0 0 0 0
e = 4 5 7 7

Обратите внимание, что выходы сети все нули, поскольку веса не обновляются до тех пор, пока не будут представлены все наборы обучающих данных. Если вы отображаете веса, вы находите

net.IW{1,1}
  ans = 0.4900 0.4100
net.b{1}
  ans =
    0.2300

Это отличается от результата после одного прохода adapt с инкрементальным обновлением.

Теперь выполните то же пакетное обучение, используя train. Поскольку правило Widrow-Hoff может использоваться в инкрементном или пакетном режиме, его можно вызвать adapt или train. (Существует несколько алгоритмов, которые могут использоваться только в пакетном режиме (например, Levenberg-Marquardt), поэтому эти алгоритмы могут быть вызваны только train.)

В этом случае входные векторы могут быть в матрице параллельных векторов или в массиве ячеек из последовательных векторов. Потому что сеть статическая и потому что train всегда действует в пакетном режиме, train преобразует любой массив ячеек из последовательных векторов в матрицу параллельных векторов. Параллельный режим операции используется по возможности, потому что он имеет более эффективную реализацию в коде MATLAB:

P = [1 2 2 3; 2 1 3 1];
T = [4 5 7 7];

Сеть настраивается таким же образом.

net = linearlayer(0,0.01);
net = configure(net,P,T);
net.IW{1,1} = [0 0];
net.b{1} = 0;

Теперь вы готовы обучать сеть. Обучите его только на одну эпоху, потому что вы использовали только один проход adapt. Функция обучения по умолчанию для линейной сети trainb, и функция обучения по умолчанию для весов и смещений learnwh, поэтому вы должны получить те же результаты, полученные с помощью adapt в предыдущем примере, где функция адаптации по умолчанию была trains.

net.trainParam.epochs = 1;
net = train(net,P,T);

Если вы отображаете веса после одной эпохи обучения, вы находите

net.IW{1,1}
  ans = 0.4900 0.4100
net.b{1}
  ans =
    0.2300

Это тот же результат, что и при обучении пакетному режиму в adapt. Со статическими сетями, adapt функция может реализовать инкрементальное или пакетное обучение, в зависимости от формата входных данных. Если данные представлены как матрица параллельных векторов, происходит пакетное обучение. Если данные представлены как последовательность, происходит инкрементальное обучение. Это не соответствует действительности для train, который всегда выполняет пакетное обучение, независимо от формата входов.

Пакетное обучение с динамическими сетями

Обучение статических сетей относительно простое. Если вы используете train сеть обучается в пакетном режиме и входы преобразуются в параллельные векторы (столбцы матрицы), даже если они первоначально переданы как последовательность (элементы массива ячеек). Если вы используете adapt, формат входа определяет метод обучения. Если входы переданы как последовательность, то сеть обучается в инкрементном режиме. Если входы переданы как параллельные векторы, то используется обучение пакетному режиму.

С динамическими сетями обучение в пакетном режиме обычно выполняется с train только, особенно если существует только одна обучающая последовательность. Чтобы проиллюстрировать это, снова рассмотрим линейную сеть с задержкой. Используйте скорость обучения 0,02 для обучения. (При использовании алгоритма градиентного спуска вы обычно используете меньшую скорость обучения для обучения в пакетном режиме, чем инкрементальное обучение, потому что все отдельные градиенты суммируются перед определением изменения шага на веса.)

net = linearlayer([0 1],0.02);
net.inputs{1}.size = 1;
net.layers{1}.dimensions = 1;
net.IW{1,1} = [0 0];
net.biasConnect = 0;
net.trainParam.epochs = 1;
Pi = {1};
P = {2 3 4};
T = {3 5 6};

Необходимо обучить сеть с той же последовательностью, которая используется для инкрементного обучения ранее, но на этот раз необходимо обновить веса только после применения всех входов (пакетный режим). Сеть моделируется в последовательном режиме, потому что вход является последовательностью, но веса обновляются в пакетном режиме.

net = train(net,P,T,Pi);

Веса после одной эпохи обучения

net.IW{1,1}
ans = 0.9000    0.6200

Это различные веса, чем вы получили бы с помощью инкрементного обучения, где веса были бы обновлены три раза в течение одного прохода через набор обучающих данных. Для пакетного обучения веса обновляются только один раз в каждую эпоху.

Обратная связь по обучению

The showWindow параметр позволяет вам задать, отображается ли окно обучения при обучении. Окно обучения появляется по умолчанию. Два других параметров, showCommandLine и show, определите, генерируется ли выход командной строки и количество эпох между обратной связью командной строки во время обучения. Например, этот код отключает окно обучения и предоставляет вам информацию о состоянии обучения каждые 35 эпох, когда сеть позже обучена с train:

net.trainParam.showWindow = false;
net.trainParam.showCommandLine = true;
net.trainParam.show= 35;

Иногда удобно отключать все обучающие отображения. Для этого отключите и окно обучения, и обратную связь в командной строке:

net.trainParam.showWindow = false;
net.trainParam.showCommandLine = false;

Окно обучения появляется автоматически при обучении. Используйте nntraintool функция для ручного открытия и закрытия окна обучения.

nntraintool
nntraintool('close')