В этом примере показано, как подготовить 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
функция, чтобы создать шумные версии каждого входного изображения, которое будет служить сетевым входом. 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
(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
- Слой Convolution для сверточных нейронных сетей
reluLayer
- Исправленный линейный модульный слой
maxPooling2dLayer
- 2D макс. слой объединения
transposedConv2dLayer
- Транспонированный слой свертки
clippedReluLayer
- Отсеченный исправил линейный модульный слой
regressionLayer
- Regression слой выхода
Создайте входной слой изображений. Чтобы упростить дополнительные проблемы, связанные с субдискретизацией и повышающей дискретизацией факторами два, выберите 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 эпох.
options = trainingOptions('adam', ... 'MaxEpochs',100, ... 'MiniBatchSize',imds.ReadSize, ... 'ValidationData',dsVal, ... 'Plots','training-progress', ... 'Verbose',false);
Теперь, когда источник данных и опции обучения сконфигурированы, обучают сверточную сеть автоэнкодера использование trainNetwork
функция.
Обучайтесь на графическом процессоре, если вы доступны. Используя графический процессор требует Parallel Computing Toolbox™, и CUDA® включил NVIDIA® графический процессор. Для получения дополнительной информации смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox). Обучение занимает приблизительно 25 минут на XP Титана NVIDIA.
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);
Визуализируйте демонстрационное входное изображение и связанное предсказание выход от сети, чтобы получить смысл того, как хорошо шумоподавление работает. Как ожидалось выходное изображение от сети удалило большинство шумовых артефактов из входного изображения. Изображение denoised является немного расплывчатым в результате кодирования и декодирования процесса.
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
(Image Processing Toolbox) функция. 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
функция помощника задает предварительную обработку, которая характерна для обучения, валидации и наборов тестов. Функция помощника выполняет эти шаги предварительной обработки.
Функция помощника требует, чтобы формат входных данных был массивом 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
trainNetwork
| trainingOptions
| transform
| combine
| imageDatastore