あかすくぱるふぇ

同人サークル「あかすくぱるふぇ」のブログです。

pix2pixではU-Netと呼ばれるネットワークを使用しています。
本記事では、下記サイトのchainer-pix2pixを参照しながら、chainerによるU-Netの実装方法を解説します。
https://github.com/pfnet-research/chainer-pix2pix

U-Netの概要については、下記論文の図1を参照してください。
U字ネットワークの左側の各層の出力を右側の各層の入力に連結するのが特徴です。
https://arxiv.org/abs/1505.04597

chainer-pix2pixからU-Netの実装を引用します。
class Encoder(chainer.Chain):
def __init__(self, in_ch):
layers = {}
w = chainer.initializers.Normal(0.02)
layers['c0'] = L.Convolution2D(in_ch, 64, 3, 1, 1, initialW=w)
layers['c1'] = CBR(64, 128, bn=True, sample='down', activation=F.leaky_relu, dropout=False)
layers['c2'] = CBR(128, 256, bn=True, sample='down', activation=F.leaky_relu, dropout=False)
layers['c3'] = CBR(256, 512, bn=True, sample='down', activation=F.leaky_relu, dropout=False)
layers['c4'] = CBR(512, 512, bn=True, sample='down', activation=F.leaky_relu, dropout=False)
layers['c5'] = CBR(512, 512, bn=True, sample='down', activation=F.leaky_relu, dropout=False)
layers['c6'] = CBR(512, 512, bn=True, sample='down', activation=F.leaky_relu, dropout=False)
layers['c7'] = CBR(512, 512, bn=True, sample='down', activation=F.leaky_relu, dropout=False)
super(Encoder, self).__init__(**layers)

def __call__(self, x):
hs = [F.leaky_relu(self.c0(x))]
for i in range(1,8):
hs.append(self['c%d'%i](hs[i-1]))
return hs

class Decoder(chainer.Chain):
def __init__(self, out_ch):
layers = {}
w = chainer.initializers.Normal(0.02)
layers['c0'] = CBR(512, 512, bn=True, sample='up', activation=F.relu, dropout=True)
layers['c1'] = CBR(1024, 512, bn=True, sample='up', activation=F.relu, dropout=True)
layers['c2'] = CBR(1024, 512, bn=True, sample='up', activation=F.relu, dropout=True)
layers['c3'] = CBR(1024, 512, bn=True, sample='up', activation=F.relu, dropout=False)
layers['c4'] = CBR(1024, 256, bn=True, sample='up', activation=F.relu, dropout=False)
layers['c5'] = CBR(512, 128, bn=True, sample='up', activation=F.relu, dropout=False)
layers['c6'] = CBR(256, 64, bn=True, sample='up', activation=F.relu, dropout=False)
layers['c7'] = L.Convolution2D(128, out_ch, 3, 1, 1, initialW=w)
super(Decoder, self).__init__(**layers)

def __call__(self, hs):
h = self.c0(hs[-1])
for i in range(1,8):
h = F.concat([h, hs[-i-1]])
if i<7:
h = self['c%d'%i](h)
else:
h = self.c7(h)
return h
EncoderとDecoderの2つ合わせてU-Netです。
Encoderの出力をDecoderに入力することでU字ネットワークを実現します。

特徴的なのは、Decoder.__call__()内で使用されているconcatという関数です。
これはVariable変数を結合する関数であり、これを用いてEncoder(U字左側)の各層の出力をDecoder(U字右側)の各層の入力に連結しています。

concat関数は連結する次元を引数axisで指定でき、デフォルト値は(0ではなく)1です。
Variable変数は(データ数, チャンネル数, 縦, 横)の4次元であるため、上記コードのようにaxisが指定されていない場合、axis=1つまり新しいチャンネルとしてEncoderの各層の出力を連結することになります。

以上がchainerでU-Netを実現する方法です。

・Abstract
深いネットワークをうまく訓練するには、数千もの注釈付きのトレーニングサンプルが必要であるという大きな同意があります。
本稿では、利用可能な注釈付きサンプルをより効率的に使用するために、データ増強の強力な使用に依存するネットワークおよびトレーニング戦略を提示します。
このアーキテクチャは、コンテキストを取得するための縮小パスと、正確なローカライゼーションを可能にする対称拡張パスで構成されています。
このようなネットワークは、非常に少数の画像からエンドツーエンドで訓練することができ、電子顕微鏡スタックにおけるニューロン構造のセグメンテーションのためのISBIチャレンジに関する従来の最良の方法(スライディングウィンドウ畳み込みネットワーク)を凌駕することを示す。
透過光顕微鏡画像(位相コントラストおよびDIC)で訓練された同じネットワークを使用して、我々はこれらのカテゴリーでISBI細胞追跡挑戦2015を大きなマージンで獲得した。
さらに、ネットワークは高速です。
最近のGPUでは、512x512イメージのセグメンテーションに1秒もかかりません。
完全な実装(Caffeに基づく)と訓練されたネットワークは、Webサイトで入手できます。

1. Introduction
過去2年間で、深い畳み込みネットワークは、多くの視覚認識タスク、例えば [7,3]において良い結果を残してきた。
畳み込みネットワークはすでに長い間存在していたが[8]、利用可能な訓練セットのサイズと考えられるネットワークのサイズのために、その成功は限られていた。
Krizhevskyらによる画期的な発見 [7]は、ImageNetデータセット上の8つの層と数百万のパラメータを持つ大規模なネットワークの監督訓練のために、100万のトレーニング画像を使用していました。
それ以来、さらに大きくて深いネットワークも訓練されてきた[12]。

畳み込みネットワークの一般的な使用方法は、イメージへの出力が単一クラスのラベルである分類タスクです。
しかしながら、多くのビジュアルタスク、特に生物医学的画像処理では、所望の出力は、ローカライゼーションを含むべきであり、すなわち、クラスラベルが各ピクセルに割り当てられると想定される。
さらに、何千ものトレーニング画像は、通常、生物医学的作業の範囲を超えています。
したがって、Ciresanら[1]は、スライディングウインドウ設定でネットワークを訓練して、そのピクセルの周りの局所領域(パッチ)を入力として提供することによって、各ピクセルのクラスラベルを予測する。
まず、このネットワークをローカライズできます。
第2に、パッチに関するトレーニングデータは、トレーニング画像の数よりもはるかに多い。
結果として得られたネットワークは、ISBI 2012でのEMセグメンテーションチャレンジを大幅に上回りました。

明らかに、Ciresanら[1]には2つの欠点がある。
まず、各パッチごとにネットワークを個別に実行する必要があり、パッチが重複するために冗長性が高いため、非常に遅いです。
第二に、ローカリゼーションの正確さと文脈の使用との間にはトレードオフがあります。
パッチを大きくすると、ローカライゼーションの精度を低下させるmax-poolingレイヤーが多く必要になりますが、小さなパッチではネットワークにはほとんどコンテキストが見えなくなります。
より最近のアプローチ[11,4]は、複数の層からのフィーチャを考慮に入れたクラス出力を提案した。
同時に、良いローカリゼーションと文脈の使用が可能です。

この論文では、より洗練されたアーキテクチャ、いわゆる "完全畳み込みネットワーク" [9]を構築する。
我々は、このアーキテクチャを修正して拡張し、非常に少数のトレーニングイメージで動作し、より正確なセグメンテーションを生成します。
図1を参照してください。
[9]の主なアイデアは、プールオペレータがアップサンプリング演算子で置き換えられている連続するレイヤーによって通常の契約ネットワークを補うことです。
したがって、これらの層は出力の分解能を高める。
ローカライズするために、収縮経路からの高分解能フィーチャが、アップサンプリングされた出力と組み合わされる。
連続した畳み込みレイヤーは、この情報に基づいてより正確な出力を組み立てることを学ぶことができます。

我々のアーキテクチャにおける1つの重要な変更点は、アップサンプリング部分において、ネットワークが文脈情報をより高い解像度の層に伝搬させることを可能にする多数の特徴チャネルも有することである。
結果として、拡張パスは、収縮パスに多かれ少なかれ対称であり、U字型アーキテクチャをもたらす。
ネットワークは、完全に接続されたレイヤを持たず、各畳み込みの有効部分のみを使用する。
すなわち、セグメンテーションマップは、入力画像において完全なコンテキストが利用可能なピクセルのみを含む。
この戦略は、オーバーラップタイル戦略(図2参照)によって任意に大きな画像をシームレスに分割することを可能にします。
画像の境界領域内のピクセルを予測するために、欠落しているコンテキストは、入力画像をミラーリングすることによって外挿される。
このタイリング戦略は、大きな画像にネットワークを適用する場合に重要です。
そうしないと、解像度はGPUメモリによって制限されるためです。
我々のタスクに関しては、利用可能な訓練データはほとんどなく、利用可能な訓練画像に弾性変形を適用することによって過剰なデータ増大を使用する。
これにより、ネットワークは、注釈付き画像コーパスにおけるこれらの変換を見る必要なく、そのような変形に対する不変性を学習することが可能になる。
これは、生物医学的セグメンテーションにおいて特に重要である。
なぜなら、組織および現実的な変形における最も一般的な変化である変形が効率的にシミュレートされ得るからである。
学習不変性のためのデータ増大の値は、Dosovitskiy et al。 [2]教師なし特徴の学習の範囲で。
多くのセルセグメンテーションタスクのもう1つの課題は、同じクラスのオブジェクトに触れることです。
この目的のために、我々は、接触するセル間の分離背景ラベルが損失関数において大きな重みを得る重み付き損失の使用を提案する。
得られたネットワークは、様々な生物医学的セグメンテーション問題に適用可能である。
この論文では、我々がCiresan et al。のネットワークを上回っているEMスタック(ISBI 2012で開始された進行中の競技会)におけるニューロン構造のセグメント化に関する結果を示す。 [1]。
さらに、ISBIセルトラッキングチャレンジ2015の光学顕微鏡画像でのセルセグメンテーションの結果を示します。
ここでは、2つの最も難しい2D透過光データセットに大きなマージンを得ました。

↑このページのトップヘ