В этом примере показано, как квантовать настраиваемые параметры в слоях свертки глубокой нейронной сети, которая имеет остаточные связи и была обучена классификации изображений с данными CIFAR-10.
Нейронные сети используют память, чтобы сохранить входные данные, параметры (веса) и активации от каждого слоя, когда вход распространяет через сеть. Большинство нейронных сетей, что вы создаете и обучаете использование использование Deep Learning Toolbox™ типы данных с плавающей запятой с одинарной точностью. Даже маленькие сети требуют, чтобы значительный объем памяти и оборудование выполнили эти арифметические операции с плавающей точкой. Эти ограничения могут запретить развертывание моделей глубокого обучения к устройствам, которые имеют низкую вычислительную силу и меньше ресурсов памяти. При помощи более низкой точности, чтобы сохранить веса и активации, можно уменьшать требования к памяти сети.
В этом примере вы используете Deep Learning Toolbox в тандеме с пакетом поддержки Библиотеки Квантования Модели Deep Learning Toolbox, чтобы уменьшать объем потребляемой памяти глубокой нейронной сети путем квантования весов, смещений и активаций слоев свертки к 8-битным масштабированным целочисленным типам данных.
Сеть в этом примере была обучена для классификации изображений с данными CIFAR-10.
Остаточные связи являются популярным элементом в архитектурах сверточной нейронной сети. Остаточная сеть является типом сети DAG, которая имеет невязку (или ярлык) связи, которые обходят основные слоя сети. Остаточные связи позволяют градиентам параметра распространить более легко от выходного слоя до более ранних слоев сети, которая позволяет обучить более глубокие сети. Эта увеличенная сетевая глубина может привести к более высокой точности на более трудных задачах. Для получения информации о сетевой архитектуре и обучении, смотрите, Обучают Остаточную Сеть для Классификации Изображений.
Чтобы запустить этот пример, необходимо было потребовать, чтобы продукты квантовали и развернули нейронную сеть для глубокого обучения в среду графического процессора. Для получения информации об этих продуктах смотрите Необходимые условия Рабочего процесса Квантования.
Загрузите предварительно обученную сеть. Для получения информации о создании и обучении сети с остаточными связями для классификации изображений самостоятельно, смотрите, Обучают Остаточную Сеть для Классификации Изображений.
load('CIFARNet-20-16.mat','trainedNet'); net = trainedNet;
Остаточная сетевая архитектура состоит из этих компонентов:
Основная ветвь со сверточным, нормализацией партии. и слоями ReLU, соединенными последовательно.
Остаточные связи, которые обходят сверточные модули основной ветви. Остаточные связи позволяют градиентам параметра течь более легко от выходного слоя до более ранних слоев сети, которая позволяет обучить более глубокие сети.
Основная ветвь сети содержит пять разделов.
Начальный раздел, содержащий изображение, ввел слой и начальную свертку с активацией.
Три этапа сверточных слоев с различными размерами элемента (32 32, 16 16, и 8 8). Каждый этап содержит сверточные модули N. Каждый сверточный модуль содержит 3х3 сверточные слои N с активациями.
Итоговый раздел с глобальным средним объединением, полностью соединенным, softmax, и слои классификации.
Обучивший сеть trainedNet
график слоев для данных CIFAR-10 с остаточными связями.
netWidth
сеть width, заданная, когда количество просачивается первые 3х3 сверточные слои сети.
numUnits
количество сверточных модулей в основной ветви сети. Поскольку сеть состоит из трех этапов, где каждый этап имеет то же количество сверточных модулей, numUnits
должно быть целочисленное кратное 3.
unitType
тип сверточного модуля в виде "standard"
или "bottleneck"
. Стандартный сверточный модуль состоит из двух 3х3 сверточных слоев. Узкое место сверточный модуль состоит из трех сверточных слоев: слой 1 на 1 для субдискретизации в размерности канала, 3х3 сверточный слой и слой 1 на 1 для повышающей дискретизации в размерности канала. Следовательно, узкое место сверточный модуль имеет на 50% более сверточные слои, чем стандартный модуль, но только половину количества пространственных 3х3 сверток. Два модульных типа имеют подобную вычислительную сложность, но общее количество распространения функций в остаточных связях в четыре раза больше, когда вы используете модули узкого места. Общая глубина, заданная как максимальное количество сверточных последовательных и полносвязные слоя, 2*numUnits
+ 2 для сетей со стандартными модулями и 3*numUnits
+ 2 для сетей с модулями узкого места.
Можно использовать analyzeNetwork
анализировать архитектуру нейронной сети для глубокого обучения.
analyzeNetwork(net)
Загрузите набор данных CIFAR-10 [1] путем выполнения кода ниже. Набор данных содержит 60 000 изображений. Каждое изображение находится 32 32 в размере и имеет три цветовых канала (RGB). Размер набора данных составляет 175 Мбайт. В зависимости от вашего интернет-соединения может занять время процесс загрузки.
datadir = tempdir; downloadCIFARData(datadir);
Загрузите обучение CIFAR-10 и протестируйте изображения как 4-D массивы. Набор обучающих данных содержит 50 000 изображений, и набор тестов содержит 10 000 изображений. Используйте тестовые изображения CIFAR-10 для сетевой валидации.
[XTrain,YTrain,XValidation,YValidation] = loadCIFARData(datadir);
Можно отобразить случайную выборку учебных изображений с помощью следующего кода.
figure;
idx = randperm(size(XTrain,4),20);
im = imtile(XTrain(:,:,:,idx),'ThumbnailSize',[96,96]);
imshow(im)
Создайте augmentedImageDatastore
возразите, чтобы использовать для калибровки и валидации. Используйте 200 случайных изображений для калибровки и 50 случайных изображений для валидации.
inputSize = net.Layers(1).InputSize; augimdsTrain = augmentedImageDatastore(inputSize,XTrain,YTrain); augimdsCalibration = shuffle(augimdsTrain).subset(1:200); augimdsValidation = augmentedImageDatastore(inputSize,XValidation,YValidation); augimdsValidation = shuffle(augimdsValidation).subset(1:50);
Этот пример использует среду выполнения графического процессора. Чтобы узнать о продуктах, требуемых квантовать и развернуть нейронную сеть для глубокого обучения в среду графического процессора, смотрите Необходимые условия Рабочего процесса Квантования.
В Командном окне MATLAB® откройте приложение Deep Network Quantizer.
deepNetworkQuantizer
Выберите New> Quantize сеть. Приложение автоматически проверяет вашу среду выполнения.
В диалоговом окне выберите среду выполнения и сеть, чтобы квантовать от базового рабочего пространства. В данном примере выберите среду выполнения GPU и сеть DAG net
.
В разделе Calibrate панели инструментов, под Калибровочными Данными, выбирают augmentedImageDatastore
объект от базового рабочего пространства, содержащего калибровочные данные augimdsCalibration
.
Нажмите Calibrate.
Deep Network Quantizer использует калибровочные данные, чтобы осуществить сеть и собрать информацию области значений для настраиваемых параметров в слоях сети.
Когда калибровка завершена, отображения приложения таблица, содержащая веса и смещения в свертке, а также полносвязные слоя сети и динамические диапазоны активаций во всех слоях сети с их минимальными и максимальными значениями во время калибровки. Справа от таблицы, гистограмм отображений приложения динамических диапазонов параметров. Серые области гистограмм указывают на данные, которые не могут быть представлены квантованным представлением. Для получения дополнительной информации о том, как интерпретировать эти гистограммы, смотрите Квантование Глубоких нейронных сетей.
В Квантовать столбце Слоя таблицы укажите, квантовать ли настраиваемые параметры в слое. Слои, которые не являются слоями свертки, не могут быть квантованы, и поэтому не могут быть выбраны. Слои, которые не квантуются, остаются в одинарной точности после квантования.
В разделе Validate панели инструментов, под Данными о Валидации, выбирают augmentedImageDatastore
объект от базового рабочего пространства, содержащего данные о валидации, augimdsValidation
.
В разделе Validate панели инструментов, в соответствии с Опциями Квантования, выбирают метрическую функцию, чтобы использовать для валидации. Приложение определяет метрическую функцию по умолчанию, чтобы использовать для валидации на основе типа сети, которую вы квантуете. Можно также добавить дополнительные пользовательские метрические функции, чтобы использовать для валидации. В данном примере введите имя пользовательской метрической функции hComputeAccuracy
. Выберите Add, чтобы добавить hComputeAccuracy
к списку метрических функций, доступных в приложении. Выберите hComputeAccuracy
как метрическая функция, чтобы использовать для валидации. Эта пользовательская метрическая функция сравнивает предсказанную метку с основной истиной и возвращает лучшую 1 точность. Пользовательская метрическая функция должна быть на пути.
Нажмите Quantize и Validate.
Приложение квантует сеть и отображает сводные данные результатов валидации. Для этого набора изображений калибровки и валидации квантование сети приводит к 2%-му уменьшению в точности с 73%-м сокращением памяти настраиваемого параметра для набора 50 изображений валидации.
После квантования и проверения сети, можно экспортировать квантованную сеть или сгенерировать код. Чтобы экспортировать квантованную сеть, выберите Export> Export Quantizer, чтобы создать dlquantizer
объект в базовом рабочем пространстве. Чтобы открыть приложение GPU Coder и сгенерировать код графического процессора от квантованной нейронной сети, выберите Export> Generate Code. Чтобы изучить, как сгенерировать код CUDA для квантованной глубокой сверточной нейронной сети с помощью GPU Coder, смотрите Генерацию кода для Квантованных Нейронных сетей для глубокого обучения.
Можно использовать несколько метрических функций, чтобы оценить эффективность квантованной сети одновременно при помощи dlquantizer
функция.
Чтобы начаться, загрузите предварительно обученную сеть и данные, и подготовьте данные к калибровке и валидации, аналогичной описанному выше.
Создайте dlquantizer
объект. Задайте сеть, чтобы квантовать и среда выполнения, чтобы использовать. Используйте calibrate
функционируйте, чтобы осуществить сеть с демонстрационными входными параметрами от augimdsCalibration
и соберите информацию области значений.
dq = dlquantizer(net,'ExecutionEnvironment','GPU'); calResults = calibrate(dq,augimdsCalibration)
calResults=72×5 table
Optimized Layer Name Network Layer Name Learnables / Activations MinValue MaxValue
_________________________________ __________________ ________________________ _________ ________
{'convInp_reluInp_Weights' } {'reluInp' } "Weights" -0.020545 0.01913
{'convInp_reluInp_Bias' } {'reluInp' } "Bias" -0.54225 2.0243
{'S1U1_conv1_S1U1_relu1_Weights'} {'S1U1_relu1'} "Weights" -0.58949 0.5883
{'S1U1_conv1_S1U1_relu1_Bias' } {'S1U1_relu1'} "Bias" -0.87623 1.9467
{'S1U1_conv2_relu11_Weights' } {'relu11' } "Weights" -0.58679 0.39988
{'S1U1_conv2_relu11_Bias' } {'relu11' } "Bias" -0.59824 1.8325
{'S1U2_conv1_S1U2_relu1_Weights'} {'S1U2_relu1'} "Weights" -0.29821 0.33049
{'S1U2_conv1_S1U2_relu1_Bias' } {'S1U2_relu1'} "Bias" -1.3102 2.0253
{'S1U2_conv2_relu12_Weights' } {'relu12' } "Weights" -0.7149 0.48284
{'S1U2_conv2_relu12_Bias' } {'relu12' } "Bias" -0.84685 1.6346
{'S1U3_conv1_S1U3_relu1_Weights'} {'S1U3_relu1'} "Weights" -0.16697 0.15356
{'S1U3_conv1_S1U3_relu1_Bias' } {'S1U3_relu1'} "Bias" -1.3796 2.1583
{'S1U3_conv2_relu13_Weights' } {'relu13' } "Weights" -0.47026 0.60147
{'S1U3_conv2_relu13_Bias' } {'relu13' } "Bias" -1.0089 1.5606
{'S2U1_conv1_S2U1_relu1_Weights'} {'S2U1_relu1'} "Weights" -0.14931 0.13792
{'S2U1_conv1_S2U1_relu1_Bias' } {'S2U1_relu1'} "Bias" -1.8735 2.4623
⋮
Задайте метрические функции в dlquantizationOptions
объект. Используйте validate
функция, чтобы квантовать настраиваемые параметры в слоях свертки сети и осуществить сеть. validate
функционируйте использует метрические функции, заданные в dlquantizationOptions
объект сравнить результаты сети до и после квантования. В данном примере используйте лучшую 1 точность, и лучшие 5 метрик точности используются, чтобы оценить эффективность сети.
dqOpts = dlquantizationOptions('MetricFcn',... {@(x)hComputeAccuracy(x,net,augimdsValidation), ... @(x)hComputeTop_5(x,net,augimdsValidation)}); validationResults = validate(dq,augimdsValidation,dqOpts)
validationResults = struct with fields:
NumSamples: 50
MetricResults: [1×2 struct]
Исследуйте MetricResults.Result
поле валидации выход, чтобы видеть эффективность квантованной сети, как измерено каждой используемой метрической функцией.
validationResults.MetricResults.Result
ans=2×3 table
NetworkImplementation MetricOutput LearnableParameterMemory(bytes)
_____________________ ____________ _______________________________
{'Floating-Point'} 0.98 1.1113e+06
{'Quantized' } 0.96 3.0057e+05
ans=2×3 table
NetworkImplementation MetricOutput LearnableParameterMemory(bytes)
_____________________ ____________ _______________________________
{'Floating-Point'} 1 1.1113e+06
{'Quantized' } 1 3.0057e+05
Чтобы визуализировать калибровочную статистику, сначала сохраните dlquantizer
объект dq.
save('dlquantObj.mat','dq')
Затем импортируйте dlquantizer
объект dq
в приложении Deep Network Quantizer путем выбора New> Import dlquantizer
объект.
Сгенерируйте код CUDA® для квантованной глубокой сверточной нейронной сети.
Напишите функцию точки входа в MATLAB® что:
Использует coder.loadDeepLearningNetwork
функционируйте, чтобы загрузить модель глубокого обучения и создать и настроить класс CNN. Для получения дополнительной информации смотрите Предварительно обученные сети Загрузки для Генерации кода.
Вызовы predict
(Deep Learning Toolbox), чтобы предсказать ответы.
type('mynet_predict.m');
function out = mynet_predict(netFile, im) persistent net; if isempty(net) net = coder.loadDeepLearningNetwork(netFile); end out = net.predict(im); end
Постоянный объект mynet
загружает DAGNetwork
объект. Первый вызов функции точки входа создает и настраивает постоянный объект. Последующие вызовы функционального повторного использования тот же объект вызвать predict
на входных параметрах, избегая восстановления и перезагрузки сетевого объекта.
codegen
Чтобы сконфигурировать настройки сборки, такие как имя выходного файла, местоположение и тип, вы создаете объекты настройки кодера. Чтобы создать объекты, используйте coder.gpuConfig
функция. Например, при генерации MEX CUDA с помощью codegen команды, используйте cfg = coder.gpuConfig('mex')
.
Чтобы задать параметры генерации кода для cuDNN, установите DeepLearningConfig
свойство к coder.CuDNNConfig
возразите, что вы создаете при помощи coder.DeepLearningConfig
.
Задайте местоположение файла MAT, содержащего калибровочные данные.
Задайте точность расчетов вывода в поддерживаемых слоях при помощи DataType
свойство. Для 8-битных целых чисел используйте 'int8'
. Точность Int8 требует, чтобы графический процессор CUDA с вычислил возможность 6,1, 6.3, или выше. Используйте ComputeCapability
свойство gpuConfig
объект установить соответствующее вычисляет значение возможности.
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); cfg.DeepLearningConfig.DataType = 'int8'; cfg.DeepLearningConfig.CalibrationResultFile = 'dlquantObj.mat'; netFile = 'mynet.mat'; save(netFile,'net');
Запустите codegen
команда. codegen
команда генерирует код CUDA от mynet_predict.m
функция точки входа.
codegen -config cfg mynet_predict -args {coder.Constant(netFile), ones(inputSize, 'single')} -report
Когда генерация кода успешна, можно просмотреть получившийся отчет генерации кода путем нажатия на View Report в командном окне MATLAB. Отчет отображен в окне Report Viewer. Если генератор кода обнаруживает ошибки или предупреждения во время генерации кода, отчет описывает проблемы и обеспечивает ссылки на проблематичный код MATLAB. См. Отчеты Генерации кода.
[1] Krizhevsky, Алекс. 2009. "Изучая Несколько Слоев Функций от Крошечных Изображений". https://www.cs.toronto.edu / ~ kriz/learning-features-2009-TR.pdf