U-net構造で、画像セグメンテーションしてみた。（１）

Kerasの練習がてらU-net構造のモデルで、画像セグメンテーションをしてみた。
画像セグメンテーションと言っても、物体の位置を白に塗り、それ以外を黒にするという2値のみのものです。

今回の物体は、猫が好きなので、猫にしました。

## 環境
- Windows10
- GeForce GTX 1080 ti
- Python
- Keras
- CUDA 9.0

## Inputs
![neko_01.png](https://qiita-image-store.s3.amazonaws.com/0/162097/2248f39d-c2cd-ad23-8d0e-e98bff62b8e3.png)![neko_06.png](https://qiita-image-store.s3.amazonaws.com/0/162097/9292058c-10ec-3897-f82f-546d6e4ce292.png)![neko_17.png](https://qiita-image-store.s3.amazonaws.com/0/162097/f7a5c170-baf6-172d-9408-6d979757d0b7.png)![neko_60.png](https://qiita-image-store.s3.amazonaws.com/0/162097/0a6d9497-8215-2dd5-b59c-dcc1ec267fa3.png)

こんな感じの猫がいる画像(60(学習用)+20(評価用))を準備
サイズは、128*128にした。
ただし、入力時は、GrayScale化し、1Channelにして扱った。

## Teachers
![neko_01.png](https://qiita-image-store.s3.amazonaws.com/0/162097/acd08975-97c0-c8ef-1e3e-f9251857c1a5.png)![neko_06.png](https://qiita-image-store.s3.amazonaws.com/0/162097/51206726-62e1-9c3c-7886-aafbd5ae98b5.png)![neko_17.png](https://qiita-image-store.s3.amazonaws.com/0/162097/9039b0b3-cabd-dc3b-7c13-50340d8fc930.png)![neko_60.png](https://qiita-image-store.s3.amazonaws.com/0/162097/30059086-fbd4-68ea-6570-c784d164c221.png)

こんな感じに、猫がいるところ(猫の範囲)を白にした画像を準備
サイズは、Inputsに同じく128*128。
DVD見ながら自分でアノテーション。
画像処理でうまくエッジが出せなかったので、ペイントツールで、猫の外枠を明らかに違う色で描いてから、エッジ抽出処理して、内側を白に変更した。
2値化して、1Channelで扱う。

## モデル
U-netの論文([*1](#注釈))の通りにすると、Outputのサイズが、inputより小さくなるが、今回は、同じにしたい。
そこで、今回は、Convolutionするときに、paddingをして、サイズを落とさないようにする実装にしてみた。
loss関数は、Dice Coefficient

こんな感じ

![Unet_Model.png](https://qiita-image-store.s3.amazonaws.com/0/162097/01cf89b9-2a0f-735f-9bd8-ec8338d1b819.png)


## 学習
バッチサイズ : 5
エポック : 100
で学習実行

学習曲線は、こんな感じ
![LearningCurve_1.png](https://qiita-image-store.s3.amazonaws.com/0/162097/1c7b571d-1867-4b85-8a3a-d1f916cb3877.png)

んん、なんか微妙？

## 結果

### 学習に使ったデータ

![neko_01.png](https://qiita-image-store.s3.amazonaws.com/0/162097/613b6658-d0c2-5618-a157-ee47ccc9b494.png)![neko_06.png](https://qiita-image-store.s3.amazonaws.com/0/162097/c9c5ac78-d9b5-a178-54b4-76043813c66b.png)![neko_17.png](https://qiita-image-store.s3.amazonaws.com/0/162097/4209fac2-f53d-df00-6b05-deab476093e0.png)![neko_60.png](https://qiita-image-store.s3.amazonaws.com/0/162097/942170e8-c7aa-acb9-1162-10be2272adde.png)
![neko_01.png](https://qiita-image-store.s3.amazonaws.com/0/162097/d5e999aa-f38d-cd1f-f86a-e763f60d7cec.png)![neko_06.png](https://qiita-image-store.s3.amazonaws.com/0/162097/924c433b-4c29-3e51-277e-f624ad073036.png)![neko_17.png](https://qiita-image-store.s3.amazonaws.com/0/162097/a2d3db3c-f031-84c7-56ed-54830b8e340b.png)![neko_60.png](https://qiita-image-store.s3.amazonaws.com/0/162097/e09fb487-3c72-7510-d386-72ae7b04f8b0.png)
![neko_01.png](https://qiita-image-store.s3.amazonaws.com/0/162097/a7f9a076-61f3-cce8-2849-83db406c7e4c.png)![neko_06.png](https://qiita-image-store.s3.amazonaws.com/0/162097/75e0b2ea-b789-ae3c-a3a4-91a37fed3b00.png)![neko_17.png](https://qiita-image-store.s3.amazonaws.com/0/162097/db108ec2-9e24-fd27-4df5-1ea52e3bce53.png)![neko_60.png](https://qiita-image-store.s3.amazonaws.com/0/162097/84d9dd7b-2931-0233-9eaa-eda529d94e2f.png)


それぞれの列で、上から順に、入力/出力/理想(教師)

出力が真っ白に。。。

### 検証用データ(学習に使用しなかったデータ)
![neko_67.png](https://qiita-image-store.s3.amazonaws.com/0/162097/a456bae8-22e3-635f-4c70-66e8a093f1b6.png)![neko_72.png](https://qiita-image-store.s3.amazonaws.com/0/162097/d1224b50-27c6-e779-9d6e-138b0298b23d.png)![neko_76.png](https://qiita-image-store.s3.amazonaws.com/0/162097/9611d861-bb5e-b172-1ec9-c42aced9a646.png)![neko_79.png](https://qiita-image-store.s3.amazonaws.com/0/162097/258b4e3b-a861-40b3-def6-2b248400d925.png)
![neko_67.png](https://qiita-image-store.s3.amazonaws.com/0/162097/08e6eb9d-c820-72a7-46b7-8ef2b60fd111.png)![neko_72.png](https://qiita-image-store.s3.amazonaws.com/0/162097/2dc1eddb-7df5-8431-c226-992cc815e5a7.png)![neko_76.png](https://qiita-image-store.s3.amazonaws.com/0/162097/599ddb5e-42c3-218b-bd0b-fe85a2036f41.png)![neko_79.png](https://qiita-image-store.s3.amazonaws.com/0/162097/b320e3c3-355b-f88e-9637-1588c677a327.png)
![neko_67.png](https://qiita-image-store.s3.amazonaws.com/0/162097/23ee9b0c-6390-756f-d12c-4985c7828e77.png)![neko_72.png](https://qiita-image-store.s3.amazonaws.com/0/162097/95e2907f-e3f8-f187-6059-20ca55abacd4.png)![neko_76.png](https://qiita-image-store.s3.amazonaws.com/0/162097/1990c9e7-650f-11df-a8de-770e3ab563a7.png)![neko_79.png](https://qiita-image-store.s3.amazonaws.com/0/162097/45c88790-c468-987a-7dd4-04f27ddd068d.png)


それぞれの列で、上から順に、入力/出力/理想

やはり、出力が真っ白。。。学習がうまく行ってないのだろうか...
学習曲線も、下がって行っているように見えないし。

## まとめ
KerasでU-net構造のモデルを書くことはできたが、
結果を見る限り学習がうまく言ってなさそう。
改良を行い、学習がうまくいくようにしたい。

と、実は、既に、改良を行ってみたので、その結果も書いていこうと思いましたが、
記事が長くなったので、
[U-net構造で、画像セグメンテーションしてみた。（２）](https://qiita.com/taashi/items/161f828472c6196633f1)に続く。

# 注釈
*1 : 参照 https://lmb.informatik.uni-freiburg.de/people/ronneber/u-net/