0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

目画像から瞼の間の領域を求める2値クラス分類モデル

Last updated at Posted at 2020-04-18

Deep Learningに関し、Toyレベルのサンプルはいろいろオープンにされていて勉強できる。また、Academic Paperに、記録狙いの巨大なNeuralNetworkが書いてある。しかし、それらの間にある、ある程度、実用レベルを狙っているが、さほど複雑でない、NeuralNetworkの情報は、あまり公開されていません。

そこで、自分がやったことに関し、似たようなことをやろうとしている方に役立つかもしれないので、残しておきます。

以下、目周辺の画像のPixelに関し、まぶたの間の領域とそれ以外を2値分類する(セグメントする)、2値クラス分類モデルです。
ここの画像は、テスト入力画像と、Sigmoid出力[0..1]を、gray scaleの[0..255]に変換したMaskとを、bitwise_orしたサンプルです。
1_1_1_20170109194545320_left_crop_6_8_maskedImage.jpg1_0_2_20161219195639772_right_light29_maskedImage.jpg39_1_4_20170105001146812_left_maskedImage.jpgimg00284_left_crop_5_8_maskedImage.jpgimg00551_right_flip_dark29_maskedImage.jpgimg08133_right_flip_crop_4_8_maskedImage.jpg

PyTorchを使っています。データローダーと、Training/testコードは、PyTorchのサイトのTutorialのもろもろのサンプルコードの微改造なので、省略します。

入力データは、
・縦48x横78pixel画像が、84K個。
・正解領域を1としそれ以外を0とするような、画像と同じサイズのマスク。
・90:10でTrainig:Test区分けしています。

データソースは、商用利用を許諾された画像を集め、Flip、明度変更、Crop、Rotationなどで、Data Argumentionしています。

正解Tagは、DlibのLandmark Tagをもとにして、輪郭をとって内側を塗りつぶし、多少のモルホロジー変換を施し作りましたが、Dlibは白人以外に弱い、眼鏡などがあると間違えやすい、などの問題があり、手修正が大変でした。

ネットワークモデルは、Sonyの小林さんという方がYouTubeに投稿しているSegmentationのTutorial動画を参考にしました。Convolutionを4層重ね、Sigmoidするだけですが、Dilationという仕組みでグローバルなコンテキストを認識するようにした。

Training結果のConfusion Matrixは数値化していませんが、どのテスト結果を見ても目領域を外していません。つまり、目領域ではないのに目領域であると判定された、False-Positiveはほとんどない。

たったこれだけのコードで、ほぼ完ぺきに目領域をセグメントできる。

class EyeMaskNet(nn.Module):
    def __init__(self):
        super(EyeMaskNet, self).__init__()

        self.conv1 = nn.Conv2d(1, 16, (3,3), dilation=(1,1), padding=(1,1))
        nn.init.kaiming_normal_(self.conv1.weight)
        self.bn1 = nn.BatchNorm2d(16)
        self.conv2 = nn.Conv2d(16, 16, (3,3), dilation=(2,2), padding=(2,2)) #dilate=2 -> kernel=5x5
        nn.init.kaiming_normal_(self.conv2.weight)
        self.bn2 = nn.BatchNorm2d(16)
        self.conv3 = nn.Conv2d(16, 16, (3,3), dilation=(4,4), padding=(4,4)) #dilate=4 -> kernel=9x9
        nn.init.kaiming_normal_(self.conv3.weight)
        self.bn3 = nn.BatchNorm2d(16)
        self.conv4 = nn.Conv2d(16, 16, (3,3), dilation=(8,8), padding=(8,8)) #dilate=8 -> kernel=17x17
        nn.init.kaiming_normal_(self.conv4.weight)
        self.bn4 = nn.BatchNorm2d(16)

        self.convf = nn.Conv2d(16, 1, (3,3), dilation=(1,1), padding=(1,1))
        nn.init.kaiming_normal_(self.convf.weight)

    def forward(self, x):
        x = x.float()
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.relu(self.bn2(self.conv2(x)))
        x = F.relu(self.bn3(self.conv3(x)))
        x = F.relu(self.bn4(self.conv4(x)))
        x = F.sigmoid(self.convf(x))
        return x
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?