В этом примере показано, как сгенерировать код CUDA® для детектора транспортного средства SSD и детектора YOLO v2 транспортного средства, который выполняет расчеты вывода в 8-битных целых числах.
Глубокое обучение является мощным методом машинного обучения, в котором вы обучаете сеть, чтобы изучить функции изображений и выполнить задачи обнаружения. Существует несколько методов для обнаружения объектов с помощью глубокого обучения, таких как Faster R-CNN, Вы Только Взгляд Однажды (YOLO v2) и SSD. Для получения дополнительной информации смотрите, что Обнаружение объектов Использует глубокое обучение YOLO v2 и Обнаружение объектов Используя Глубокое обучение SSD.
Архитектуры нейронной сети, используемые для применения глубокого обучения, содержат много слоев обработки, включая сверточные слои. Модели глубокого обучения обычно работают над большими наборами маркированных данных. Выполнение вывода на этих моделях в вычислительном отношении интенсивно, используя существенное количество памяти. Нейронные сети используют память, чтобы сохранить входные данные, параметры (веса) и активации от каждого слоя, когда вход распространяет через сеть. Глубокие нейронные сети, обученные в MATLAB, используют типы данных с плавающей запятой с одинарной точностью. Даже сети, которые малы в размере, требуют, чтобы значительный объем памяти и оборудование выполнили эти арифметические операции с плавающей точкой. Эти ограничения могут запретить развертывание моделей глубокого обучения к устройствам, которые имеют низкую вычислительную силу и меньшие ресурсы памяти. При помощи более низкой точности, чтобы сохранить веса и активации, можно уменьшать требования к памяти сети.
Можно использовать Deep Learning Toolbox в тандеме с пакетом поддержки Библиотеки Квантования Модели Deep Learning Toolbox, чтобы уменьшать объем потребляемой памяти глубокой нейронной сети путем квантования весов, смещений и активаций слоев свертки к 8-битным масштабированным целочисленным типам данных. Затем можно использовать GPU Coder™, чтобы сгенерировать код CUDA для квантованной сети.
Загрузите предварительно обученный детектор объектов, чтобы избежать необходимости ожидать обучения завершиться.
detectorType = 2
detectorType = 2
switch detectorType case 1 if ~exist('ssdResNet50VehicleExample_20a.mat','file') disp('Downloading pretrained detector...'); pretrainedURL = 'https://www.mathworks.com/supportfiles/vision/data/ssdResNet50VehicleExample_20a.mat'; websave('ssdResNet50VehicleExample_20a.mat',pretrainedURL); end case 2 if ~exist('yolov2ResNet50VehicleExample_19b.mat','file') disp('Downloading pretrained detector...'); pretrainedURL = 'https://www.mathworks.com/supportfiles/vision/data/yolov2ResNet50VehicleExample_19b.mat'; websave('yolov2ResNet50VehicleExample_19b.mat',pretrainedURL); end end
Downloading pretrained detector...
Этот пример использует набор данных небольшого транспортного средства, который содержит 295 изображений. Многие из этих изображений прибывают из Автомобилей Калифорнийского технологического института 1 999 и 2 001 набор данных, используемый с разрешением и доступный в Калифорнийском технологическом институте Вычислительный веб-сайт Видения, созданный Пьетро Пероной. Каждое изображение содержит один или два помеченных экземпляра транспортного средства. Небольшой набор данных полезен для исследования метода обучения, но на практике, более помеченные изображения необходимы, чтобы обучить устойчивый детектор. Извлеките изображения транспортного средства и загрузите достоверные данные транспортного средства.
unzip vehicleDatasetImages.zip data = load('vehicleDatasetGroundTruth.mat'); vehicleDataset = data.vehicleDataset;
Обучающие данные хранятся в таблице. Первый столбец содержит путь к файлам изображений. Остальные столбцы содержат метки ROI для транспортных средств. Отобразите первые несколько строк данных.
vehicleDataset(1:4,:)
ans=4×2 table
imageFilename vehicle
_________________________________ _________________
{'vehicleImages/image_00001.jpg'} {[220 136 35 28]}
{'vehicleImages/image_00002.jpg'} {[175 126 61 45]}
{'vehicleImages/image_00003.jpg'} {[108 120 45 33]}
{'vehicleImages/image_00004.jpg'} {[124 112 38 36]}
Разделите набор данных в обучение, валидацию и наборы тестов. Выберите 60% данных для обучения, 10% для калибровки и остаток для проверки обученного детектора.
rng(0); shuffledIndices = randperm(height(vehicleDataset)); idx = floor(0.6 * length(shuffledIndices) ); trainingIdx = 1:idx; trainingDataTbl = vehicleDataset(shuffledIndices(trainingIdx),:); calibrationIdx = idx+1 : idx + 1 + floor(0.1 * length(shuffledIndices) ); calibrationDataTbl = vehicleDataset(shuffledIndices(calibrationIdx),:); validationIdx = calibrationIdx(end)+1 : length(shuffledIndices); validationDataTbl = vehicleDataset(shuffledIndices(validationIdx),:);
Используйте imageDatastore
и boxLabelDatastore
создать хранилища данных для загрузки изображения и данных о метке во время обучения и оценки.
imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,'vehicle')); imdsCalibration = imageDatastore(calibrationDataTbl{:,'imageFilename'}); bldsCalibration = boxLabelDatastore(calibrationDataTbl(:,'vehicle')); imdsValidation = imageDatastore(validationDataTbl{:,'imageFilename'}); bldsValidation = boxLabelDatastore(validationDataTbl(:,'vehicle'));
Объедините изображение и хранилища данных метки поля.
trainingData = combine(imdsTrain,bldsTrain); calibrationData = combine(imdsCalibration,bldsCalibration); validationData = combine(imdsValidation,bldsValidation);
Отобразите одно из учебных изображений и меток поля.
data = read(calibrationData);
I = data{1};
bbox = data{2};
annotatedImage = insertShape(I,'Rectangle',bbox);
annotatedImage = imresize(annotatedImage,2);
figure
imshow(annotatedImage)
Чтобы уменьшать вычислительную стоимость выполнения примера, задайте сетевой входной размер, который соответствует минимальному размеру, требуемому запускать сеть.
inputSize = []; switch detectorType case 1 inputSize = [300 300 3]; % Minimum size for SSD case 2 inputSize = [224 224 3]; % Minimum size for YOLO v2 end
Задайте количество классов объектов, чтобы обнаружить.
numClasses = width(vehicleDataset)-1;
Увеличение данных используется, чтобы улучшить сетевую точность путем случайного преобразования исходных данных во время обучения. При помощи увеличения данных можно добавить больше разнообразия в обучающие данные, на самом деле не имея необходимость увеличить число помеченных обучающих выборок.
Используйте преобразования, чтобы увеличить обучающие данные:
Случайным образом зеркальное отражение изображения и сопоставленного поля помечает горизонтально.
Случайным образом масштабируя изображение и сопоставленные метки поля.
Дрожание цвет изображения.
Обратите внимание на то, что увеличение данных не применяется к тестовым данным. Идеально, тестовые данные является представительным для исходных данных и оставленный немодифицированный для несмещенной оценки.
augmentedCalibrationData = transform(calibrationData,@augmentVehicleData);
Визуализируйте увеличенные обучающие данные путем чтения того же изображения многократно.
augmentedData = cell(4,1); for k = 1:4 data = read(augmentedCalibrationData); augmentedData{k} = insertShape(data{1},'Rectangle',data{2}); reset(augmentedCalibrationData); end figure montage(augmentedData,'BorderSize',10)
Предварительно обработайте увеличенные калибровочные данные, чтобы подготовиться к калибровке сети.
preprocessedCalibrationData = transform(augmentedCalibrationData,@(data)preprocessVehicleData(data,inputSize));
Считайте предварительно обработанные калибровочные данные.
data = read(preprocessedCalibrationData);
Отобразите поля изображения и ограничительные рамки.
I = data{1};
bbox = data{2};
annotatedImage = insertShape(I,'Rectangle',bbox);
annotatedImage = imresize(annotatedImage,2);
figure
imshow(annotatedImage)
Загрузите предварительно обученный детектор.
switch detectorType case 1 % Load pretrained SSD detector for the example. pretrained = load('ssdResNet50VehicleExample_20a.mat'); detector = pretrained.detector; case 2 % Load pretrained YOLO v2 detector for the example. pretrained = load('yolov2ResNet50VehicleExample_19b.mat'); detector = pretrained.detector; end
Как быстрый тест, запустите детектор на одном тестовом изображении.
data = read(calibrationData);
I = data{1,1};
I = imresize(I,inputSize(1:2));
[bboxes,scores] = detect(detector,I, 'Threshold', 0.4);
Отобразите результаты.
I = insertObjectAnnotation(I,'rectangle',bboxes,scores);
figure
imshow(I)
Оцените обученный детектор объектов на большом наборе изображений, чтобы измерить уровень. Computer Vision Toolbox™ обеспечивает функции, чтобы измерить общие метрики детектора объектов, такие как средняя точность (evaluateDetectionPrecision
) и средние журналом коэффициенты непопаданий (evaluateDetectionMissRate
). В данном примере используйте среднюю метрику точности, чтобы оценить эффективность. Средняя точность обеспечивает один номер, который включает способность детектора сделать правильные классификации (precision
) и способность детектора найти все соответствующие объекты (recall
).
Примените к тестовым данным то же преобразование предварительной обработки, что и к обучающим данным. Обратите внимание на то, что увеличение данных не применяется к тестовым данным. Идеально, тестовые данные является представительным для исходных данных и оставленный немодифицированный для несмещенной оценки.
preprocessedValidationData = transform(validationData,@(data)preprocessVehicleData(data,inputSize));
Запустите детектор на всех тестовых изображениях.
detectionResults = detect(detector, preprocessedValidationData,'Threshold',0.4);
Оцените детектор объектов с помощью средней метрики точности.
[ap,recall,precision] = evaluateDetectionPrecision(detectionResults,preprocessedValidationData);
Точность/отзыв (PR), который подсвечивает кривая, насколько точный детектор на различных уровнях отзыва. Идеально, точность 1 на всех уровнях отзыва. Используя большее количество данных может помочь улучшить среднюю точность, но может потребовать большего количества учебного времени. Постройте кривую PR.
figure plot(recall,precision) xlabel('Recall') ylabel('Precision') grid on title(sprintf('Average Precision = %.2f',ap))
Создайте dlquantizer
возразите и задайте детектор, чтобы квантовать. По умолчанию среда выполнения установлена в графический процессор. Чтобы узнать о продуктах, требуемых квантовать и развернуть детектор в среду графического процессора, смотрите Необходимые условия Рабочего процесса Квантования.
quantObj = dlquantizer(detector)
quantObj = dlquantizer with properties: NetworkObject: [1×1 yolov2ObjectDetector] ExecutionEnvironment: 'GPU'
Задайте метрическую функцию в dlquantizationOptions
объект.
quantOpts = dlquantizationOptions; quantOpts = dlquantizationOptions('MetricFcn', ... {@(x)hVerifyDetectionResults(x, detector.Network, preprocessedValidationData)});
Используйте calibrate
функционируйте, чтобы осуществить сеть с демонстрационными входными параметрами и собрать информацию области значений. calibrate
функционируйте осуществляет сеть и собирает динамические диапазоны весов и смещений в свертке и полносвязных слоях сети, а также динамические диапазоны активаций во всех слоях сети. Функция возвращает таблицу. Каждая строка таблицы содержит информацию об области значений для настраиваемого параметра оптимизированной сети.
calResults = calibrate(quantObj,preprocessedCalibrationData)
calResults=147×5 table
Optimized Layer Name Network Layer Name Learnables / Activations MinValue MaxValue
____________________________________________ _____________________ ________________________ ________ ________
{'conv1_activation_1_relu_Weights' } {'activation_1_relu'} "Weights" -9.3984 9.511
{'conv1_activation_1_relu_Bias' } {'activation_1_relu'} "Bias" -2.6468 6.3474
{'res2a_branch2a_activation_2_relu_Weights'} {'activation_2_relu'} "Weights" -0.85967 0.35191
{'res2a_branch2a_activation_2_relu_Bias' } {'activation_2_relu'} "Bias" -5.0999 5.6429
{'res2a_branch2b_activation_3_relu_Weights'} {'activation_3_relu'} "Weights" -0.24903 0.32103
{'res2a_branch2b_activation_3_relu_Bias' } {'activation_3_relu'} "Bias" -2.749 5.1706
{'res2a_branch1_Weights' } {'bn2a_branch1' } "Weights" -2.4565 1.1476
{'res2a_branch1_Bias' } {'bn2a_branch1' } "Bias" -5.3913 22.913
{'res2a_branch2c_activation_4_relu_Weights'} {'activation_4_relu'} "Weights" -1.6711 1.6394
{'res2a_branch2c_activation_4_relu_Bias' } {'activation_4_relu'} "Bias" -6.8159 9.2926
{'res2b_branch2a_activation_5_relu_Weights'} {'activation_5_relu'} "Weights" -0.46713 0.34267
{'res2b_branch2a_activation_5_relu_Bias' } {'activation_5_relu'} "Bias" -2.9678 3.5533
{'res2b_branch2b_activation_6_relu_Weights'} {'activation_6_relu'} "Weights" -0.42871 0.57949
{'res2b_branch2b_activation_6_relu_Bias' } {'activation_6_relu'} "Bias" -2.697 2.1982
{'res2b_branch2c_activation_7_relu_Weights'} {'activation_7_relu'} "Weights" -1.1761 1.3237
{'res2b_branch2c_activation_7_relu_Bias' } {'activation_7_relu'} "Bias" -4.9467 5.1857
⋮
Используйте validate
функция, чтобы квантовать настраиваемые параметры в слоях свертки сети и осуществить сеть. Функция использует метрическую функцию, заданную в dlquantizationOptions
объект сравнить результаты сети до и после квантования.
Исследуйте MetricResults.Result
поле валидации выход, чтобы видеть эффективность квантованной сети. Первая строка в таблице результатов содержит информацию для исходной, реализации с плавающей точкой. Вторая строка содержит информацию для квантованной реализации. Вывод метрической функции отображен в MetricOutput
столбец.
valResults = validate(quantObj,preprocessedValidationData,quantOpts)
valResults = struct with fields:
NumSamples: 88
MetricResults: [1×1 struct]
Statistics: [2×2 table]
valResults.MetricResults.Result
ans=2×2 table
NetworkImplementation MetricOutput
_____________________ ____________
{'Floating-Point'} 0.77119
{'Quantized' } 0.75244
Метрики показывают, что квантование уменьшает необходимую память приблизительно на 75% и сетевую точность приблизительно на 3%.
Чтобы визуализировать калибровочную статистику, используйте приложение Deep Network Quantizer. Во-первых, сохраните dlquantizer
объект.
save('dlquantObj.mat','quantObj')
В Командном окне MATLAB® откройте приложение Deep Network Quantizer.
deepNetworkQuantizer
Затем импортируйте dlquantizer
объект dq
в приложении Deep Network Quantizer путем выбора New> Import dlquantizer
объект.
После того, как вы обучите и оцените детектор, можно сгенерировать код для ssdObjectDetector
или yolov2ObjectDetector
использование GPU Coder™. Для получения дополнительной информации смотрите Генерацию кода для Обнаружения объектов при помощи Одного Детектора Мультиполя Выстрела (Computer Vision Toolbox) и Генерация кода для Обнаружения объектов при помощи YOLO v2.
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; % Check compute capability of GPU gpuInfo = gpuDevice; cc = gpuInfo.ComputeCapability; % Create deep learning code generation configuration object cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); % INT8 precision requires a CUDA GPU with minimum compute capability of % 6.1, 6.3, or higher cfg.GpuConfig.ComputeCapability = cc; cfg.DeepLearningConfig.DataType = 'int8'; cfg.DeepLearningConfig.CalibrationResultFile = 'dlquantObj.mat';
Запустите codegen
команда, чтобы сгенерировать код CUDA.
codegen -config cfg mynet_detect -args {coder.Constant(detectorType), ones(inputSize, 'single')} -report
Когда генерация кода успешна, можно просмотреть получившийся отчет генерации кода путем нажатия на View Report в командном окне MATLAB. Отчет отображен в окне Report Viewer. Если генератор кода обнаруживает ошибки или предупреждения во время генерации кода, отчет описывает проблемы и обеспечивает ссылки на проблематичный код MATLAB. См. Отчеты Генерации кода.
[1] Лю, Вэй, Драгомир Ангуелов, Думитру Эрхэн, Кристиан Сзеджеди, Скотт Рид, Ченг Янг Фу и Александр К. Берг. "SSD: Один Детектор Мультиполя Выстрела". В Компьютерном зрении - ECCV 2016, отредактированный Бастианом Лайбе, Иржи Матасом, Nicu Sebe и Максом Веллингом, 9905:21-37. Хан: Springer International Publishing, 2016. https://doi.org/10.1007/978-3-319-46448-0_2
[2] Redmon, Джозеф и Али Фархади. "YOLO9000: Лучше, Быстрее, Более сильный". На 2 017 Конференциях по IEEE по Компьютерному зрению и Распознаванию образов (CVPR), 6517-25. Гонолулу, HI: IEEE, 2017. https://doi.org/10.1109/CVPR.2017.690
dlquantizer
(Deep Learning Toolbox) | dlquantizationOptions
(Deep Learning Toolbox) | calibrate
(Deep Learning Toolbox) | validate
(Deep Learning Toolbox) | coder.loadDeepLearningNetwork
| codegen