ニューラルネットワークで入力を変換し、有用な出力を抽出する方法


9

機械学習に関するAdam Geitgeyのブログに出会ってからずっと、ニューラルネットワークを理解しようと努めてきました。私はできる限り多くのことを読んで(把握できる)、幅広い概念といくつかの仕組み(数学は非常に弱いにもかかわらず)、ニューロン、シナプス、重み、コスト関数、逆伝播を理解していると信じていますしかし、実際の問題をニューラルネットワークソリューションに変換する方法を理解することはできませんでした。

ポイントのケースは、アダムGeitgeyは、使用例、を含むデータセット所与住宅価格予測システムとして与える寝室の特許スクエアを。フィート近隣、および販売価格では、ニューラルネットワークをトレーニングして家の価格を予測できます。ただし、コードで可能なソリューションを実際に実装するまでには至っていません。例として、彼に最も近いのは、重みを実装する方法を示す基本的な関数です。

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
  price = 0

  # a little pinch of this
  price += num_of_bedrooms * 1.0

  # and a big pinch of that
  price += sqft * 1.0

  # maybe a handful of this
  price += neighborhood * 1.0

  # and finally, just a little extra salt for good measure
  price += 1.0

  return price 

他のリソースは数学に重点を置いているようで、理解できる唯一の基本的なコード例(つまり、すべてが歌うわけではなく、すべてが踊るイメージ分類コードベース)は、ニューラルネットワークをXORにトレーニングする実装です1と0のみを扱うゲート。

ですから、私の橋渡しができないように見えるというギャップがあります。住宅価格予測問題に戻ると、ニューラルネットワークへのフィードにどのようにデータを適合させることができるでしょうか。例えば:

  • ベッドルーム数:3
  • 平方 フィート:2000
  • エリア:ノーマルタウン
  • セール価格:$ 250,000

32000は数値なので、ニューラルネットワークに直接フィードできますか?または、それらを別のものに変換する必要がありますか?同様に、Normaltownの値、つまり文字列についてはどうですか。ニューラルネットワークが理解できる値に変換するにはどうすればよいでしょうか。データ全体で一貫している限り、インデックスのような数値を選択できますか?

私が見たほとんどのニューラルネットワークの例では、レイヤー間を通過する数値は0から1または-1から1のいずれかです。処理の最後に、出力値を$ 185,000などの使用可能な値に変換するにはどうすればよいですか。

住宅価格予測の例は、3つのデータポイントに大幅に簡略化されているため、おそらく特に有用な問題ではありません。しかし、私はこのハードルを乗り越えて、疑似現実のデータを使用してトレーニングし、疑似現実の答えを吐き出す非常に基本的なアプリを書くことができれば、私はそれを後退させてキックできると思うだけです機械学習についてさらに掘り下げます。

回答:


10

これは、最初にANNをコーディングしようとしたときに自分と取り組んだ良い質問です。

以下は、優れた汎用ソリューションであり、適切に動作する数値データを予測するためにコードに実装したものです。データが適切に動作していない場合(つまり、外れ値が多い場合)、入力と出力を正規化する作業をさらに行う必要がある場合があります。ここでは、より高度な方法のいくつかについて説明します

注:アクティベーション関数としてf(x)= tanh(x)を使用していると想定します。そうでない場合でも、これを読んだ後にデータを正規化する方法を推論できるはずです。

入力データを準備する方法:

基本的な考え方は、各入力パラメーターの大幅な変動を、それらの入力がフィードされるニューロンのアクティブ化の大幅な変動に反映させることです。tanh(x)作動関数の導関数のプロットを見ると、有意な勾配の領域が原点から1または2の距離内にあることがわかります。これは、活性化関数への入力が2000または3000(導関数が無視できるほど小さいxの値)であるかどうかに関係なく、活性化の出力はほぼ同じになるため、ニューロンの状態は、 2000と3000。ネットワークは、その範囲の値から予測力を生み出すことはありません。

したがって、家の平方フィートをニューロンに入力する場合は、平方フィートを正規化して、ネットワークが2000と3000の違いを認識できるようにする必要があります。これを行う1つの方法として、データは、ニューロンが入力zスコア正規化することで「通知」されます。

  • (トレーニングセットから)すべてのフッテージ値を収集し、平均と標準偏差を計算します。平均と標準偏差を保存します---テスト時に新しい平方フィートの値を正規化するには、この情報が必要です。

  • 平均を差し引き、結果を標準偏差で割ることにより平方フッテージ値のベクトルを正規化します(もちろん、要素ごとにすべての演算)。平均を差し引くと、データの中心が原点になり、標準偏差で除算すると、そのほとんどが-1から1の間になるため、ニューロンの出力は入力に最も敏感になります。これは、各入力値がそのz-scoreに置き換えられるため、z-score正規化と呼ばれます。

  • 入力変数ごとに上記を実行します。

ここで、ニューロンを介して各入力値を置くと、ニューロンの出力は-1と1の間のアクティブ化になります(tanh(x)の画像を見てください)。これは既にアクティベーション関数の「敏感な」範囲にあるため、最初の非表示レイヤーに送信する前に、入力レイヤーニューロンの出力を変更することを心配する必要はありません。隠れ層のニューロンに前の層の出力を直接与えるだけです-それらはそれらをうまく処理することができます。

最後の層(出力ニューロン)に到達すると、再び-1と1の間の別のアクティブ化が得られます。これを問題の家の値に変換し直す必要があります。その値を次のように使用するかどうかテストセットの予測、またはトレーニング中のエラーの計算。ただし、これを行うには、一貫していて、トレーニングとテストで同じ非正規化手順を使用する必要があります。これについて考える1つの方法は、出力ニューロンが1を返す場合、ネットワークが予測として可能な最大の家の値を返すことを意味します。ネットワークが見積もることができる最高の価値は何ですか?ここでの正しいアプローチは、単にアプリケーションによって異なります。これは私がやったことです:

  • [the / each]出力変数の平均を計算して保存します。
  • 平均からの出力変数の最大偏差を計算します。Python:MaxDev = max([abs(DataPoint-numpy.mean(TrainingData)) for DataPoint in TrainingData])
  • ネットワークが-1と1の間の出力を返す場合、出力を乗算MaxDevして平均に追加します。

正規化-再正規化スキームが適切かどうかを確認するために実行できる2つの基本的なクイックチェック(これらは必要ですが、おそらく十分な条件ではありません):

  1. すべての入力値が平均(たとえば、寝室の平均数、平均平方フィートなど)である場合、ネットワークの出力は、出力変数(たとえば、家の値)の平均と同じですか?(そのはず。)
  2. すべての入力値が異常に高い/低い場合、ネットワークの出力も異常に高い/低いですか?(これは、すべての入力が出力に明確に関連している場合にのみ機能します...それらのいくつかが逆に関連している場合は、もう少し考える必要があります)。

ここで紹介するスキームがこれら2つの条件を満たすことを確認してください。

このスキームでは、ネットワークでトレーニングデータセットの家の値の範囲の家の値のみを予測できることに注意してください。アプリケーションによっては、この動作が望ましい場合と望ましくない場合があります。

たとえば、ネットワークで負の家の値を予測できないようにする場合があります。これをどのように行うかを考えてください。-1が0にマップされるように、出力を非正規化します。

ネットワークが予測できる値に制限を設定しない場合は、[-1,1]の範囲をすべての実数にマップする関数を介してネットワークの出力を実行できます... arctanh(x)のように!トレーニング中にこれを行う限り、ネットワークはこれに対応するように重みを調整します。

これがお役に立てば幸いです。他にご不明な点がありましたらお知らせください。ちなみに私のANNモジュールはPythonなので、言語固有のアドバイスがあるかもしれません。


これはとても役に立ちました!私が遭遇するすべてのブログ/チュートリアルは、このプロセスを(ほとんど故意に)説明することを避けているようですが、はい、すべてが理にかなっています。正しく消化するのにしばらく時間がかかりますが、フォローアップの質問があれば戻ってきます。とても感謝しております!
デビッド

いくつか質問があります。私の平方なら 足のトレーニングデータが{2000、800、850、550、2000}だった場合、{1900、1500、600}のzスコア入力は(正しく計算されていれば){1.0496、0.4134、-1.0177}になります。したがって、これらの値の1つは1より大きく、1つは-1より小さくなります。それらを入力層ノードに入力するか、1&-1に丸めるか?1900と600がこれらの値を550〜2000の範囲内にあるのに生成するのはなぜですか?このような小さなデータセットがあるので、これは単なるデータのトリックですか?
デビッド

0andthemaximum

入力は厳密に1から-1の間である必要はないことに注意してください。入力に必要なのは、ほとんどのデータがその範囲内にあることだけです。1より大きいまたは小さい値は、ポイントが平均から複数の標準偏差から離れていることを意味し、そのポイントはデータの上限に近くなります。データが[-1、1]の外に出るのは少しまれで、[-2、2]の外に出るのはさらにまれで、[-3、3]の外に出るのは非常にまれです。tanh(x)を見ると、高感度範囲が厳密に-1と1の間にあるだけでなく、それよりも少し遠くにあることがわかります。
MarkoBakić2017

出力の非正規化に関して、そのmin-max非正規化は私が私の実装で行ったことであり、あなたの解釈は正しいですが、必ずしもそうする必要はありません。1が家の最大値の2倍に対応するようにすることもできます。これにより、ネットワークは、訓練した値を超える家の値を予測できます。
MarkoBakić2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.