【AIアート】PortillaとSimoncelliのテクスチャ合成のPythonコードを公開しました。 A Parametric Texture Model based on Joint Statistics of Complex Wavelet Coeffcients
最終更新日: 2018/09/02 6:31am
こんにちは。経理の小高です。
明日から10日ほどお休みをいただきます(この間京都に行ってきたばかりだろ、という声もありますが)ので、この数カ月取り組んできた課題を整理しなくちゃと思いました。
ブログのカテゴリーをAIにしてありますが、今回はディープラーニングではなく「ディープラーニングが出てくる前」のテクスチャ合成法についてです。
かなり長くなっちゃいますがお付き合いください。
まず、Githubに2つのリポジトリをアップしました。両方ともPython3で書いた小さいコードです。
さて、本論です。
今から3カ月ほど前、いろいろな文献で以下の論文について言及されていることを知りました。
(注記)草稿の方がGoogle検索の上にでてくるのでご注意くださいませ。
雑誌掲載が2000年ですからディープラーニングが注目される(2012年)ずっと前。いろいろな論文や記事を見ている感じでは、最高の「テクスチャ合成アルゴリズム」と考えられてきたようです。
不思議なことにこの論文に関係する日本語のウェブポストが見つかりません。話題として古いというのもありますが、AIによるテクスチャ合成に関して大量の解説記事があるのと対照的です。
サンプルを使って、この論文のアルゴリズムで当時のテクスチャ合成がどの程度のレベルであったのか見てみましょう。
(注記)オリジナル画像の著作権は以下のサイトが所有しています。合成されたイメージは上のGithubに公開したコードで生成しました。
Representation and Synthesis of Visual Texture(NYU)
図:オリジナル画像(木肌)
図:合成した画像
図:オリジナル画像(人工的に生成したテクスチャ)
図:合成した画像
結構すごい、と思いました。論文はグレースケールのテクスチャを合成する方法について書かれていますが、ニューヨーク大学のウェブサイト(上記)にはカラーの例があります。
それに加えてMatlabのコードがダウンロードできます。Matlabのコードは、2000年にグレースケールバージョンが公開されて2009年にカラーバージョンが公開されています。最新のMatlab R2018aでも(少し直せば)動かすことができました。
ニューヨーク大学で開発したMatlabコード(Github)
図:オリジナル画像(ラディッシュ)
図:合成した画像
図:オリジナル画像(小石)
図:合成した画像
小石の例では少し崩れていますが、著者らは「〇の始点と終点が交わる」ことを検出するのが(この方法では)できないと書いています。それでもラディッシュの例などは結構いいです。オリジナル画像には左下に版権を表記する黄色い部分があります。合成した写像にある黄色に部分はこの影響と思われます(小石の例)。
さて、ここで以前のブログ「【AI】本物はどちら?? ディープラーニングモデルのとてつもなく感動的な性質」でとりあげたAIを使った方法(Gatysらによる合成法)ではどうなるかというと、以下のようになります。
図:AIで合成した画像(ラディッシュ)
図:AIで合成した画像(ラディッシュ)
どうでしょう。明らかにAI(ディープラーニングモデル)で合成した結果の方が「本物らしい」ですよね。Gatysらの論文でも触れられているように、左下の黄色い部分も再現されています(文字らしきものすら見えます。とはいえ、これはテクスチャではないですよね)。
さて、PortillaとSimoncelliの論文に戻ります。
タイトルが「Parametric Texture Model Based on Joint Statistics of Complex Wavelet Coefficient」となっています。これらは以下のような意味です。
- Parametric Texture Model => テクスチャを「数式で表されたモデル(確率モデル)」とする立場の論文です
- Joint Statistics => テクスチャを表現するピクセル値を、(単独ではなく)同時に考慮するという意味です。
- Complex Wavelet Coefficient => 周波数解析をフーリエ変換ではなくウェーブレット変換で行うという意味です。この変換は複素関数として定義されていて、ウェーブレット係数に基づいた特徴量を使用しましょう、と解釈できます。
こういったタイトルになっているのは、ある意味で「時代性」もありそうです。ウェーブレット変換は私が学生の頃(80年代)に使われ始めた方法です。この論文で利用されているのは(正確な意味で)ウェーブレットではないのですが、新規性があるのでタイトルにいれたのだと思います。2番目の同時性については、この論文が「勝とうとしている相手」との差別化が意識されていると思われます。
その相手は
Pyramid-Based Texture Analysis/Synthesis, Heeger and Bergen (1995)
のようです。Heegerらの論文では、テクスチャ合成をする際に「ピクセルの値は互いに独立」という仮定を置いていますが、Portillaらは「互いに関係する」という立場をとります。
これに関連しますが、PortillaとSimoncelliの論文(他にも同じテーマの論文があります)で必ず触れられているのがユレス(Julesz)による以下の論文です。
Visual Pattern Discrimination, Juresz(1962)
(注記)この論文はインターネットで購入しました。$35だったと記憶しています。
Portillaらによれば、Juleszの研究がテクスチャ研究の端緒だ、とのこと。上の論文は、コンピュータが出てきたばかりの時代に書かれています。最新のコンピュータを使えば(動物実験や視覚に障害のある人を探さなくても)視覚の研究ができると書かれているのが印象的でした。
この論文では、コンピュータで2種類のパターンを生成して「これらのパターンを見分けるための要因」が検証されています。コンピュータでパターンを生成するわけですから、前提条件として規則性(論文ではマイクロパターンという小さいパターンが使われます)とランダム性を決めなければなりません。Juleszは、画像(論文では画面)の点はお互いに関連をもっている、と仮定しています(N階のマルコフチェーンであるという意味)。
「視覚の冒険(下条信輔著、1995年)」という本が手元にあって、第1章がユレス(本ではユレシュ)先生のインタビューになっています。コンピュータを使って視覚研究を切り拓いたスーパーヒーローのようです。
マルコフ性を仮定することとN次の同時確率を考えることは同じですから、Portillaらは「Heegerらと違って、我々は(由緒正しい)Juleszの考えに基づいている」ということも主張したかったのだとも思われます。ただ、先のJulrszの論文には数学的記述はなく、あくまで視覚研究の論文でした。(門外漢の私にはユレスの研究についてこれ以上の意見を述べる資格がありません)。
最後にparametric texture modelという部分は、テクスチャ合成を「単なるアルゴリズムではなくて数学的なフレームワークの中で考えていきますよ」と宣言している部分。これはユレスの立場でもあります。
この論文を「読まなくちゃな」と思ったのも、これを知っておきたかったからです。
さて、前置きが長かったですが以上のことを踏まえればこの論文はほとんど読めます。
PortillaらはJuleszの立場をとりますので、テクスチャ(ピクセル)を均質な変化率(確率)をもつ2次元のマルコフチェーンとします。この仮定から(マルコフチェーンでおなじみの)エルゴード性などが議論されます。確率論的な記述方法で書かれていますが、とくに気にせず読んでしまうべきでしょう(レフリーから何か言われたのかもしれません)。
テクスチャを特徴づける量(特徴量)は制約関数(constraint functions)と呼ばれ、(前置きの長い議論がありますが)最終的には最急勾配法で最適化計算をします。
この論文には「肝心の特徴量が数式で表現されていない」という大問題があるのですけど、それ以前に(自分の不勉強のせいで)Steerable Pyramidというフィルターでドハマりしてしまいました。このフィルターは、イメージ的にはラプラシアンピラミッドと同様のものです。画像を段階的に縮小していくことで低周波要素を取り出します。上記のHeegerとBergen(1995)のテクスチャ合成もこれを用いた手法となっています。
フィルターは周波数領域で定義されます。周波数領域でフィルターを定義することは合理的な構成法です。その理由は
- 周波数領域でフィルターを定義することで「どの範囲の波を通過(非通過)させる」か簡単に定義できる。(視覚的にも表現できる)
- フィルターの適用は画像とフィルターの畳み込み演算ですが、周波数領域では単純な積となる。(畳み込みのフーリエ変換の性質)
です。この2つを合わせれば、パスさせる周波数を決めればいい、という単純なことになります。
Steerable Pyramidを定義するために、Portillaらの論文には以下の式が記載されています。
Portilla and Simoncelli (2000)より抜粋
このうちLは(周波数領域で定義された)ローパスフィルター、Hはハイパスフィルター、Bは(方向のある)バンドパスフィルターを示しています。BはHとGの積で表されています。座標系は極座標系で、Hは振幅、Gは位相(角度)に関する要素です。
これらのうち、Bが「Steerable(回転する)」というこのフィルターの特徴を表しています。なんでSteerableなのかは見てしまった方が速いです。下は4方向(上の式のK=4)のBの等高線図です(Githubのpythonコードで生成できます)。このフィルターを(フーリエ変換した)画像にかけ合わせます。紫の部分は0ですので、この領域の周波数はフィルターを通過しません。
図:Steerableなフィルター(周波数領域)
1周ぐるっと回っていますね。「360度方向を問わない」というのがSteerable Filterの「売り」です。逆をいえば、フィルターを使う際に「方向」を気にする必要がありません。「テクスチャを回転したら違うテクスチャと認識された!」ということが起こっては不都合です。
フィルターGをPortillaらの論文にあるのようにおくとSteerableにならない(上のような原点対象なフィルターにならない)、とずっと悩んでいました。それに加えて、論文タイトルにあるようなウェーブレットでもないし、複素関数でもありません。
結論をいうと、Portillaらの式からは(自分の納得できる)Steerable Pyramidを作成できず、以下の論文に助けてもらいました。
The Heeger-Bergen Pyramid-Based Texture Synthesis Algorithm, Briand,T. et al. (2014)
Briandらの論文には、「実関数」のSteerable Pyramidの完全な式が掲載されています。
Briand et a. (2014)より抜粋
Githubのpythonコードでは、上のG(最後の式)を使ってバンドパスフィルターを定義しています。(Briandさんありがとう!あなたたちの論文がなければできませんでした。)
Heegerらでも指摘されていますし、公開したpythonコードでの合成例(上記)からもわかるのですが、フィルターを(複素関数ではなく)実関数としても結果はあまり変わらないようです。
pythonのコードではnumpyのfftモジュールを使っています。フーリエ変換(画像ですから2次元のフーリエ変換)をすると複素数成分がでてきますが、それはそのままにして計算するようになっています。
Portillaらの方法は、ウェーブレット変換(波の時間領域と周波数領域への分解)ではないのですが、文を読む限りでは上記のフィルターをしてウェーブレットと呼んでいます(wavelet decompostionという言い方がちらほら出てきます)。また、論文中にヒルベルト変換対(係数の実部と虚部を直行させること)がでてくるのですが、この具体的な形が記載されていないのも悩んだ部分です。
Steerable Pyramidそのものは(この論文に関係なく)一般的に使えるフィルターなのですけど、「いい感じのPythonプログラム」が見つからなかったのも「はまり込んだ大きな理由」でした。いくつかGithubにありますが納得できない感じで。GithubにSteerable Pyramidのモジュールを独立して公開したのは、このためです。
Steerableフィルターの定義式は複数あるようです。以下の論文にSteerable Filterについて詳しくきさいされています(その他の参考文献はpythonの先頭のコメント中に記載しました)。具体的なフィルターについてはあまり詳しく調べていないのですけど、この論文を読む限りではSteerableであるための条件(Steerable Theorem)は緩いように感じました。興味深いのは、Steerableフィルターの具体的構成法として、ガウス関数の導関数を使っていることです。これを読むとSteerableフィルターがガボールフィルターの発展形なのだなと感じます。
Design and Use of Steerable Filters,W.Freeman and E.Adelson (1991)
ここまでできるとあとは「テクスチャ合成」の部分だけです。しかし、(先にも書きましたが)この論文には特徴量を表す数式がほとんどなく言葉で説明されています。。平均、分散、歪度、尖度といったものはそれでいいのですけど、auto-correlationとか言い始めると厳密にはなんなのですか?となってしまいます(自己相関という言葉は物理と統計ではちょいと違います)。
2.2節に特徴量が「言葉で」説明されています。
- Marginal Statistics:平均、分散、歪度、尖度、レンジ
- Coefficient Correlation:自己相関。タイトルにある同時性。
- Magnitude Correlation:フィルターBを通過した値の相互の相関。Magnitudeですから絶対値を使います。
- Cross-Scale Phase Correlation:わかりにくいですね。CrossはScaleとPhaseにかかっています。Cross -Scale Correlationは「ピラミッドの階層間の相関」を表します。ピラミッドの階層間に相関がある、という意味です。Cross-Phase Correlationはトリッキー。フィルターBを通過した値は極座標表示で位相をもっています。この位相を2倍した値との相関を特徴量します。エッジ抽出のためと書かれています。
最初、これを言葉通りに受け取って、そのままpythonでコード起こしたのですが全然ダメでした。
最終的にはPortillaらが配布しているMatlabコードを解析して「こういう特徴量を使うのかぁ」という作業を延々と続けてpythonにポーティングしました。
ノートに式を書き起こしながらやったのですが、結論を言えば「これは(論文に)書けないなぁ」という感じ。下はノートです。添え字が増えすぎて書ききれなくなってます。
図:ノートがぐちゃぐちゃなところ
詳しい特徴量についてはpythonのコードをごらんくださいませ。
さて、pythonを動かしていただくと実行中に落っこちるかもしれません。
理由は2つあります。
- 逆行列の算出や多項式の解法(これらはpythonのモジュールで行っています)がある。論文のAppendixの部分。Matlabからほぼほぼ同じにpythonに移しました。
- 有効桁数ってどうすればいいの?っていうくらい数字が暴れる
特に前者はかなり強引なコードになっています。
繰り返しの1回目でかなりはっきりテクスチャが再現されますので、Portillaらの特徴量によって、かなり正確にテクスチャを表現できることがわかります(驚き)。10回も繰り返せば収束する(これもすごい)し、軽いのでCPUで動かせます(これもすごい)。
長くなりましたね。最後にカラー画像についてです。
論文はグレースケールについて書かれていますが、カラー画像を扱う場合には、主成分分析(Principal Component Analysis)をつかってRGBチャネルを回転させ、新しい座標系からチャネルを取り出してグレースケールのロジックをあてはめます。
(原理的にはそうなのですが、配布されているMatlabコードにはカラー固有のロジックが組み込まれていました。pythonでグレースケールとカラーのコードが分かれているのはそのためです)
PCAの計算ロジックはBriandらに記載がありますが、pythonではscikit-learnにPCAというモジュールがあるのでこれを使うこともできます。公開したpythonでは普通に固有値、固有ベクトルから計算しています。これは「一般的なPCAの使い方(寄与率の高い軸だけ選んで次元を削減する)」と違って、PCAチャネルで合成したテクスチャを最終的にRBGチャネルに戻す必要があるためです。
また、PCAチャネルでは「チャネル間が無相関になる(逆に、これがPCAの目的です)」のですが、PortillaらのMatlabのコードではチャネル間の相関を計算するようにコードされています(理由は分かりません)。
また、matlabのコードに一部間違いがあって、「色の合成」がうまくありません。(pythonの方ではこの部分を修正しています。)
さて、ここくれば「なんでAIはすごいの?」という問いの答えが出てきます。
ベストセラーになった「人工知能は人間を超えるか…ディープラーニングの先にあるもの(松尾豊著)」に「AIを使うことで特徴量の選択から解放される」ということが書かれています。Portillaらの論文がすごいところは、「考え付く限りありったけの特徴量を考え出して」いて、しかも「コードとして実行可能なこと」にあると思います。特徴量を抽出するために、Steerable Pyramidをつくってフーリエ変換して、それを戻して、といったことを繰り返します。上のノートのように「こんなにぐちゃぐちゃだと論文に式をかけない!!」というくらいなわけですから。
これに対してGatysらの方法は「1つの式でテクスチャを表現」してしまいます。なおかつ結果も「よりいいもの」になっています。
AIってすごい、ですね。
ですけど、
AIを褒めたたえるために何カ月もこんなことやってたの?
というとこれもちょっと違うのです。
Gatysの合成法では、VGGという(訓練済みの)ディープラーニングモデルを使います。こういった巨大なディープラーニングモデルは「まったく中身が見えない」のですね。これを可視化する手法が論文になるくらいです。そうなると、気に入らないところがあっても直せない、というジレンマに陥ります。なんでこうなるかわからないのですから、当然です。
この意味で、ディープラーニングはかなり「実験科学」だと感じます。結果から推測・解釈をする。
逆をいえば、これは、特徴量から解放されることの対価と言えるのではなかろうかと思います。
反面、改良する余地が大きいのは、Portillaらの方法です。なんでこうなるのかを書き下すのは大変ですが、不可能ではありません(ノートやホワイトボードがぐちゃぐちゃになりますけど)。
ディープラーニングを使った方法とPortillaらの方法は、最新式の車と70年代の車の違いのように感じます。
AIは(私のような門外漢でも)簡単に利用できてしまいます。結果にびっくりするから楽しいですよね。とはいえ、人間飽きちゃいます。オートマは楽だけど、マニュアルの方がいいよな、みたいな部分があったりする。
それがこの論文を(休日を全部使って)読んだ理由です。
長くなった上にまとまりませんでしたね。うーーん。
関連する記事
【AI】本物はどちら?? ディープラーニングモデルのとてつもなく感動的な性質 Texture Synthesis Using Convolutional Neural Networks
【AI】名画で川越を変換する。A Neural Algorithm of Artistic Style概論
←「【ホームページ】真面目なSEOの実証実験:結果発表」前の記事へ 次の記事へ「【ご注意下さい】billing@global.jcb 及びbilling@jcb.co.jpのアドレスを詐称した詐欺メール」→