Обучение XOR с глубокой нейронной сетью - PullRequest
0 голосов
/ 26 июня 2019

Я новичок в углубленном изучении, поэтому начну с самого простого теста: XOR learning.

В новой редакции G & W «Цифровая обработка изображений» авторы приводят пример обучения XOR с помощью глубокой сети с 3 слоями: входной, скрытый и выходной (каждый слой имеет 2 нейрона.) И сигмоидой в качестве функция активации сети.

Для инициализации сети они говорят: «Мы использовали альфа = 1,0, начальный набор гауссовских случайных весов с нулевым средним и стандартное отклонение 0,02 » (альфа - скорость обучения градиентного спуска). Обучение было проведено с 4 помеченными примерами:

X = [1 -1 -1 1;1 -1 1 -1];%MATLAB syntax
R = [1 1 0 0;0 0 1 1];%Labels

Я написал следующий код MATLAB для реализации процесса сетевого обучения:

function output = neuralNet4e(input,specs)


NumPat = size(input.X,2);%Number of patterns
NumLayers = length(specs.W);
for kEpoch = 1:specs.NumEpochs

    % forward pass

    A = cell(NumLayers,1);%Output of each neuron in each layer
    derZ = cell(NumLayers,1);%Activation function derivative on each neuron dot product 
    A{1} = input.X;

    for kLayer = 2:NumLayers

       B = repmat(specs.b{kLayer},1,NumPat);
       Z = specs.W{kLayer} * A{kLayer - 1} + B;
       derZ{kLayer} = specs.activationFuncDerive(Z);
       A{kLayer} = specs.activationFunc(Z);

    end

    % backprop

    D =  cell(NumLayers,1);
    D{NumLayers} = (A{NumLayers} - input.R).* derZ{NumLayers};
    for kLayer = (NumLayers-1):-1:2

        D{kLayer} = (specs.W{kLayer + 1}' * D{kLayer + 1}).*derZ{kLayer};

    end

    %Update weights and biases

    for kLayer = 2:NumLayers

        specs.W{kLayer} = specs.W{kLayer} - specs.alpha * D{kLayer} * A{kLayer - 1}' ;
        specs.b{kLayer} = specs.b{kLayer} - specs.alpha * sum(D{kLayer},2);

    end

end

output.A = A;

end

Теперь, когда я использую их настройку (т. Е. Инициализация весов со стандартным значением = 0,02)

clearvars
s = 0.02;
input.X = [1 -1 -1 1;1 -1 1 -1];
input.R = [1 1 0 0;0 0 1 1];
specs.W = {[];s * randn(2,2);s * randn(2,2)};
specs.b = {[];s * randn(2,1);s * randn(2,1)};
specs.activationFunc = @(x) 1./(1 + exp(-x));
specs.activationFuncDerive = @(x) exp(-x)./(1 + exp(-x)).^2;
specs.NumEpochs = 1e4;
specs.alpha = 1;
output = neuralNet4e(input,specs);

Я получаю (после 10000 эпох), что окончательный результат в сети output.A{3} = [0.5 0.5 0.5 0.5;0.5 0.5 0.5 0.5]

но когда я изменил s = 0.02; на s = 1;, я получил output.A{3} = [0.989 0.987 0.010 0.010;0.010 0.012 0.0.98 0.98] как положено.

Можно ли получить эти результаты при `s = 0,02; ' и я делаю что-то не так в моем коде? или стандартное отклонение 0,02 это просто опечатка?

1 Ответ

1 голос
/ 27 июня 2019

Судя по вашему коду, я не вижу ошибок. Насколько мне известно, результат, который вы получили,

[0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5]

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

В вашем примере s = 0,02 ограничивает значения рандомизированных весов и смещений. Изменение этого значения на s = 1 делает рандомизированные значения неизменными / немасштабированными.

Чтобы заставить s = 0,02 работать, вы можете попытаться свести к минимуму количество эпох или, возможно, понизить альфа.

Надеюсь, это поможет.

...