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

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

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

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

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

Сгенерируйте код 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 функция. Для примера при генерации 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

См. также

Приложения

Функции

Похожие темы