cBlog

Tips for you.

ゼロから作るSRCNN(超解像畳み込みニューラルネットワーク)

スポンサーリンク
※当ブログのAmazon、iTunes、サウンドハウス等のリンクはアフィリエイトを利用しています。

ゼロから作るDeep Learning [1]に倣い、SRCNN (Super-Resolution Convolutional Neural Network) [2]をディープラーニングフレームワークを使わずに作りました。ディープラーニングによる超解像の学習にご利用ください。

github.com

ゼロから作るDeep Learningのコードをコピペではなく一応理解しながら自分のスタイルで書きましたが、写経には違いないので本家のフォークとしてみました。GitHubビギナーなのでフォークの流儀はよくわかりません。貢献するつもりがないのならフォークするなみたいなことも見かけました[3]。結局フォークとしましたが、本家へコントリビュートする気は今のところありません。(余談は後述)

CPUなので重いです。思ったよりも収束性が悪く、コード自体は4日ほどで大体書けたのですがイタレーションが少ないとボケたままなので、それに気づくまで悩みました。PlaidMLがちゃんと動くようになったら使いたいです。

 

勾配の導出

ほとんど[1]に揃っていたので、自分でやる必要があったのは層を重ねるところとこれくらいでした。

出力層をMSEAsLossレイヤとして実装しました。順伝播時は畳み込み結果から二乗誤差を出力し、逆伝播時は入力の勾配倍を出力します。推論時は畳み込み最終層の出力を結果とします。

損失関数が

\begin{align}
L(\Theta) &= \frac{1}{N} \sum_{n = 1}^N \|F(\mathbf{Y}_n; \Theta) - \mathbf{X}_n\|^2 \\
&= \frac{1}{N} \sum_{n = 1}^N \sum_{c = 1}^C \sum_{i = 1}^I \sum_{j = 1}^J (F(Y_n(c, i, j); \Theta) - X_n(c, i, j))^2
\end{align}

なので(論文と添字は変えています)、勾配は

\begin{align}
\frac{\partial L}{\partial Y_n(c, i, j)} = \frac{2}{N} (F(Y_n(c, i, j); \Theta) - X_n(c, i, j))
\end{align}

となるかと思います。基本、論文に忠実に実装したので損失関数とPSNRで正規化を分けていますが、ここで一気にNCIJで割る方が素直だと思います。その他、重みの初期化法や畳み込みの最終層だけ重みを変えているところも再現しています。

 

軽く結果

人物画像を学習させて試してみました。アップスケーリング率は3。1024枚の33x33の画像(輝度情報のみ)をバッチサイズ64で2000エポック回してみた結果です。13時間かかりました(2コアCore i7 3.1 GHz)がまだ収束していないような… 64枚の画像をバッチサイズ8で5000エポック回してやっと収束したかなという感じです(それでも170分)。Momentumだしクソ初期値だしBatch Normalizationなしですけどね。ここで言っている収束とは、収束曲線出力する余力がなかったのでターミナルに流れる数字を目で追ってみた印象ですが、やっぱりCPUきつい。GPUのパワーが欲しくなりました。

前話が長くなりましたが、結果です。左からBicubic(入力)、SRCNN(出力)、オリジナルです。人物画像、論文にある画像2枚、絵を載せます。

 

人物画像

SRCNNの出力結果(人物画像)

32.11 dB→32.68 dB

 

butterfly

SRCNNの出力結果(butterfly)

22.69 dB→23.32 dB

 

zebra

SRCNNの出力結果(zebra)

25.37 dB→26.46 dB

 

popup_miku [4]

SRCNNの出力結果(popup_miku)

24.82 dB→25.27 dB

 

くっきりしたけどジャギる。

 

余談

MITライセンスなので改変は認められていると思いますが、オリジナルのソースコードを改変して公開したい場合、ライセンス表記をどうすればいいのか迷いました。とりあえずライセンスの継承を示したくて、LICENSE.md(自分)の他にLICENSE_ORIGINAL.md(フォーク元)を作ってみましたがこれでいいのかどうか。[5][6]では併記の例があります。

フォークせずにコード書き始めたのでcloneするのが怖かったです。だから、cloneじゃなくinitしてpushしたら当然蹴られたのでgit push -f origin masterしたらフォーク元の作業履歴吹き飛ばしちゃった////

 

おわりに

ディープラーニングやPythonは理解した気でいましたが、やっぱり自分で書くとわかっていないところが浮き彫りになりますね。高度な超解像技術を実装するのは夢でした。今後、オリジナルの手法*1を考案できたらと思います。

 

参考文献

[1]

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

 

[2] [1501.00092] Image Super-Resolution Using Deep Convolutional Networks

[3] >fork する意味 github には fork という機能がある。fork は git...

[4] "For Creators," http://piapro.net/en_for_creators.html

[5] github - How do I adapt an existing licence from a forked project giving all due credit to the original author? - Stack Overflow

[6] github - MITライセンスのソフトウェアをフォークした場合のライセンス表記 - スタック・オーバーフロー

*1:昔言ってたやつは失敗した