Python 中国語コミュニティ (ID: python-china) 人工ニューラル ネットワーク (ANN) は、人間の監視を必要とする多くの日常的なタスクにうまく適用されてきましたが、その複雑さのために、その仕組みやトレーニング方法を理解することは困難です。 このブログでは、ニューラル ネットワークとは何か、どのように機能するか、外れ値の検出や金融時系列の予測などの問題にどのように適用するかについて詳しく説明しました。 この記事では、シンプルなフィードフォワード ニューラル ネットワークがトレーニング中に一連の入力をさまざまな空間にマッピングして、より簡単に理解できるようにする方法を視覚的に示します。 データ仕組みを示すために、まず「おもちゃ」のデータセットを作成しました。 2 つのクラス (0 と 1) に均一に分散された 400 個のサンプルが含まれ、各サンプルには 2 つの次元 (X0 と X1) があります。 注: すべてのデータは、平均 [-1, 0, 1]、標準偏差 [0.5, 0.5, 0.5] の 3 つのランダム正規分布から取得されています。 ネットワークアーキテクチャ次のステップは、ANN の構造を次のように定義することです。 隠し層は最小の次元 (2 ニューロン) を持ち、ネットワークが各サンプルの位置を 2D 散布図にマッピングしていることを示します。 前の図には示されていませんが、各レイヤーには出力を変更するアクティベーション関数があります。 •入力層には、入力値を複製するための線形活性化関数があります。 • 隠れ層には ReLU または tanh 活性化関数があります。 •出力層には、入力値を[0, 1]の範囲に「縮小」するシグモイド活性化関数があります。 電車ネットワークのアーキテクチャに加えて、ニューラル ネットワークのもう 1 つの重要な側面はトレーニング プロセスです。 ANN をトレーニングする方法は多数ありますが、最も一般的なのはバックプロパゲーション プロセスです。 バックプロパゲーション プロセスでは、まずすべてのトレーニング例 (またはバッチ) がネットワークに送られ、次にオプティマイザーが損失関数に基づいてネットワークの重みを更新する方法を計算し、学習率に基づいて重みを更新します。 損失が収束するか、一定数のエポックが経過するか、ユーザーがトレーニングを停止すると、トレーニング プロセスは停止します。エポックとは、すべてのデータがネットワークに送信され、順方向計算 + 逆伝播プロセスが完了することを意味します。 私たちのケーススタディでは、隠れ層の 2 つの異なる活性化関数 (ReLU と Tanh) と 3 つの異なる学習率 (0.1、0.01、0.001) を使用してアーキテクチャをトレーニングしました。 入力サンプルの周囲には、その場所のサンプルに対してモデルによって提供される予測確率を示す点の「グリッド」があります。これにより、モデルはトレーニング中により明確な境界を生成できるようになります。 - # 進化を抱くフィギュア
- f,軸= plt .subplots(1, 3, figsize =(18, 6), gridspec_kw ={'height_ratios':[.9]})
- f.subplots_adjust(上= 0 .82)
- # 進化を記録するカメラ
- カメラ=カメラ(f)
- # エポック数
- エポック= 20
- # エポックタイムを繰り返す
- i が範囲(エポック)内である場合:
- # モデルを評価する (acc, loss)
- 評価=モデル.evaluate(x_train, y_train, verbose = 0 )
- # 中間モデルを生成する
- model_hid_1 =モデル(model.input、model.get_layer("hidden_1").output)
- model_act_1 =モデル(model.input、model.get_layer("activation_1").output)
- # データを生成する
- df_hid_1 = pd .DataFrame(model_hid_1.predict(x_train)、列=['X0'、'X1'])
- df_hid_1['y'] = y_train
- df_act_1 = pd .DataFrame(model_act_1.predict(x_train)、列=['X0'、'X1'])
- df_act_1['y'] = y_train
- # メッシュグリッドを生成(200 個の値)
- x = np .linspace(x_train[:,0].min(), x_train[:,0].max(), 200)
- y = np .linspace(x_train[:,1].min(), x_train[:,1].max(), 200)
- xv, yv = np.meshgrid (x, y)
- # メッシュグリッドの強度を生成する
- df_mg_train = pd .DataFrame(np.stack((xv.flatten(), yv.flatten()), axis = 1 ), columns = ['X0', 'X1'])
- df_mg_train['y'] = model.predict(df_mg_train.values)
- df_mg_hid_1 = pd .DataFrame(model_hid_1.predict(df_mg_train.values[:,:-1]),列=['X0', 'X1'])
- df_mg_hid_1['y'] = model.predict(df_mg_train.values[:,:-1])
- df_mg_act_1 = pd .DataFrame(model_act_1.predict(df_mg_train.values[:,:-1]),列=['X0', 'X1'])
- df_mg_act_1['y'] = model.predict(df_mg_train.values[:,:-1])
- # データセットを表示
- ax = sns .scatterplot( x = 'X0' 、 y = 'X1' 、 data = df_mg_train 、 hue = 'y' 、 x_jitter = True 、 y_jitter = True 、 legend = None 、 ax = axes [0]、 palet = sns .diverging_palette(220, 20, as_cmap = True )、 alpha = 0 .15)
- ax = sns .scatterplot( x = 'X0' 、 y = 'X1' 、 data = df_train 、 hue = 'y' 、 legend = None 、 ax = axes [0]、 palet = sns .diverging_palette(220, 20, n = 2 ))
- ax.set_title('入力レイヤー')
- ax = sns .scatterplot( x = 'X0' 、 y = 'X1' 、 data = df_mg_hid_1 、 hue = 'y' 、 x_jitter = True 、 y_jitter = True 、 legend = None 、 ax = axes [1]、 palet = sns .diverging_palette(220, 20, as_cmap = True )、 alpha = 0 .15)
- ax = sns .scatterplot( x = 'X0' 、 y = 'X1' 、 data = df_hid_1 、 hue = 'y' 、 legend = None 、 ax = axes [1]、 palet = sns .diverging_palette(220, 20, n = 2 ))
- ax.set_title('非表示レイヤー')
- # 現在のエポックとメトリックを表示します
- ax.text( x = 0.5 、 y = 1.15 、 s = 'Epoch {}'. format(i+1)、 fontsize = 16 、 weight = 'bold' 、 ha = 'center' 、 va = 'bottom' 、 transform = ax.transAxes )
- ax.text( x = 0.5 、 y = 1.08 、 s = '精度 {:.3f} - 損失 {:.3f}'。 format(evaluation[1]、evaluation[0])、 fontsize = 13 、 ha = 'center' 、 va = 'bottom' 、 transform = ax.transAxes )
- ax = sns .scatterplot( x = 'X0' 、 y = 'X1' 、 data = df_mg_act_1 、 hue = 'y' 、 x_jitter = True 、 y_jitter = True 、 legend = None 、 ax = axes [2]、 palet = sns .diverging_palette(220, 20, as_cmap = True )、 alpha = 0 .15)
- ax = sns .scatterplot( x = 'X0' 、 y = 'X1' 、 data = df_act_1 、 hue = 'y' 、 legend = None 、 ax = axes [2]、 palet = sns .diverging_palette(220, 20, n = 2 ))
- ax.set_title('アクティベーション')
- # プロットを表示
- plt.show()
- # GIFを生成するための呼び出し
- カメラ.スナップ()
- # 損失< = 0.263 の場合は実行を停止します (必要ない場合は 200 回のループを回避します)
- 評価[0] < = 0.263の場合:
- 壊す
- # モデルを1エポックトレーニングする
- model.fit(x_train, y_train,エポック= 1 、詳細= 0 )
ReLU アクティベーション Tanh アクティベーション注: バイナリ分類問題を扱っているため、使用される損失関数はバイナリクロスエントロピーであり、オプティマイザーは Adam と呼ばれるオリジナルの確率的勾配降下法 (SGD) の修正版です。エポックが 200 に達するか、損失が 0.263 未満になると、モデルのトレーニングは停止します。 |