Javaでのロジスティック回帰

1. 前書き

ロジスティック回帰は、機械学習(ML)プラクティショナーツールボックスの重要な手段です。
このチュートリアルでは、*ロジスティック回帰の背後にある主要なアイデアを探ります*。
最初に、MLパラダイムとアルゴリズムの簡単な概要から始めましょう。

2. 概要

MLを使用すると、人間に優しい用語で定式化できる問題を解決できます。 ただし、この事実は、ソフトウェア開発者にとっての課題となる可能性があります。 私たちは、コンピューターに優しい用語で定式化できる問題に対処することに慣れています。 たとえば、人間として、写真上のオブジェクトを簡単に検出したり、フレーズのムードを確立したりできます。 このような問題をコンピューターでどのように定式化できますか?
MLには、解決策を考え出すために、_training_ *と呼ばれる特別な段階があります。 この段階で、入力データをアルゴリズムに送り、最適なパラメーターセット(いわゆる重み)を見つけようとします。 アルゴリズムに入力する入力データが多いほど、予測からより正確な予測が得られます。
*トレーニングは反復MLワークフローの一部です:*
link:/uploads/ml1-100x14.png%20100w []データの取得から始めます。 多くの場合、データはさまざまなソースから取得されます。 したがって、同じ形式にする必要があります。 データセットが研究領域を公正に表すことも管理する必要があります。 モデルが赤いリンゴでトレーニングされたことがない場合、モデルを予測することはほとんどできません。
次に、データを消費し、予測を行うことができるモデルを構築する必要があります。 * MLには、すべての状況で適切に機能する事前定義モデルはありません。*
正しいモデルを検索するときに、モデルの構築、トレーニング、予測の確認、モデルの破棄が簡単に発生する可能性があります。 この場合、戻って別のモデルを構築し、プロセスを再度繰り返す必要があります。

3. MLパラダイム

MLでは、使用可能な入力データの種類に基づいて、3つの主要なパラダイムを選択できます。
  • 教師あり学習(画像分類、オブジェクト認識、
    感情分析)

  • 教師なし学習(異常検出)

  • 強化学習(ゲーム戦略)

    このチュートリアルで説明するケースは、教師あり学習に属します。*

4. MLツールボックス

MLには、モデルを構築するときに適用できるツールのセットがあります。 それらのいくつかに言及しましょう:
  • 線形回帰

  • ロジスティック回帰

  • ニューラルネットワーク

  • サポートベクターマシン

  • k最近傍

    *予測性の高いモデルを構築する場合、いくつかのツールを組み合わせることができます。*実際、このチュートリアルでは、モデルはロジスティック回帰とニューラルネットワークを使用します。

5. MLライブラリ

JavaはMLモデルのプロトタイピングに最も一般的な言語ではありませんが、__ __itはMLを含む多くの分野で堅牢なソフトウェアを作成するための信頼できるツールとして評判があります。 そのため、Javaで記述されたMLライブラリが見つかる場合があります。
このコンテキストでは、事実上の標準ライブラリhttps://www.tensorflow.org/install/lang_java[Tensorflow]に言及する場合がありますが、これにはJavaバージョンもあります。 もう1つの注目に値するのは、https://www.baeldung.com/deeplearning4j [Deeplearning4j]というディープラーニングライブラリです。 これは非常に強力なツールであり、このチュートリアルでも使用します。

6.  数字認識のロジスティック回帰

ロジスティック回帰の主な考え方は、入力データのラベルを可能な限り正確に予測するモデルを構築することです。
いわゆる損失関数または目的関数が最小値に達するまでモデルをトレーニングします。 損失関数は、実際のモデル予測と予想される予測(入力データのラベル)に依存します。 私たちの目標は、実際のモデル予測と予想される予測の相違を最小限にすることです。
その最小値に満足できない場合は、別のモデルを作成して、トレーニングを再度実行する必要があります。
ロジスティック回帰の動作を確認するために、手書き数字の認識について説明します。 この問題はすでに古典的な問題になっています。 Deeplearning4jライブラリには、APIの使用方法を示す一連の現実的なhttps://github.com/deeplearning4j/dl4j-examples/tree/master/dl4j-examples/src/main/java/org/deeplearning4j/examples[examples]があります。 。 このチュートリアルのコード関連部分は、https://github.com/deeplearning4j/dl4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/convolution/mnist/に基づいています。 MnistClassifier.java [_MNIST Classifier_]。

6.1. 入力データ

入力データとして、手書き数字のよく知られたhttps://en.wikipedia.org/wiki/MNIST_database[MNISTデータベース]を使用します。 入力データとして、28×28ピクセルのグレースケール画像があります。 各画像には、画像が表す数字である自然なラベルがあります。
link:/uploads/ml2-100x62.png%20100w []
*作成するモデルの効率を推定するために、入力データをトレーニングセットとテストセットに分割します。*
DataSetIterator train = new RecordReaderDataSetIterator(...);
DataSetIterator test = new RecordReaderDataSetIterator(...);
入力画像にラベルを付けて2つのセットに分割したら、「データの詳細化」段階は終了し、「モデルの構築」に進むことができます。

6.2. モデル構築

前述したように、すべての状況でうまく機能するモデルはありません。 それでも、長年のMLでの研究の後、科学者は手書き数字の認識で非常にうまく機能するモデルを見つけました。 ここでは、いわゆるhttp://yann.lecun.com/exdb/lenet/[LeNet-5]モデルを使用します。
LeNet-5は、28×28ピクセルの画像を10次元ベクトルに変換する一連のレイヤーで構成されるニューラルネットワークです。
link:/uploads/ml3-100x17.png%20100w [] 10次元の出力ベクトルには、入力画像のラベルが0、1、2などの確率が含まれています。
たとえば、出力ベクトルが次の形式の場合:
{0.1, 0.0, 0.3, 0.2, 0.1, 0.1, 0.0, 0.1, 0.1, 0.0}
つまり、入力画像がゼロになる確率は0.1、1が0になる、2になる確率は0.3などです。 最大確率(0.3)はラベル3に対応することがわかります。
モデル構築の詳細に飛び込みましょう。 Java固有の詳細は省略し、MLの概念に集中します。
_MultiLayerNetwork_オブジェクトを作成して、モデルをセットアップしました。
MultiLayerNetwork model = new MultiLayerNetwork(config);
そのコンストラクターで、_MultiLayerConfiguration_オブジェクトを渡す必要があります。 これは、ニューラルネットワークのジオメトリを記述するまさにそのオブジェクトです。 ネットワークジオメトリを定義するには、すべてのレイヤーを定義する必要があります。
最初の方法と2番目の方法でこれを行う方法を示しましょう。
ConvolutionLayer layer1 = new ConvolutionLayer
    .Builder(5, 5).nIn(channels)
    .stride(1, 1)
    .nOut(20)
    .activation(Activation.IDENTITY)
    .build();
SubsamplingLayer layer2 = new SubsamplingLayer
    .Builder(SubsamplingLayer.PoolingType.MAX)
    .kernelSize(2, 2)
    .stride(2, 2)
    .build();
レイヤーの定義には、ネットワーク全体のパフォーマンスに大きく影響するアドホックパラメーターが大量に含まれていることがわかります。 *これはまさに、すべての人の中で優れたモデルを見つける能力が重要になる場所です。*
これで、_MultiLayerConfiguration_オブジェクトを作成する準備ができました。
MultiLayerConfiguration config = new NeuralNetConfiguration.Builder()
    // preparation steps
    .list()
    .layer(layer1)
    .layer(layer2)
    // other layers and final steps
    .build();
_MultiLayerNetwork_コンストラクターに渡します。

6.3. トレーニング

構築したモデルには、431080のパラメーターまたは重みが含まれています。 ここでは、この数値の正確な計算は行いませんが、**最初のレイヤーには24x24x20 = 11520以上の重みがあることに注意してください。**
トレーニング段階は次のように簡単です:
model.fit(train);
最初、431080パラメーターにはランダムな値がありますが、トレーニング後、モデルのパフォーマンスを決定する値を取得します。 モデルの予測性を評価する場合があります。
Evaluation eval = model.evaluate(test);
logger.info(eval.stats());
LeNet-5モデルは、たった1回のトレーニング反復(エポック)でさえ、ほぼ99%という非常に高い精度を達成します。 より高い精度を達成したい場合は、プレーン_for-loop_を使用してより多くの反復を行う必要があります。
for (int i = 0; i < epochs; i++) {
    model.fit(train);
    train.reset();
    test.reset();
}

6.4. 予測

ここで、モデルをトレーニングし、テストデータの予測に満足しているので、まったく新しい入力でモデルを試すことができます。 このために、新しいクラス_MnistPrediction_を作成します。このクラスでは、ファイルシステムから選択したファイルから画像をロードします。
INDArray image = new NativeImageLoader(height, width, channels).asMatrix(file);
new ImagePreProcessingScaler(0, 1).transform(image);
変数_image_には、28×28グレースケールに縮小された画像が含まれています。 モデルにフィードすることができます:
INDArray output = model.output(image);
変数_output_には、ゼロ、1、2などの画像の確率が含まれます。
少し遊んで数字2を書き、この画像をデジタル化し、モデルにフィードしてみましょう。 次のようなものが表示される場合があります。
link:/uploads/ml4-100x18.png%20100w []ご覧のとおり、最大値0.99のコンポーネントにはインデックス2があります。 これは、モデルが手書き数字を正しく認識したことを意味します。

7. 結論

このチュートリアルでは、機械学習の一般的な概念について説明しました。 手書き数字認識に適用したロジスティック回帰の例でこれらの概念を説明しました。
いつものように、https://github.com/eugenp/tutorials/tree/master/ml/ [GitHub repository]で対応するコードスニペットを見つけることができます。