SinGAN: Learning a Generative Model from a Single Natural Image 論文まとめ
SinGANという論文を軽く読んだのでメモ。
この記事は自分用にまとめたもので間違っている可能性があります。
もし間違い等あればご指摘して頂けると助かります。
どんなもの?
1枚の学習画像の内部統計をキャプチャする無条件の(つまり、ノイズから生成する)生成モデル。
つまりSinGANは画像「1枚だけ」から、それと似たような画像を生成出来る。
推論時に任意の解像度に変更可能で, 下層の入力画像をいじることで, ペイントから画像への変換、画像の編集、画像の調和、超解像度およびアニメーションを、アーキテクチャの変更やさらなるチューニングなしで実行するために使用できる。
先行研究と比べてどこがすごい?
1枚の自然画像に対してGANベースのモデルを提案したものはあるが、画像を画像にマッピングする(ある画像を入れると必ず決まった画像が出力される)ので、ランダムサンプルの生成には向いていない。
というか1枚の画像で生成するGANは今までテクスチャを生成するものがほとんどだった(らしい)。
その証拠に従来の1枚の画像で生成できるGANを使うとFigure 3のようになる。
非テクスチャ画像だと意味のあるサンプルを生成していない。一方SinGANはPSGAN、Deep Texture Synthesisよりうまく描画できている。SinGANではテクスチャ画像に限定されずに一般的な自然画像(非テクスチャ画像)でも1枚の画像から生成が可能になった(Figure 1)。
技術や手法のキモはどこ?
軽量なFCN (Fully Convolutional Network)のGANを何層かに積み重ねたようなGANピラミッドによって構成され、それぞれが異なるスケールでパッチの分布をキャプチャする。学習が完了すると、SinGANはさまざまな高品質の画像サンプル(任意のサイズ)を生成できる。
以下のFigure 4はSinGANの全体図である。各スケールに対してPatchGANを行うイメージ。
ピラミッド形式のGANで学習と推論の両方が「荒い→精巧」のような流れで行われる。
各スケールで Generator は、すべてのオーバーラップパッチを Discriminator がダウンサンプリングされた学習画像 のパッチと騙されるような画像サンプルを生成するように学習する。
大雑把な流れは以下の図のようになる。
パッチサイズとは?
patchGANというGANで用いられたものです。パッチサイズごとにDiscriminatorがRealかFakeを判定している。
https://blog.shikoan.com/pytorch_pix2pix_colorization/より
https://blog.paperspace.com/unpaired-image-to-image-translation-with-cyclegan/より
(追記:なおSinGANでは識別器だけでなく生成器にもpatchGANを適用してあるとのことです。言葉足らずで申し訳ございませんでした。 参考https://github.com/Yagami360/MachineLearning-Papers_Survey/issues/40)
Generator
画像サンプルの生成は、最も粗いスケール N (Figure 4の1番下側)から開始し、すべてのジェネレーターに最も細かいスケール 0 (Figure 4の1番上側)まで順次渡していく。
以下の図は Generator の様子。
Generatorは5つの畳み込みブロック(「Conv3x3」-「BatchNorm」-「LeakyReLU)」)を持つFCN (Fully Convolutional Network)である(つまり畳み込み層のみのネットワーク)。
ブロックごとに、最も粗いスケールで32個のカーネル(畳み込みフィルターのこと)から開始し、4スケールごとに2倍のカーネル数にする。
は と同じアーキテクチャで、パッチサイズは11×11。
なおノイズマップの次元を変更することにより、テスト時に任意のサイズとアスペクト比の画像を生成できる。
Discriminator
各Discriminator はマルコフ識別器(PatchGAN)であり、 の各N×NパッチがRealかFakeか(つまり、 のパッチijがRealかFakeか)を判別する。
学習
GANを粗いスケールから細かいスケールまで順番に学習される。
各GANが学習されると、固定される。
Loss
n番目のGANのトレーニング損失は敵対項と再構成項で構成。
敵対損失 は、 のパッチの分布と生成されたサンプルのパッチの分布の間の距離に対してペナルティを科す。
論文では敵対的損失に対してWGAN-GP損失(最終的な識別損失=パッチ識別マップの平均)を用いているよう。
再構成損失 は、 特定のノイズマップセットからを生成できることを保証するために
を設定する。なお は固定されたノイズマップ(学習中にサンプリングされたノイズで学習中は固定されたまま)。
以上を踏まえて再構成損失 を以下のように定義する。
は からの再構成画像で、各スケールでのノイズ の標準偏差 の決定に使用されるらしい。
は に比例し、そのスケールで追加する必要がある詳細の量を示すらしい。
どうやって有効だと検証した?
以下はランダム画像サンプル生成結果。
1つの画像でSinGANをトレーニングした後、モデルは新しい構造とオブジェクト構成を表すリアルなランダム画像サンプルを生成できる。
また学習画像のパッチ分布は保持される。
以下は高解像度の生成結果。
以下はさまざまなスケールからの生成(推論時)。
より細かいスケールnから生成するために、ダウンサンプリングされた元の画像 をそのスケールへの入力とする。
これにより、生成された構造のスケールを制御することができる。
例えば、Zebraの形状とポーズを保持し から生成を開始することでストライプテクスチャのみを変更できる。
以下は異なる数のスケールでの学習の効果。
SinGANのスケールの数は、結果に大きく影響する。
スケールの数が少ないモデルは、テクスチャのみをキャプチャする。
スケールの数が増えると、SinGANは画像内物体のより大きな構造をキャプチャすることができるということを示している。
以下は超解像の結果。
以下はペイント→写真変換の結果。
以下は画像編集の結果。
以下は画像調和の結果。
議論はある?
色々なものに応用できる点が本当にすごいしクオリティも高い。
Twitterでは「SinGANがbest paperかぁ...」みたいな微妙な反応がちらほらあったのが気になりました。
次に読むべき論文は?
参考
http://peluigi.hatenablog.com/entry/2019/10/29/190927
https://github.com/Yagami360/MachineLearning-Papers_Survey/issues/40
著者実装(Pytorch)
Normalization Layers
Normalization Layersについて調べてた時以下の記事が非常に分かりやすかったので日本語で要約しました。
www.quora.com
- Normalization Layers
- Batch Normalization
- Layer Normalization
- Instance Normalization
- Group Normalization
- おまけ
- 引用記事
Normalization Layers
がCNNの特徴マップとします。
にはの4つの次元があるため、は4次元テンソルとして表すことができます。
以下の例では、は、それぞれサイズ6×6で4個の特徴マップを持ち、4サンプルで1バッチだとします。
normalization layerはデータから平均と分散を計算し、次のように特徴マップを正規化します。
ここで、
- γはスケーリングパラメータ
- βはシフトパラメーター
- ϵは数値の不安定性(ゼロ除算の問題) を回避するためのもの
基本的に normalization layer でこの一般的な定式は同じですが、それらの間の違いはとの計算方法です。
以下で主な normalization layer を要約し、それらがどのように機能するか説明します。
Batch Normalization
Batch Normalizationは、各チャンネルに対してとを計算します。
例えば次の図のように、各色付きグループは、1つのスカラーと1つのスカラーになります。
,
Layer Normalization
Layer Normalizationは各サンプルに対してとを計算します。
,
Instance Normalization
Instance Normalizationは各サンプルと各チャンネルに対してとを個別で計算します。
,
Group Normalization
Group Normalizationは各サンプルおよび各グループに対してとを個別で計算します。 以下はの例です。
,
おまけ
Instance NormalizationやGroup NormalizationというNormalizationについて調べると必ずと言っていいほど出てくるこの図。 凄い、分かりやすいですね^^
みたいに言っている記事が多いのですが初見の私が見たらマジで意味不明でした...(補足)そもそもなぜNormalizationは必要?
引用記事
Improving the Robustness of Deep Neural Networks via Stability Training 軽く読んだのでメモ
Improving the Robustness of Deep Neural Networks via Stability Training という論文を少しだけ読んだのでメモ。
後ろの方雑になってしまったけど許してください...
どんなもの?
画像の視覚入力の小さな摂動(変化)は、ニューラルネットワークの出力を大きく歪める可能性がある。
例えば図1で
「ほぼ重複しているが、若干違いがあるような画像のペア」の例が左と真ん中の列(赤いお花と建物の画像)。
imageAが元画像、imageBがJPEG圧縮して quality factor が 50 の画像。
quality factorの数値を変えることによりJPEGの圧縮率が変わるらしい
右の列(草生えてるやつ)は全く異なる画像のペア画像。
変化(difference)の小さい画像は変化の大きな画像に匹敵する(Dという距離を測る指標があり、左と真ん中の列のD値と右の列のD値が匹敵していることが分かりますね)。
本論文ではそのような微細な変化のあるデータセットを安定させる分類方法を提案した。
先行研究と比べてどこがすごい?
- JPEG-50 圧縮による変化
- トリミングを若干ずらすRandom cropping (論文だとoffset = 10)
- thumbnail resizingによる変化
のような変化を加えた画像に対しても従来の学習方法より安定した特徴量が得られることを確認した。以下その学習方法を Stability Training と呼ぶ。
技術や手法のキモはどこ?
L_0 を今まで用いてきたLoss(例えば画像分類タスクだとSoftmax cross entropy)として、それにα倍された L_stability と呼ばれる新しいLossを足す。
x は入力、x' は歪めた(変化を加えた)画像
L_stability は出力 f(x) を f(x') に近づけるLossである。
詳しくは後述。
①特徴埋め込みのためのStability
ここでは Ranking triplet を用いている。
論文では
a→q
と表現する文字が変わっているようが意味は同じようです(多分)。
目的は以下のようにすることです。
hinge lossを使ってL_0を
L2距離を使った stability loss を
と定義することができる。
②分類のためのStability
分類で一般に用いられる cross-entropy loss をL_0として定義し、
KL-divergence を用いて stability loss を
と定義できる。
まとめると以下の図3のようになる。
どうやって有効だと検証した?
図4は特徴距離D(L2距離)の比較
図5は
- JPEG-50 圧縮による変化
- トリミングを若干ずらすRandom cropping (論文だとoffset = 10)
- thumbnail resizingによる変化
のような変化を加えた画像に対する従来の学習方法と提案手法の比較。
議論はある?
次に読むべき論文は?
これ気になってます
ChainerでCutMix実装
CutMixをChainerで実装してCifar-10で実験してみました。
割と無理やりなコードなのでそのうちちゃんと書き直したいと思います...
CutMixについて
論文:https://arxiv.org/abs/1905.04899
他の画像を切り取って重ねる新しめData Augmentation。(ラベル処理は多分Mixupと一緒) CutoutとMixup組み合わせたような手法。
x_A(学習画像)とx_B(貼り付ける画像)を用意して貼り付ける(以下の式)。
難しく見えるがただ他の画像を切り抜いて貼り付けているだけ。
また貼り付ける画像の大きさは以下の式で決まる。
λ∈[0,1]は、ベータ分布Beta(α,α)からのサンプリングにより取得する。
αはハイパーパラメータなので自由に設定できる。
以下はベータ分布図。
ラベルも以下の式のように足し合わせる。
まとめると以下の画像のようになる。
以下Mixup、Cutout、CutMixの比較(論文より)
結果
ResNet50モデルを使いました またα=0.2のみで試しています。
ResNet50(resize, random_rotate, random_flip) validation accuracy : 0.78291
ResNet50(Manifold Mixup + resize, random_rotate, random_flip) validation accuracy : 0.814062
ResNet50(CutMix) validation accuracy : 0.833285
tags: Cutmix
Chainer
ChainerでManifold Mixup実装
Manifold Mixup
入力層ではなく隠れ層における表現でmixupを行う。 隠れ層でmixupを行うことで従来よりも良い精度になったという。
- 実装コード(どこかミスがあれば教えて下さると助かります...!)
コードのおおざっぱな説明
chainerでManifold MixUp実装してます。 モデルはとりあえずresnet50だけで試しています。
主にResNet50モデルのforward部分を大幅にいじりました。 論文著者による実装(pytorch)を参考にして書きました。
- model/resnet_fine_manifoldmixup.py
class BaseResNet50(chainer.Chain): def __init__(self): super(BaseResNet50, self).__init__() with self.init_scope(): self.conv1 = L.Convolution2D(3, 64, 7, 2, 3) self.bn1 = L.BatchNormalization(64) self.res2 = R.BuildingBlock(3, 64, 64, 256, 1) self.res3 = R.BuildingBlock(4, 256, 128, 512, 2) self.res4 = R.BuildingBlock(6, 512, 256, 1024, 2) self.res5 = R.BuildingBlock(3, 1024, 512, 2048, 2) def forward(self, x, target, mixup_hidden, lam, layer_mix): if mixup_hidden: if layer_mix == None: layer_mix = random.randint(0, 5) h = x if layer_mix == 0: h, t_a, t_b = mixup_data(h, target, lam) h = self.bn1(self.conv1(h)) h = F.max_pooling_2d(F.relu(h), 3, stride=2) if layer_mix == 1: h, t_a, t_b = mixup_data(h, target, lam) h = self.res2(h) if layer_mix == 2: h, t_a, t_b = mixup_data(h, target, lam) h = self.res3(h) if layer_mix == 3: h, t_a, t_b = mixup_data(h, target, lam) h = self.res4(h) if layer_mix == 4: h, t_a, t_b = mixup_data(h, target, lam) h = self.res5(h) if layer_mix == 5: h, t_a, t_b = mixup_data(h, target, lam) return h, t_a, t_b else: h = self.bn1(self.conv1(x)) h = F.max_pooling_2d(F.relu(h), 3, stride=2) h = self.res2(h) h = self.res3(h) h = self.res4(h) h = self.res5(h) return h
分類に使用する時はtrain_manifoldmixup.pyで以下のようにManifoldMixupClassiferで包みます。 * train_manifoldmixup.py
model = ManifoldMixupClassifer(ResNet50_Manifold_Mixup(), mixup_hidden=True, mixup_alpha=0.2, layer_mix=None)
結果
今回はCIFAR10の学習で比較してみた(α=0.2)。
Manifold Mixupなし validation accuracy : 0.78291
Manifold Mixupあり validation accuracy : 0.814062
NONLINEAR CONJUGATE GRADIENTS FOR SCALING SYNCHRONOUS DISTRIBUTED DNN TRAININGについてまとめた
「NONLINEAR CONJUGATE GRADIENTS FOR SCALING SYNCHRONOUS DISTRIBUTED DNN TRAINING」の論文をまとめました
論文pdf:https://arxiv.org/pdf/1812.02886.pdf
落合フォーマット(http://lafrenze.hatenablog.com/entry/2015/08/04/120205)でまとめました。
どんなもの?
ここではDeep neural networkのoptimizerとしてstochastic preconditioned nonlinear conjugate gradientのアルゴリズムを提案・評価をしています。
つまり非線形共役勾配法をoptimizerとして応用してみたといった感じです。
http://www.orsj.or.jp/archive2/or59-03/or59_3_131.pdf
http://www.kurims.kyoto-u.ac.jp/~kyodo/kokyuroku/contents/pdf/1362-13.pdf
を見れば分かりやすいと思います。
ちなみに論文によると
We hypothesize that with large mini-batches, the variance of the gradients is reduced, which makes NLCG method effective for DNN training.(大規模なミニバッチでは勾配の分散が減少し、それが非線形共役勾配法を深層学習に適用できると仮定した。
とあるように大規模なミニバッチに注目しています。
先行研究と比べてどこがすごい?
近年Deep Neural Network (DNN)学習では、未だにoptimizerのアルゴリズムとしてStochastic Gradient Descent (SGD)などが主流として使われています。
SGDなどよりも大きなミニバッチサイズを使用できる効率的なアルゴリズムだと主張しています。
~ 補足 ~ ※SGDの他にMomentum SGD、RMSProp、 Adam (Kingma & Ba, 2014),、ADAGradなどの1次微分を用いた最適化手法があります。 共役勾配法を使うなら2次微分を用いる最適化手法ニュートン法とかでもいいのではとも考えられます。 ですが論文では
と書いてありました。 対してK-FAC(https://medium.com/@osawa1021/k-fac%E3%81%A8%E3%81%AF-de30537f7096)のような最近の自然勾配に基づく方法やNeumannべき級数を使った方法(Krishnan et al 2017)の方がImageNet分類のような大規模な問題をうまく訓練することができるらしいです。 |
技術や手法のキモはどこ?
以下の2つが挙げられます。
・分散深層学習: Data Parallel
恐らく重要なのは後者ですが論文に書いてあった分散深層学習についても書きます。
分散深層学習 : Data Parallel
「分散深層学習」にはData ParallelとModel Parallelという2通りのアプローチがあることが知られています。
Data Parallelは、全プロセスに同じモデルのコピーをして訓練することでバッチサイズをプロセス数倍し、学習を高速化させる手法です。
深層学習を以下の図のように簡略化して描くとするなら
分散深層学習 : Data Parallelは以下のように描けます。
これにより1024GPU上でImageNetによるResNet-50の学習を15分で行うなどの実績を上げています。このような複数プロセス、複数ノードを用いた分散深層学習によってニューラルネットの訓練は高速に行えるようになっており、分散深層学習は現在の深層学習の基盤を支えているといえます。
より詳しく知るなら論文を読むことをおすすめします。
論文中に出てくるWorkers, Seversって何だ?となりますが、説明は以下の図のようになります。
Calculate Preconditioner(Preconditionerを計算する)とは一体何でしょうか。
まずはここについて見ていきます。
(1)Quasi Newton Pre-conditioner
非線形共役勾配法はヘッセ逆行列を求める必要があるため、これを最適化する必要があります。
~ 補足 ~ 古い記事になってしまいますがhttp://www.orsj.or.jp/archive2/or59-03/or59_3_131.pdfでは ” 目的関数のヘッセ行列やその近似行列を利用する必要があるため、記憶容量や計算量の関係で,問題に対して直接適用することができないことがある” という問題が挙げられているためヘッセ(逆)行列を求めるのは処理的に重いことが分かります(実際どうなのかは分かりませんが…)。 |
そこでヘッセ行列を準ニュートン法で用いられるBFGSという更新方法に着目しています。
BFGS法によるヘッセ行列の近似は以下の式で表される。ヘッセ行列の対角成分を求めるという制限をかけることで処理を軽くしているようです(通常は対角成分だけではない)。過去の勾配との差を取れさえすれば良いのがキモらしいです。
これにより処理が軽くなったとのことです(メモリ上で計算する必要がなくなった)。
以上を用いた処理(Quasi Newton)Pre-conditionerのアルゴリズムは以下です。
分かりづらかった場合は準ニュートン法で調べると分かるかもしれません。
(2)Online Stochastic Line Search
次にについて見ていきます。
はglobal step lengthと呼ばれるもので以下の図のようなふるまいをします。
次にについてです。は1.0で初期化されています。
Loss関数がある一定の割合(論文では2%)以上増加したらの値を2.5%減少させます。
一方でLoss関数が減少もしくは変化がない(論文ではLoss関数の増加量が1%未満)ならを2.5%増加させます(最大で1.0になるまで)。
閾値1%、2%、2.5%はLoss関数の分散に依存するハイパーパラメータであるのでより良い性能のために調整することも良いと思われます。
どうやって有効だと検証した?
非線形共役勾配法を使って「Resnet-50モデルを用いたImageNet画像分類」と「Resnet-32モデルを用いたCIFAR-100画像分類」を行っています。
ここでは「Resnet-50モデルを用いたImageNet画像分類」の結果だけ見ていきます。
以下の図6は「Resnet-50モデルを用いたImageNet画像分類」によるLoss関数です。
・RMS_65K ( RMSProp )
・MOM_65K ( SGD with momentum )
・NCG_FR_65K ( 非線形共役勾配法( FletcherReaves ) )
・NCG_PR_65K ( 非線形共役勾配法( PolakRibiere ) )
の4つのoptimizerを用いて比較しています。
処理に必要な実測時間( Wall time( hours ) )は以下の図7のようになります。
どちらにおいても非線形共役勾配法の収束性が優れていることが分かります。
次に以下の図は「Resnet-50モデルを用いたImageNet画像分類」でさまざまなoptimizerを使用して学習されたResnet50モデルのトップ1のテスト精度を示しています。そしてmini-batchサイズを512から98304に変化させたときのグラフです(epoch数は90)。
さらにbatchサイズ65536のときに注目してepoch数を変化させてみると以下の図のようになります。
batchサイズ98304のときに注目してepoch数を変化させてみると以下の図のようになります。
議論はある?
大規模なミニバッチを使用した学習は分散深層学習をスケールアップするのに必要不可欠となります。
この論文ではNLCG optimizer(非線形共役勾配法)が共役勾配とPre-conditionerを使用して既存の方法より学習の収束速度を向上できたことを実証しました。
この研究では主に大規模なミニバッチにフォーカスを当てていました。
そのため勾配は分散が小さく、Pre-conditionerと共役探索方向の計算が意味のあるものになり、安定します。
ですがミニバッチが非常に小さくなると(例えば128)、勾配の分散が増大し、NLCG法が不安定になります。
そのためより小さなミニバッチ、高勾配分散に対して安定したNLCG法を考える必要があります。
次に読むべき論文は?
未定。
Using Deep Learning for Image-Based Plant Disease Detectionまとめた
Using Deep Learning for Image-Based Plant Disease Detectionを落合フォーマットでまとめました。
どんなもの?
Deep neural networksで植物病害診断の改善を試みた。
データセットは26の病気をもつ14種類の植物画像54,306枚のを用いている(FIGURE 1)。
先行研究と比べてどこがすごい?
当時従来の方法と呼ばれていたものは、
- SIFT
- SURF
がある。
これらは特徴量を事前に定義しておかなければならないため(手作業)中々ヘビーでしんどい。
だがDeep neural networkはそういった問題を克服できる。
技術や手法のキモはどこ?
葉の原画像color(a, d)に対してグレースケール(b, e)にしたり葉の部分のみ切り取った画像(c, f)をそれぞれ用意して実験を行った。
それぞれ以下を方法組み合わたら計60回の実験設定になる。
ちなみに以下のTransfer Learningというのは今でいう転移学習のこと(多分)である。
AlexNetとGoogLeNetのTransfer LearningはImageNetを用いたpretrainモデルを使ってる。
また、ハイパーパラメータは以下を利用した。
- epoch数 : 30
- optimizer : SGD(Stochastic Gradient Descent)って書いてあるけど多分Momentum SGD
- Momentum : 0.9
- Base learning rate : 0.005
- Weight decay : 0.0005
- Learning rate policy : Step(30/3 epoch = 10ごとに学習率を減らす)
- Gamma : 0.1
- Batch size : 24(GoogLeNet), 100(AlexNet)
どうやって有効だと検証した?
FIGURE3は30epoch学習させた時の平均F1スコアとloss関数のグラフをまとめたものである。
以下のTABLE 1はその実験の結果である(平均F1スコアで評価)
grayscaleは全体的に低い。color(原画像)とsegmented(切り抜き画像)ではわずかにcolorの方が良い結果になっている。
もっともよいモデルはGoogLeNet(Transfer learning)のTRAIN : 80%, TEST : 20%、colorの場合であった。平均F1スコアは0.9934だった。
FIGURE4は(A)にような画像が与えられたときのAlexNet(TrainFromScratch, TRAIN : 80%, TEST : 20%, color)の1番最初の畳み込み層を可視化したもの(B)である。
議論はある?
異なった環境下の葉の写真を用いてテストしたら精度が約31%ほどに落ちた。より多くの異なった環境の学習画像を用意しなければならない課題がある。
また今回は1種類(同種)の葉に対して診断を行ったので植物に種類を特定して病気を診断できるようにする必要がある。
次に読むべき論文は?
どなたか教えて下さい