Main Content

メモリに制限があるハードウェアのための機械学習モデルの圧縮

この例では、メモリに制限があるハードウェアへの展開用に機械学習モデルのサイズを小さくする方法を示します。モデル圧縮ワークフローを示すために、この例では環境が発している音に基づいて環境を分類する音響シーン分類 (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              

xTrainxEval、および xTest に、ウェーブレット散乱を使用して TUT 音響シーン データ セットから抽出された特徴量が格納されています。yTrainyEval、および yTest には、xTrainxEval、および xTest にそれぞれ対応する 15 種類の音響シーン ラベルが格納されています。この例では、xTrainyTrain を使用してモデルに学習させ、学習させたモデルの精度を xTestyTest を使用してテストします。最適化の手順では、xEvalyEval をホールドアウト検証セットとして使用します。

TUT 音響シーン データ セットには、開発データ (TUT-acoustic-scenes-2017-development [3]) とテスト データ (TUT-acoustic-scenes-2017-evaluation [4]) があります。開発データで 4 分割の交差検証設定が提供されます。xTrainxEval は交差検証設定の最初の分割で定義される学習セットと評価セットのサブセットからそれぞれ取得され、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);

分類モデルのタイプの選択

分類学習器アプリを使用して、この例の分類モデルのタイプを選択します。

  1. [アプリ] タブでアプリ ギャラリーを開きます。次に、[機械学習および深層学習] グループの [分類学習器] をクリックします。

  2. [分類学習器] タブで、[ファイル] セクションの [新規セッション] をクリックし、[ワークスペースから] を選択します。ダイアログ ボックスで、応答変数として yTrain を指定し、予測子として xTrain の変数を指定します。

  3. アプリの [モデル] セクションで [すべて] をクリックします。このオプションは、選択したデータ セットに対して使用できる事前設定済みのすべてのモデルに学習させます。

  4. [学習] セクションで、[すべてを学習] をクリックして [すべてを学習] を選択します。

学習させたモデルを精度のスコアに基づいて比較したり、クラスの予測をプロットすることで結果を可視化したり、混同行列や 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 つのタイプ (AllAroundDirectional) にグループ化します。

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 未満になります。

少ない特徴量でのモデルの学習

重要な特徴量のみを使用してモデルを作成することで、精度をあまり低下させずに機械学習モデルを小さくできます。xTrainxTest、および 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);

NumLayersStandardize、および 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 プロパティ) を使用して予測できます。

  • アンサンブル — NumLearningCyclesLearnersで決まる学習器の数と各学習器のサイズ。アンサンブルのメモリ フットプリントは中規模から大規模です。

  • ガウス過程回帰 (回帰のみ) — アクティブ セットのサイズ (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.

[3] TUT Acoustic scenes 2017, Development dataset

[4] TUT Acoustic scenes 2017, Evaluation dataset

参考

| | |

関連するトピック