Skip to content

Commit

Permalink
Added both covariance options to the testing python file
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinp committed Sep 19, 2016
1 parent f3dd6b1 commit df15395
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 52 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Bayesian Convolutional Neural Network to infer Sun Direction

1. Download and compile [Caffe-Sl](https://github.com/wanji/caffe-sl) (we use their L2Norm layer).

2. Ensure that the lmdb and cv2 python packages are installed.
2. Ensure that the **lmdb** and **cv2** python packages are installed (e.g. through pip).

3. Clone sun-bcnn:
```
Expand Down
14 changes: 4 additions & 10 deletions scripts/gen_mean_file.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
#!/usr/bin/env sh
DATA=/media/stars/SunBPN2
TOOLS=~/Research/caffe-posenet/build/tools
DATA=/sunbcnn-data
TOOLS=~/caffe-sl/build/tools

$TOOLS/compute_image_mean $DATA/kitti_sun_train_07_lmdb $DATA/kitti_sun_train_07_lmdb_mean.binaryproto
echo "Done 07."
$TOOLS/compute_image_mean $DATA/kitti_sun_train_07_lmdb $DATA/kitti_sun_train_08_lmdb_mean.binaryproto
echo "Done 08."
$TOOLS/compute_image_mean $DATA/kitti_sun_train_07_lmdb $DATA/kitti_sun_train_09_lmdb_mean.binaryproto
echo "Done 09."
$TOOLS/compute_image_mean $DATA/kitti_sun_train_07_lmdb $DATA/kitti_sun_train_10_lmdb_mean.binaryproto
echo "Done 10."
$TOOLS/compute_image_mean $DATA/train_lmdb_file $DATA/mean_file.binaryproto
echo "Done."
103 changes: 62 additions & 41 deletions scripts/test_sun_bcnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,35 @@
import argparse
import math
import pylab
from sklearn.preprocessing import normalize
from mpl_toolkits.mplot3d import Axes3D
import lmdb
import random

# Make sure that caffe is on the python path:
caffe_root = '/home/valentinp/Research/caffe-sl/' # Change to your directory to caffe-posenet
import sys
sys.path.insert(0, caffe_root + 'python')

import caffe

caffe_root = '~/caffe-sl/' # Change to your directory to caffe-sl
sys.path.insert(0, caffe_root + 'python') # Ensure pycaffe is on the path

from caffe.io import datum_to_array

estimation_type = 0 #1 or 0. If 1, the covariances will be estimated by propagating the covariance of unit norm vectors to a 2x2 azimuth, zenith covariances
# If 0, all unit norm vectors will be first converted to azimuth, zenith angles, then averaged and covarianced.


# Import arguments
parser = argparse.ArgumentParser()
parser.add_argument('--model', type=str, required=True)
parser.add_argument('--weights', type=str, required=True)
parser.add_argument('--dataset', type=str, required=True)
parser.add_argument('--meanfile', type=str, required=True)
args = parser.parse_args()


caffe.set_mode_gpu()

# Load the net
net = caffe.Net(args.model,
args.weights,
caffe.TEST)

# Extract the image dimensions and the amount of stochastic passes
sample_size = net.blobs['data'].data.shape[0]
sample_w = net.blobs['data'].data.shape[2]
sample_h = net.blobs['data'].data.shape[3]
Expand All @@ -44,15 +45,16 @@
lmdb_cursor = lmdb_txn.cursor()
datum = caffe.proto.caffe_pb2.Datum()

# Number of samples in the test dataset
test_samples = lmdb_env.stat()['entries']

count = 0

blob_meanfile = caffe.proto.caffe_pb2.BlobProto()
data_meanfile = open(args.meanfile , 'rb' ).read()
blob_meanfile.ParseFromString(data_meanfile)
meanfile = np.squeeze(np.array( caffe.io.blobproto_to_array(blob_meanfile)))

#Compute the jacobian of cosdist(u_est,v_true) wrt [x,y,z] of u_est
def computeCosDistJacob(u_est, v_true):
G = np.empty([1,3])
nu = np.linalg.norm(u_est)
Expand All @@ -70,10 +72,10 @@ def computeCosDistJacob(u_est, v_true):

return G

#Compute the jacobian of zenaz(u_est,v_true) wrt [x,y,z] of u_est
def computeZenAzJacob(u_est, v_true):
G = np.empty([2,3])


dthz_dx = 0
dthz_dy = 1.0/math.sqrt(1-math.pow(u_est[1],2))
dthz_dz = 0
Expand Down Expand Up @@ -110,6 +112,8 @@ def convertToZenAz(u_mat):
#azimuth error
zenaz_mat[1, i] = math.atan2(u_est[0], u_est[2])
return zenaz_mat


def convertZenAzToVec(zen, az):
y = -math.cos(zen)
x = math.sin(az)*math.cos(zen)
Expand Down Expand Up @@ -141,27 +145,17 @@ def convertToCosineDist(u_mat, u_mat_true):
label = np.array(datum.float_data)
data = caffe.io.datum_to_array(datum)

#Subtract mean from image
data = data-meanfile

w = data.shape[1]
h = data.shape[2]

## Take center crop...
#x_c = int(w/2)
#y_c = int(h/2)
#input_image = data[:,x_c-sample_w/2:x_c+sample_w/2,y_c-sample_h/2:y_c+sample_h/2]
input_image = data
batch = np.repeat([input_image],sample_size,axis=0)
## ... or take random crop
#batch = np.zeros((sample_size,3,sample_w,sample_h))
#for i in range(0, sample_size):
# x = random.randint(0,w-sample_w)
# y = random.randint(0,h-sample_h)
# input_image = data[:,x:x+sample_w,y:y+sample_h]
# batch[i,:,:,:] = input_image

net.forward_all(data = batch)

#Extract the predicted direction vectors (where N=sample_size)
predicted_vec_mat = net.blobs['cls3_fc_xyz_norm'].data
predicted_vec_mat = np.squeeze(predicted_vec_mat).T #3xN

Expand All @@ -172,31 +166,56 @@ def convertToCosineDist(u_mat, u_mat_true):
#Rotate to avoid signularities at zen = 0
rotMat = np.array([[1.,0.,0.], [0.,0.,1.], [0.,-1.,0.]])

zenaz_mat = convertToZenAz(rotMat.dot(predicted_vec_mat))
zenaz = np.mean(zenaz_mat, axis=1)

#Option 1: Convert to az,zen first, then covariance
if estimation_type == 1:
zenaz_mat = convertToZenAz(rotMat.dot(predicted_vec_mat))
zenaz = np.mean(zenaz_mat, axis=1)

cosinedist_mat = convertToCosineDist(predicted_vec_mat, true_vec_mat)
error_angle_mat = np.arccos(1.0 - cosinedist_mat)*180/math.pi

zenaz_mat_true = convertToZenAz(rotMat.dot(true_vec_mat))
cosinedist_mean = np.mean(cosinedist_mat)
error_angle = np.mean(error_angle_mat)
zenaz_error = np.mean(zenaz_mat-zenaz_mat_true, axis=1)* 180/math.pi

#Variance
covariance_zenaz = math.pow(180/math.pi, 2)*np.cov(zenaz_mat,rowvar=1)
variance_angle = np.var(error_angle_mat)

predicted_vec = convertZenAzToVec(zenaz[0], zenaz[1])
predicted_vec = rotMat.T.dot(predicted_vec)

zenaz = zenaz*180/math.pi

cosinedist_mat = convertToCosineDist(predicted_vec_mat, true_vec_mat)
error_angle_mat = np.arccos(1.0 - cosinedist_mat)*180/math.pi
#Option 0: Stay in unit norms, and propagate covariance through Jacobians
else:
predicted_vec_mean = np.mean(predicted_vec_mat, axis=0)
predicted_vec = predicted_vec_mean / np.linalg.norm(predicted_vec_mean)

error_angle = math.acos(np.dot(true_vec,predicted_vec)/(np.linalg.norm(true_vec)*np.linalg.norm(predicted_vec)))
error_angle = error_angle * 180/math.pi

zenaz_mat_true = convertToZenAz(rotMat.dot(true_vec_mat))
cosinedist_mean = np.mean(cosinedist_mat)
error_angle = np.mean(error_angle_mat)
zenaz_error = np.mean(zenaz_mat-zenaz_mat_true, axis=1)* 180/math.pi
#Rotate to avoid signularities at zen = 0
rotMat = np.array([[1.,0.,0.], [0.,0.,1.], [0.,-1.,0.]])

#Variance
covariance_zenaz = math.pow(180/math.pi, 2)*np.cov(zenaz_mat,rowvar=1)
variance_angle = np.var(error_angle_mat)
if np.isnan(variance_angle):
print cosinedist_mat
break
zenaz = computeZenAz(rotMat.dot(predicted_vec)) * 180/math.pi
zenaz_error = zenaz - computeZenAz(rotMat.dot(true_vec)) * 180/math.pi

#Variance
covariance_vec = np.cov(predicted_vec_mat,rowvar=0)

#Jacobian into zenith and azimuth angles
G_zenaz = computeZenAzJacob(rotMat.dot(predicted_vec), rotMat.dot(true_vec))
covariance_zenaz = math.pow(180/math.pi, 2)*np.dot(np.dot(G_zenaz, covariance_vec), G_zenaz.T)


#Jacobian into error (cosine distance) angle
G_cos = computeCosDistJacob(predicted_vec, true_vec)
variance_angle = math.pow(180/math.pi, 2)*np.dot(np.dot(G_cos, covariance_vec), G_cos.T)

predicted_vec = convertZenAzToVec(zenaz[0], zenaz[1])
predicted_vec = rotMat.T.dot(predicted_vec)

#Convert to degrees for Saving
zenaz = zenaz*180/math.pi

predicted_vec_hist[:,count] = predicted_vec
true_vec_hist[:,count] = true_vec
Expand All @@ -206,6 +225,7 @@ def convertToCosineDist(u_mat, u_mat_true):
zenaz_error_hist[:,count] = zenaz_error
covariance_zenaz_hist[:,:,count] = covariance_zenaz
count += 1

print 'Iteration: ', count
print 'Vector Error (deg): ', error_angle
print ('Zenith error (deg): %f, Azimuth error (deg): %f' % (zenaz_error[0],zenaz_error[1]))
Expand All @@ -214,6 +234,7 @@ def convertToCosineDist(u_mat, u_mat_true):
print 'WARNING!! Zenith angle less than 5 degrees!'
print 'Uncertainty (deg): ', math.sqrt(variance_angle)


median_err = np.median(error_angle_hist)
median_std = np.median(np.sqrt(variance_angle_hist))

Expand Down

0 comments on commit df15395

Please sign in to comment.