無料の Python 機械学習コース 6: ニューラル ネットワーク アルゴリズム

無料の Python 機械学習コース 6: ニューラル ネットワーク アルゴリズム

ニューラルネットワークは人間の脳を模倣するために開発されました。まだ実現されていないものの、ニューラル ネットワークは機械学習に非常に効果的です。 1980年代から1990年代にかけて人気がありました。最近、ますます人気が出てきています。おそらく、コンピューターは大規模なニューラル ネットワークを妥当な時間内に実行できるほど高速だからでしょう。この記事では、Python でニューラル ネットワーク アルゴリズムをゼロから開発する方法について説明します。

「ニューラル ネットワークのアイデア」セクションを注意深く読むことをお勧めします。しかし、よくわからない場合は心配しないでください。実行セクションに進みます。私はそれを細かく分解しました。繰り返しになりますが、すべてのコードを自分で実行すると、より明確になります。

[[360033]]

ニューラルネットワークの仕組み

単純なニューラル ネットワークでは、ニューロンが基本的な計算単位となります。入力機能を受け取り、それを出力として生成します。基本的なニューラル ネットワークは次のようになります。


ここで、「layer1」は入力フィーチャです。 「レイヤー 1」は別のノードであるレイヤー 2 に入力され、最終的に予測されたカテゴリまたは仮説を出力します。レイヤー2は隠しレイヤーです。複数の隠しレイヤーを使用できます。

データセットと精度の要件に基づいてニューラル ネットワークを設計する必要があります。

前方伝播

レイヤー 1 からレイヤー 3 に移動するプロセスは、順方向伝播と呼ばれます。前方伝播の手順:

(1)各入力特徴量の係数θを初期化する。入力機能が 10 個あるとします。たとえば、トレーニング例が 100 個あるとします。これは 100 行のデータを意味します。この場合、入力行列のサイズは 100 x 10 になります。ここで、theta1 のサイズを決定します。行数は入力機能の数と同じである必要があります。この例では、値は 10 です。列の数は、選択した隠し層のサイズにする必要があります。

(2)入力特徴Xを対応するθで乗算し、バイアス項を加える。結果を活性化関数に渡します。

シグモイド、tanh、relu、softmax、swishなど、いくつかの活性化関数が利用可能です。

ニューラル ネットワークを説明するために、シグモイド活性化関数を使用します。


ここで、「a」は隠し層またはレイヤー2を表し、bはバイアスを表します。

g(z)はシグモイド活性化関数である。


(3)隠れ層のtheta2を初期化する。サイズは、隠し層の長さに出力クラスの数を掛けた値になります。この例では、隠し層がもうないので、次の層が出力層になります。

(4)その後は前と同じ手順を繰り返す必要があります。シータ層と隠し層を掛け合わせ、シグモイド活性化層に通して仮説または予測出力を取得します。

バックプロパゲーション

バックプロパゲーションは、出力層からレイヤー 2 に移動するプロセスです。その過程で、誤差を計算します。

(1)まず、仮説を元の出力yから減算する。それが私たちの増分値になります。


(2)次にθ2の勾配を計算します。 delta3 を theta2 で乗算します。それを「a2」×「1-a2」で乗算します。次の式では、「a」の上付き文字 2 はレイヤー 2 を表します。四角形と勘違いしないでください。


(3)勾配の非正規化形式は、訓練サンプル数mに応じてダイビングデルタから計算される。

ネットワークのトレーニング

シータを変更します。 Theta1 は、入力特徴に学習率と delta2 を乗算することによって得られます。シータの大きさに注意してください。


順方向伝播と逆方向伝播のプロセスが繰り返され、最適なコストに達するまでパラメータが継続的に更新されます。これはコスト関数の式です。繰り返しになりますが、コスト関数は予測が元の出力変数からどれだけ離れているかを表します。


お気づきかもしれませんが、このコスト関数の式はロジスティック回帰コスト関数とほぼ同様です。

ニューラルネットワークの実装

Coursera の Andrew Ng の機械学習コースのデータセットを使用します。次のリンクからデータセットを自由にダウンロードしてください。

https://github.com/rashida048/Machine-Learning-With-Python/blob/master/ex3d1.xlsx

ここでは、ニューラル ネットワークを実装するためのステップ バイ ステップのアプローチを示します。よりよく理解するために、各コード行を自分で実行し、出力を印刷することをお勧めします。

(1)まず、必要なパッケージとデータセットをインポートします。

  1. pandasをpdとしてインポートする
  2. numpyをnpとしてインポートする
  3. xls = pd.ExcelFile ('ex3d1.xlsx')
  4. df = pd .read_excel(xls, 'X',ヘッダー=なし)

以下はデータセットの最初の 5 行です。これらはデジタルピクセル値です。データセットを自由にダウンロードして、以下の手順に従ってください。

このデータセットでは、入力変数と出力変数が別々の Excel ワークシートに整理されています。出力変数をノートブックにインポートしてみましょう。

  1. y = pd .read_excel(xls, 'y',ヘッダー=なし)

これもデータセットの最初の 5 行のみです。出力変数は 1 ~ 10 の間の数値です。このプロジェクトの目標は、「df」に保存されている入力変数を使用して数値を予測することです。

(2)入力変数と出力変数の次元を求める

  1. df.shapey.シェイプ

入力変数または df の形状は 5000 x 400 で、出力変数または y の形状は 5000 x 1 です。

(3)ニューラルネットワークの定義

簡単にするために、25 個のニューロンからなる 1 つの隠し層のみを使用します。

  1. 隠しレイヤー= 25  

出力クラスを調べます。

  1. y y_arr = y[0].unique()
  2. #出力:
  3. 配列([10, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype = int64 )

上記のように、出力クラスは 10 個あります。

(4)θとバイアスを初期化する

レイヤー1とレイヤー2のthetaをランダムに初期化します。レイヤーが 3 つあるので、theta1 と theta2 が存在します。

  • シータ1の形状: レイヤー1のサイズ x レイヤー2のサイズ
  • theta2の形状: レイヤー2のサイズ x レイヤー3のサイズ

ステップ 2 から、「df」の形状は 5000x400 になります。つまり、入力機能は 400 個あります。したがって、レイヤー1のサイズは400です。隠し層のサイズを 25 に指定したので、layer2 のサイズは 25 になります。出力クラスは 10 個あります。したがって、レイヤー3のサイズは10です。

  • シータ1の形状: 400 x 25
  • θ2の形状: 25 x 10

同様に、ランダムに初期化された 2 つのバイアス項 b1 と b2 が存在します。

  • b1の形状: レイヤー2のサイズ(この場合は25)
  • b2の形状: レイヤー3のサイズ(この場合は10)

ランダムにシータを初期化する関数を定義します。

  1. def randInitializeWeights(Lin, Lout):
  2. エピ= (6**1/2) / (Lin + Lout)**0.5
  3. w = np .random.rand(Lout, Lin)*(2*epi) -epi
  4. 戻る

この関数を使用してθを初期化します

  1. 隠しレイヤー= 25  
  2. 出力= 10  
  3. theta1 = randInitializeWeights (len(df.T), hidden_​​layer)
  4. theta2 = randInitializeWeights (hidden_​​layer, 出力)
  5. シータ= [シータ1, シータ2]

ここで、バイアス項を上記のように初期化します。

  1. b1 = np.random.randn (25,)
  2. b2 = np.ランダム.randn (10,)

(5)順伝播を実装する

「順方向伝播」セクションの式を使用します。


便宜上、θとXを掛け合わせる関数を定義する。

  1. def z_calc(X, θ):
  2. np.dot(X, theta.T) を返す

活性化関数も数回使用します。シグモイド活性化

  1. シグモイド(z)を定義します:
  2. 1/(1+ np.exp(-z)) を返す

ここで、順方向伝播を段階的に説明します。まず、z項を計算します。

  1. z1 = z_calc (df,theta1) + b1

このz1を活性化関数に通して隠れ層を取得します。

  1. a1 =シグモイド(z1)

a1 は隠れ層です。 a1の形状は5000x25です。同じプロセスを繰り返して、レイヤー3または出力レイヤーを計算します。

  1. z2 = z_calc (a1,theta2) + b2
  2. a2 =シグモイド(z2)

a2 の形状は 5000x10 です。10 列は 10 個のクラスを表します。 a2 はレイヤー 3 または最終出力または仮説です。この例のように隠し層がさらにある場合は、同じプロセスを繰り返して、ある層から別の層に転送します。入力特徴を使用して出力層を計算するプロセスは、順方向伝播と呼ばれます。これを 1 つの関数にまとめると、任意の数のレイヤーに対して順方向伝播を実行できます。

  1. l = 3 #レイヤーの数
  2. b = [b1, b2]
  3. def仮説(df, theta):
  4. a = []
  5. z = []
  6. iが範囲(0, l-1)の場合:
  7. z1 = z_calc (df,theta[i]) + b[i]
  8. 出力=シグモイド(z1)
  9. a.append(出力)
  10. z.append(z1)
  11. df =アウト 
  12. 戻る、a、z

(6)バックプロパゲーションを実装する

これは、勾配を逆方向に計算し、シータを更新するプロセスです。その前に、「y」を変更する必要があります。 「y」には10個のクラスがあります。ただし、各クラスを列に分ける必要があります。たとえば、最初の列はクラス 10 用です。残りのクラスについては、10 を 1 に、0 を 1 に置き換えます。このようにして、クラスごとに個別の列を作成します。

  1. y1 = np .zeros([len(df), len(y_arr)])
  2. y1 = pd .DataFrame(y1)
  3. iが範囲(0, len(y_arr))内にある場合:
  4. jが範囲(0, len(y1))内にある場合:
  5. y[0][j] == y_arr[i]の場合:
  6. y1.iloc[j, i] = 1
  7. それ以外:
  8. y1.iloc[j, i] = 0
  9. y1.head()

ここで、まず順方向伝播をステップごとに説明し、それをすべて 1 つの関数にまとめ、逆方向伝播についても同じことを行います。上記のバックプロパゲーション セクションの勾配式を使用して、まず delta3 を計算します。順方向伝播の実装から z1、z2、a1、a2 を使用します。

  1. del3 = y1 -a2

次に、次の式を使用して delta2 を計算します。


これは delta2 です:

  1. del2 = np .dot(del3, theta2) * a1*(1 - a1)

ここで新しい概念を学ぶ必要があります。それはS字型のグラデーションです。 S 型勾配の式は次のとおりです。


気づけば、これは増分式の a(1 — a) とまったく同じです。なぜならaはシグモイド(z)だからです。これは慣例なので、すべてをまとめて関数を記述するときに、delta2 式の a(1-a) 項をこのシグモイド勾配に置き換えます。まったく同じです。 2つだけ説明したいことがあります。シグモイド勾配の関数を書いてみましょう。

  1. sigmoid_grad(z)を定義します:
  2. シグモイド(z)*(1 - シグモイド(z))を返す

最後に、次の式を使用して theta を更新します。


学習率を選択する必要があります。 0.003を選択しました。他の学習率を試して、その効果を確認することをお勧めします。

  1. θ1 = np .dot(del2.T, pd.DataFrame(a1)) * 0.003
  2. θ2 = np .dot(del3.T, pd.DataFrame(a2)) * 0.003

これが theta を更新する方法です。このプロセスは、後方に進むため、バックプロパゲーションと呼ばれます。バックプロパゲーションの関数を記述する前に、コスト関数を定義する必要があります。バックプロパゲーション法にコストの計算も組み込んだからです。順方向伝播中に追加することもできますが、ネットワークのトレーニング時に分離することもできます。これはコスト関数の方法です

  1. 定義コスト関数(y, y_calc, l):
  2. (np.sum(np.sum(-np.log(y_calc)*y - np.log(1-y_calc)*(1-y))))/m を返します。

ここで、m はトレーニング例の数です。すべてをまとめると:

  1. y1 = np .zeros([len(df), len(y_arr)])
  2. y1 = pd .DataFrame(y1)
  3. iが範囲(0, len(y_arr))内にある場合:
  4. jが範囲(0, len(y1))内にある場合:
  5. y[0][j] == y_arr[i]の場合:
  6. y1.iloc[j, i] = 1
  7. それ以外:
  8. y1.iloc[j, i] = 0
  9. y1.head()

(7)ネットワークのトレーニング

ネットワークを 20 エポックトレーニングします。このコード スニペットで theta を再度初期化します。 theta を使ってアップデートしたからです。したがって、再度初期化しないと、更新された theta から開始することになります。でも、もう一度やり直したいんです。

  1. theta1 = randInitializeWeights (len(df.T), hidden_​​layer)
  2. theta2 = randInitializeWeights (hidden_​​layer, 出力)
  3. シータ= [シータ1, シータ2]
  4. コストリスト= []
  5. iが範囲(20)内にある場合:
  6. θ、コスト=バックプロパゲーション(df、θ、y1、0.003)
  7. cost_list.append(コスト)
  8. コストリスト

学習率 0.003 を使用し、20 エポック実行しました。ただし、下記の GitHub リンクを確認してください。さまざまな学習速度と期間を試し、最終的にここにたどり着きました。

各エポックで計算されたコストのリストと、最終的に更新されたシータが取得されます。この最終シータを使用して出力を予測します。

(8)出力を予測し、精度を計算する

出力を予測するには、単に hypothesis 関数を使用してこの更新された theta を渡すだけです。

  1. 出力、a、 z =仮説(df、theta)

精度を計算してみましょう。

  1. 精度= 0  
  2. iが範囲(0, len(out))内にある場合:
  3. jが範囲(0, len(out[i]))内にある場合:
  4. out[i][j] > = 0.5かつy1.iloc[i, j] == 1の場合:
  5. 精度 += 1
  6. 精度/長さ(自由度)

精度は100%です。完璧ですよね?ただし、常に 100% の精度が得られるとは限りません。データセットによっては、70% の精度が得られればかなり良い場合もあります。

おめでとうございます!これで完全なニューラル ネットワークが開発されました。

結論は

より単純な分類問題の場合、ロジスティック回帰は依然として非常に有効です。しかし、より複雑な問題の場合、ニューラル ネットワークの方がより良い結果を提供できます。ご覧のとおり、順方向伝播と逆方向伝播の両方を通じて、トレーニング データをより適切に学習します。ニューラルネットワークは、自然言語処理や画像分類などの分野で AI 業界で非常に優れたパフォーマンスを発揮しています。

以下は Github からの完全な動作コード リンクです。

https://github.com/rashida048/Machine-Learning-With-Python/blob/master/NeuralNetworkFinal.ipynb

<<:  2021年にはAI機能を導入する企業がますます増える

>>:  顔認識はどのようにして国民の個人情報を侵害するのでしょうか?犯罪者がアリペイを騙し取るために3D顔モデルを作成

推薦する

私たちは本当にロボットの「カンブリア紀の進化」に近づいているのでしょうか?

ロボット工学の分野は驚異的なスピードで進歩しており、多くの専門家がこの急速な発展を生物学における「カ...

ディープラーニングを使用してコンピュータービジョンのすべての作業を完了するにはどうすればよいですか?

コンピュータービジョンをやってみたいですか?最近では、ディープラーニングが主流となっています。大規模...

タオバオのメイン検索リコールシナリオにおけるマルチモーダル技術の探究

検索リコールは検索システムの基礎として、効果向上の上限を決定します。私たちが直面している主な課題は、...

周明氏との対話: ラストマイルを解決するために大きなモデルを使用するときは、理想主義にならないでください。

ゲスト | 周明執筆者 | Yun Zhaoある夜、湘源の湧き水が、広大で無限に湧き出しました。 C...

...

自然言語処理技術により、機械はより人間的な視点から問題を解決できるようになる。

編集者注: テクノロジーは、数学や物理学に関連する問題を解決する上で重要な役割を果たすことができます...

Google Brain エンジニアの講演: TensorFlow とディープラーニング

この記事は、Google Brain エンジニアの Zhou Yuefeng 氏が QCon Sha...

...

Programiz: 多くの人がChatGPTを使ってプログラミングを学んでおり、Web開発分野はAIの影響を最も受けやすい

プログラマー育成ウェブサイトProgramizは10月18日、ChatGPTがプログラミング教育分野...

教師あり学習、教師なし学習、強化学習とは何ですか?ついに誰かが明らかにした

[[337832]] 01 用語このセクションでは、機械学習の概要とその 3 つの分類 (教師あり学...

機械学習と人工知能の未来について語る

[[258702]] [51CTO.com クイック翻訳] 機械学習 (ML) と人工知能 (AI)...

...

人工知能とモノのインターネットの統合後の応用シナリオは何ですか?

AI をクラウドからエッジに移行することで、主要市場で IoT の幅広い導入を妨げてきた帯域幅とセ...

分散型コンセンサスアルゴリズム: 想像以上に複雑

1. 分散システムの難しさ張大鵬は難しい問題に遭遇した。彼らの会社には貴重なデータを保存しているサー...