В этом примере показано, как обучить сверточную нейронную сеть шумоподавления (DnCNN), затем используйте сеть, чтобы уменьшать артефакты сжатия JPEG в изображении.
Пример показывает, как обучить сеть DnCNN и также обеспечивает предварительно обученную сеть DnCNN. Если вы принимаете решение обучить сеть DnCNN, использование CUDA-способного графического процессора NVIDIA™ с вычисляют возможность 3.0, или выше настоятельно рекомендован (требует Parallel Computing Toolbox™).
Сжатие изображения используется, чтобы уменьшать объем потребляемой памяти изображения. Один популярный и мощный метод сжатия используется форматом изображения JPEG, который использует добротность, чтобы задать объем сжатия. Сокращение качественного значения приводит к более высокому сжатию и меньшему объему потребляемой памяти, за счет визуального качества изображения.
Сжатие JPEG с потерями, означая, что процесс сжатия заставляет изображение терять информацию. Для изображений JPEG эта информационная потеря появляется как блокирующиеся артефакты в изображении. Как показано на рисунке, больше сжатия приводит к большему количеству информационной потери и более сильных артефактов. Текстурированные области с высокочастотным содержимым, такие как трава и облака, выглядят расплывчатыми. Резкий край, такой как крыша дома и поручней на маяке, вызове выставки.
Разблокирование JPEG является процессом сокращения эффектов артефактов сжатия в изображениях JPEG. Несколько методов разблокирования JPEG существуют, включая более эффективные методы то глубокое обучение использования. Этот пример реализует один такой основанный на глубоком обучении метод, который пытается минимизировать эффект артефактов сжатия JPEG.
Этот пример использует встроенную глубокую сверточную нейронную сеть прямого распространения, названную DnCNN
. Сеть была, в основном, спроектирована, чтобы удалить шум из изображений. Однако архитектура DnCNN может также быть обучена удалить артефакты сжатия JPEG или увеличить разрешение изображения.
Ссылочная бумага [1] использует остаточную стратегию обучения, подразумевая, что сеть DnCNN учится оценивать остаточное изображение. Остаточное изображение является различием между нетронутым изображением и искаженной копией изображения. Остаточное изображение содержит информацию об искажении изображения. В данном примере искажение появляется как артефакты блокирования JPEG.
Сеть DnCNN обучена, чтобы обнаружить остаточное изображение от яркости цветного изображения. Канал яркости изображения, Y, представляет яркость каждого пикселя через линейную комбинацию красных, зеленых, и синих пиксельных значений. В отличие от этого два канала цветности изображения, Cb и Cr, являются различными линейными комбинациями красных, зеленых, и синих пиксельных значений, которые представляют информацию о цветовом различии. DnCNN обучен с помощью только канал яркости, потому что человеческое восприятие более чувствительно к изменениям в яркости, чем изменения в цвете.
Если яркость нетронутого изображения и яркость изображения, содержащего артефакты сжатия JPEG, затем вход к сети DnCNN и сеть учится предсказывать от обучающих данных.
Если сеть DnCNN изучает, как оценить остаточное изображение, она может восстановить неискаженную версию сжатого изображения JPEG путем добавления остаточного изображения в сжатый канал яркости, затем преобразования изображения назад в цветовое пространство RGB.
Загрузите Сравнительный тест IAPR TC-12, который состоит из 20 000 все еще естественных изображений [2]. Набор данных включает фотографии людей, животных, города и т.д. Размер файла данных составляет ~1.8 Гбайт. Если вы не хотите загружать обучающий набор данных, должен был обучить сеть, то можно загрузить предварительно обученную сеть DnCNN путем ввода load('pretrainedJPEGDnCNN.mat')
в командной строке. Затем перейдите непосредственно к разделу Perform JPEG Deblocking Using DnCNN Network в этом примере.
Используйте функцию помощника, downloadIAPRTC12Data
, загружать данные. Эта функция присоединена к примеру как к вспомогательному файлу.
imagesDir = tempdir;
url = "http://www-i6.informatik.rwth-aachen.de/imageclef/resources/iaprtc12.tgz";
downloadIAPRTC12Data(url,imagesDir);
Этот пример обучит сеть с небольшим подмножеством TC IAPR 12 Исходных данных. Загрузите imageCLEF обучающие данные. Все изображения являются 32-битными цветными изображениями JPEG.
trainImagesDir = fullfile(imagesDir,'iaprtc12','images','00'); exts = {'.jpg','.bmp','.png'}; imdsPristine = imageDatastore(trainImagesDir,'FileExtensions',exts);
Перечислите количество учебных изображений.
numel(imdsPristine.Files)
ans = 251
Чтобы создать обучающий набор данных, читайте в нетронутых изображениях и выпишите изображения в формате файла JPEG с различными уровнями сжатия.
Укажите, что качественные значения изображения JPEG раньше представляли артефакты сжатия изображения. Качественные значения должны быть в области значений [0, 100]. Маленькие качественные значения приводят к большему количеству сжатия и более сильных артефактов сжатия. Используйте более плотную выборку маленьких качественных значений, таким образом, обучающие данные имеют широкий диапазон артефактов сжатия.
JPEGQuality = [5:5:40 50 60 70 80];
Сжатые изображения хранятся на диске как файлы MAT в директории compressedImagesDir
. Вычисленные остаточные изображения хранятся на диске как файлы MAT в директории residualImagesDir
. Файлы MAT хранятся как тип данных double
для большей точности при обучении сети.
compressedImagesDir = fullfile(imagesDir,'iaprtc12','JPEGDeblockingData','compressedImages'); residualImagesDir = fullfile(imagesDir,'iaprtc12','JPEGDeblockingData','residualImages');
Используйте функцию помощника createJPEGDeblockingTrainingSet
предварительно обрабатывать обучающие данные. Эта функция присоединена к примеру как к вспомогательному файлу.
Для каждого нетронутого учебного изображения функция помощника пишет копию изображения с добротностью 100, чтобы использовать в качестве ссылочного изображения и копий изображения с каждой добротностью, чтобы использовать в качестве сетевых входных параметров. Функция вычисляет яркость (Y) канал ссылки и сжатых изображений в типе данных double
для большей точности при вычислении остаточных изображений. Сжатые изображения хранятся на диске как.MAT файлы в директории compressedDirName
. Вычисленные остаточные изображения хранятся на диске как.MAT файлы в директории residualDirName
.
[compressedDirName,residualDirName] = createJPEGDeblockingTrainingSet(imdsPristine,JPEGQuality);
Используйте случайный datastore экстракции закрашенной фигуры, чтобы накормить обучающими данными сеть. Этот datastore извлекает случайные соответствующие закрашенные фигуры из двух хранилищ данных изображений, которые содержат сетевые входные параметры и желали сетевых ответов.
В этом примере сетевые входные параметры являются сжатыми изображениями. Желаемые сетевые ответы являются остаточными изображениями. Создайте datastore изображений под названием imdsCompressed
из набора сжатых файлов изображений. Создайте datastore изображений под названием imdsResidual
из набора вычисленных остаточных файлов изображений. Оба хранилища данных требуют функции помощника, matRead
, считать данные изображения из файлов изображений. Эта функция присоединена к примеру как к вспомогательному файлу.
imdsCompressed = imageDatastore(compressedDirName,'FileExtensions','.mat','ReadFcn',@matRead); imdsResidual = imageDatastore(residualDirName,'FileExtensions','.mat','ReadFcn',@matRead);
Создайте imageDataAugmenter
(Deep Learning Toolbox), который задает параметры увеличения данных. Используйте увеличение данных во время обучения варьироваться обучающие данные, который эффективно увеличивает сумму доступных обучающих данных. Здесь, увеличение задает случайное вращение 90 градусами и случайные отражения в направлении X.
augmenter = imageDataAugmenter( ... 'RandRotation',@()randi([0,1],1)*90, ... 'RandXReflection',true);
Создайте randomPatchExtractionDatastore
от двух хранилищ данных изображений. Задайте размер закрашенной фигуры 50 50 пикселей. Каждое изображение генерирует 128 случайных закрашенных фигур размера 50 50 пиксели. Задайте мини-пакетный размер 128.
patchSize = 50; patchesPerImage = 128; dsTrain = randomPatchExtractionDatastore(imdsCompressed,imdsResidual,patchSize, ... 'PatchesPerImage',patchesPerImage, ... 'DataAugmentation',augmenter); dsTrain.MiniBatchSize = patchesPerImage;
Случайный datastore экстракции закрашенной фигуры dsTrain
обеспечивает мини-пакеты данных к сети в итерации эпохи. Предварительно просмотрите результат чтения от datastore.
inputBatch = preview(dsTrain); disp(inputBatch)
InputImage ResponseImage ______________ ______________ {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double} {50×50 double}
Создайте слои встроенной сети DnCNN при помощи dnCNNLayers
функция. По умолчанию сетевая глубина (количество слоев свертки) равняется 20.
layers = dnCNNLayers
layers = 1x59 Layer array with layers: 1 'InputLayer' Image Input 50x50x1 images 2 'Conv1' Convolution 64 3x3x1 convolutions with stride [1 1] and padding [1 1 1 1] 3 'ReLU1' ReLU ReLU 4 'Conv2' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 5 'BNorm2' Batch Normalization Batch normalization with 64 channels 6 'ReLU2' ReLU ReLU 7 'Conv3' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 8 'BNorm3' Batch Normalization Batch normalization with 64 channels 9 'ReLU3' ReLU ReLU 10 'Conv4' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 11 'BNorm4' Batch Normalization Batch normalization with 64 channels 12 'ReLU4' ReLU ReLU 13 'Conv5' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 14 'BNorm5' Batch Normalization Batch normalization with 64 channels 15 'ReLU5' ReLU ReLU 16 'Conv6' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 17 'BNorm6' Batch Normalization Batch normalization with 64 channels 18 'ReLU6' ReLU ReLU 19 'Conv7' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 20 'BNorm7' Batch Normalization Batch normalization with 64 channels 21 'ReLU7' ReLU ReLU 22 'Conv8' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 23 'BNorm8' Batch Normalization Batch normalization with 64 channels 24 'ReLU8' ReLU ReLU 25 'Conv9' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 26 'BNorm9' Batch Normalization Batch normalization with 64 channels 27 'ReLU9' ReLU ReLU 28 'Conv10' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 29 'BNorm10' Batch Normalization Batch normalization with 64 channels 30 'ReLU10' ReLU ReLU 31 'Conv11' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 32 'BNorm11' Batch Normalization Batch normalization with 64 channels 33 'ReLU11' ReLU ReLU 34 'Conv12' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 35 'BNorm12' Batch Normalization Batch normalization with 64 channels 36 'ReLU12' ReLU ReLU 37 'Conv13' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 38 'BNorm13' Batch Normalization Batch normalization with 64 channels 39 'ReLU13' ReLU ReLU 40 'Conv14' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 41 'BNorm14' Batch Normalization Batch normalization with 64 channels 42 'ReLU14' ReLU ReLU 43 'Conv15' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 44 'BNorm15' Batch Normalization Batch normalization with 64 channels 45 'ReLU15' ReLU ReLU 46 'Conv16' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 47 'BNorm16' Batch Normalization Batch normalization with 64 channels 48 'ReLU16' ReLU ReLU 49 'Conv17' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 50 'BNorm17' Batch Normalization Batch normalization with 64 channels 51 'ReLU17' ReLU ReLU 52 'Conv18' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 53 'BNorm18' Batch Normalization Batch normalization with 64 channels 54 'ReLU18' ReLU ReLU 55 'Conv19' Convolution 64 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 56 'BNorm19' Batch Normalization Batch normalization with 64 channels 57 'ReLU19' ReLU ReLU 58 'Conv20' Convolution 1 3x3x64 convolutions with stride [1 1] and padding [1 1 1 1] 59 'FinalRegressionLayer' Regression Output mean-squared-error
Обучите сеть с помощью стохастического градиентного спуска с импульсом (SGDM) оптимизация. Задайте установки гиперпараметров для SGDM при помощи trainingOptions
(Deep Learning Toolbox) функция.
Обучение глубокой сети длительно. Ускорьте обучение путем определения высокой скорости обучения. Однако это может заставить градиенты сети взрываться или расти неудержимо, предотвратив сеть от обучения успешно. Чтобы сохранить градиенты в значимой области значений, включите усечение градиента установкой 'GradientThreshold'
к 0.005
, и задайте 'GradientThresholdMethod'
использовать абсолютное значение градиентов.
maxEpochs = 30; initLearningRate = 0.1; l2reg = 0.0001; batchSize = 64; options = trainingOptions('sgdm', ... 'Momentum',0.9, ... 'InitialLearnRate',initLearningRate, ... 'LearnRateSchedule','piecewise', ... 'GradientThresholdMethod','absolute-value', ... 'GradientThreshold',0.005, ... 'L2Regularization',l2reg, ... 'MiniBatchSize',batchSize, ... 'MaxEpochs',maxEpochs, ... 'Plots','training-progress', ... 'Verbose',false);
После конфигурирования опций обучения и случайного datastore экстракции закрашенной фигуры, обучите сеть DnCNN с помощью trainNetwork
(Deep Learning Toolbox) функция. Чтобы обучить сеть, установите doTraining
параметр в следующем коде к true
. CUDA-способный графический процессор NVIDIA™ с вычисляет возможность 3.0, или выше настоятельно рекомендован для обучения.
Если вы сохраняете doTraining
параметр в следующем коде как false
, затем пример возвращает предварительно обученную сеть DnCNN.
Примечание: Обучение занимает приблизительно 40 часов на Титане NVIDIA™ X и может взять еще дольше в зависимости от вашего оборудования графического процессора.
% Training runs when doTraining is true doTraining = false; if doTraining modelDateTime = datestr(now,'dd-mmm-yyyy-HH-MM-SS'); [net,info] = trainNetwork(dsTrain,layers,options); save(['trainedJPEGDnCNN-' modelDateTime '-Epoch-' num2str(maxEpochs) '.mat'],'net','options'); else load('pretrainedJPEGDnCNN.mat'); end
Можно теперь использовать сеть DnCNN, чтобы удалить артефакты сжатия JPEG из новых изображений.
Чтобы выполнить использование разблокирования JPEG DnCNN, выполните остающиеся шаги этого примера. Остаток от примера показывает как:
Создайте демонстрационные тестовые изображения с артефактами сжатия JPEG на трех различных уровнях качества.
Удалите артефакты сжатия с помощью сети DnCNN.
Визуально сравните изображения до и после разблокирования.
Оцените качество сжатых и разблокированных изображений путем определения количества их подобия неискаженному ссылочному изображению.
Создайте демонстрационные изображения, чтобы оценить результат разблокирования изображения JPEG с помощью сети DnCNN. Набор тестовых данных, testImages
, содержит 21 неискаженное изображение, поставленное в Image Processing Toolbox™. Загрузите изображения в imageDatastore
.
exts = {'.jpg','.png'}; fileNames = {'sherlock.jpg','car2.jpg','fabric.png','greens.jpg','hands1.jpg','kobi.png',... 'lighthouse.png','micromarket.jpg','office_4.jpg','onion.png','pears.png','yellowlily.jpg',... 'indiancorn.jpg','flamingos.jpg','sevilla.jpg','llama.jpg','parkavenue.jpg',... 'peacock.jpg','car1.jpg','strawberries.jpg','wagon.jpg'}; filePath = [fullfile(matlabroot,'toolbox','images','imdata') filesep]; filePathNames = strcat(filePath,fileNames); testImages = imageDatastore(filePathNames,'FileExtensions',exts);
Отобразите изображения тестирования как монтаж.
montage(testImages)
Выберите одно из изображений, чтобы использовать в качестве ссылочного изображения для разблокирования JPEG. Можно опционально использовать собственное несжатое изображение в качестве ссылочного изображения.
indx = 7; % Index of image to read from the test image datastore Ireference = readimage(testImages,indx); imshow(Ireference) title('Uncompressed Reference Image')
Создайте три сжатых тестовых изображения с JPEG Quality
значения 10, 20, и 50.
imwrite(Ireference,fullfile(tempdir,'testQuality10.jpg'),'Quality',10); imwrite(Ireference,fullfile(tempdir,'testQuality20.jpg'),'Quality',20); imwrite(Ireference,fullfile(tempdir,'testQuality50.jpg'),'Quality',50);
Считайте сжатые версии изображения в рабочую область.
I10 = imread(fullfile(tempdir,'testQuality10.jpg')); I20 = imread(fullfile(tempdir,'testQuality20.jpg')); I50 = imread(fullfile(tempdir,'testQuality50.jpg'));
Отобразите сжатые изображения как монтаж.
montage({I50,I20,I10},'Size',[1 3]) title('JPEG-Compressed Images with Quality Factor: 50, 20 and 10 (left to right)')
Вспомните, что DnCNN обучен с помощью только канал яркости изображения, потому что человеческое восприятие более чувствительно к изменениям в яркости, чем изменения в цвете. Преобразуйте сжатые до JPEG изображения от цветового пространства RGB до цветового пространства YCbCr с помощью rgb2ycbcr
функция.
I10ycbcr = rgb2ycbcr(I10); I20ycbcr = rgb2ycbcr(I20); I50ycbcr = rgb2ycbcr(I50);
Для того, чтобы выполнить прямую передачу сети, используйте denoiseImage
функция. Эта функция использует точно те же методы обучения и процедуры тестирования для шумоподавления изображение. Можно думать об артефактах сжатия JPEG как о типе шума изображения.
I10y_predicted = denoiseImage(I10ycbcr(:,:,1),net); I20y_predicted = denoiseImage(I20ycbcr(:,:,1),net); I50y_predicted = denoiseImage(I50ycbcr(:,:,1),net);
Каналам цветности не нужна обработка. Конкатенация разблокированной яркости образовывает канал с исходными каналами цветности, чтобы получить разблокированное изображение в цветовом пространстве YCbCr.
I10ycbcr_predicted = cat(3,I10y_predicted,I10ycbcr(:,:,2:3)); I20ycbcr_predicted = cat(3,I20y_predicted,I20ycbcr(:,:,2:3)); I50ycbcr_predicted = cat(3,I50y_predicted,I50ycbcr(:,:,2:3));
Преобразуйте разблокированное изображение YCbCr в цветовое пространство RGB при помощи ycbcr2rgb
функция.
I10_predicted = ycbcr2rgb(I10ycbcr_predicted); I20_predicted = ycbcr2rgb(I20ycbcr_predicted); I50_predicted = ycbcr2rgb(I50ycbcr_predicted);
Отобразите разблокированные изображения как монтаж.
montage({I50_predicted,I20_predicted,I10_predicted},'Size',[1 3]) title('Deblocked Images with Quality Factor 50, 20 and 10 (Left to Right)')
Чтобы получить лучшее визуальное понимание улучшений, исследуйте меньшую область в каждом изображении. Задайте видимую область (ROI) с помощью векторного roi
в формате [x y высота ширины]. Элементы задают x-и y-координату левого верхнего угла, и ширину и высоту ROI.
roi = [30 440 100 80];
Обрежьте сжатые изображения к этому ROI и отобразите результат как монтаж.
i10 = imcrop(I10,roi); i20 = imcrop(I20,roi); i50 = imcrop(I50,roi); montage({i50 i20 i10},'Size',[1 3]) title('Patches from JPEG-Compressed Images with Quality Factor 50, 20 and 10 (Left to Right)')
Обрежьте разблокированные изображения к этому ROI и отобразите результат как монтаж.
i10predicted = imcrop(I10_predicted,roi); i20predicted = imcrop(I20_predicted,roi); i50predicted = imcrop(I50_predicted,roi); montage({i50predicted,i20predicted,i10predicted},'Size',[1 3]) title('Patches from Deblocked Images with Quality Factor 50, 20 and 10 (Left to Right)')
Определите количество качества разблокированных изображений через четыре метрики. Можно использовать displayJPEGResults
функция помощника, чтобы вычислить эти метрики для сжатых и разблокированных изображений в добротностях 10, 20, и 50. Эта функция присоединена к примеру как к вспомогательному файлу.
Структурный индекс Подобия (SSIM). SSIM оценивает визуальный удар трех характеристик изображения: яркость, контраст и структура, против ссылочного изображения. Чем ближе значение SSIM к 1, тем лучше тестовое изображение соглашается со ссылочным изображением. Здесь, ссылочное изображение является неискаженным оригинальным изображением, Ireference
, перед сжатием JPEG. Смотрите ssim
для получения дополнительной информации об этой метрике.
Пиковое отношение сигнал-шум (PSNR). Чем больше значение PSNR, тем более сильный сигнал по сравнению с искажением. Смотрите psnr
для получения дополнительной информации об этой метрике.
Средство анализа качества изображения естественности (NIQE). NIQE измеряет перцепционное качество изображения с помощью модели, обученной от естественных сцен. Меньшие баллы NIQE указывают на лучшее перцепционное качество. Смотрите niqe
для получения дополнительной информации об этой метрике.
Изображение Blind/Referenceless Пространственное Качественное Средство анализа (BRISQUE). BRISQUE измеряет перцепционное качество изображения с помощью модели, обученной от естественных сцен с искажением изображения. Меньшие баллы BRISQUE указывают на лучшее перцепционное качество. Смотрите brisque
для получения дополнительной информации об этой метрике.
displayJPEGResults(Ireference,I10,I20,I50,I10_predicted,I20_predicted,I50_predicted)
------------------------------------------ SSIM Comparison =============== I10: 0.90624 I10_predicted: 0.91286 I20: 0.94904 I20_predicted: 0.95444 I50: 0.97238 I50_predicted: 0.97482 ------------------------------------------ PSNR Comparison =============== I10: 26.6046 I10_predicted: 27.0793 I20: 28.8015 I20_predicted: 29.3378 I50: 31.4512 I50_predicted: 31.8584 ------------------------------------------ NIQE Comparison =============== I10: 7.2194 I10_predicted: 3.9478 I20: 4.5158 I20_predicted: 3.0685 I50: 2.8874 I50_predicted: 2.4106 NOTE: Smaller NIQE score signifies better perceptual quality ------------------------------------------ BRISQUE Comparison ================== I10: 52.372 I10_predicted: 38.9271 I20: 45.3772 I20_predicted: 30.8991 I50: 27.7093 I50_predicted: 24.3845 NOTE: Smaller BRISQUE score signifies better perceptual quality
[1] Чжан, K., В. Цзо, И. Чен, Д. Мэн и Л. Чжан, "Вне гауссова Denoiser: невязка, узнающая о глубоком CNN для шумоподавления изображений". IEEE® Transactions на обработке изображений. Февраль 2017.
[2] Grubinger, M. P. Ущелье, Х. Мюллер и Т. Дезелэерс. "Сравнительный тест IAPR TC-12: Новый Ресурс Оценки для Визуальных Информационных систем". Продолжения ресурсов OntoImage 2006 Языка Для Извлечения Изображений На основе содержимого. Генуя, Италия. Издание 5, май 2006, p. 10.
denoiseImage
| dnCNNLayers
| randomPatchExtractionDatastore
| rgb2ycbcr
| ycbcr2rgb
| trainingOptions
(Deep Learning Toolbox) | trainNetwork
(Deep Learning Toolbox)