Подготовьте Datastore к регрессии от изображения к изображению

Этот пример показывает, как подготовить datastore к обучению сеть регрессии от изображения к изображению использование transform и функций combine ImageDatastore.

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

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

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

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

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

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

imds.ReadSize = 500;

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

rng(0)

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

imds = shuffle(imds);

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

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

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

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

Используйте функцию combine, чтобы объединить шумные изображения и нетронутые изображения в один datastore, который кормит данными trainNetwork. Этот объединенный datastore читает пакеты данных в массив 2D ячейки столбца как ожидалось 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™, включая:

Создайте входной слой изображений. Чтобы упростить дополнительные проблемы, связанные с субдискретизацией и повышающей дискретизацией факторами два, выберите 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];

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

Обучите сеть с помощью оптимизатора Адама. Задайте гиперустановки параметров при помощи функции trainingOptions. Обучайтесь в течение 100 эпох. Объединенные хранилища данных (созданный, когда вы используете функцию combine) не поддерживают перестановку, поэтому задают параметр Shuffle как 'never'.

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

Обучите сеть

Теперь, когда источник данных и опции обучения сконфигурированы, обучают сверточную сеть автоэнкодера использование функции trainNetwork. CUDA-способный графический процессор NVIDIA™ с вычисляет возможность 3.0, или выше настоятельно рекомендован для обучения.

Примечание: Обучение занимает приблизительно 25 минут на XP Титана NVIDIA™ графический процессор.

net = trainNetwork(dsTrain,layers,options);

Оцените производительность сети шумоподавления

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

ypred = predict(net,dsTest);

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

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

Оцените производительность сети путем анализа пикового отношения сигнал-шум (PSNR).

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

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

Сводные данные

Этот пример показал, как использовать transform и функции combine ImageDatastore, чтобы настроить предварительную обработку данных, требуемую для обучения и оценки сверточного автоэнкодера на наборе данных цифры.

Поддерживание функций

Функция помощника 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.

Функция помощника требует, чтобы формат входных данных был массивом 2D ячейки столбца данных изображения, которые совпадают с форматом данных, возвращенных функцией 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. Идентичные вращения применяются к сетевому входу и соответствующим ожидаемым ответам. Функция требует, чтобы формат входных данных был массивом 2D ячейки столбца данных изображения, которые совпадают с форматом данных, возвращенных функцией 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

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

| | | |

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

Больше о