# HG changeset patch # User Laman # Date 2019-05-11 16:29:29 # Node ID 006c6f1aab13ee29963ee354782d604d66f50bf1 # Parent 4381957e967eef6f36b894d06633a91609b92294 Euclidean distance as a loss function diff --git a/exp/kerokero/k_util.py b/exp/kerokero/k_util.py new file mode 100644 --- /dev/null +++ b/exp/kerokero/k_util.py @@ -0,0 +1,14 @@ +import math + +import keras.backend as K + +def singleUnorderedLoss(yTrue,yPred): + d1=sum(math.sqrt(min((yTrue[i*2]-yPred[j*2])**2+(yTrue[i*2+1]-yPred[j*2+1])**2 for j in range(4))) for i in range(4)) + d2=sum(math.sqrt(min((yTrue[i*2]-yPred[j*2])**2+(yTrue[i*2+1]-yPred[j*2+1])**2 for i in range(4))) for j in range(4)) + return (d1+d2)/2 + + +def averageDistance(yTrue,yPred): + squares=K.square(yTrue-yPred) + distances=K.sqrt(K.sum(squares,-1)) + return K.mean(distances,-1) diff --git a/exp/kerokero/prepare_data.py b/exp/kerokero/prepare_data.py --- a/exp/kerokero/prepare_data.py +++ b/exp/kerokero/prepare_data.py @@ -41,7 +41,7 @@ class Sample: img=np.float32(img)/128-1 grid=Corners(c.transform(m) for c in self.grid) grid=list(map(lambda p: 2*p/self.SIDE-EPoint(1,1), grid)) - return (img,grid,list(itertools.chain.from_iterable(grid))) + return (img,grid) def _getCenter(self): (a,b,c,d)=self.grid @@ -88,7 +88,7 @@ def harvestDir(path): for b in boards: sample=Sample(img,b.grid) # sample.show() - (transformedImg,transformedGrid,label)=sample.transform() + (transformedImg,label)=sample.transform() # Sample(np.uint8((transformedImg+1)*128),map(lambda c: (c+EPoint(1,1))*Sample.SIDE/2,transformedGrid)).show() yield (transformedImg,label) diff --git a/exp/kerokero/test.py b/exp/kerokero/test.py --- a/exp/kerokero/test.py +++ b/exp/kerokero/test.py @@ -3,12 +3,17 @@ import logging as log import numpy as np from keras.models import load_model +import keras.losses +import keras.metrics from prepare_data import loadDataset,Sample from analyzer.epoint import EPoint from analyzer.corners import Corners +from k_util import averageDistance import config as cfg +keras.losses.averageDistance=averageDistance +keras.metrics.averageDistance=averageDistance parser=argparse.ArgumentParser() parser.add_argument("model") @@ -24,14 +29,14 @@ with np.load(args.data) as data: testLabels=data["testLabels"] log.info("done") -log.info(model.evaluate(testImages.reshape((-1,224,224,1)),testLabels)) +log.info(model.evaluate(testImages.reshape((-1,224,224,1)),testLabels.reshape((-1,4,2)))) for img in testImages: label=model.predict(np.reshape(img,(1,224,224,1))) print(label) points=[] for i in range(4): - points.append(EPoint((label[0][i*2]+1)*112,(label[0][i*2+1]+1)*112)) + points.append(EPoint((label[0][i][0]+1)*112,(label[0][i][1]+1)*112)) corners=Corners(points) sample=Sample(np.uint8((img+1)*128),corners) sample.show() diff --git a/exp/kerokero/train.py b/exp/kerokero/train.py --- a/exp/kerokero/train.py +++ b/exp/kerokero/train.py @@ -4,11 +4,17 @@ import argparse import logging as log import numpy as np -from keras.layers import Conv2D,Dropout,Dense,Flatten,MaxPooling2D,BatchNormalization,GlobalAveragePooling2D +from keras.layers import Conv2D,Dropout,Dense,Flatten,MaxPooling2D,BatchNormalization,GlobalAveragePooling2D,Reshape from keras.models import Sequential,load_model from keras.callbacks import TensorBoard,ModelCheckpoint +import keras.losses +import keras.metrics import config as cfg +from k_util import averageDistance + +keras.losses.averageDistance=averageDistance +keras.metrics.averageDistance=averageDistance parser=argparse.ArgumentParser() parser.add_argument("data") @@ -41,17 +47,17 @@ def createCNN(): model.add(BatchNormalization(input_shape=(224,224,1))) - model.add(Conv2D(24,(5,5),border_mode="same",init="he_normal",activation="relu",input_shape=(224,224,1),dim_ordering="tf")) - model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2),border_mode="valid")) + model.add(Conv2D(24,(5,5),padding="same",kernel_initializer="he_normal",activation="relu",input_shape=(224,224,1),data_format="channels_last")) + model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2),padding="valid")) model.add(Conv2D(36,(5,5),activation="relu")) - model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2),border_mode="valid")) + model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2),padding="valid")) model.add(Conv2D(48,(5,5),activation="relu")) - model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2),border_mode="valid")) + model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2),padding="valid")) model.add(Conv2D(64,(3,3),activation="relu")) - model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2),border_mode="valid")) + model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2),padding="valid")) model.add(Conv2D(64,(3,3),activation="relu")) @@ -60,8 +66,9 @@ def createCNN(): model.add(Dense(500,activation="relu")) model.add(Dense(90,activation="relu")) model.add(Dense(8)) + model.add(Reshape((4,2))) - model.compile(optimizer="rmsprop",loss="mse",metrics=["mae","accuracy"]) + model.compile(optimizer="rmsprop",loss=averageDistance,metrics=["mae","accuracy"]) return model @@ -82,7 +89,7 @@ checkpoint=ModelCheckpoint(args.save_mod model.fit( trainImages.reshape((-1,224,224,1)), - trainLabels, + trainLabels.reshape((-1,4,2)), epochs=args.epochs, initial_epoch=args.initial_epoch, batch_size=20, @@ -90,4 +97,4 @@ model.fit( callbacks=[tensorboard,checkpoint] ) -log.info(model.evaluate(testImages.reshape((-1,224,224,1)),testLabels)) +log.info(model.evaluate(testImages.reshape((-1,224,224,1)),testLabels.reshape((-1,4,2))))