ニューラルネットワークのハッカーガイド。 第2章:機械学習。 SVMをニューラルネットワークにまとめる

内容:

第1章:実際の価値の図
パート1:

  :        №1:   
      
      





パート2:

   №2:  
      
      





パート3:

   №3:  
      
      





パート4:

         
      
      





パート5:

    «»   " "
      
      





パート6:

      
      
      







第2章:機械学習
パート7:

   
      
      





パート8:

         (SVM)
      
      





パート9:

   SVM   
      
      





パート10:

    :  
      
      









興味深い事実は、SVMは単なる別のタイプの非常に単純なスキーム(スコア= a * x + b * y + cを計算するスキームであり、a、b、cは重み関数、x、yはデータ入力ポイントです) ) より複雑な機能に簡単に拡張できます。 たとえば、バイナリ分類を実行する2層ニューラルネットワークを作成してみましょう。 今後は次のようになります。



 //    x,y var n1 = Math.max(0, a1*x + b1*y + c1); //  1-   var n2 = Math.max(0, a2*x + b2*y + c2); // 2-  var n3 = Math.max(0, a3*x + b3*y + c3); // 3-  var score = a4*n1 + b4*n2 + c4*n3 + d4; // 
      
      







上記の定義は、3つの隠れニューロン(n1、n2、n3)を持つ2層ニューラルネットワークであり、各隠れニューロンに対して整流線形要素(Rectified Linear UnitまたはReLU)の非線形性を使用します。 ご覧のとおり、いくつかのパラメーターがあります。つまり、分類器がより複雑になり、SVMなどの単純な線形決定ルールを使用するだけでなく、意思決定の境界を複雑にする可能性があります。 別の表現方法は、3つの隠されたニューロンのそれぞれが線形分類器であり、現時点ではそれらの上に追加の線形分類器を作成していることです。 では、さらに深く見ていきましょう:)。 それでは、この2層ニューラルネットワークをトレーニングしましょう。 コードは、上記のSVMコードの例と非常によく似ています。パッセージを前後に変更するだけです。



 //    var a1 = Math.random() - 0.5; //    -0,5  0,5 // ...        for(var iter = 0; iter < 400; iter++) { //      var i = Math.floor(Math.random() * data.length); var x = data[i][0]; var y = data[i][1]; var label = labels[i]; //    var n1 = Math.max(0, a1*x + b1*y + c1); //  1-   var n2 = Math.max(0, a2*x + b2*y + c2); // 2-  var n3 = Math.max(0, a3*x + b3*y + c3); // 3-  var score = a4*n1 + b4*n2 + c4*n3 + d4; //  //    var pull = 0.0; if(label === 1 && score < 1) pull = 1; //    !  . if(label === -1 && score > -1) pull = -1; //    !  . //         //      «»  var dscore = pull; var da4 = n1 * dscore; var dn1 = a4 * dscore; var db4 = n2 * dscore; var dn2 = b4 * dscore; var dc4 = n3 * dscore; var dn3 = c4 * dscore; var dd4 = 1.0 * dscore; //  //     ReLU,   // ..      ,    «» var dn3 = n3 === 0 ? 0 : dn3; var dn2 = n2 === 0 ? 0 : dn2; var dn1 = n1 === 0 ? 0 : dn1; //      1 var da1 = x * dn1; var db1 = y * dn1; var dc1 = 1.0 * dn1; //      2 var da2 = x * dn2; var db2 = y * dn2; var dc2 = 1.0 * dn2; //      3 var da3 = x * dn3; var db3 = y * dn3; var dc3 = 1.0 * dn3; // !    ! //  ,         x,y //      .     //      ,   x,y //     ,    //  (..   ) ,    da1 += -a1; da2 += -a2; da3 += -a3; db1 += -b1; db2 += -b2; db3 += -b3; da4 += -a4; db4 += -b4; dc4 += -c4; // ,    var step_size = 0.01; a1 += step_size * da1; b1 += step_size * db1; c1 += step_size * dc1; a2 += step_size * da2; b2 += step_size * db2; c2 += step_size * dc2; a3 += step_size * da3; b3 += step_size * db3; c3 += step_size * dc3; a4 += step_size * da4; b4 += step_size * db4; c4 += step_size * dc4; d4 += step_size * dd4; //   ,     . // ! }
      
      







これが、ニューラルネットワークのトレーニング方法です。 当然、コードを慎重にブロックに分割する必要がありますが、すべてを明確かつ明確に説明できることを期待して、この例を具体的に示しました。 後で、これらのネットワークを使用するための最適な方法を検討し、コードをよりきちんとした、モジュール化された、より合理的な方法で構造化します。



それまでの間、2層ニューラルネットワークは実際にはそれほど難しくないという結論に達したと思います。フロントパスの式を記述し、結果として最後に値を解釈してから、この値を正または特定の例でこの値がどのようにあるべきかに応じて、負の方向。 エラーの逆伝播後にパラメーターを更新することにより、将来この特定の例を検討する際に、ネットワークが更新前に発行した値ではなく、必要な値を提供する可能性が高くなります。



All Articles