量子化れ深层学习ネットワークの生成生成
深層学習では、畳み込み層などのさまざまな処理層を含むニューラル ネットワーク アーキテクチャが使用されます。深層学習モデルは通常、ラベル付きデータの大量のセットに対して動作します。これらのモデルの学習や推論の実行には多くの計算量が必要になるので、大量のメモリが消費されます。ニューラル ネットワークでは、入力がネットワーク経由で伝播するときに、各層からの入力データ、パラメーター (重み)、および活性化を保存するためにメモリが使用されます。事前学習済みのニューラル ネットワークと Deep Learning Toolbox™ を使用して学習されたニューラル ネットワークのほとんどで、単精度浮動小数点データ型が使用されます。小規模なネットワークでも、これらの浮動小数点算術演算を実行するには大量のメモリとハードウェアが必要です。このような制限は、計算能力が低く、メモリ リソースが少ない場合にデバイスへの深層学習モデルの展開を妨げる可能性があります。重みと活性化を保存するための精度を下げることによって、ネットワークのメモリ要件を緩和させることができます。
深度学习工具箱と深度学习工具箱模型量化库サポートサポートをし,层层,,バイアス,,およびおよび化をををビットビットビットにされた整数整数データ化にに化化するするするするするするするすることによってによってメモリGPU Coder™ををを使用ししてて,,量子量子化化されれたたたネットワークネットワークにに最适®コードをでき。生成されたコードは,®CUDA Deep Neural Network library (cuDNN) または TensorRT™ の高性能な推論ライブラリを利用します。また、生成されたコードは、ソース コード、スタティック ライブラリ、またはダイナミック ライブラリ、あるいは、さまざまな NVIDIA GPU プラットフォームに展開できる実行可能ファイルとしてプロジェクトに統合できます。
量子化ネットワークを使用した GPU での画像分類
この例では、GPU Coder を使用して量子化された深層畳み込みニューラル ネットワークの CUDA コードを生成し、イメージを分類します。この例では、事前学習済みのsqueezenet
(深度学习工具箱)畳み込みニューラル ネットワークを使用して、量子化されたネットワークの転送学習、量子化、および CUDA コード生成を行う方法を示します。
Squeezenetは100万枚超えるイメージで学习ておりをををををををををを个个のカテゴリカテゴリカテゴリカテゴリカテゴリカテゴリカテゴリカテゴリ(特徴表现ています。ネットワークはイメージを取り,イメージイメージ内内ののオブジェクトのラベルをを各オブジェクトオブジェクトオブジェクトカテゴリカテゴリのの
サードパーティの必要条件
必須
CUDA 対応 NVIDIA® GPU および互換性のあるドライバー。
オプション
スタティック ライブラリ、ダイナミック ライブラリ、または実行可能ファイルなどの MEX 以外のビルドについて、この例では以下の要件も適用されます。
NVIDIA CUDA Toolkit。
NVIDIA cuDNN ライブラリ。
コンパイラおよびライブラリの環境変数。詳細は、サードパーティハードウェアと前提条件なる制品の设定を参照しください。
Squeezenetを使用し学习学习
新しいのに対してを実行するには,転移学习学习ののののののののののののの畳み込み畳み込み畳み込み畳み込み畳み込み畳み込みネットワークを微调整微调整ししますます。。転移学习学习でははは,开始としてでき。通常,転移学习によってネットワークを方方がが,,ランダムランダムランダムにに初期化さされれたた重み重みででゼロゼロからからネットワークネットワークにににに学习さよりもももも学习イメージし,新しいタスク学习済み特徴高速に転移転移ます。
学習データの読み込み
新しいイメージを解凍してイメージ データストアとして読み込みます。関数imageDatastore
は,にてイメージに自动ラベルを付け,このをImageDatastore
として格纳。イメージデータストア使用使用と,メモリメモリないデータデータなどなどののの大きな大きなイメージをを格纳格纳しし,,畳み込みニューラルニューラルネットワークのの学习中にイメージイメージバッチ70%をををのの。分割にを学习学习しししししししししししし30%ををにににsplitEachLabel
は、imds
データストアを 2 つの新しいデータストアに分割します。
解压缩('MerchData.zip');imds = imageDatastore('MerchData',...“包括橡皮folders”,真的,...“ Labelsource”,“折叠式”);[imdsTrain,imdsValidation] = splitEachLabel(imds,0.7,“随机”);numTrainImages = numel(imdsTrain.Labels); idx = randperm(numTrainImages,4); img = imtile(imds,'Frames', idx); figure imshow(img) title('Random Images from Training Dataset');
事前学习のネットワークの読み込み
事前学習済みの SqueezeNet ネットワークを読み込みます。必要なサポート パッケージがインストールされていない場合、ダウンロード用リンクが表示されます。
网= squeezenet;
オブジェクト网
にはdagnetwork
オブジェクトが格納されています。最初の層であるイメージ入力層には、サイズが 227 x 227 x 3 の入力イメージが必要です。ここで、3 はカラー チャネルの数です。関数analyzeNetwork
(深度学习工具箱)を使用てネットワークアーキテクチャ的に可视てて表示し,,ネットワークネットワーク关するエラーや问题问题を検出してて,ネットワークネットワークに详细详细情报情报情报情报情报情报ををを,层と学习可能パラメーターパラメーター学习ななパラメーターの総数,および再再帰层の状态状态パラメーターのののサイズサイズ
inputSize = net.Layers(1).InputSize;
最後の層の置き換え
の畳み込み,入力イメージを分类ために最后最后最后可能ななとと最终最终最终最终分类分类分类分类分类分类分类层层层层层がが使用使用するするするするイメージイメージイメージイメージイメージののの特徴特徴をを'conv10'
および'ClassificationLayer_predictions'
は、ネットワークによって抽出された特徴を組み合わせてクラス確率、損失値、および予測ラベルにまとめる方法に関する情報を含んでいます。
新しいイメージを分類するために事前学習済みのネットワークを再学習させるには、これら 2 つの層を新しいデータセットに適応させた新しい層に置き換えます。これは手動で行うことも、補助関数Findlayerstoreplace
を使用してこれらの層を自動的に見つけることもできます。
lgraph = layerGraph(net); [learnableLayer,classLayer] = findLayersToReplace(lgraph); numClasses = numel(categories(imdsTrain.Labels)); newConvLayer = convolution2dLayer([1, 1],numClasses,'WeightLearnRateFactor',...10,'biaslearnrateFactor',10,"Name",'new_conv');lgraph = replaceLayer(lgraph,'conv10',newConvLayer); newClassificatonLayer = classificationLayer(' Name','new_classoutput');lgraph = replaceLayer(lgraph,'ClassificationLayer_predictions',new Classificatonlayer);
ネットワークの学習
ネットワークにはサイズが 227 x 227 x 3 の入力イメージが必要ですが、イメージ データストアにあるイメージのサイズは異なります。拡張イメージ データストアを使用して学習イメージのサイズを自動的に変更します。学習イメージに対して実行する追加の拡張演算として、学習イメージを縦軸に沿ってランダムに反転させる演算や、水平方向および垂直方向に最大 30 ピクセルだけランダムに平行移動させる演算を指定します。データ拡張は、ネットワークで過適合が発生したり、学習イメージの正確な詳細が記憶されたりすることを防止するのに役立ちます。
PixelRange = [-30 30];ImageAugmenter = Imagedataaugmenter(...'RandXReflection',真的,...'RandXTranslation',PixelRange,...'RandYTranslation',pixelRange); augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain,...'DataAugmentation',imageAugmenter);
他のデータ拡張を実行せずに検証イメージのサイズを自動的に変更するには、追加の前処理演算を指定せずに拡張イメージ データストアを使用します。
augimdsValidation = augmentedImagedatastore(inputsize(1:2),imdsvalidation);
学習オプションを指定します。転移学習の場合、事前学習済みのネットワークの初期の層からの特徴 (転移された層の重み) を保持します。転移層での学習速度を下げるため、初期学習率を小さい値に設定します。上記の手順では、畳み込み層の学習率係数を大きくして、新しい最後の層での学習時間を短縮しています。この学習率設定の組み合わせによって、新しい層でのみ学習が急速に進み、他の層での学習速度は低下します。転移学習の実行時には、同じエポック数の学習を行う必要はありません。エポックとは、学習データセット全体の完全な学習サイクルのことです。エポックごとにすべてのデータが考慮されるように、ミニバッチのサイズを 11 に指定します。学習中は验证频率
回のごとネットワークがされます。
选项=训练('sgdm',...“ MINIBATCHSIZE”,11,...“ maxepochs”7...'InitialLearnRate',2e-4,...'Shuffle',“每个段”,...'验证data',augimdsValidation,...“验证频率”,3,...'Verbose',错误的,...“阴谋”,“训练过程”);
転移層と新しい層とで構成されるネットワークに学習させます。
NetTransfer = Trainnetwork(AugimdsTrain,Lgraph,选项);
classNames = netTransfer.Layers(end).Classes; save('mySqueezenet.mat','netTransfer');
ネットワークの量子化
dlquantizer
オブジェクトを,量子するネットワークをし。。。
QUANTOBJ = dlQuantizer(NetTransfer);
量子ののの动作比较するに使用れるメトリクス关数を定义定义。。。
类型('hcomputemodelaccuracy.m');
函数精度= hComputeModelAccuracy(预测法onScores, net, dataStore) %% Computes model-level accuracy statistics % Load ground truth tmp = readall(dataStore); groundTruth = tmp.response; % Compare with predicted label with actual ground truth predictionError = {}; for idx=1:numel(groundTruth) [~, idy] = max(predictionScores(idx,:)); yActual = net.Layers(end).Classes(idy); predictionError{end+1} = (yActual == groundTruth(idx)); %#ok end % Sum all prediction errors. predictionError = [predictionError{:}]; accuracy = sum(predictionError)/numel(predictionError); end
dlquantizationOptions
オブジェクトのメトリクス関数を指定します。
量子='MetricFcn',...{@(x)hComputeModelAccuracy(x,netTransfer,augimdsValidation)});
関数校准
を使用して、サンプル入力でネットワークを実行し、範囲情報を収集します。関数校准
は、ネットワークを実行し、ネットワークの畳み込み層と全結合層の重みとバイアスのダイナミック レンジ、およびネットワークのすべての層内の活性化のダイナミック レンジを収集します。この関数はテーブルを返します。テーブルの各行に、最適化されたネットワークの学習可能パラメーターの範囲情報が含まれています。
calResults = calibrate(quantObj,augimdsTrain); save('squeezenetCalResults.mat','calResults');save('squeezenetquantobj.mat','quantObj');
関数证实
を使用して、ネットワークの畳み込み層内の学習可能パラメーターを量子化し、ネットワークを実行することができます。この関数は、量子化の前後のネットワークの結果を比較するためにdlquantizationOptions
オブジェクトで定義されたメトリクス関数を使用します。
valresults = validate(QuantObj,AugimdSvalidation,Quantopts);
エントリポイント関数の作成
MATLAB で次を行うエントリポイント関数を記述します。
関数
coder.loadDeepLearningNetwork
を使用深层学习を読み込み,,,クラスクラス作成て设定する。详细详细は,,コード生成の学习済みのネットワーク読み込み読み込みを参照しください。関数
预测
を呼び出し応答を予测。。
类型('precadive_int8.m');
功能out = predict_int8(netFile, in) persistent mynet; if isempty(mynet) mynet = coder.loadDeepLearningNetwork(netFile); end out = predict(mynet,in); end
永続オブジェクトmynet
はdagnetwork
オブジェクトを。ポイント关数への呼び出しで永続オブジェクトオブジェクトが作成作成さされれててささますますます。。。后続后続后続预测
に同じオブジェクトが再利用され、ネットワーク オブジェクトの再構成と再読み込みが回避されます。
メモ
キャリブレーション ステップと検証ステップで実行されたすべての前処理演算が設計ファイルに必ず含まれるようにしてください。
代码根
を使用したコード生成
出力ファイル名、場所、タイプなどのビルド設定を構成するには、コーダー構成オブジェクトを作成します。このオブジェクトを作成するには、関数coder.gpuconfig
を使用ます。たとえば,代码根
コマンドを使用して CUDA MEX を生成する場合、cfg = coder.gpuconfig('mex');
を使用します。
cuDNN のコード生成パラメーターを指定するには、DeepLearningConfig
プロパティを,coder.DeepLearningConfig
を使用して作成したcoder.CuDNNConfig
オブジェクトに设定ます。
cfg = coder.gpuConfig('mex');cfg.targetlang ='C ++';cfg.GpuConfig.ComputeCapability ='6.1';cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');cfg.deeplearningconfig.autuning = true;cfg.deeplearningconfig.calibrationResultFile ='squeezenetquantobj.mat';cfg.DeepLearningConfig.DataType ='int8';
キャリブレーション含む含む含むファイル场所を指定し。。。
DataType
プロパティを使用することによって、サポートされている層での推論計算の精度を指定します。8 ビット整数には、'int8'
を使用ます。コードのの计算能力
プロパティを使用して、適切な Compute Capability 値に設定します。
代码根
コマンドを実行ます。代码根
コマンドは、MATLAB エントリポイント関数predive_int8.m
から CUDA コードを生成します。
输入= {coder.constant('mySqueezenet.mat'),ones(inputSize,'uint8')}; codegen-configcfg-argsinputspredive_int8
代码生成成功。
コード生成に成功したら、MATLAB コマンド ウィンドウで[レポートの表示]をクリックすることで、結果のコード生成レポートを表示できます。レポートがレポート ビューアー ウィンドウに表示されます。コード生成時にコード ジェネレーターによりエラーまたは警告が検出されると、レポートでは問題が説明され、問題のある MATLAB コードへのリンクが提供されます。
生成された MEX の実行
分類するイメージのサイズは、ネットワークの入力サイズと同じでなければなりません。分類するイメージを読み取り、そのサイズをネットワークの入力サイズに変更します。このサイズ変更では、イメージの縦横比が多少変化します。
testImage = imread(“ merchdatatest.jpg”);testImage = imresize(testImage,inputSize(1:2));
入力イメージに対して SqueezeNet の predict を呼び出します。
predivectscores(::,1)= preditive(netTransfer,sistimage)';predivectscores(::,2)= predition_int8_mex('mySqueezenet.mat',证词);
予测ラベルそれら対応确率をヒストグラム表示します。
h = figure; h.Position(3) = 2*h.Position(3); ax1 = subplot(1,2,1); ax2 = subplot(1,2,2); image(ax1,testImage); barh(ax2,predictScores) xlabel(ax2,'Probability')yticklabels(ax2,classNames)ax2.xlim = [0 1.1];ax2.yaxislocation ='剩下';传奇('Matlab Single','Cudnn 8位整数');sgtitle('Predictions using Squeezenet')
補助関数
功能[learnableLayer,classLayer] = findLayersToReplace(lgraph)%FindlayerStore(Lgraph)找到单个分类层和%在该层的可学习(完全连接或卷积)层% graph lgraph.if〜Isa(lgraph,'nnet.cnn.LayerGraph') error(“参数必须是一个layergraph对象。”)end% Get source, destination, and layer names.src = string(lgraph.Connections.Source); dst = string(lgraph.Connections.Destination); layerNames = string({lgraph.Layers.Name}');%找到分类层。图层图必须有一个%分类层。isClassificationLayer = arrayfun(@(l)...(isa(l,'nnet.cnn.layer.ClassificationOutputLayer')...| isa(l,'nnet.layer.ClassificationLayer')),...lgraph.Layers);ifsum(isClassificationLayer)〜= 1错误('Layer graph must have a single classification layer.')endclassLayer = lgraph.Layers(isClassificationLayer);% Traverse the layer graph in reverse starting from the classification% layer. If the network branches, throw an error.CurrentLayerIdx = find(isClassificationLayer);尽管真的ifnumel(currentLayerIdx) ~= 1 msg = ['Layer graph must have a single learnable layer '...“在分类层之前。”]; error(msg)endcurrentLayerType = class(lgraph.Layers(currentLayerIdx)); isLearnableLayer = ismember(currentLayerType,...['nnet.cnn.layer.FullyConnectedLayer','nnet.cnn.layer.Convolution2DLayer');ifisLearnableLayer learnableLayer = lgraph.Layers(currentLayerIdx);returnendcurrentDstIdx = find(layerNames(currentLayerIdx) == dst); currentLayerIdx = find(src(currentDstIdx) == layerNames);endend
制限
cuDNN version 8.1.0 を使用して
int8
の精度で推論を実行する場合、NVIDIA ライブラリの問題により、パフォーマンスが大幅に低下する可能性があります。NVIDIA CUDA Deep Neural Network library (cuDNN) ライブラリを対象にする場合は、8 ビット整数の量子化で以下の層がサポートされません。
leakyReluLayer
剪辑器
globalaveragePooling2Dlayer
参考
アプリ
- 深网量化(深度学习工具箱)
関数
dlquantizer
(深度学习工具箱)|dlquantizationOptions
(深度学习工具箱)|校准
(深度学习工具箱)|证实
(深度学习工具箱)|coder.loadDeepLearningNetwork
|代码根