概要
GCP上でtensorflowで去年の某衛星画像コンペのデータで遊んでみる。
GCP で tensorflow 遊び2の続き。
定義ファイルを読んで画像を読み込み正規化してCNNを行うscriptを発見・修正して
適宜CNN部の実験を行えるようにしていた。
実験
conv1x1というのがアリだと読んだのでそれも試してみる。
baseは前回のCNN4で以下の構造。
## [32,32,7]pixel
## -> [3,3,7,16] kernel -> [32,32,16]pixel -> [16,16,16]pixel
## -> [3,3,16,32] kernel -> [16,16,32]pixel -> [8,8,32]pixel
## -> [3,3,32,32] kernel -> [8,8,32]pixel -> [4,4,32]pixel
## -> [128]FC
## -> 2
train1.zip で学習、train2.zip で判定。
学習はshuffleしたものを読み込み100ファイルでバッチを作って50回学習で全ファイル舐めたら1ステップとする。
ステップの進行でIoUがどう推移するか。
CNN42
3層目のconv3x3をconv1x1で置き換え。
## [32,32,7]pixel
## -> [3,3,7,16] kernel -> [32,32,16]pixel -> [16,16,16]pixel
## -> [3,3,16,32] kernel -> [16,16,32]pixel -> [8,8,32]pixel
## -> [1,1,32,32] kernel -> [8,8,32]pixel -> [4,4,32]pixel
## -> [128]FC
## -> 2
CNN43
各3x3のconvolutionに1x1のconvolutionを後続させる。
## [32,32,7]pixel
## -> [3,3,7,16] kernel -> [32,32,16]pixel -> [1,1,16,16] kernel -> [32,32,16]pixel -> [16,16,16]pixel
## -> [3,3,16,32] kernel -> [16,16,32]pixel -> [1,1,32,32] kernel -> [16,16,32]pixel -> [8,8,32]pixel
## -> [3,3,32,32] kernel -> [8,8,32]pixel -> [1,1,32,32] kernel -> [8,8,32]pixel -> [4,4,32]pixel
## -> [128]FC
## -> 2
CNN44
CNN自体はCNN4と同じだが、最後FCで長さ128のベクトルになった時点で、元画像の7層それぞれの画素値の平均・標準偏差を連結して長さ142のベクトルを作る。
## [32,32,7]pixel
## -> [3,3,7,16] kernel -> [32,32,16]pixel -> [16,16,16]pixel
## -> [3,3,16,32] kernel -> [16,16,32]pixel -> [8,8,32]pixel
## -> [3,3,32,32] kernel -> [8,8,32]pixel -> [4,4,32]pixel
## -> [128]FC -> [142]
## -> 2
結果
# CNN4
40 1 0.5109186746987951
40 2 0.5540834845735028
40 3 0.6401020082881734
40 4 0.5314047029702971
# CNN42
42 1 0.58096
42 2 0.5930057280675309
42 3 0.627724795640327
42 4 0.6567137169743033
42 5 0.6170007710100232
42 6 0.6047528517110267
# CNN43
43 1 0.0012836970474967907
43 2 0.5393416298675231
43 3 0.5103817816476892
43 4 0.5507159904534606
43 5 0.6504182754182755
43 6 0.613016367887763
# CNN44
44 1 0.44843423799582466
44 2 0.3419382141345747
44 3 0.5388956066102378
44 4 0.41763005780346824
44 5 0.6155913978494624
44 6 0.6650469711694201
単純に最後をconv1x1にしただけのCNN42でももとのCNN4よりはよい。
凝ったことをしたCNN43は成果が出るまで時間がかかっているがその後過学習で(?)評価値は下がっている(このあとどう推移するのか?)
正規化する前の画像の輝度情報を連結したCNN44は時間はかかっているが一番高い評価を出している(この後どう推移するのかは不明)
(遊びだからまあいいんだけど)なんか見返してたら IoU とかそのへん全然計算間違えていたことに気が付いて再計算。
どれが良さそうとかの評価は上と変化なし。
(CNN4は他と合わせて6まで計算し直している)
やはり頭使わないで場当たり的に script 直してったら駄目だなということで、真面目に定義通りに計算する script はこちら
#! /usr/bin/env python
## usage
## grep train_ results.xxxx > results.xxxx.train
## Judge.py test_master.tsv results.xxxx.train
import sys, os
import functools
if __name__ == '__main__':
if len(sys.argv) > 2:
f = open(sys.argv[1])
filenames0 = f.readlines()
f.close()
header = filenames0.pop(0)
filenamedic = {}
for l in filenames0:
ll = l.split()
filenamedic[ll[0]] = ll[1]
f = open(sys.argv[2])
filenames2 = f.readlines()
f.close()
TP = 0
TN = 0
FP = 0
FN = 0
RES = map(lambda l: filenamedic[l.split()[0]]+l.split()[1], filenames2)
RES2 = {'00':0, '01':0, '10':0, '11':0}
for i in RES:
RES2[i] += 1
IOU = RES2['11'] / (RES2['11']+RES2['10']+RES2['01'])
precision = RES2['11'] / (RES2['11'] + RES2['01'])
recall = RES2['11'] / (RES2['11'] + RES2['10'])
print(RES2['00'], RES2['01'], RES2['10'], RES2['11'], IOU, precision, recall)
else:
print('command filename dir/')
python の reduce()
で count ってどうやればよかったんだろう?
python の lambda はちょー不便
lambda 式で頑張ろうとするから無理なのであって、関数定義しちゃえば reduce 使えるな
RES = map(lambda l: filenamedic[l.split()[0]]+l.split()[1], filenames2)
RES0 = {'00':0, '01':0, '10':0, '11':0}
def fun(acc, cur):
acc[cur] += 1
return acc
RES2 = functools.reduce(fun, RES, RES0)
ふーん、acc, cur の順なのね。
でもまあダサい