まだ理解していないフーリエ変換。ニューラルネットワークはそれを学習するのにたった30行以上のコードしか使用しませんでした

まだ理解していないフーリエ変換。ニューラルネットワークはそれを学習するのにたった30行以上のコードしか使用しませんでした

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載しています。転載の際は出典元にご連絡ください。

私たちの生活において、天体観測から MP3 プレーヤーのスペクトルまで、すべてはフーリエ変換なしでは不可能でしょう。

簡単に言えば、離散フーリエ変換 (DFT)とは、複雑な波形を異なる周波数成分に分割することです。

たとえば、音波レコーダーを使用して音を表示すると、実際には、生活の中での音のほとんどは非常に複雑で、混沌としています。

フーリエ変換により、これらの混沌とし​​た音波は正弦波に変換され、私たちが普段目にする音楽スペクトルの姿になります。

[[403197]]

しかし、実際の計算では、このプロセスは実は非常に複雑です。

音波を連続関数とみなすと、一連の三角関数の重ね合わせとして一意に表現できます。ただし、重ね合わせのプロセスでは、各三角関数の重み係数が異なります。増やす必要があるものもあれば、減らす必要があるものもあり、増やす必要がないものもあります。

フーリエ変換は、これらの三角関数とそれぞれの重みを求めることです。

なんと偶然でしょう!この検索プロセスはニューラル ネットワークと非常によく似ています。

ニューラル ネットワークの本質は、実際には関数を近似することです。

ニューラルネットワークをトレーニングしてフーリエ変換を解くことはできないのでしょうか?

これは実際に実現可能であり、最近誰かが彼のトレーニングプロセスと結果をオンラインで投稿しました。

DFT = ニューラルネットワーク

ニューラルネットワークをトレーニングするにはどうすればいいですか?このネットユーザーが提示したアイデアは以下の通り。

まず、離散フーリエ変換 (DFT) を人工ニューラル ネットワークとして考えます。これは、バイアスや活性化関数がなく、重みに特定の値を持つ単層ネットワークです。出力ノードの数は、フーリエ変換計算後の周波数の数に等しくなります。

具体的な方法は以下の通りです。

これが DFT です:

  • k はN サンプルあたりのサイクル数を表します。
  • N は信号の長さを表します。
  • サンプル n における信号の値を表します。

信号はすべての正弦波信号の合計として表すことができます。

yk は、信号 x 内の周波数 k の正弦波に関する情報を提供する複素値です。yk から正弦波の振幅と位相を計算できます。

行列形式では、次のようになります。

以下は、k の特定の値に対するフーリエ値です。

ただし、通常は、完全なスペクトル、つまり [0,1,...N-1] の k の値を計算します。これは、行列で表すことができます (k は列ごとに増加し、n は行ごとに増加します)。

簡略化すると次のようになります。

これは、バイアスとアクティベーション関数のないニューラル ネットワーク層なので、見覚えがあるはずです。

指数行列には、複素フーリエ重みと呼ばれる重みが含まれています。通常、ニューラル ネットワークの重みはわかりませんが、ここではわかります。

  • 複数形なし

ニューラル ネットワークでは通常、複素数は使用しません。これに対応するには、行列のサイズを 2 倍にして、左側に実数が含まれ、右側に虚数が含まれるようにする必要があります。

意思

DFT に代入すると次のようになります。

次に、実数部 (余弦形式) を使用して行列の左半分を表し、虚数部 (正弦形式) を使用して行列の右半分を表します。

簡略化すると次のようになります。

意思

これをフーリエ重みといいます。

y^とyは実際には同じ情報を含んでいるが、y^

複素数は使用されていないため、長さは y の 2 倍になります。

つまり、

または

振幅と位相を表すが、通常は

ここで、ネットワークにフーリエ層を追加します。

フーリエ重みを使用してフーリエ変換を計算する

ニューラルネットワークを使って実装できるようになりました

高速フーリエ変換 (FFT) を使用して正しいことを確認します。

  1. matplotlib.pyplot を plt としてインポートします
  2. y_real = y[:, :信号長]
  3. y_imag = y[:, 信号長:]
  4. tvals = np.arange(信号長).reshape([- 1 , 1 ])
  5. freqs = np.arange(signal_length).reshape([ 1 , - 1 ])
  6. arg_vals = 2 * np.pi * tvals * freqs / signal_length
  7. 正弦波 = (y_real * np.cos(arg_vals) - y_imag * np.sin(arg_vals)) / 信号長
  8. 再構築された信号 = np.sum(正弦波、軸 = 1 )
  9. print( 'rmse:' , np.sqrt(np.mean((x - reconstructed_signal)** 2 )))
  10. plt.サブプロット( 2,1,1 )
  11. plt.plot(x[ 0 ,:]) をプロットします。
  12. plt.title( '元の信号' )
  13. plt.サブプロット( 2,1,2 )
  14. plt.plot(再構築された信号)
  15. plt.title( 'DFT 後の正弦波から再構成された信号' )
  16. plt.tight_layout()
  17. plt.show()
  1. 実効平均値: 2.3243522568191728e -15

得られた小さな誤差値は、計算された結果が目的のものであることを証明します。

  • 別のアプローチは信号を再構築することです。
  1. matplotlib.pyplot を plt としてインポートします
  2. y_real = y[:, :信号長]
  3. y_imag = y[:, 信号長:]
  4. tvals = np.arange(信号長).reshape([- 1 , 1 ])
  5. freqs = np.arange(signal_length).reshape([ 1 , - 1 ])
  6. arg_vals = 2 * np.pi * tvals * freqs / signal_length
  7. 正弦波 = (y_real * np.cos(arg_vals) - y_imag * np.sin(arg_vals)) / 信号長
  8. 再構築された信号 = np.sum(正弦波、軸 = 1 )
  9. print( 'rmse:' , np.sqrt(np.mean((x - reconstructed_signal)** 2 )))
  10. plt.サブプロット( 2,1,1 )
  11. plt.plot(x[ 0 ,:]) をプロットします。
  12. plt.title( '元の信号' )
  13. plt.サブプロット( 2,1,2 )
  14. plt.plot(再構築された信号)
  15. plt.title( 'DFT 後の正弦波から再構成された信号' )
  16. plt.tight_layout()
  17. plt.show()
  1. 実効平均値: 2.3243522568191728e -15

最後に、DFT 後の正弦波信号から再構成された信号と元の信号がうまく重なり合っていることがわかります。

勾配降下法によるフーリエ変換の学習

ここで、ニューラル ネットワークが実際に学習する部分が来ます。このステップでは、以前のように重みを事前に計算する必要はありません。

まず、FFT を使用してニューラル ネットワークをトレーニングし、離散フーリエ変換を学習します。

  1. テンソルフローをtfとしてインポートする
  2. 信号長 = 32
  3. # トレーニング用の重みベクトルを初期化します:
  4. W_learned = tf.Variable(np.random.random([signal_length, 2 * signal_length]) - 0.5 )
  5. # 比較のための予想重量:
  6. W_expected = create_fourier_weights(信号長)
  7. 損失 = []
  8. rmses = []
  9. i が範囲( 1000 )内である場合:
  10. # 各反復ごとにランダムな信号を生成します。
  11. x = np.random.random([ 1 , 信号長]) - 0.5
  12. # FFT を使用して期待される結果を計算します。
  13. fft = np.fft.fft(x)
  14. y_true = np.hstack([fft.real, fft.imag])
  15. tf.GradientTape() をテープとして使用:
  16. y_pred = tf.matmul(x, W_learned)
  17. 損失 = tf.reduce_sum(tf.square(y_pred - y_true))
  18. # 勾配降下法で重みをトレーニングする:
  19. W_gradient = テープ.gradient(損失、W_learned)
  20. W_learned = tf.Variable(W_learned - 0.1 * W_gradient)
  21. 損失.append(損失)
  22. rmses.append(np.sqrt(np.mean((W_learned - W_expected)** 2 )))
  1. 最終損失値1 .6738563548424711e- 09
  2. 最終重みのrmse値3.1525832404710523e -06

結果は上記の通りであり、ニューラル ネットワークが実際に離散フーリエ変換を学習できることが確認されています。

DFTを学習するためのネットワークのトレーニング

高速フーリエ変換法を使用するだけでなく、ネットワークを通じて入力信号を再構築することによって DFT を学習することもできます。 (オートエンコーダと同様)。

オートエンコーダ(AE)は、半教師あり学習や教師なし学習で使用される人工ニューラルネットワーク(ANN)の一種です。その機能は、入力情報を学習対象として、入力情報に対する表現学習を行うことです。

  1. W_learned = tf.Variable(np.random.random([signal_length, 2 * signal_length]) - 0.5 )
  2. tvals = np.arange(信号長).reshape([- 1 , 1 ])
  3. freqs = np.arange(signal_length).reshape([ 1 , - 1 ])
  4. arg_vals = 2 * np.pi * tvals * freqs / signal_length
  5. cos_vals = tf.cos(arg_vals) / 信号長
  6. sin_vals = tf.sin(arg_vals) / 信号長
  7. 損失 = []
  8. rmses = []
  9. i が範囲( 10000 )内である場合:
  10. x = np.random.random([ 1 , 信号長]) - 0.5
  11. tf.GradientTape() をテープとして使用:
  12. y_pred = tf.matmul(x, W_learned)
  13. y_real = y_pred[:, 0 :信号長]
  14. y_imag = y_pred[:, 信号長:]
  15. 正弦波 = y_real * cos_vals - y_imag * sin_vals
  16. 再構築された信号 = tf.reduce_sum(正弦波、軸 = 1 )
  17. 損失 = tf.reduce_sum(tf.square(x - 再構築された信号))
  18. W_gradient = テープ.gradient(損失、W_learned)
  19. W_learned = tf.Variable(W_learned - 0.5 * W_gradient)
  20. 損失.append(損失)
  21. rmses.append(np.sqrt(np.mean((W_learned - W_expected)** 2 )))
  1. 最終損失値4 .161919455121241e- 22
  2. 最終重みのrmse値0.20243339269590094

著者はこのモデルで多くのテストを実行しましたが、最終的に得られた重みは上記の例ほどフーリエ重みに近いものではありませんが、再構築された信号は一貫していることがわかります。

代わりに振幅と位相を入力してみましょう。

  1. W_learned = tf.Variable(np.random.random([signal_length, 2 * signal_length]) - 0.5 )
  2. 損失 = []
  3. rmses = []
  4. i が範囲( 10000 )内である場合:
  5. x = np.random.random([ 1 , 信号長]) - .5
  6. tf.GradientTape() をテープとして使用:
  7. y_pred = tf.matmul(x, W_learned)
  8. y_real = y_pred[:, 0 :信号長]
  9. y_imag = y_pred[:, 信号長:]
  10. 振幅 = tf.sqrt(y_real** 2 + y_imag** 2 ) / 信号長
  11. 位相 = tf.atan2(y_imag, y_real)
  12. 正弦波 = 振幅 * tf.cos(arg_vals + 位相)
  13. 再構築された信号 = tf.reduce_sum(正弦波、軸 = 1 )
  14. 損失 = tf.reduce_sum(tf.square(x - 再構築された信号))
  15. W_gradient = テープ.gradient(損失、W_learned)
  16. W_learned = tf.Variable(W_learned - 0.5 * W_gradient)
  17. 損失.append(損失)
  18. rmses.append(np.sqrt(np.mean((W_learned - W_expected)** 2 )))
  1. 最終損失値2 .2379359316633115e- 21
  2. 最終重みのrmse値0.2080118219691059

再構築された信号が再び一貫していることがわかります。

ただし、前と同様に、振幅と位相を入力して得られる最終的な重みは、フーリエ重みとまったく同じではありません(ただし、非常に近い値になります)。

このことから、最終的な重みは最も正確ではないものの、局所的な最適解が得られるという結論が導き出されます。

このようにして、ニューラル ネットワークはフーリエ変換を学習しました。

  • この方法についてはまだ疑問が残ることを指摘しておく価値がある。

まず、計算された重みが実際のフーリエ重みとどの程度異なるかが説明されていません。

さらに、モデルにフーリエ層を含めることでどのような利点が得られるのかは明らかではありません。

<<:  「コピー+貼り付け」に別れを告げ、ディープラーニングOCRに基づくPDFからテキストへの変換を実現

>>:  AIを活用してパイロットプロジェクトを計画する方法

ブログ    
ブログ    
ブログ    

推薦する

2022 年に AI はサイバーセキュリティ分野に何をもたらすでしょうか?

[[439421]] [51CTO.com クイック翻訳]近年、人工知能(AI)は私たちの日常生活...

...

さまざまな業界がエッジAIから得られるメリット

ご存知のとおり、人工知能は計算能力を消費し、多数のデータセンターを必要とします。 しかし、適切な状況...

自動化された機械学習は AI 研究の次の主流となるでしょうか?データサイエンティストの意見

自動化された機械学習は、過去 1 年間で大きな関心を集めるトピックになりました。 KDnuggets...

汎用人工知能(AGI)の分野で達成すべき4つの大きなマイルストーン

GPT と GAN で多くの進歩があったにもかかわらず、AGI は解決が難しい問題のままです。本質的...

...

警告! 「リップリーディング」キーでデータを盗む、AIは本当に怖い

コンピューターに頼って悪者を即座に見つけることができれば素晴らしいのですが、問題は AI システムが...

適切な機械学習アルゴリズムを簡単に選択する方法を教えます。

[[327632]] 【51CTO.com クイック翻訳】この質問に対する単純で明確な答えはありま...

Googleは従業員に対し、生成AIの秘密を「漏らしたり」、直接コードを書いたりしないように警告している。

ロイター通信によると、6月15日のニュースでは、Googleは生成AIの最も熱心な支持者の1つである...

...

ナレッジグラフは銀行のビジネスモデルをどのように変えるのでしょうか?

金融部門は、個人の購入から大規模な取引まで、莫大な富につながる大量の貴重なデータを定期的に生成してお...

従来のセキュリティ手法を覆し、AIがWebセキュリティを再定義

Amazonが2006年にEC2サービスをリリースしてから11年が経ちました。この 11 年間で、A...

倪光南:AI開発は教訓を学ぶべき、コア技術は購入したり置き換えたりすることはできない

「ここ数年、情報技術分野で私たちが学んだ最大の教訓の一つは、主要な中核技術は私たち自身の独立したイノ...

数秒で理解:小売業における画像認識

【51CTO.comオリジナル記事】スーパーマーケットに入ったところを想像してみてください。計量のた...