メモリに制限があるハードウェアのための機械学習モデルの圧縮
この例では、メモリに制限があるハードウェアへの展開用に機械学習モデルのサイズを小さくする方法を示します。モデル圧縮ワークフローを示すために、この例では環境が発している音に基づいて環境を分類する音響シーン分類 (ASC) タスクのモデルを作成します。ASC は、デバイス、ロボット、その他の用途におけるコンテキスト アウェアネスの基礎となる汎用のマルチクラス分類問題です [1]。
使用可能なメモリ サイズが 30 KB である補聴器用のモデルを作成するとします。まず、マルチクラスの ASC タスクを単純化してバイナリ分類問題にしてから、次の手順を実行します。
重要な特徴量を選択することで特徴量の数を減らす。
機械学習モデルのサイズを制限する連結制約を使用してハイパーパラメーターを最適化する。
モデル パラメーターを量子化する。
メモリ サイズを小さくするためのハイパーパラメーターの最適化の詳細については、を参照してください。
データの読み込み
acousticscenes
データ セットを読み込み、データ セットの変数を表示します。
load("acousticscenes.mat")
whos
Name Size Bytes Class Attributes xEval 300x286 686400 double xTest 300x286 686400 double xTrain 1500x286 3432000 double yEval 300x1 2102 categorical yTest 300x1 2102 categorical yTrain 1500x1 3302 categorical
xTrain
、xEval
、および xTest
に、ウェーブレット散乱を使用して TUT 音響シーン データ セットから抽出された特徴量が格納されています。yTrain
、yEval
、および yTest
には、xTrain
、xEval
、および xTest
にそれぞれ対応する 15 種類の音響シーン ラベルが格納されています。この例では、xTrain
と yTrain
を使用してモデルに学習させ、学習させたモデルの精度を xTest
と yTest
を使用してテストします。最適化の手順では、xEval
と yEval
をホールドアウト検証セットとして使用します。
TUT 音響シーン データ セットには、開発データ (TUT-acoustic-scenes-2017-development
[3]) とテスト データ (TUT-acoustic-scenes-2017-evaluation
[4]) があります。開発データで 4 分割の交差検証設定が提供されます。xTrain
と xEval
は交差検証設定の最初の分割で定義される学習セットと評価セットのサブセットからそれぞれ取得され、xTest
はテスト データ セットのサブセットから取得されます。これらの変数を TUT 音響シーン データ セットのサブセットから取得する方法については、Acoustic Scene Recognition Using Late Fusion (Audio Toolbox)の例で説明しています。
データ セットを正規化します。
[xTrain,mu,sigma] = normalize(xTrain); xEval = normalize(xEval,center=mu,scale=sigma); xTest = normalize(xTest,center=mu,scale=sigma);
分類モデルのタイプの選択
分類学習器アプリを使用して、この例の分類モデルのタイプを選択します。
[アプリ] タブでアプリ ギャラリーを開きます。次に、[機械学習および深層学習] グループの [分類学習器] をクリックします。
[分類学習器] タブで、[ファイル] セクションの [新規セッション] をクリックし、[ワークスペースから] を選択します。ダイアログ ボックスで、応答変数として
yTrain
を指定し、予測子としてxTrain
の変数を指定します。アプリの [モデル] セクションで [すべて] をクリックします。このオプションは、選択したデータ セットに対して使用できる事前設定済みのすべてのモデルに学習させます。
[学習] セクションで、[すべてを学習] をクリックして [すべてを学習] を選択します。
学習させたモデルを精度のスコアに基づいて比較したり、クラスの予測をプロットすることで結果を可視化したり、混同行列や ROC 曲線を使用して性能をチェックしたりできます。分類学習器の詳細については、分類学習器アプリにおける分類モデルの学習を参照してください。
この例では、次の 5 つのモデル タイプを扱います。
2 層ニューラル ネットワーク
線形判別
判別分析学習器をもつランダム部分空間アンサンブル
線形 SVM
ロジスティック回帰
モデルの名前を格納する変数を作成します。
MdlNames = ["Bilayered NN","Linear Discriminant", ... "Subspace Discriminant","Linear SVM","Logistic Regression"]';
マルチクラス分類モデルの学習
コマンド ラインで近似関数を使用して 5 つのモデルに学習させてから、学習させたモデルのサイズを関数 compact
を使用して小さくします。関数 compact
により、予測に必要がない情報が破棄されます。
SVM モデルとロジスティック回帰モデルはバイナリ分類のみをサポートします。そのため、関数 fitcecoc
を使用して、線形 SVM 学習器をもつマルチクラス分類モデルとロジスティック回帰学習器をもつマルチクラス分類モデルに学習させます。ロジスティック回帰モデルには templateLinear
学習器を使用します。この場合、fitcecoc
からコンパクトなモデル オブジェクト (CompactClassificationECOC
) が返されるため、関数 compact
は使用しません。
rng("default") % For reproducibility multiMdls = cell(5,1); % Bilayered NN multiMdls{1} = compact(fitcnet(xTrain,yTrain,LayerSizes=[10 10])); % Linear Discriminant multiMdls{2} = compact(fitcdiscr(xTrain,yTrain)); % Subspace Discriminant multiMdls{3} = compact(fitcensemble(xTrain,yTrain, ... Method="Subspace",Learners="discriminant", ... NumLearningCycles=30,NPredToSample=25)); % Linear SVM multiMdls{4} = compact(fitcecoc(xTrain,yTrain)); % Logistic Regression tLinear = templateLinear(Learner="logistic"); multiMdls{5} = fitcecoc(xTrain,yTrain,Learners=tLinear);
出力の表示形式を bank
と指定し、小数点以下 2 桁まで表示します。
format("bank")
補助関数 helperMdlMetrics
を使用して、テスト データ セットでモデルをテストします。この関数は、モデルの精度 (パーセント) とモデルのサイズ (KB) を含むモデル メトリクスの table を返します。関数 helperMdlMetrics
のコードについては、この例の最後に示してあります。
multiMdlTbl = helperMdlMetrics(multiMdls,xTest,yTest); tbl1 = multiMdlTbl; tbl1.Properties.RowNames = MdlNames; disp(tbl1)
Accuracy Model Size ________ __________ Bilayered NN 54.33 36.17 Linear Discriminant 53.33 2776.71 Subspace Discriminant 50.67 881.54 Linear SVM 34.33 901.90 Logistic Regression 50.00 1937.67
モデルのサイズはいずれも 30 KB を超えており、精度の値はほとんどのモデルで約 50% です。
問題をバイナリ分類として単純化
用途が補聴器であることから、データ セットに含まれる 15 種類に音を分類するのではなく、背景音と特定の音源からの音を区別することだけを目的とします。関数mergecats
を使用して、音のタイプを 2 つのタイプ (AllAround
と Directional
) にグループ化します。
AllAround = ["beach","forest_path","park","office","home", ... "library","city_center","residential_area"]; Directional = ["train","bus","car","tram","grocery_store", ... "metro_station","cafe/restaurant"]; yTrainMapped = mergecats(yTrain,AllAround,"AllAround"); yTrainMapped = mergecats(yTrainMapped,Directional,"Directional"); yEvalMapped = mergecats(yEval,AllAround,"AllAround"); yEvalMapped = mergecats(yEvalMapped,Directional,"Directional"); yTestMapped = mergecats(yTest,AllAround,"AllAround"); yTestMapped = mergecats(yTestMapped,Directional,"Directional");
最初の 2 つの主成分のグループ化された散布図を作成して、バイナリのグループ化が機能しているかどうかを確認します。
figure [~,score] = pca(xTrain); gscatter(score(:,1),score(:,2),yTrainMapped) xlabel("First principal component") ylabel("Second principal component")
バイナリ分類モデルの学習
モデルにバイナリ音ラベル yTrainMapped
を学習させます。線形 SVM モデルについては、関数discardSupportVectors
を使用してサポート ベクターを破棄することでメモリ サイズを小さくします。以降にモデルで新しいデータを予測するときは、モデル プロパティ Beta
に格納された線形予測子の係数を使用して予測できます。ロジスティック回帰モデルについては、関数 fitclinear
を使用して学習データが格納されていないコンパクトなモデルを返します。
rng("default") binaryMdls = cell(5,1); % Bilayered NN binaryMdls{1} = compact(fitcnet(xTrain,yTrainMapped,LayerSizes=[10 10])); % Linear Discriminant binaryMdls{2} = compact(fitcdiscr(xTrain,yTrainMapped)); % Subspace Discriminant binaryMdls{3} = compact(fitcensemble(xTrain,yTrainMapped, ... Method="Subspace",Learners="discriminant",NumLearningCycles=30,NPredToSample=25)); % Linear SVM binaryMdls{4} = discardSupportVectors(compact(fitcsvm(xTrain,yTrainMapped))); % Logistic Regression binaryMdls{5} = fitclinear(xTrain,yTrainMapped,Learner="logistic");
バイナリ分類モデルをテスト データ セット yTestMapped
でテストします。
binaryMdlTbl = helperMdlMetrics(binaryMdls,xTest,yTestMapped); tbl2 = table(multiMdlTbl,binaryMdlTbl); tbl2.Properties.RowNames = MdlNames; tbl2.Properties.VariableNames = ["Multiclass","Binary"]; disp(tbl2)
Multiclass Binary Accuracy Model Size Accuracy Model Size ______________________ ______________________ Bilayered NN 54.33 36.17 99.33 31.89 Linear Discriminant 53.33 2776.71 98.00 1314.90 Subspace Discriminant 50.67 881.54 99.33 552.08 Linear SVM 34.33 901.90 97.00 8.74 Logistic Regression 50.00 1937.67 98.67 18.60
学習させたモデルで、バイナリ分類問題の音響シーンが正確に分類されています。線形 SVM モデルとロジスティック回帰モデルが 30 KB 未満になります。
少ない特徴量でのモデルの学習
重要な特徴量のみを使用してモデルを作成することで、精度をあまり低下させずに機械学習モデルを小さくできます。xTrain
、xTest
、および xEval
には 286 個の特徴量が含まれています。関数fscmrmr
を使用して 50 個の特徴量を選択します。
idx = fscmrmr(xTrain,yTrainMapped); xTrainSelected = xTrain(:,idx(1:50)); xEvalSelected = xEval(:,idx(1:50)); xTestSelected = xTest(:,idx(1:50));
選択された特徴量を使用してバイナリ分類モデルに学習させます。
rng("default") feat50binaryMdls = cell(5,1); % Bilayered NN feat50binaryMdls{1} = compact(fitcnet(xTrainSelected,yTrainMapped,LayerSizes=[10 10])); % Linear Discriminant feat50binaryMdls{2} = compact(fitcdiscr(xTrainSelected,yTrainMapped)); % Subspace Discriminant feat50binaryMdls{3} = compact(fitcensemble(xTrainSelected,yTrainMapped, ... Method="Subspace",Learners="discriminant",NumLearningCycles=30,NPredToSample=25)); % Linear SVM feat50binaryMdls{4} = discardSupportVectors(compact(fitcsvm(xTrainSelected,yTrainMapped))); % Logistic Regression feat50binaryMdls{5} = fitclinear(xTrainSelected,yTrainMapped,Learner="logistic");
モデルをテスト データ セット yTestMapped
でテストします。
feat50binaryMdlTbl = helperMdlMetrics(feat50binaryMdls,xTestSelected,yTestMapped); tbl3 = table(multiMdlTbl,binaryMdlTbl,feat50binaryMdlTbl); tbl3.Properties.RowNames = MdlNames; tbl3.Properties.VariableNames = ["Multiclass","Binary","50 Features"]; disp(tbl3)
Multiclass Binary 50 Features Accuracy Model Size Accuracy Model Size Accuracy Model Size ______________________ ______________________ ______________________ Bilayered NN 54.33 36.17 99.33 31.89 90.67 11.38 Linear Discriminant 53.33 2776.71 98.00 1314.90 95.33 51.70 Subspace Discriminant 50.67 881.54 99.33 552.08 91.33 541.91 Linear SVM 34.33 901.90 97.00 8.74 96.33 4.82 Logistic Regression 50.00 1937.67 98.67 18.60 97.00 12.18
線形 SVM モデルとロジスティック回帰モデルに加え、2 層ニューラル ネットワーク モデルも 30 KB 未満になります。ただし、特徴量の数を減らしたことで、学習済みモデルの精度が低下しています。
既定の表示形式に戻します。
format("default")
連結制約によるニューラル ネットワークの最適化
モデルのメモリ使用量を制限しながら、モデルの最適なハイパーパラメーターを見つけます。制約は機械学習モデルのタイプによって異なります。たとえば、SVM モデルでサポート ベクターの数を制限したり、ニューラル ネットワーク モデルでパラメーターの数を制限したりできます。ベイズ最適化の詳細と SVM モデルに対する例については、ベイズ最適化の制約を参照してください。この例では、2 層ニューラル ネットワーク モデルについての連結制約による最適化を示します。
連結制約による最適化を行うには、最適化するハイパーパラメーターを指定し、カスタマイズされた目的関数を定義します。その後、関数bayesopt
を使用して、目的関数に基づいて最適なハイパーパラメーターを見つけます。
まず、関数hyperparameters
を使用して、2 層ニューラル ネットワーク モデルの既定のハイパーパラメーターを取得します。
params_bilayeredNet = hyperparameters("fitcnet",xTrainSelected,yTrainMapped);
NumLayers
、Standardize
、および Layer_3_Size
については最適化されないように、それらに対応する 1 番目、3 番目、9 番目のハイパーパラメーターを変更します。このようにすると、2 層のモデルを作成し、標準化なしで学習データを使用できます。学習データは既に標準化されています。
params_bilayeredNet(1).Range = [1 2]; % NumLayers params_bilayeredNet(1).Optimize = false; params_bilayeredNet(3).Optimize = false; % Standardize params_bilayeredNet(9).Optimize = false; % Layer_3_Size
カスタマイズされた目的関数 helperOptimizeConstrainedBilayer
を使用します。この関数は、特定のパラメーターのセットを学習データ セットに使用して 2 層ニューラル ネットワーク モデルに学習させ、ホールドアウト検証セットの損失を返します。関数 helperOptimizeConstrainedBilayer
のコードについては、この例の最後に示してあります。さらに、この関数はモデルの重みパラメーターの数の上限を受け入れ、制約の値を返します。制約の値が正の場合、パラメーターの数が指定されている制限を超えていることを示します。
ハイパーパラメーターを受け取って関数 helperOptimizeConstrainedBilayer
を呼び出す関数ハンドル fun
を定義します。重みパラメーターの数の上限を 300 と指定します。
fun = @(params)helperOptimizeConstrainedBilayer(params,xTrainSelected,yTrainMapped,xEvalSelected,yEvalMapped,300);
関数 bayesopt
を呼び出すときに、目的関数を fun
と指定し、ハイパーパラメーターを params_bilayeredNet
と指定します。さらに、NumCoupledConstraints
を 1 と指定して、目的関数に連結制約が 1 つあることを示します。再現性を得るために、乱数シードを設定し、expected-improvement-plus
の獲得関数を使用します。
rng("default") resultNN = bayesopt(fun,params_bilayeredNet, ... AcquisitionFunctionName="expected-improvement-plus", ... NumCoupledConstraints=1);
|==================================================================================================================================================| | Iter | Eval | Objective | Objective | BestSoFar | BestSoFar | Constraint1 | Activations | Lambda | Layer_1_Size | Layer_2_Size | | | result | | runtime | (observed) | (estim.) | | | | | | |==================================================================================================================================================| | 1 | Infeas | 0.076667 | 3.8313 | NaN | 0.076667 | 2.4e+03 | none | 7.6806e-06 | 15 | 115 | | 2 | Best | 0.07 | 1.1425 | 0.07 | 0.070445 | -196 | none | 0.0001221 | 2 | 1 | | 3 | Infeas | 0.46667 | 0.15246 | 0.07 | 0.070862 | 1.39e+03 | sigmoid | 45.438 | 26 | 14 | | 4 | Best | 0.063333 | 1.3051 | 0.063333 | 0.063353 | -52.5 | tanh | 2.6069e-05 | 4 | 8 | | 5 | Accept | 0.11333 | 1.4743 | 0.063333 | 0.063423 | -58.5 | relu | 2.2423e-05 | 4 | 7 | | 6 | Accept | 0.07 | 1.1222 | 0.063333 | 0.063344 | -196 | none | 0.0001411 | 2 | 1 | | 7 | Infeas | 0.046667 | 1.5327 | 0.063333 | 0.06318 | 1.95e+04 | tanh | 1.2269e-07 | 300 | 16 | | 8 | Infeas | 0.11333 | 5.227 | 0.063333 | 0.063575 | 9.47e+04 | tanh | 0.045218 | 298 | 267 | | 9 | Accept | 0.46667 | 0.023516 | 0.063333 | 0.063332 | -196 | none | 9.1357 | 2 | 1 | | 10 | Infeas | 0.46667 | 0.025527 | 0.063333 | 0.063332 | 1.42e+03 | relu | 3.0052 | 30 | 7 | | 11 | Best | 0.046667 | 2.0311 | 0.046667 | 0.046678 | -172 | relu | 6.691e-09 | 2 | 7 | | 12 | Accept | 0.046667 | 1.0284 | 0.046667 | 0.046675 | -52.5 | tanh | 6.7859e-09 | 4 | 8 | | 13 | Accept | 0.086667 | 2.4386 | 0.046667 | 0.046686 | -172 | relu | 1.1251e-07 | 2 | 7 | | 14 | Accept | 0.46667 | 0.024936 | 0.046667 | 0.04668 | -58.5 | tanh | 60.245 | 4 | 7 | | 15 | Best | 0.03 | 1.0594 | 0.03 | 0.030086 | -58.5 | tanh | 0.0011383 | 4 | 7 | | 16 | Infeas | 0.12333 | 0.12629 | 0.03 | 0.03007 | 296 | sigmoid | 6.766e-09 | 10 | 8 | | 17 | Accept | 0.076667 | 0.71763 | 0.03 | 0.030071 | -146 | none | 8.2973e-09 | 3 | 1 | | 18 | Best | 0.023333 | 1.0659 | 0.023333 | 0.026599 | -58.5 | tanh | 0.0009958 | 4 | 7 | | 19 | Accept | 0.026667 | 1.01 | 0.023333 | 0.02661 | -52.5 | tanh | 0.0009402 | 4 | 8 | | 20 | Accept | 0.05 | 1.3193 | 0.023333 | 0.026601 | -226 | sigmoid | 1.086e-05 | 1 | 8 | |==================================================================================================================================================| | Iter | Eval | Objective | Objective | BestSoFar | BestSoFar | Constraint1 | Activations | Lambda | Layer_1_Size | Layer_2_Size | | | result | | runtime | (observed) | (estim.) | | | | | | |==================================================================================================================================================| | 21 | Accept | 0.036667 | 1.0198 | 0.023333 | 0.027248 | -110 | tanh | 0.00090677 | 3 | 8 | | 22 | Infeas | 0.053333 | 5.9702 | 0.023333 | 0.027181 | 1.41e+04 | tanh | 0.00048938 | 283 | 1 | | 23 | Infeas | 0.12333 | 0.37451 | 0.023333 | 0.027429 | 1.71e+04 | relu | 7.1367e-09 | 238 | 23 | | 24 | Accept | 0.076667 | 0.92349 | 0.023333 | 0.029543 | -248 | none | 6.7138e-07 | 1 | 1 | | 25 | Accept | 0.046667 | 1.3113 | 0.023333 | 0.02962 | -226 | tanh | 1.1434e-07 | 1 | 8 | | 26 | Accept | 0.043333 | 1.3654 | 0.023333 | 0.029659 | -168 | sigmoid | 9.1787e-07 | 2 | 8 | | 27 | Accept | 0.043333 | 0.71783 | 0.023333 | 0.029584 | -226 | tanh | 0.0018534 | 1 | 8 | | 28 | Infeas | 0.06 | 3.8672 | 0.023333 | 0.030036 | 1.31e+04 | sigmoid | 2.3192e-06 | 257 | 2 | | 29 | Accept | 0.066667 | 1.257 | 0.023333 | 0.026647 | -226 | tanh | 0.00050488 | 1 | 8 | | 30 | Accept | 0.036667 | 0.70965 | 0.023333 | 0.028015 | -52.5 | tanh | 0.0044111 | 4 | 8 |
__________________________________________________________ Optimization completed. MaxObjectiveEvaluations of 30 reached. Total function evaluations: 30 Total elapsed time: 60.5813 seconds Total objective function evaluation time: 44.1746 Best observed feasible point: Activations Lambda Layer_1_Size Layer_2_Size ___________ _________ ____________ ____________ tanh 0.0009958 4 7 Observed objective function value = 0.023333 Estimated objective function value = 0.029092 Function evaluation time = 1.0659 Observed constraint violations =[ -58.500000 ] Best estimated feasible point (according to models): Activations Lambda Layer_1_Size Layer_2_Size ___________ _________ ____________ ____________ tanh 0.0011383 4 7 Estimated objective function value = 0.028015 Estimated function evaluation time = 1.0464 Estimated constraint violations =[ -58.501089 ]
bayesopt
は、制約を満たすハイパーパラメーターでホールドアウト検証セットの誤差が最小になる最適なものを特定します。関数 bestPoint
を使用して、最適化の結果 resultNN
から最良の点を抽出します。
[optimalParams,CriterionValue1,iteration] = bestPoint(resultNN)
optimalParams=1×4 table
Activations Lambda Layer_1_Size Layer_2_Size
___________ _________ ____________ ____________
tanh 0.0011383 4 7
CriterionValue1 = 0.0332
iteration = 15
2 層ニューラル ネットワーク モデルに最適なハイパーパラメーターで学習させます。
rng("default") modelNNOpt = compact(fitcnet(xTrainSelected,yTrainMapped, ... Activations=char(optimalParams.Activations), ... LayerSizes=[optimalParams.Layer_1_Size optimalParams.Layer_2_Size], ... Lambda=optimalParams.Lambda));
学習させたモデルの精度とサイズを調べます。
OptimizedNNAccuracy = (1-loss(modelNNOpt,xTestSelected,yTestMapped))*100
OptimizedNNAccuracy = 93.3333
OptimizedNNSize = whos("modelNNOpt").bytes/1024
OptimizedNNSize = 8.3555
Simulink ブロックによるモデル パラメーターの量子化
Simulink ブロックでモデル パラメーターを量子化することで機械学習モデルのメモリ フットプリントを減らすこともできます。Statistics and Machine Learning Toolbox™ には、学習済みの機械学習モデルを Simulink モデルにインポートできる各種の予測ブロックが用意されています。それらの予測ブロックで、一部またはすべてのモデル パラメーターのデータ型を単精度、固定小数点、半精度などに指定できます。固定小数点変換の例については、固定小数点展開用の行動認識 Simulink モデルを参照してください。
この例では、ClassificationNeuralNetwork Predictブロックを含む Simulink モデル slexAcousticSceneClassificationNNPredictExample.slx
が用意されています。このモデルを開きます。
SimMdlName = 'slexAcousticSceneClassificationNNPredictExample';
open_system(SimMdlName)
ClassificationNeuralNetwork Predict ブロックをダブルクリックして、[ブロック パラメーター] ダイアログ ボックスを開きます。[データ型] タブでモデル パラメーターのデータ型を指定できます。メモリ サイズを小さくするには、層のデータ型を single
と指定します。データ型の指定の詳細については、データ型アシスタントを利用したデータ型の指定 (Simulink)を参照してください。
Simulink モデルの入力データを準備します。関数 single
を使用して、予測子データ (xTestSelected
) を単精度に変換します。
soundInput.time = (0:size(xTestSelected,1)-1)'; soundInput.signals(1).values = single(xTestSelected); soundInput.signals(1).dimensions = size(xTestSelected,2);
Simulink モデルをシミュレートし、結果を変数 out
に代入します。
out = sim(SimMdlName);
To Workspace (Simulink)ブロックで記録されたデータを使用して、予測ブロックの精度を調べます。
pred = categorical(out.simout.Data,unique(out.simout.Data),["AllAround","Directional"]); QuantizedNNAccuracy = sum(pred == yTestMapped)/length(yTestMapped)*100
QuantizedNNAccuracy = 93.3333
量子化されたモデル パラメーターのサイズを調べます。
p = Simulink.Mask.get("slexAcousticSceneClassificationNNPredictExample/ClassificationNeuralNetwork Predict"); vars = p.getWorkspaceVariables; blockParams = vars(end).Value; save("params.mat","blockParams") s = dir("params.mat"); QuantizedNNSize = s.bytes/1024
QuantizedNNSize = 2.4951
モデル圧縮のまとめ
2 層ニューラル ネットワーク モデルのモデル圧縮ワークフローにおけるモデルのサイズと精度の変化を表示します。一般に、追加のモデル圧縮方式を適用すると、モデルの精度が多少低下します。
NNccuracy = [multiMdlTbl{1,"Accuracy"} binaryMdlTbl{1,"Accuracy"} ... feat50binaryMdlTbl{1,"Accuracy"} ... OptimizedNNAccuracy QuantizedNNAccuracy]; NNSize = [multiMdlTbl{1,"Model Size"} binaryMdlTbl{1,"Model Size"} ... feat50binaryMdlTbl{1,"Model Size"} ... OptimizedNNSize QuantizedNNSize]; ModelType = ["Multiclass","Binary","50 Features","Optimized","Single Precision"]; figure yyaxis left b = bar(NNSize); xtips = b.XEndPoints; ytips = b.YEndPoints; labels = string(round(b.YData,2)); text(xtips,ytips,labels,HorizontalAlignment="center",VerticalAlignment="bottom", ... Color='#0072BD') ylabel("Model Size [KB]") yyaxis right plot(NNccuracy,"-o") ylabel("Accuracy [%]") xticklabels(ModelType) grid on
2 層ニューラル ネットワーク モデルの場合、特徴量の数を減らした後にモデルのサイズが 30 KB 未満に減少しています。制約付き最適化と単精度へのデータの変換によって、モデルのサイズがさらに小さくなっています。
最初のマルチクラス分類モデルの精度が他のモデルに比べて低いのは、マルチクラス モデルでは音を 15 種類に分類しているためです。マルチクラス問題を単純化してバイナリ分類問題にした後は、90% を超えるテスト データがモデルで正確に分類されています。特徴量の数を減らした時点でモデルの精度が低下していますが、制約付き最適化の手順で精度が改善され、単精度へのデータの変換でも精度は低下していません。
補助関数
関数 helperMdlMetrics
は、学習済みモデル (Mdls
) とテスト データ セット (X
および Y
) の cell 配列を受け取り、モデルの精度 (パーセント) とモデルのサイズ (KB) を含むモデル メトリクスの table を返します。この補助関数は、モデルのサイズの推定に関数 whos
を使用します。ただし、関数 whos
で返されるサイズは、生成コード内の展開に必要な実際のモデルのサイズよりも大きくなることがあります。たとえば、予測に必要がない情報は生成コードに含まれません。ロジスティック回帰学習器を使用する CompactClassificationECOC
モデルについて考えてみます。MATLAB ワークスペース内の CompactClassificationECOC
モデル オブジェクトのバイナリ学習器には ModelParameters
プロパティがあります。ただし、このプロパティは生成コード内の展開用に準備されたモデルには含まれません。
function tbl = helperMdlMetrics(Mdls,X,Y) numMdl = length(Mdls); metrics = NaN(numMdl,2); for i = 1 : numMdl Mdl = Mdls{i}; MdlInfo = whos("Mdl"); metrics(i,:) = [(1-loss(Mdl,X,Y))*100 MdlInfo.bytes/1024]; end tbl = array2table(metrics, ... VariableNames=["Accuracy","Model Size"]); end
関数 helperOptimizeConstrainedBilayer
は、特定のパラメーターのセットを学習データに使用して 2 層ニューラル ネットワーク モデルに学習させ、ホールドアウト検証セットの損失を返します。さらに、この関数はモデルの重みパラメーターの数の上限 (maxSize
) を受け入れ、制約の値を返します。制約の値が正の場合、パラメーターの数が指定されている制限 maxSize
を超えていることを示します。
function [objective,constraint] = helperOptimizeConstrainedBilayer(params,xTrain,yTrain,xEval,yEval,maxSize) mdl = fitcnet(xTrain,yTrain, ... Activations=char(params.Activations), ... LayerSizes=[params.Layer_1_Size params.Layer_2_Size], ... Lambda=params.Lambda); objective = loss(mdl,xEval,yEval); numClasses = size(unique(yTrain),1); sizeEst = size(xTrain,2)*params.Layer_1_Size + ... params.Layer_1_Size*params.Layer_2_Size + ... params.Layer_2_Size*numClasses; constraint = sizeEst - maxSize - 0.5; end
詳細
連結制約による最適化では、メモリ使用量を制限するために、機械学習モデルのタイプに応じて次のハイパーパラメーターを最小化することを検討できます。
決定木 — 葉ノードの観測値の最小数 (MinLeafSize) と決定分岐の最大数 (MaxNumSplits)。決定木モデルのメモリ フットプリントは小規模です。
線形判別とロジスティック回帰 — 特徴量とクラスの数。線形判別モデルとロジスティック回帰モデルのメモリ フットプリントはどちらも小規模から中規模です。
浅層ニューラル ネットワーク — 全結合層の数と各層の隠れユニットの数 (LayerSizes)。浅層ニューラル ネットワーク モデルのメモリ フットプリントは小規模から中規模です。
"k" 最近傍法 — 学習データのサイズ、最近傍の数 (NumNeighbors)、Kd 木アルゴリズムの葉ノードにおけるデータ点の最大数 (BucketSize)。"k" 最近傍法モデルのメモリ フットプリントは中程度です。
サポート ベクター マシン (SVM) — ボックス制約 (BoxConstraint) で決まるサポート ベクターの数。SVM のメモリ フットプリントは中規模から大規模です。線形カーネル関数を使用する SVM モデルでは、関数
discardSupportVectors
を使用してモデルからサポート ベクターを破棄することでフットプリントを削減できます。削減した SVM モデルで以降に新しいデータを予測するときは、モデルに格納された予測子の係数 (Beta
プロパティ) を使用して予測できます。アンサンブル — NumLearningCyclesとLearnersで決まる学習器の数と各学習器のサイズ。アンサンブルのメモリ フットプリントは中規模から大規模です。
ガウス過程回帰 (回帰のみ) — アクティブ セットのサイズ (ActiveSetSize)。ガウス過程回帰モデルのメモリ フットプリントは中規模から大規模です。
機械学習モデルのメモリ使用量はいくつかの要因で決まります。ただし、一般に、決定木モデルのメモリ フットプリントは小規模です。線形判別モデル、ロジスティック回帰モデル、浅層ニューラル ネットワーク モデルのメモリ フットプリントは小規模から中規模、"k" 最近傍法のメモリ フットプリントは中規模になります。SVM、アンサンブル、ガウス過程モデルのメモリ フットプリントは中規模から大規模です。線形カーネル関数を使用する SVM モデルでは、関数 discardSupportVectors
を使用してモデルからサポート ベクターを破棄することでフットプリントを削減できます。削減した SVM モデルで以降に新しいデータを予測するときは、モデルに格納された予測子の係数 (Beta
プロパティ) を使用して予測できます。
メモリに制限があるハードウェアに展開するときは、学習データの指定に table ではなく行列を使用することが推奨されます。table を使用して学習データを指定すると、モデルのメモリ フットプリントのかなりの割合が PredictorNames
などの一部のモデル プロパティに占められる可能性があります。
参考文献
[1] Mesaros, Annamaria, Toni Heittola, and Tuomas Virtanen. Acoustic Scene Classification: An Overview of DCASE 2017 Challenge Entries. In proc. International Workshop on Acoustic Signal Enhancement, 2018.
[2] Lostanlen, Vincent, and Joakim Anden. Binaural Scene Classification with Wavelet Scattering. Technical Report, DCASE2016 Challenge, 2016.
参考
fscmrmr
| bayesopt
| discardSupportVectors
| ClassificationNeuralNetwork Predict