Подготовьте 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 функция для тасования данных цифр перед обучением.

imds = shuffle(imds);

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

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

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

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

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

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

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

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

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

dsTrain = transform(dsTrain,@augmentImages);

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

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

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

Визуализируйте примеры парных шумных и первозданных изображений с помощью montage (Image Processing Toolbox) функция. Обучающие данные выглядят правильно. Шум от соли и перца появляется на входных изображениях в левом столбце. Кроме сложения шума, входа изображение и изображение отклика одинаковы. Рандомизированное вращение на 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-D максимального слоя объединения

  • 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 требуется Parallel Computing Toolbox™ и графический процессор с поддержкой CUDA ® NVIDIA ®. Для получения дополнительной информации смотрите Поддержку GPU by Release (Parallel Computing Toolbox). Обучение занимает около 25 минут на NVIDIA Titan XP.

net = trainNetwork(dsTrain,layers,options);

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

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

Получите выходные изображения из тестового набора при помощи 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 выходного изображения выше шумного входного изображения, как и ожидалось.

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

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

function dataOut = addNoise(data)

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

end

The commonPreprocessing Функция helper задает предварительную обработку, которая является общей для наборов обучения, валидации и тестов. Функция helper выполняет эти шаги предварительной обработки.

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

  2. Измените размер данных изображения, чтобы соответствовать размеру входа слоя с помощью imresize (Image Processing Toolbox) функция.

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

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

The 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

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

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

См. также

| | | |

Похожие примеры

Подробнее о