Этот пример показов, как квантовать настраиваемые параметры в слоях свертки глубокой нейронной сети, которая имеет остаточные связи и была обучена классификации изображений с CIFAR-10 данными.
Нейронные сети используют память для хранения входных данных, параметров (весов) и активаций с каждого слоя, когда вход распространяется через сеть. Большинство нейронных сетей, которые вы создаете и обучаете с помощью Deep Learning Toolbox™, используют одноточные типы данных с плавающей точкой. Даже небольшие сети требуют значительного объема памяти и оборудования для выполнения этих арифметических операций с плавающей точкой. Эти ограничения могут препятствовать развертыванию моделей глубокого обучения на устройствах с низкой вычислительной степенью и меньшими ресурсами памяти. Используя более низкую точность для хранения весов и активаций, можно уменьшить требования сети к памяти.
В этом примере вы используете Deep Learning Toolbox в паре с пакетом поддержки Deep Learning Toolbox Model Quantization Library, чтобы уменьшить площадь памяти глубокой нейронной сети путем квантования весов, смещений и активаций слоев свертки до 8-битных масштабированных целочисленных типов данных.
Сеть в этом примере была обучена классификации изображений с CIFAR-10 данными.
Остаточные соединения являются популярным элементом в архитектурах сверточных нейронных сетей. Остаточная сеть является типом сети DAG, которая имеет остаточные (или ярлыковые) соединения, которые обходят основные слои сети. Остаточные связи позволяют градиентам параметров легче распространяться от выхода слоя к более ранним слоям сети, что позволяет обучать более глубокие сети. Это увеличение глубины сети может привести к более высоким точностям для более сложных задач. Для получения информации об архитектуре сети и обучении см. раздел «Train остаточной сети для классификации изображений».
Чтобы запустить этот пример, вы должны иметь продукты, необходимые для квантования и развертывания нейронной сети для глубокого обучения в среде графический процессор. Для получения информации об этих продуктах см. необходимые условия рабочего процесса квантования».
Загрузите предварительно обученную сеть. Для получения информации о создании и обучении сети с остаточными соединениями для самостоятельной классификации изображений смотрите Train остаточной сети для классификации изображений.
load('CIFARNet-20-16.mat','trainedNet'); net = trainedNet;
Невязка сети состоит из следующих компонентов:
Основная ветвь со сверточными, нормализацией партии . и слоями ReLU соединена последовательно.
Остаточные связи, которые обходят сверточные модули основной ветви. Остаточные связи позволяют градиентам параметра легче течь от выхода слоя к более ранним слоям сети, что позволяет обучать более глубокие сети.
Основная ветвь сети содержит пять разделов.
Начальный раздел, содержащий входной слой изображения и начальную свертку с активацией.
Три стадии сверточных слоев с различными размерами функции (32 на 32, 16 на 16 и 8 на 8). Каждый каскад содержит N сверточных модули. Каждый сверточный модуль содержит N 3 на 3 сверточных слоев с активациями.
Заключительный раздел с глобальным средним объединением, полносвязными, softmax и классификационными слоями.
Обученная сетевая trainedNet
является график слоев для CIFAR-10 данных с остаточными соединениями.
netWidth
- ширина сети, заданная как количество фильтров в первых сверточных слоях сети 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
Выберите «Создать» > «Квантовать сеть». Приложение автоматически проверяет ваше окружение выполнения.
В диалоговом окне выберите окружение выполнения и сеть для квантования из базового рабочего пространства. В данном примере выберите окружение выполнения графический процессор и сеть DAG net
.
В разделе Калибровка панели инструментов в разделе Данных калибровки выберите augmentedImageDatastore
объект из базового рабочего пространства, содержащего данные калибровки augimdsCalibration
.
Щелкните Калибровать (Calibrate).
Deep Network Quantizer использует данные калибровки для упражнения сети и сбора информации о области значений для настраиваемых параметров в слоях сети.
Когда калибровка завершена, приложение отображает таблицу, содержащую веса и смещения в свертке, а также полносвязные слои сети и динамические области значений активаций во всех слоях сети с их минимальными и максимальными значениями во время калибровки. Справа от таблицы приложение отображает гистограммы динамических областей значений параметров. Серые области гистограмм указывают данные, которые не могут быть представлены квантованным представлением. Для получения дополнительной информации о том, как интерпретировать эти гистограммы, смотрите Квантование Глубоких Нейронных Сетей.
В столбце «Слой квантования» таблицы укажите, нужно ли квантовать настраиваемые параметры в слое. Слои, которые не являются слоями свертки, не могут быть квантованы, и поэтому не могут быть выбраны. Слои, которые не квантуются, остаются с одинарной точностью после квантования.
В разделе Валидация панели инструментов в разделе Данные валидации выберите augmentedImageDatastore
объект из базового рабочего пространства, содержащего данные валидации, augimdsValidation
.
В разделе Валидация панели инструментов в разделе Опции квантования выберите метрическую функцию, которая будет использоваться для валидации. Приложение определяет метрическую функцию по умолчанию, которая будет использоваться для валидации, на основе типа сети, которую вы квантуете. Можно также добавить дополнительные пользовательские метрические функции для валидации. В данном примере введите имя пользовательской метрической функции hComputeAccuracy
. Выберите Добавить для добавления hComputeAccuracy
в список метрических функций, доступных в приложении Выберите hComputeAccuracy
как метрическая функция, используемая для валидации. Эта пользовательская функция метрики сравнивает предсказанную метку с основной истиной и возвращает точность верхнего уровня. Пользовательская функция метрики должна быть в пути.
Щелкните Квантовать и Проверить.
Приложение квантует сеть и отображает сводные данные результатов валидации. Для этого набора изображений калибровки и валидации квантование сети приводит к снижению точности на 2% с сокращением настраиваемого параметра на 73% для набора 50 изображений валидации.
После квантования и проверки сети можно экспортировать квантованную сеть или сгенерировать код. Чтобы экспортировать квантованную сеть, выберите Экспорт > Экспортом Quantzer, чтобы создать dlquantizer
объект в базовом рабочем пространстве. Чтобы открыть приложение GPU Coder и сгенерировать графический процессор из квантованной нейронной сети, выберите экспорт > 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
функция для квантования настраиваемых параметров в слоях свертки сети и осуществления сети. The 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
функция. Для примера при генерации CUDA MEX с помощью команды 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
команда. The codegen
команда генерирует код CUDA из mynet_predict.m
функция точки входа.
codegen -config cfg mynet_predict -args {coder.Constant(netFile), ones(inputSize, 'single')} -report
Когда генерация кода успешна, можно просмотреть результат отчета генерации кода, нажав View Report в Командном Окне MATLAB. Отчет отображается в окне Средство Просмотра. Если генератор кода обнаруживает ошибки или предупреждения во время генерации кода, отчет описывает проблемы и предоставляет ссылки на проблемный код MATLAB. См. «Отчеты генерации кода».
[1] Крижевский, Алекс. 2009. «Изучение нескольких слоев функций из крошечных изображений». https://www.cs.toronto.edu/~kriz/learning-features-2009-TR.pdf