Обучите сеть Используя функцию модели

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

Importdata

digitTrain4DArrayData функционируйте загружает изображения, их классификации и их углы от вертикали. Загрузите данные и найдите категории классификации рукописных цифр.

[XTrain,YTrain,ThetaTrain] = digitTrain4DArrayData;
cats = categories(YTrain);
numClasses = numel(cats);
n = length(ThetaTrain);
disp(cats)
    '0'
    '1'
    '2'
    '3'
    '4'
    '5'
    '6'
    '7'
    '8'
    '9'

Просмотрите подмножество изображений.

idx = randperm(numel(YTrain),64);
I = imtile(XTrain(:,:,:,idx));
figure
imshow(I)

Просмотрите углы того же подмножества изображений.

disp(reshape(ThetaTrain(idx),8,8)')
     9   -18    21     5    -5    21   -31    13
   -24   -11   -17    12    -6    -6    39   -38
    -8   -15   -14   -42   -28   -44   -23     7
    -2    21    11   -38     3   -18    30    44
   -34    40    33   -20    12   -36    43   -39
   -30   -30   -30    27    38   -15    25     9
    14    45    43   -17    36   -11    39    10
   -29    -6   -41   -23    43   -33     2   -29

Создайте функцию модели и параметры

Функция модели является ответом сети к данным. Самый легкий способ создать функцию модели состоит в том, чтобы использовать встроенные функции тулбокса. model функция помощника передает данные через три набора пакетных сверткой шагов нормы-ReLU, выполненных полностью связанными шагами с 10 категориями для классификации цифр и одной категорией для угла цифры. Функция имеет два выходных параметров: вектор вероятностей для классификации и предсказанного угла.

Код для model функция помощника в конце этого примера.

model функционируйте использует структуру параметров, где параметры являются весами нейронной сети для глубокого обучения. Чтобы инициализировать модель для обучения, необходимо дать значения для параметров. Рекомендуемый подход должен установить многие начальные параметры к ненулевым значениям. Для тех параметров используйте Распределение Гаусса с одинарной точностью со средним значением 0 и стандартным отклонением 0.01 путем вызова initializeGaussian функция помощника, которая появляется в конце этого примера.

Чтобы включить автоматическое дифференцирование, создайте структуру параметра как dlarray записи.

parameters.W1 = dlarray(initializeGaussian([5,5,1,16]));
parameters.b1 = dlarray(zeros(16,1,'single'));

parameters.Offset1 = dlarray(zeros(16,1,'single'));
parameters.Scale1 = dlarray(ones(16,1,'single'));

parameters.Ws = dlarray(initializeGaussian([1,1,16,32]));
parameters.bs = dlarray(zeros(32,1,'single'));

parameters.W2 = dlarray(initializeGaussian([3,3,16,32]));
parameters.b2 = dlarray(zeros(32,1,'single'));

parameters.Offset2 = dlarray(zeros(32,1,'single'));
parameters.Scale2 = dlarray(ones(32,1,'single'));

parameters.W3 = dlarray(initializeGaussian([3,3,32,32]));
parameters.b3 = dlarray(zeros(32,1,'single'));

parameters.Offset3 = dlarray(zeros(32,1,'single'));
parameters.Scale3 = dlarray(ones(32,1,'single'));

parameters.W4 = dlarray(initializeGaussian([10,1568]));
parameters.b4 = dlarray(zeros(numClasses,1,'single'));

parameters.R1 = dlarray(initializeGaussian([1,1568]));
parameters.B5 = dlarray(zeros(1,1,'single'));

Цель и расчет градиента

Чтобы создать целевую функцию, необходимо объединить функциональные выходные параметры модели в скалярное значение. modelGradients функция помощника вычисляет потерю классификации как перекрестную энтропию классификации и добавляет 5% среднеквадратичной ошибки регрессии, чтобы создать цель. Кроме того, с помощью автоматического дифференцирования, функция также вычисляет градиент цели. Код для modelGradients функция помощника появляется в конце этого примера.

Задайте опции обучения

Чтобы обучить сеть, используйте стохастический градиентный спуск с импульсом (sgdm). Уравнения, которые задают учебный цикл,

wn+1=wn-fnL+α(wn-wn-1).

Здесь wn вес (параметр) вектор в итерации n, fn градиент целевой функции при итерации n, L изучить уровень, и α срок импульса. Инициализируйте скорость vel как пустой ([]); vel представляет wn-wn-1.

velocity = [];

sgdmupdate функция выполняет учебный цикл с помощью значений по умолчанию L=0.01 и импульс α=0.9. Определите номер учебных эпох к 20.

numEpochs = 20;

Задайте мини-пакетный размер 100.

miniBatchSize = 100;

Задайте, чтобы построить процесс обучения.

plots = "training-progress";

Обучайтесь на графическом процессоре, если вы доступны. Используя графический процессор требует Parallel Computing Toolbox™, и CUDA® включил NVIDIA®, графический процессор с вычисляет возможность 3.0 или выше. Если у вас нет графического процессора, установите executionEnvironment к "cpu".

executionEnvironment = "auto";

Обучите модель

Инициализируйте график процесса обучения.

if plots == "training-progress"
    figure
    lineLossTrain = animatedline;
    xlabel("Iteration")
    ylabel("Loss")
end

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

iteration = 0;
start = tic;

for epoch = 1:numEpochs
    p = randperm(n);
    for i = 1:miniBatchSize:n
        iteration = iteration + 1;
        x = XTrain(:,:,:,i:(i+miniBatchSize-1));
        X = single(x);
        Y = YTrain(i:(i+miniBatchSize-1));
        T = cast(cats == Y','single');
        T2 = ThetaTrain(i:(i+miniBatchSize-1));
        T2 = single(T2);
        
        dlX = dlarray(X,'SSCB');
        if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu"
            dlX = gpuArray(dlX);
        end
        
        [loss, grad] = dlfeval(@(X, T, T2, parameters)modelGradients(X, T, T2, parameters),dlX,T,T2,parameters);
        [parameters,velocity] = sgdmupdate(parameters,grad,velocity);
        
        if plots == "training-progress"
            D = duration(0,0,toc(start),'Format','hh:mm:ss');
            addpoints(lineLossTrain,iteration,double(gather(extractdata(loss))))
            title("Epoch: " + epoch + ", Elapsed: " + string(D))
            drawnow
        end 
    end
end

Вычислите точность модели на тестовых данных

digitTest4DArrayData функционируйте тестовые изображения загрузок и их связанные категории и углы.

[XTest,YTest,ThetaTest] = digitTest4DArrayData;

Используйте digitAngleModel функция, чтобы классифицировать тестовые изображения на основе обученной структуры параметра и сравнить классификации с истинными значениями.

[YPred,ThetaPred] = model(dlarray(XTest,'SSCB'), parameters);
[~,I] = max(extractdata(YPred),[],1);
C = cats(I);
accuracy = 100*(sum(C==YTest)/numel(C))
accuracy = 99.5400

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

Найдите получившуюся среднеквадратичную ошибку предсказанных углов цифры по сравнению с истинными углами.

th = extractdata(ThetaPred);
th = th(:);
anglerms = sqrt(mean((th - ThetaTest).^2))
anglerms = single
    7.3652

Угловые прогнозы являются более шумными, чем прогнозы цифры.

Просмотрите 10 случайных углов цифры по сравнению с их истинными значениями.

r = randperm(length(YTest),10);
tt = table(th(r),ThetaTest(r),'VariableNames',{'Predicted','True'})
tt=10×2 table
    Predicted    True
    _________    ____

     -7.2183      -5 
      35.014      38 
     -32.087     -34 
      12.619      19 
     -26.397     -13 
      31.299      30 
     -9.4692      -9 
     -29.969     -32 
     -28.972     -32 
      24.677      36 

Функции помощника

Следующий код для model функция помощника.

 function [dlY1,dlY2] = model(dlX,parameters)

    dlY1 = dlconv(dlX,parameters.W1,parameters.b1,'Padding',2);
    dlY1 = batchnorm(dlY1,parameters.Offset1,parameters.Scale1);
    dlY1 = relu(dlY1);

    dlYbranch = dlconv(dlY1,parameters.Ws,parameters.bs,'Stride',2);
    dlYbranch = batchnorm(dlYbranch,parameters.Offset2,parameters.Scale2);

    dlY1 = dlconv(dlY1,parameters.W2,parameters.b2,'Padding',1,'Stride',2);
    dlY1 = batchnorm(dlY1,parameters.Offset2,parameters.Scale2);
    dlY1 = relu(dlY1);

    dlY1 = dlconv(dlY1,parameters.W3,parameters.b3,'Padding',1);
    dlY1 = batchnorm(dlY1,parameters.Offset3,parameters.Scale3);

    dlY1 = dlY1 + dlYbranch;
    dlY1 = relu(dlY1);

    dlY1 = avgpool(dlY1,2,'Stride',2);
    dlY2 = fullyconnect(dlY1,parameters.R1,parameters.B5);
    dlY1 = fullyconnect(dlY1,parameters.W4,parameters.b4);
    dlY1 = softmax(dlY1);
 end

Следующий код для initializeGaussian функция помощника.

function parameter = initializeGaussian(parameterSize)
    parameter = randn(parameterSize, 'single') .* 0.01;
end

Следующий код для modelGradients функция помощника.

function [loss, grad] = modelGradients(dlX,T,T2,parameters)
    [y,y2] = model(dlX,parameters);
    loss = crossentropy(y,T) + 0.05*sqrt(mean((y2(:)-T2(:)).^2));
    grad = dlgradient(loss,parameters);
end

Смотрите также

| | | | | | | | |

Похожие темы