Pythonで機械学習モデルの複雑さを明示的に測定する方法はありますか
モデルのデバッグに興味があります。推奨されるポイントの1つは、モデルを「それほど複雑でない」モデルと比較して、最も複雑なモデルでパフォーマンスが大幅に向上するかどうかを確認することです。
それは私の質問を提起します:
あなたが持っていると仮定アンサンブルモデルと分類タスクのための線形モデルを「アンサンブルモデルが線形モデルよりも複雑であることを考えるのが自然なようです」
しかし、そのような用語で2つ以上のモデルを比較できるようにするために、モデルの複雑さを数値的に測定する方法は何でしょうか。
そのようなタスクに役立つPythonの実装はありますか?
回答
モデルの複雑さを測定するためのモデルにとらわれない方法については聞いたことがありません。いくつかの戦略がありますが、それらはモデルに依存します。
さまざまなモデルファミリを使用して問題に取り組むことができます。
以下のために線形モデル、あなたが使用しているゼロ以外のパラメータの数をカウントすることができます。予測に使用された特徴の数。
以下のために決定木、あなたは木が達成することが最大の深さをカウントすることができます。
以下のためにニューラルネットワーク、あなたのNNが最適化されていることを、パラメータの数をカウントすることができます。
以下のためのアンサンブル方法(ランダムフォレスト昇圧勾配)あなたは、モデルで使用されるさまざまな弱学習の集約を使用することができます。
Python実装の場合、測定するモデルに応じていくつかの実装があります。あなたが気づいたらそれらのいくつかは本当に測定が簡単です。
異なるモデルファミリ間で複雑さを比較するのは直感的に困難です。4つの係数を持つ線形回帰またはmax_depth = 3の決定木より複雑なものは何ですか?
ディープラーニングの複雑さのトピックについて、ヒントン、オリオール、ジェフディーンは、ニューラルネットワークの知識を蒸留する論文を発表しました。彼らがニューラルネットワークの複雑さを単純化することについて話しているところ。
少しナイーブかもしれませんが、最初に頭に浮かぶアイデアは、トレーニング中に推定する必要のあるパラメーターの数を単純に数えることです。仮説空間が大きいため、推定する必要のある値が多いほど、モデルは複雑になります。 。たとえば、線形モデルに必要なのは$n+1$ パラメータ( $n$特徴の数)、アンサンブルモデルに必要なパラメーターの数は、すべての学習者のパラメーターの数の合計であるため、より多くなる可能性があります。このアイデアは、パラメーターの値の範囲を考慮に入れるように改良することができます。
非常に大まかな概算として、Pythonでモデルを表すオブジェクトのサイズを簡単に計算できます(モデルの表現がスペース効率が良いと仮定すると、常にそうであるとは限りません)。
ご存知かもしれませんが、「複雑さ」はコンピュータサイエンスの用語です。通常、複雑さは「big-O表記」で測定され、入力の数が増えるにつれてソリューションが時間とともにどのようにスケーリングするかと関係があります。たとえば、この投稿では、畳み込み層の計算の複雑さについて説明しています。
ただし、ディープラーニングでは、競合するニューラルネットワークアーキテクチャは通常、同じタイプの問題(ImageNet分類など)に同じアルゴリズム(バックプロパゲーション)を適用しています。唯一の違いはアーキテクチャです。さらに、ほとんどのアーキテクチャは、同様の計算要素(たとえば、畳み込み層と線形層)を使用します。したがって、複雑さの代用としてパラメータの数を使用するのが慣例です。これは概算にすぎないことは事実です。2つのネットワークが同じ数のパラメーターを持っていても、必要な操作の数が異なる場合があります。ただし、アーキテクチャが異なると一般に上記の類似点がありますが、サイズが数桁異なる可能性があることを考えると、これは一般的に適切な概算です。
参考として、EfficientNetPaperの図1を検討してください。彼らは、トレーニング可能なパラメーターの数を「モデルサイズ」の代用として使用し、パラメーターの数は多かれ少なかれランタイムと線形相関していることに注意します。
トレーニング可能なパラメーターの数をカウントするPython関数の場合、これは、Keras、Tensorflow、PyTorchなどを使用しているかどうかによって異なります。Kerasでは、これは1行ですmodel.count_params()
。PyTorchでは、ここでmodel.parameters()
説明するように計算できます。
ここで他の回答で述べられているように、モデルの複雑さについて話すとき、私たちは通常、モデルが学習するパラメーターの数について考えています。誰かがそれほど複雑でないモデルと比較することについて話すとき、彼らはしばしば直感的にそれほど複雑でないモデル(同じクラスのモデル、たとえばニューロンの少ないニューラルネットワーク、またはより単純なクラスのモデル、たとえば線形モデル)と比較することを意味しますランダムフォレストではなく)。
非常に異なるモデル間のモデルの複雑さを考える1つの方法は、コルモゴロフの複雑さです。これは、保存された(漬け物などの)モデルが占めるスペースの量を調べることで概算できます。あなたが与えた例では、アンサンブルが線形モデルよりも単純でない限り、アンサンブルは線形モデルよりも多くのディスクスペースを占有します(たとえば、それぞれ10個の学習係数を持つ2つの線形モデルと200個の学習係数を持つ線形モデルのアンサンブル)。
1つのオプションは、ベイズ情報量基準(BIC)です。これは、パラメーターの数にペナルティを課しながら、最大化された尤度によって測定された、モデリング適合に報酬を与えることを試みるモデル選択基準です。
BICの1つの実装はRegscorePyパッケージに含まれています。
1.しかし、そのような用語で2つ以上のモデルを比較できるようにするために、モデルの複雑さを数値的に測定する方法は何でしょうか。
VC次元を使用して、モデルの複雑さを数値形式で測定できます。ウィキペディアのVapnik–Chervonenkis次元を参照してください。
2.そのようなタスクに役立つPythonの実装はありますか?
VC次元について説明するスタック交換リンクがすでにあります。VC次元を計算する方法は?