exponenta event banner

Подготовка хранилища данных для регрессии между изображениями

В этом примере показано, как подготовить хранилище данных для обучения сети регрессии «изображение-изображение» с использованием transform и combine функции ImageDatastore.

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

Подготовка данных с использованием конвейера предварительной обработки

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

Загрузка неточных изображений из набора цифровых данных в виде imageDatastore. Хранилище данных содержит 10 000 синтетических изображений цифр от 0 до 9. Изображения генерируются путем применения случайных преобразований к цифровым изображениям, созданным различными шрифтами. Каждая цифра изображения составляет 28 на 28 пикселей. Хранилище данных содержит равное количество изображений для каждой категории.

digitDatasetPath = fullfile(matlabroot,'toolbox','nnet', ...
    'nndemos','nndatasets','DigitDataset');
imds = imageDatastore(digitDatasetPath, ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

Укажите большой размер для чтения, чтобы минимизировать стоимость ввода-вывода файла.

imds.ReadSize = 500;

Задайте начальное число глобального генератора случайных чисел, чтобы помочь воспроизводимости результатов.

rng(0)

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

imds = shuffle(imds);

Используйте splitEachLabel функция для разделения imds в три хранилища данных изображений, содержащие нетронутые изображения для обучения, проверки и тестирования.

[imdsTrain,imdsVal,imdsTest] = splitEachLabel(imds,0.95,0.025);

Используйте transform функция для создания шумных версий каждого входного изображения, которое будет служить сетевым входом. transform функция считывает данные из базового хранилища данных и обрабатывает данные с помощью операций, определенных в вспомогательной функции addNoise (определяется в конце этого примера). Выходные данные transform функция является TransformedDatastore.

dsTrainNoisy = transform(imdsTrain,@addNoise);
dsValNoisy = transform(imdsVal,@addNoise);
dsTestNoisy = transform(imdsTest,@addNoise);

Используйте combine функция объединения шумных и неточных изображений в единое хранилище данных, которое подает данные в trainNetwork. Это объединенное хранилище данных считывает пакеты данных в массив ячеек из двух столбцов, как ожидалось trainNetwork. Выходные данные combine функция является CombinedDatastore.

dsTrain = combine(dsTrainNoisy,imdsTrain);
dsVal = combine(dsValNoisy,imdsVal);
dsTest = combine(dsTestNoisy,imdsTest);

Используйте transform для выполнения дополнительных операций предварительной обработки, которые являются общими как для хранилища данных ввода, так и для хранилища данных ответа. commonPreprocessing функция помощника (определенный в конце этого примера) изменяет размеры входа и изображений ответа к 32 на 32 пикселя, чтобы соответствовать входному размеру сети, и нормализует данные по каждому изображению к диапазону [0, 1].

dsTrain = transform(dsTrain,@commonPreprocessing);
dsVal = transform(dsVal,@commonPreprocessing);
dsTest = transform(dsTest,@commonPreprocessing);

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

dsTrain = transform(dsTrain,@augmentImages);

Увеличение уменьшает переоборудование и добавляет надежность наличию вращений в обучаемой сети. Рандомизированное увеличение не требуется для наборов данных проверки или теста.

Предварительный просмотр предварительно обработанных данных

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

Визуализация примеров парных шумных и неточных изображений с помощью montage(Панель инструментов обработки изображений). Данные обучения выглядят правильно. Шум соли и перца появляется на входных изображениях в левом столбце. Кроме добавления шума, входное изображение и ответное изображение одинаковы. Рандомизированное вращение на 90 градусов применяется как к входным, так и к ответным изображениям одинаковым образом.

exampleData = preview(dsTrain);
inputs = exampleData(:,1);
responses = exampleData(:,2);
minibatch = cat(2,inputs,responses);
montage(minibatch','Size',[8 2])
title('Inputs (Left) and Responses (Right)')

Определение сети сверточного автокодера

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

В этом примере определяется сеть сверточного автокодера с использованием уровней из Deep Learning Toolbox™, включая:

  • imageInputLayer - Слой ввода изображения

  • convolution2dLayer - Сверточный слой для сверточных нейронных сетей

  • reluLayer - Слой выпрямленного линейного блока

  • maxPooling2dLayer - 2-й макс. слой объединения

  • transposedConv2dLayer - Транспонированный сверточный слой

  • clippedReluLayer - Подрезанный слой выпрямленного линейного блока

  • regressionLayer - Уровень регрессионного вывода

Создайте слой ввода изображения. Чтобы упростить проблемы заполнения, связанные с понижающей дискретизацией и повышающей дискретизацией на два фактора, выберите размер ввода 32 на 32, поскольку 32 чисто делится на 2, 4 и 8.

imageLayer = imageInputLayer([32,32,1]);

Создайте слои кодирования. Понижение дискретизации в кодере достигается максимальным объединением с размером пула 2 и шагом 2.

encodingLayers = [ ...
    convolution2dLayer(3,16,'Padding','same'), ...
    reluLayer, ...
    maxPooling2dLayer(2,'Padding','same','Stride',2), ...
    convolution2dLayer(3,8,'Padding','same'), ...
    reluLayer, ...
    maxPooling2dLayer(2,'Padding','same','Stride',2), ...
    convolution2dLayer(3,8,'Padding','same'), ...
    reluLayer, ...
    maxPooling2dLayer(2,'Padding','same','Stride',2)];

Создайте уровни декодирования. Декодер дискретизирует кодированный сигнал с использованием транспонированного уровня свертки. Создайте транспонированный слой свертки с правильным коэффициентом увеличения дискретизации с помощью createUpsampleTransponseConvLayer функция помощника. Эта функция определена в конце этого примера.

Сеть использует clippedReluLayer в качестве конечного уровня активации для принудительного вывода в диапазоне [0, 1].

decodingLayers = [ ...
    createUpsampleTransponseConvLayer(2,8), ...
    reluLayer, ...
    createUpsampleTransponseConvLayer(2,8), ...
    reluLayer, ...
    createUpsampleTransponseConvLayer(2,16), ...
    reluLayer, ...
    convolution2dLayer(3,1,'Padding','same'), ...
    clippedReluLayer(1.0), ...
    regressionLayer];    

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

layers = [imageLayer,encodingLayers,decodingLayers];

Определение параметров обучения

Обучение сети с помощью оптимизатора Adam. Задайте параметры гиперпараметра с помощью trainingOptions функция. Поезд на 100 эпох.

options = trainingOptions('adam', ...
    'MaxEpochs',100, ...
    'MiniBatchSize',imds.ReadSize, ...
    'ValidationData',dsVal, ...
    'Plots','training-progress', ...
    'Verbose',false);

Обучение сети

Теперь, когда сконфигурированы источник данных и варианты обучения, обучайте сеть сверточного автокодера с помощью trainNetwork функция.

Обучение на GPU, если он доступен. Для использования графического процессора требуются параллельные вычислительные Toolbox™ и графический процессор NVIDIA ® с поддержкой CUDA ®. Дополнительные сведения см. в разделе Поддержка графического процессора по выпуску (Панель инструментов параллельных вычислений). Обучение на NVIDIA Titan XP занимает около 25 минут.

net = trainNetwork(dsTrain,layers,options);

modelDateTime = string(datetime('now','Format',"yyyy-MM-dd-HH-mm-ss"));
save(strcat("trainedImageToImageRegressionNet-",modelDateTime,".mat"),'net');    

Оценка производительности сети Denoising

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

ypred = predict(net,dsTest);

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

inputImageExamples = preview(dsTest);
montage({inputImageExamples{1},ypred(:,:,:,1)});

Оценка рабочих характеристик сети путем анализа пикового отношения сигнал/шум (PSNR).

ref = inputImageExamples{1,2};
originalNoisyImage = inputImageExamples{1,1};
psnrNoisy = psnr(originalNoisyImage,ref)
psnrNoisy = single
    17.8455
psnrDenoised = psnr(ypred(:,:,:,1),ref)
psnrDenoised = single
    21.8439

PSNR выходного изображения выше, чем ожидаемое шумное входное изображение.

Вспомогательные функции

addNoise функция помощника добавляет шум соли и перца к изображениям с помощью imnoise(Панель инструментов обработки изображений). addNoise функция требует, чтобы формат входных данных был массивом ячеек данных изображения, который соответствует формату данных, возвращаемых read функция ImageDatastore.

function dataOut = addNoise(data)

    dataOut = data;
    for idx = 1:size(data,1)
       dataOut{idx} = imnoise(data{idx},'salt & pepper');
    end

end

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

  1. Преобразование данных изображения в тип данных single.

  2. Изменение размера изображения в соответствии с размером входного слоя с помощью imresize(Панель инструментов обработки изображений).

  3. Нормализовать данные в диапазоне [0, 1] с помощью rescale функция.

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

function dataOut = commonPreprocessing(data)

    dataOut = cell(size(data));
    for col = 1:size(data,2)
        for idx = 1:size(data,1)
            temp = single(data{idx,col});
            temp = imresize(temp,[32,32]);
            temp = rescale(temp);
            dataOut{idx,col} = temp;
        end
    end
end

augmentImages вспомогательная функция добавляет рандомизированные повороты на 90 градусов к данным с помощью rot90 функция. Идентичные повороты применяются к сетевому входу и соответствующим ожидаемым ответам. Функция требует, чтобы формат входных данных был массивом ячеек из двух столбцов данных изображения, который соответствует формату данных, возвращаемых read функция CombinedDatastore.

function dataOut = augmentImages(data)

    dataOut = cell(size(data));
    for idx = 1:size(data,1)
        rot90Val = randi(4,1,1)-1;
        dataOut(idx,:) = {rot90(data{idx,1},rot90Val),rot90(data{idx,2},rot90Val)};
    end
end

createUpsampleTransposeConvLayer вспомогательная функция определяет транспонированный сверточный слой, который увеличивает размер входного слоя на заданный коэффициент.

function out = createUpsampleTransponseConvLayer(factor,numFilters)

    filterSize = 2*factor - mod(factor,2); 
    cropping = (factor-mod(factor,2))/2;
    numChannels = 1;
    
    out = transposedConv2dLayer(filterSize,numFilters, ... 
        'NumChannels',numChannels,'Stride',factor,'Cropping',cropping);
end

См. также

| | | |

Связанные примеры

Подробнее