Квантуйте остаточную сеть, обученную для классификации изображений, и сгенерируйте код CUDA

В этом примере показано, как квантовать настраиваемые параметры в слоях свертки глубокой нейронной сети, которая имеет остаточные связи и была обучена классификации изображений с данными 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);

Квантуйте сеть для развертывания графического процессора Используя приложение Deep Network Quantizer

Этот пример использует среду выполнения графического процессора. Чтобы узнать о продуктах, требуемых квантовать и развернуть нейронную сеть для глубокого обучения в среду графического процессора, смотрите Необходимые условия Рабочего процесса Квантования.

В Командном окне 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

Сгенерируйте код CUDA® для квантованной глубокой сверточной нейронной сети.

Создайте функцию точки входа

Напишите функцию точки входа в MATLAB® что:

  1. Использует coder.loadDeepLearningNetwork функционируйте, чтобы загрузить модель глубокого обучения и создать и настроить класс CNN. Для получения дополнительной информации смотрите Предварительно обученные сети Загрузки для Генерации кода.

  2. Вызовы 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

Смотрите также

Приложения

Функции

Похожие темы