1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

chainer.links.Linearを使って離散コサイン変換

Last updated at Posted at 2016-02-03

ざっとググったところ出てこなかったこともあり、メモ。
離散コサイン変換(Discrete Cosine Transform, DCT)をchainer.links.Linearクラスを使って作成してみました。

離散コサイン変換とは、高速フーリエ変換(Fast Fourier Transform, FFT)の親戚で、FFTの実数部を引き出すのと同じ意味合いになります。(詳しい解説は他の方の説明に頼ります)

以下の関数DCT(wave)を使うと、scipy.fftpack.dct(wave)と同じ結果が返ってくることを確認しました。
モジュールのimportは、Chainerのチュートリアルに準じて行っています。

DCT.py
def DCT(wave):
    num_base = np.size(wave.data[0,:])
    lDCT = L.Linear(num_base,num_base)
    for n in range(num_base):
        for k in range(num_base):
            lDCT.W.data[k,n] = 2*np.cos(np.pi*k*(2*n+1)/(2*num_base))
    lDCT.b.data[:] = 0.0
    return lDCT(wave)

私がはまった点は、
・Linearに渡すのはVariable形式
・np.array([[入力ベクトル]])のように、次元を2次元にして渡す
という点です。
これを使うとDCTを使ったChainや誤差関数を作れる(はず)です。(まだ未使用です)

(追記:2016年2月4日)
逆離散コサイン変換(Inverse DCT, IDCT)も作ってみました。
Scipyのドキュメントより、scipy.fftpack.dct(wave)はデフォルトでType2を返します。
この場合逆変換はType3を使用すればよいので、実装は以下の通りとしました。

IDCT.py
def IDCT(wave):
    num_base = np.size(wave.data[0,:])
    lIDCT = L.Linear(num_base,num_base)
    for n in range(num_base):
        for k in range(num_base):
            if(n==0):
                lIDCT.W.data[k,n] = 0.0
            else:
                lIDCT.W.data[k,n] = 2*np.cos(np.pi*(k+0.5)*n/num_base)
    lIDCT.b.data[:] = wave.data[0,0]
    return lIDCT(wave)

このIDCTの注意点は、バッチ処理には使えない(!)ということです。
よりよい実装があればよいのですが。。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?