ココアのお勉強ブログ

技術職の一般人です。趣味でコード書いたりソフト触ったり。

bert as service のベクトル表現を用いて文書分類メモ

日本語BERTで文表現ベクトルを得る環境を作る

日本語BERTによってベクトルを出せるようにする

以下の記事の通りに、日本語BERTによって文表現ベクトルを計算するサーバーを作ります。
https://qiita.com/shimaokasonse/items/97d971cd4a65eee43735
Google Colabolatoryでやる場合は

!pip install bert-serving-client
!pip install -U bert-serving-server[http]
!nohup bert-serving-start -model_dir=./bert-jp/ > out.file 2>&1 &
from bert_serving.client import BertClient
bc = BertClient()

としないと動かないです。

以上でbert-as-serviceから文表現ベクトルを得ることができました。

文書分類

分類するためのデータセットの準備

live コーパスを使っていきます(9クラス分類)。
live コーパスをダウンロードし,解凍します。

$ wget https://www.rondhuit.com/download/ldcc-20140209.tar.gz
$ tar zxf ldcc-20140209.tar.gz > /dev/null

データセットの整形

とりあえず以下のような形にもっていきます。

Text Label
0 text1 label1
1 text2 label2
2 text3 label3
... ... ...
import os 
import random
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
import numpy as np
import glob

def parse_to_wakati(text):
    return text

categories = [
    "sports-watch", "topic-news", "dokujo-tsushin", "peachy",
    "movie-enter", "kaden-channel", "livedoor-homme", "smax",
    "it-life-hack",
]

docs = []
for category in categories:
    for f in glob.glob(f"./text/{category}/{category}*.txt"):
        # 1ファイルごとに処理
        with open(f, "r") as fin:
            # nextで1行取得する(__next__を呼ぶ)
            url = next(fin).strip()
            date = next(fin).strip()
            title = next(fin).strip()
            body = "\n".join([line.strip() for line in fin if line.strip()])
      
        docs.append((category, url, date, title, body))

df = pd.DataFrame(
        docs,
        columns=["category", "url", "date", "title", "body"],
        dtype="category"
)
# 日付は日付型に変更(今回使うわけでは無い)
df["date"] = pd.to_datetime(df["date"])

# wakati body
df = df.assign(
    Text=lambda df: df['body'].apply(parse_to_wakati)
)

# ラベルエンコーダは、ラベルを数値に変換する
le = LabelEncoder()

# ラベルをエンコードし、エンコード結果をyに代入する
df = df.assign(
    Label=lambda df: pd.Series(le.fit_transform(df.category))
)

labels = np.sort(df['Label'].unique())
labels = [str(f) for f in labels]

idx = df.index.values

idx_train, idx_val = train_test_split(idx, random_state=123)
train_df = df.loc[idx_train, ['Text', 'Label']]
val_df = df.loc[idx_val, ['Text', 'Label']]

↑のコードを実行するとTextとLabelのペアを作ることができます。
↓train_dfの一例

自作データとかの場合train_dfのような形 Text, Label となるようにCSVファイルを既に用意してもらった方が簡単化と思います。

Kerasで分類する

Kerasを用いてbert as serviceから得られたベクトル表現に対して分類をします。
以下でネットワークを構築します。

import numpy as np

from sklearn import datasets
from sklearn.model_selection import train_test_split

from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.utils import np_utils
from sklearn import preprocessing

# BERTから得るベクトル表現をこのモデルに流し込む
def build_multilayer_perceptron():
    model = Sequential()
    # 隠れ層512は好きに変えて良い
    model.add(Dense(512, input_shape=(768,)))
    model.add(Activation('relu'))
    # liveコーパスは9クラス分類なので9
    model.add(Dense(9))
    model.add(Activation('softmax'))
    return model
    

x = train_df["Text"].values.tolist()
x = list(map(parse,x))
X = bc.encode(x,is_tokenized=True)
Y = train_df["Label"].values
train_X, test_X, train_Y, test_Y = train_test_split(X, Y, train_size=0.8)
print(train_X.shape, test_X.shape, train_Y.shape, test_Y.shape)
model = build_multilayer_perceptron()
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
                metrics=['accuracy'])

分類を実行します。

# epoch数,batch_sizeは適宜変更する
model.fit(train_X, train_Y, nb_epoch=200, batch_size=16, verbose=1)

"""
4420/4420 [==============================] - 1s 184us/step - loss: 0.0265 - acc: 0.9930
Epoch 198/200
4420/4420 [==============================] - 1s 177us/step - loss: 0.1637 - acc: 0.9493
Epoch 199/200
4420/4420 [==============================] - 1s 184us/step - loss: 0.2781 - acc: 0.9120
Epoch 200/200
4420/4420 [==============================] - 1s 179us/step - loss: 0.0248 - acc: 0.9943
"""

評価します。

# モデル評価
loss, accuracy = model.evaluate(test_X, test_Y, verbose=0)
print("Accuracy = {:.2f}".format(accuracy))

transformersのBERT

色々めんどくさいことしましたが transformers を使えば日本語学習済BERTを非常に簡単に利用できるようになりました(つい最近)。
https://twitter.com/huggingface/status/1205283603128758277
huggingface/transformers の日本語BERTで文書分類器を作成する記事 https://qiita.com/nekoumei/items/7b911c61324f16c43e7e
試してみたら非常に簡単でした。
分類 BertForSequenceClassification だけでなく以下から色々なタスクを扱えるようです。

# Each architecture is provided with several class for fine-tuning on down-stream tasks, e.g.
BERT_MODEL_CLASSES = [BertModel, BertForPreTraining, BertForMaskedLM, BertForNextSentencePrediction,
                      BertForSequenceClassification, BertForTokenClassification, BertForQuestionAnswering]

bert as serviceは一応CPUでも動くようなのでGPUないけど回したいみたいな人にはいいのかなと思いました。
NLP界隈の人間ではないので詳しいことまでは分かりませんが。

eXpose: A Character-Level Convolutional Neural Network with Embeddings For Detecting Malicious URLs, File Paths and Registry Keys

論文リンク:https://arxiv.org/abs/1702.08568
※少し古めの論文です

CLCNN(Character-Level Convolutional Neural Network)とは

CNNは画像に対して提案された手法で、基本的に自然言語では時系列モデルであるRNNとかLSTMが用いられる。
CNNを自然言語処理でも用いるなら1次元方向のみの畳み込みになる。



https://www.slideshare.net/sheemap/convolutional-neural-netwoks より

実際にCNNを用いて文書分類を行ったネットワークが Character-Level Convolutional Neural Networks(CLCNN)で高い精度を達成している。

処理の流れ

①文字を局所表現(埋め込み表現)にする

カーネルサイズが違う枚数のCNNに並列に入れて特徴を出力

https://www.slideshare.net/tdualdir/devsumi-107931922 より

③特徴を1つに結合

④全結合層に通して分類

となる。

全体のモデルの構造は以下のようになる。

次回は CE CLCNN について書きます。

twitterの顔アイコンを描く

彌冨研アドベントカレンダー16日目を担当させて頂きます。
B4のほっとここあです。
私は4年生になって初めてエンジニア界隈の人をtwitterでフォローしました。
皆さん個性的なアイコンで面白いですよね。
あとアニメイラストをアイコンにしている人多いなぁと感じました。
でも時々「(え...そのアイコン無断使用して大丈夫なん...!?)」と思うときがあります。
気持ちは分かるし自分だってめっちゃうまい絵師が描いたイラストをアイコンにしたいですが怒られたら嫌なのでやってません
そこで発想を転換します。自分で描けばいいんだ...!というわけで簡単にデジタルで描く記事を書きました。

(GANで生成したアニメ画像って著作権どうなるんだろう?)

デジタルで描くって何?

私が大学1年生のとき、「そもそもデジタルで描くって何?」と思っていたので一応説明しておきます。
デジタルで描くとは、パソコン・ペンタブ・液タブのような電子機器を用いて描くことを指します。
対称にアナログで描くとは、紙にペン・絵具、水彩(マーカー)のようなものをもちいた、電子機器を用いずに描くことを指します。

画材

一般的に、絵を描くために使う道具を画材といいます。
デジタルイラストの場合は大きく分けると次の 3つが必要です。

※最近ではipadでもイラストを描けるようになり,ipadApple Pencilを持っていれば誰でも気軽にお絵描きできるようになりました。

グラフィックソフト

絵を描くためのソフトウェアです。ペイントソフトとも呼ぶそうです。 よく使われるものとして以下のソフトウェアが挙げられます。

CLIP STUDIO PAINT PRO/EX
Adobe Photoshop CC
・Medibang Paint Pro(無料)
アイビスペイント(無料)
など

5,000円程かかりますがこの中で1番おすすめなのはCLIP STUDIO PAINTです。機能が非常に多く、ユーザサポートが充実しているからです。
正直これで5,000円でいいの??って思うくらいです。
ですが今回は無料で使えるMedibang Paint Proを使ってイラストの工程を書いていこうと思います。

実際に描いていく

顔についてざっくり

ざっくり自分が顔を描くとき考えてるのは以下です。

ただ最近はフリーのトレス素材が充実しているため参考にしたりなぞったりして絵を描いたりしてもいいと思います。
「顔 トレスフリー」とかで調べると良いと思います。著作権が心配なので画像は載せませんが、吉村拓也さんという方がトレスフリー画像や絵の描き方をtwitterなどで共有していておすすめです。いつも助かっています。

顔のアタリを描く(トレスフリー素材を使わない時)

顔のアタリを描きていきます。身体のラフも入ってますが気にしないで下さい。
どうせtwitterのアイコンには入りきらないので。

アタリをもとにラフを描く

ラフをもとに線画

ブラシはペン(4px)を使っています。色は黒です。

髪の毛のパターンとかどうすればええねん...ってなりますが基本的に色んな参考絵の髪のパターンを組み合わせて丸パクリ感を消していきます(今回関係ないけど服のシワパターンもそんな感じ)。弊研だとアンサンブルでやるって言えば理解できるかな。

髪はつむじから流れを意識して描きます。また元のラフより少し離して描きます。

塗る(これは見なくていい)

「!?」と思ったかもしれませんが自分が塗るとこんな感じです。いきなりこの塗りに挑戦しようとすると難しいので誰でも簡単にできる塗りを紹介しようと思います。

塗り講座

さっきまでのイラストと同じような工程で以下の線画を描きました。

こっから色塗りに入りますがその前にレイヤーについて理解しておいてください。
* レイヤーについて

乗算レイヤーという合成レイヤーを使って塗る初心者向けのアプローチで塗ります。
ざっくり以下のリンクを見てください。
* 乗算で影を塗る

↓新しいレイヤーを線画レイヤーの下に作ってグレーで影を描きます。 影を描いた後、影を描いたレイヤーブレンドを乗算レイヤーにして下さい。

↓新しいレイヤーをさらに線画レイヤーの下に作って下塗りを描きます。

目を塗る

※目だけに塗りを適用したいときクリッピング機能が役に立ちます
クリッピング機能について

↓目の下らへんにオレンジ追加

↓グラデーション(黒)

↓瞳(黄色)

↓ハイライト(白)

髪にハイライトをつける

顔に赤をのせる

それっぽいの完成

もうワンステップレベルを上げた塗り

先程の塗りでも十分良いのですが、グラデーションを使ってもっと塗りを良くします。

できました!

他にもテクスチャを使って水彩っぽくする技術もあるのでもしよかったら以下の記事読んでください。
アニメ塗りを水彩画風にする

hotcocoastudy.hatenablog.jp

あとがき

最近初心者でも気軽にイラストが描けるようになりました。
↓3Dを使って楽に描いたり
https://hotcocoastudy.hatenablog.jp/entry/2019/02/20/013653

分かりやすい塗りの本とかも増えてきてとても嬉しいです。
↓塗りの参考書読みながら描いたイラスト
https://hotcocoastudy.hatenablog.jp/entry/2019/03/23/115503

というわけで深層学習とは無縁の記事でした、ありがとうございました。

AUGMIX: A SIMPLE DATA PROCESSING METHOD TO IMPROVE ROBUSTNESS AND UNCERTAINTY 自分用にメモ

論文リンク
AugMix: A Simple Method to Improve Robustness and Uncertainty under Data Shift | OpenReview
公式実装(Pytorch)
GitHub - google-research/augmix: AugMix: A Simple Data Processing Method to Improve Robustness and Uncertainty

どんなもの?

Datasetのshiftの下で、堅牢性と不確実性を改善する、シンプルだけど効果的な方法を提案。
下のgif(公式実装より引用)を見ると概要が良く分かる。

先行研究と比べてどこがすごい?

Hendrycks&Dietterichによって提案されたベンチマークで目に見えない崩壊?に対する堅牢性を大幅に改善したらしい。
CIFAR-10-C、CIFAR-100-Cで前のSOTAと Clean Error(壊れてないtestデータに対する通常の分類Error)の差を半分以上縮めたらしい。
よく分からないけどとりあえずError率下がったってことかな...?
https://twitter.com/balajiln/status/1202764043733229568 より)

技術や手法のキモはどこ?

連続してシフト処理(多分色空間的なシフトも含む?)みたいなことをすると元の画像から遠く離れた(異なる)画像を生成し、非現実的な画像になってしまうことがある(下図)。
でもこの違いは、ステップ数を調整することでバランスを取れる。
複数の拡張画像を生成してmixすることで多様性を高めることができる。

実際のアルゴリズムと画像に対する処理の流れが以下のようになる。

まずAugmentAndMix関数(2:~14:)について見ていきます。

Step1

画像のmix比の重み w_k を乱数で決める。

公式実装だと以下のようにしてる。

# alpha=1, width=3
ws = np.float32(
     np.random.dirichlet([alpha] * width))
# 出力例array([0.15282747, 0.6870145 , 0.160158  ], dtype=float32)

widthは3で固定だった。

Step2

i(=[1,2,3])それぞれについてoperationsを3つずつ(op1,op2,op3)ランダムで決める。
ここで言うoperationsとはtranslate_x(x軸方向に画像をずらす)、rotate(回転処理)のような処理を指す。
ちなみに公式実装ではoperationsは以下のリストからランダムに選ばれるようになっていた。

augmentations = [
    autocontrast, equalize, posterize, rotate, solarize, shear_x, shear_y,
    translate_x, translate_y
]

op_1,op_2,op_3 を決めたから全て適用するというわけではなく、
1. op_1だけ適用するか
2. op_1を適用した後さらにop_2を適用するか
3. op_1を適用しop_2を適用した後さらに op_3も適用するか

の3択 [op1,op12,op123]からさらにランダムで1つ決めます。

f:id:hotcocoastudy:20191207144419p:plain

それらk(=3)個の処理画像をStep1で求めた重みを使ってアルファ合成します。

これにより得た画像を x_{aug} とします。

Step3

ベータ分布 Beta(β,β)から乱数 mを得ます。

mを合成比として使用し元画像[tex:x{orig}]と[tex:x{aug}]をアルファ合成します。

以上により得た最終的な画像を  x_{augmix} とします。
これを返すことでAugmentAndMix関数ができます。

実際には元画像 [tex:x{orig}] に対して2回のAugMix処理をして [tex:x{augmix1}] と x_{augmix2}の2つの画像を得た後、

通常のLoss(SoftmaxCrossEntropyとか)に加えて以下のようなJensen-Shannon divergenceを加えたLossで評価する。

以上がAugMixの一連の流れになります。

※Jensen-Shannon divergenceについては以下の記事程度の理解です。
http://yusuke-ujitoko.hatenablog.com/entry/2017/05/07/200022

補足 Jensen-Shannon Consistency Lossは、多様な入力範囲に対して、安定性、一貫性をモデルに促すらしい。よく分からんけど。

どうやって有効だと検証した?

上で説明したけどもう一度、 Hendrycks&Dietterichによって提案されたベンチマークで目に見えない崩壊?に対する堅牢性を大幅に改善したらしい。
CIFAR-10-C、CIFAR-100-Cで前のSOTAと Clean Error(壊れてないtestデータに対する通常の分類Error)の差を半分以上縮めたらしい。

https://twitter.com/balajiln/status/1202764043733229568 より)

AugMixは、予測不確実性の推定も大幅に改善した。 AugMix + Deep Ensemblesは、増加するデータシフトの下でImageNet-CでSOTAキャリブレーションを達成した(Ovadia et al。2019)。 https://twitter.com/balajiln/status/1202765799636627457 より)

議論はある?

次に読むべき論文は?

Adversarial Examples Improve Image Recognition

分かりづらい解説記事になってしまってすみません...
何か間違いとかあったら指摘してもらえると嬉しいです

Self-training with Noisy Student improves ImageNet classification適当に読んだ

Self-training with Noisy Student improves ImageNet classification

論文リンク:https://arxiv.org/abs/1911.04252

どんなもの?

ディープラーニングは、近年の画像認識で顕著な成功を示しているが最新のモデルは、教師付き学習で訓練されており、適切に機能するにはラベル付き画像の大きなコーパスが必要。
最先端のモデルの精度と堅牢性を向上させるためには、ラベルなし画像も大量に使用するできるようにしたい。

先行研究と比べてどこがすごい?

ImageNetで87.4%のtop1精度を達成した簡単な自己学習方法。

技術や手法のキモはどこ?

step1

ラベル付き画像 {(x_1,y_1),(x_2,y_2),(x_n,y_n) } とし,ラベルなし画像を{ x_1,x_2,...,x_m }とする。

step2

ラベル付き画像を使用して、一般の Cross Entropy Loss を使用して教師モデルを学習。

step3

次に、教師モデルを使用して、ラベルなし画像に擬似ラベルをつける。

step4

次に、ラベル付き画像とラベルなし画像の両方の Cross Entropy Loss の合計を最小化するStudentモデルを学習。
この時Studentモデルにはノイズ(RandAugment、Dropout、Stochastic Depth)を加えて学習させる。

step5

最後に、新しい疑似ラベルを生成し、新しいStudentモデルを訓練するために、StudentモデルをTeacherモデルとして戻すことで処理を繰り返す。

どうやって有効だと検証した?

ImageNetで87.4%のtop1精度を達成した。

議論はある?

次に読むべき論文は?

SinGAN: Learning a Generative Model from a Single Natural Image 論文まとめ

SinGANという論文を軽く読んだのでメモ。

この記事は自分用にまとめたもので間違っている可能性があります。

もし間違い等あればご指摘して頂けると助かります。

どんなもの?

1枚の学習画像の内部統計をキャプチャする無条件の(つまり、ノイズから生成する)生成モデル。

つまりSinGANは画像「1枚だけ」から、それと似たような画像を生成出来る。

推論時に任意の解像度に変更可能で, 下層の入力画像をいじることで, ペイントから画像への変換、画像の編集、画像の調和、超解像度およびアニメーションを、アーキテクチャの変更やさらなるチューニングなしで実行するために使用できる。

f:id:hotcocoastudy:20191030011214p:plain

Figure 1: Image generation learned from a single training image. We propose SinGAN–a new unconditional generative model trained on a single natural image. Our model learns the image’s patch statistics across multiple scales, using a dedicated multi-scale adversarial training scheme; it can then be used to generate new realistic image samples that preserve the original patch distribution while creating new object configurations and structures.

先行研究と比べてどこがすごい?

f:id:hotcocoastudy:20191030011520p:plain

Figure 2: Image manipulation. SinGAN can be used in various image manipulation tasks, including: transforming a paint (clipart) into a realistic photo, rearranging and editing objects in the image, harmonizing a new object into an image, image super-resolution and creating an animation from a single input. In all these cases, our model observes only the training image (first row) and is trained in the same manner for all applications, with no architectural changes or further tuning (see Sec. 4).

1枚の自然画像に対してGANベースのモデルを提案したものはあるが、画像を画像にマッピングする(ある画像を入れると必ず決まった画像が出力される)ので、ランダムサンプルの生成には向いていない。

というか1枚の画像で生成するGANは今までテクスチャを生成するものがほとんどだった(らしい)。
その証拠に従来の1枚の画像で生成できるGANを使うとFigure 3のようになる。

f:id:hotcocoastudy:20191030011600p:plain

Figure 3: SinGAN vs. Single Image Texture Generation. Single image models for texture generation [3, 16] are not designed to deal with natural images. Our model can produce realistic image samples that consist of complex textures and non-reptititve global structures.

非テクスチャ画像だと意味のあるサンプルを生成していない。一方SinGANはPSGAN、Deep Texture Synthesisよりうまく描画できている。SinGANではテクスチャ画像に限定されずに一般的な自然画像(非テクスチャ画像)でも1枚の画像から生成が可能になった(Figure 1)。

技術や手法のキモはどこ?

軽量なFCN (Fully Convolutional Network)のGANを何層かに積み重ねたようなGANピラミッドによって構成され、それぞれが異なるスケールでパッチの分布をキャプチャする。学習が完了すると、SinGANはさまざまな高品質の画像サンプル(任意のサイズ)を生成できる。

以下のFigure 4はSinGANの全体図である。各スケールに対してPatchGANを行うイメージ。

f:id:hotcocoastudy:20191030011753p:plain

Figure 4: SinGAN’s multi-scale pipeline. Our model consists of a pyramid of GANs, where both training and inference are done in a coarse-to-fine fashion. At each scale, Gn learns to generate image samples in which all the overlapping patches cannot be distinguished from the patches in the down-sampled training image, xn, by the discriminator Dn; the effective patch size decreases as we go up the pyramid (marked in yellow on the original image for illustration). The input to Gn is a random noise image zn, and the generated image from the previous scale x˜n, upsampled to the current resolution (except for the coarsest level which is purely generative). The generation process at level n involves all generators {GN . . . Gn} and all noise maps {zN , . . . , zn} up to this level. See more details at Sec. 2.

ピラミッド形式のGANで学習と推論の両方が「荒い→精巧」のような流れで行われる。

各スケールで Generator G_n は、すべてのオーバーラップパッチを Discriminator D_n がダウンサンプリングされた学習画像 x_n のパッチと騙されるような画像サンプルを生成するように学習する。

大雑把な流れは以下の図のようになる。

f:id:hotcocoastudy:20191104171753p:plain

 

f:id:hotcocoastudy:20191031121738p:plain

 

パッチサイズとは?

patchGANというGANで用いられたものです。パッチサイズごとにDiscriminatorがRealかFakeを判定している。

「patch GAN」の画像検索結果"

https://blog.shikoan.com/pytorch_pix2pix_colorization/より

f:id:hotcocoastudy:20191030020031p:plain

patchGANは決められたパッチサイズごとにRealかFakeかを判別する

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)である(つまり畳み込み層のみのネットワーク)。

f:id:hotcocoastudy:20191030012519p:plain

ブロックごとに、最も粗いスケールで32個のカーネル(畳み込みフィルターのこと)から開始し、4スケールごとに2倍のカーネル数にする。 

D_nG_nと同じアーキテクチャで、パッチサイズは11×11。

なおノイズマップの次元を変更することにより、テスト時に任意のサイズとアスペクト比の画像を生成できる。

Discriminator

各Discriminator D_nはマルコフ識別器(PatchGAN)であり、 x_nの各N×NパッチがRealかFakeか(つまり、 x_nのパッチijがRealかFakeか)を判別する。

 

学習

GANを粗いスケールから細かいスケールまで順番に学習される。

各GANが学習されると、固定される。

Loss

f:id:hotcocoastudy:20191030020848p:plain

n番目のGANのトレーニング損失は敵対項と再構成項で構成。

敵対損失 L_{adv}は、 x_nのパッチの分布と生成されたサンプル\tilde{x}_nのパッチの分布の間の距離に対してペナルティを科す。

論文では敵対的損失に対してWGAN-GP損失(最終的な識別損失=パッチ識別マップの平均)を用いているよう。

再構成損失 L_{rec}は、 特定のノイズマップセットからx_nを生成できることを保証するために

f:id:hotcocoastudy:20191031120828p:plain

を設定する。なお z^∗は固定されたノイズマップ(学習中にサンプリングされたノイズで学習中は固定されたまま)。

以上を踏まえて再構成損失 L_{rec}を以下のように定義する。

f:id:hotcocoastudy:20191030022737p:plain

f:id:hotcocoastudy:20191030022805p:plain

\tilde{x}^{rec}_nG_nからの再構成画像で、各スケールでのノイズ z_n標準偏差 σ_nの決定に使用されるらしい。

σ_nRMSE (\tilde{x}^{rec}_n)↑^r, x_n に比例し、そのスケールで追加する必要がある詳細の量を示すらしい。

どうやって有効だと検証した?

 以下はランダム画像サンプル生成結果。

1つの画像でSinGANをトレーニングした後、モデルは新しい構造とオブジェクト構成を表すリアルなランダム画像サンプルを生成できる。

また学習画像のパッチ分布は保持される。

f:id:hotcocoastudy:20191030030655p:plain

Figure 6: Random image samples. After training SinGAN on a single image, our model can generate realistic random image samples that depict new structures and object configurations, yet preserve the patch distribution of the training image. Because our model is fully convolutional, the generated images may have arbitrary sizes and aspect ratios. Note that our goal is not image retargeting – our image samples are random and optimized to maintain the patch statistics, rather than preserving salient objects. See SM for more results and qualitative comparison to image retargeting methods.

 以下は高解像度の生成結果。

f:id:hotcocoastudy:20191030031124p:plain

Figure 7: High resolution image generation. A random sample produced by our model, trained on the 243 × 1024 image (upper right corner); new global structures as well as fine details are realistically generated. See 4Mpix examples in SM.

 以下はさまざまなスケールからの生成(推論時)。

より細かいスケールnから生成するために、ダウンサンプリングされた元の画像 x_nをそのスケールへの入力とする。

これにより、生成された構造のスケールを制御することができる。

例えば、Zebraの形状とポーズを保持し n = N -1から生成を開始することでストライプテクスチャのみを変更できる。

f:id:hotcocoastudy:20191030031302p:plain

Figure 8: Generation from different scales (at inference). We show the effect of starting our hierarchical generation from a given level n. For our full generation scheme (n = N), the input at the coarsest level is random noise. For generation from a finer scale n, we plug in the downsampled original image, xn, as input to that scale. This allows us to control the scale of the generated structures, e.g., we can preserve the shape and pose of the Zebra and only change its stripe texture by starting the generation from n = N −1.

以下は異なる数のスケールでの学習の効果。

SinGANのスケールの数は、結果に大きく影響する。

スケールの数が少ないモデルは、テクスチャのみをキャプチャする。

スケールの数が増えると、SinGANは画像内物体のより大きな構造をキャプチャすることができるということを示している。

f:id:hotcocoastudy:20191030031915p:plain

Figure 9: The effect of training with a different number of scales. The number of scales in SinGAN’s architecture strongly influences the results. A model with a small number of scales only captures textures. As the number of scales increases, SinGAN manages to capture larger structures as well as the global arrangement of objects in the scene.

以下は超解像の結果。

f:id:hotcocoastudy:20191030032320p:plain

Figure 10: Super-Resolution. When SinGAN is trained on a low resolution image, we are able to super resolve. This is done by iteratively upsampling the image and feeding it to SinGAN’s finest scale generator. As can be seen, SinGAN’s visual quality is better than the SOTA internal methods ZSSR [46] and DIP [51]. It is also better than EDSR [32] and comparable to SRGAN [30], external methods trained on large collections. Corresponding PSNR and NIQE [40] are shown in parentheses.

以下はペイント→写真変換の結果。

f:id:hotcocoastudy:20191030032401p:plain

Figure 11: Paint-to-Image. We train SinGAN on a target image and inject a downsampled version of the paint into one of the coarse levels at test time. Our generated images preserve the layout and general structure of the clipart while generating realistic texture and fine details that match the training image. Well-known style transfer methods [17, 38] fail in this task.

以下は画像編集の結果。

f:id:hotcocoastudy:20191030032453p:plain

Figure 12: Editing. We copy and paste a few patches from the original image (a), and input a downsampled version of the edited image (b) to an intermediate level of our model (pretrained on (a)). In the generated image (d), these local edits are translated into coherent and photo-realistic structures. (c) comparison to Photoshop content aware move.

以下は画像調和の結果。

f:id:hotcocoastudy:20191030032551p:plain

Figure 13: Harmonization. Our model is able to preserve the structure of the pasted object, while adjusting its appearance and texture. The dedicated harmonization

議論はある? 

 色々なものに応用できる点が本当にすごいしクオリティも高い。

Twitterでは「SinGANがbest paperかぁ...」みたいな微妙な反応がちらほらあったのが気になりました。

次に読むべき論文は?

 InGAN : http://openaccess.thecvf.com/content_ICCV_2019/html/Shocher_InGAN_Capturing_and_Retargeting_the_DNA_of_a_Natural_Image_ICCV_2019_paper.html

参考

 http://peluigi.hatenablog.com/entry/2019/10/29/190927

 https://github.com/Yagami360/MachineLearning-Papers_Survey/issues/40

 

著者実装(Pytorch)

 https://github.com/tamarott/SinGAN

Normalization Layers

Normalization Layersについて調べてた時以下の記事が非常に分かりやすかったので日本語で要約しました。
www.quora.com

Normalization Layers

h がCNNの特徴マップとします。
hには(batch, channel, width, height)の4つの次元があるため、hは4次元テンソルとして表すことができます。
以下の例では、h_{ncij}は、それぞれサイズ6×6で4個の特徴マップを持ち、4サンプルで1バッチだとします。
f:id:hotcocoastudy:20191012104225p:plain

normalization layerはデータから平均μと分散σ^ 2を計算し、次のように特徴マップを正規化します。
f:id:hotcocoastudy:20191012104702p:plain
ここで、

  • γはスケーリングパラメータ
  • βはシフトパラメーター
  • ϵは数値の不安定性(ゼロ除算の問題) を回避するためのもの

基本的に normalization layer でこの一般的な定式は同じですが、それらの間の違いはμσ^ 2の計算方法です。

以下で主な normalization layer を要約し、それらがどのように機能するか説明します。

Batch Normalization

Batch Normalizationは、各チャンネルに対してμσ^ 2を計算します。
例えば次の図のように、各色付きグループは、1つのスカラーμと1つのスカラーσ^ 2になります。
μ∈R^ C, σ^ 2∈R^ C f:id:hotcocoastudy:20191012105526p:plain

Layer Normalization

Layer Normalizationは各サンプルに対してμσ^ 2を計算します。
μ∈R^ N, σ^ 2∈R^ N f:id:hotcocoastudy:20191012111304p:plain

Instance Normalization

Instance Normalizationは各サンプルと各チャンネルに対してμσ^ 2を個別で計算します。
μ∈R^ {N×C}, σ^ 2∈R^ {N×C} f:id:hotcocoastudy:20191012111319p:plain

Group Normalization

Group Normalizationは各サンプルおよび各グループに対してμσ^ 2を個別で計算します。 以下はgroup=2の例です。
μ∈R^ {N×\frac{C}g}, σ^ 2∈R^ {N×\frac{C}g} f:id:hotcocoastudy:20191012111757p:plain

おまけ

Instance NormalizationやGroup NormalizationというNormalizationについて調べると必ずと言っていいほど出てくるこの図。 f:id:hotcocoastudy:20191012112457p:plain 凄い、分かりやすいですね^^
みたいに言っている記事が多いのですが初見の私が見たらマジで意味不明でした...

(補足)そもそもなぜNormalizationは必要?

引用記事