├── kaggle.py ├── prepare_test.py ├── Readme.md ├── prepare_train.py ├── facial.c └── ftest.c /kaggle.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | 3 | a = pd.read_csv('result.txt',header=0) 4 | b = pd.read_csv('IDlookup.csv',header=0) 5 | 6 | b = b.drop('Location',axis=1) 7 | 8 | merged = b.merge(a,on=['ImageId','FeatureName']) 9 | 10 | merged.to_csv('kaggle.csv', cols=['RowId_x','Location'], index=False, index_label='RowId' ) -------------------------------------------------------------------------------- /prepare_test.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | import pylab as pl 4 | from skimage import transform 5 | from numpy import ravel 6 | 7 | from sklearn import linear_model, cross_validation 8 | from sklearn.svm import SVR 9 | 10 | 11 | df = pd.read_csv('test.csv', header=0) 12 | #df = df.interpolate() 13 | 14 | x = df['Image'].values 15 | 16 | 17 | X = [] 18 | 19 | for k in xrange(len(x)): 20 | img = np.fromstring(x[k], dtype = np.uint8, sep=' ', count=96*96) 21 | X.append ( ravel(transform.resize (img.reshape(96,96) , (48,48))) ) 22 | 23 | X = np.asarray(X,'float32') 24 | 25 | # Scaling 0-1 26 | 27 | X = X/256 28 | 29 | 30 | print 'X shape:', X.shape 31 | 32 | 33 | outputs = 30 34 | 35 | 36 | # Writing training data 37 | f = open("ftest.txt", "w") 38 | f.write ( str(X.shape[0]) + ' ' + str(X.shape[1]) + '\n' ) 39 | 40 | for k in range(len(X)): 41 | f.write( ' '.join(map(str, X[k] )) + '\n' ) 42 | 43 | f.close() 44 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | #Kaggle Facial Keypoints regression using FANN neural network in C 2 | 3 | This code is used to perform simple linear regression to detect 30 facial keypoints on grayscale images using FANN neural network library. Very fast using native c code. 4 | 5 | #What is Needed 6 | ``` 7 | FANN library 8 | Python 9 | Numpy/Scipy 10 | Scikit-learn 11 | Pandas 12 | ``` 13 | Note: It works in windows, linux and mac 14 | 15 | #Description 16 | ``` 17 | prepare_test.py -> Dumps the images as training data for FANN to read 18 | prepare_train.py -> Prepares and dumps the test data to FANN format 19 | facial.c -> Neural network trainer 20 | ftest.c -> Testing and predictions (produces results.txt) 21 | kaggle.py -> Produces kaggle.csv from results.txt (results to upload to kaggle) 22 | ``` 23 | # How to Run 24 | 25 | First you have to compile all the C code. Make sure you download the training.csv and test.csv from Kaggle facial keypoints project 26 | ``` 27 | gcc facial.c -o facial -lfann2 -lm -I /usr/local/include/fann 28 | gcc ftest.c -o ftest -lfann2 -lm -I /usr/local/include/fann 29 | ``` 30 | then 31 | ``` 32 | python prepare_train.py 33 | python prepare_test.py 34 | ./facial 35 | ./ftest 36 | python kaggle.py 37 | ``` 38 | 39 | #More information 40 | 41 | http://corpocrat.com/2015/02/24/facial-keypoints-extraction-using-deep-learning-with-caffe/ 42 | -------------------------------------------------------------------------------- /prepare_train.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | import pylab as pl 4 | from skimage import transform 5 | from skimage import data, io, filter 6 | from skimage.filter import threshold_otsu 7 | 8 | from numpy import ravel 9 | 10 | from sklearn import linear_model, cross_validation 11 | from sklearn.svm import SVR 12 | 13 | 14 | df = pd.read_csv('training.csv', header=0) 15 | df = df.interpolate() 16 | 17 | x = df['Image'].values 18 | 19 | df = df.drop('Image',axis=1) 20 | y = df.values 21 | #print 'y orig', y[0] 22 | 23 | y = y.astype('float32'); 24 | 25 | X = [] 26 | 27 | for k in xrange(len(x)): 28 | img = np.fromstring(x[k], dtype = np.uint8, sep=' ', count=96*96) 29 | #thresh = threshold_otsu(img.reshape(96,96)) 30 | #img = img.reshape(96,96) > thresh 31 | #img = filter.sobel(img.reshape(96,96)) 32 | X.append ( ravel(transform.resize (img.reshape(96,96) , (48,48))) ) 33 | 34 | X = np.asarray(X,'float32') 35 | y = y / (2 * 96) 36 | 37 | # Scaling 0-1 38 | 39 | X = X/256 40 | 41 | 42 | print 'X,y shape:', X.shape, y.shape 43 | 44 | 45 | X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y, test_size=0.1, random_state=0) 46 | 47 | 48 | outputs = 30 49 | 50 | print 'ytrain', y_train.shape 51 | 52 | # Writing training data 53 | f = open("facial-train.txt", "w") 54 | f.write ( str(X_train.shape[0]) + ' ' + str(X_train.shape[1]) + ' ' + str(outputs) + '\n' ) 55 | 56 | for k in range(len(X_train)): 57 | f.write( ' '.join(map(str, X_train[k] )) + '\n' ) 58 | f.write( ' '.join(map(str, y_train[k] )) + '\n' ) 59 | 60 | f.close() 61 | 62 | # Writing test data 63 | 64 | f = open("facial-test.txt", "w") 65 | f.write ( str(X_test.shape[0]) + ' ' + str(X_test.shape[1]) + ' ' + str(outputs) + '\n' ) 66 | 67 | for n in range(len(X_test)): 68 | f.write( ' '.join(map(str, X_test[n] )) + '\n' ) 69 | f.write( ' '.join(map(str, y_test[n] )) + '\n' ) 70 | f.close() -------------------------------------------------------------------------------- /facial.c: -------------------------------------------------------------------------------- 1 | #include "fann.h" 2 | #include 3 | 4 | int main() 5 | { 6 | const unsigned int max_epochs = 1000; 7 | const unsigned int epochs_between_reports = 10; 8 | 9 | const unsigned int num_input = 48*48; 10 | const unsigned int num_output = 30; 11 | const unsigned int num_layers = 2; 12 | const unsigned int num_neurons_hidden = 25; 13 | 14 | const float desired_error = (const float) 0.0000; 15 | 16 | fann_type *calc_out; 17 | unsigned int i; 18 | int incorrect,ret = 0; 19 | int orig,pred; float max =0 ; 20 | float learning_rate = 0.01; 21 | 22 | 23 | struct fann *ann = fann_create_standard(num_layers, num_input, num_output); 24 | 25 | fann_set_activation_function_hidden(ann, FANN_SIGMOID); 26 | fann_set_activation_function_output(ann, FANN_LINEAR); 27 | fann_set_learning_rate(ann, learning_rate); 28 | 29 | fann_train_on_file(ann, "facial-train.txt", max_epochs, 30 | epochs_between_reports, desired_error); 31 | 32 | fann_reset_MSE(ann); 33 | 34 | 35 | 36 | struct fann_train_data *data = fann_read_train_from_file("facial-test.txt"); 37 | 38 | printf("Testing network..\n"); 39 | 40 | for(i = 0; i < fann_length_train_data(data); i++) { 41 | 42 | calc_out = fann_test(ann, data->input[i], data->output[i] ); 43 | 44 | printf ("%i ", i ); 45 | 46 | max = calc_out[0]; 47 | int maxo = data->output[i][0]; 48 | 49 | for (int n=0; n<30; n++) { 50 | printf (" %.2f/%.2f(%.2f) ",calc_out[n]*(2*96), data->output[i][n]*(2*96), data->output[i][n]*(2*96) - calc_out[n]*(2*96) ); 51 | 52 | 53 | 54 | } 55 | 56 | printf ("\n"); 57 | 58 | 59 | } 60 | 61 | printf("Mean Square Error: %f\n", fann_get_MSE(ann)); 62 | //printf ("Incorrect %i\n", incorrect); 63 | 64 | fann_save(ann, "facial.net"); 65 | 66 | fann_destroy_train(data); 67 | fann_destroy(ann); 68 | 69 | 70 | 71 | return 0; 72 | } -------------------------------------------------------------------------------- /ftest.c: -------------------------------------------------------------------------------- 1 | #include "fann.h" 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | 8 | 9 | fann_type *calc_out; 10 | fann_type *calc_out2; 11 | unsigned int i; 12 | int incorrect,ret = 0; 13 | int counter = 0; 14 | 15 | FILE *fp; 16 | FILE *fp2; 17 | 18 | char *features[] = { 19 | "left_eye_center_x","left_eye_center_y","right_eye_center_x","right_eye_center_y", 20 | "left_eye_inner_corner_x","left_eye_inner_corner_y","left_eye_outer_corner_x", 21 | "left_eye_outer_corner_y","right_eye_inner_corner_x","right_eye_inner_corner_y", 22 | "right_eye_outer_corner_x","right_eye_outer_corner_y","left_eyebrow_inner_end_x", 23 | "left_eyebrow_inner_end_y","left_eyebrow_outer_end_x","left_eyebrow_outer_end_y", 24 | "right_eyebrow_inner_end_x", "right_eyebrow_inner_end_y","right_eyebrow_outer_end_x", 25 | "right_eyebrow_outer_end_y","nose_tip_x","nose_tip_y","mouth_left_corner_x","mouth_left_corner_y", 26 | "mouth_right_corner_x","mouth_right_corner_y","mouth_center_top_lip_x","mouth_center_top_lip_y", 27 | "mouth_center_bottom_lip_x","mouth_center_bottom_lip_y" 28 | 29 | }; 30 | 31 | 32 | printf("Testing network..\n"); 33 | //printf("Mean Square Error: %f\n", fann_get_MSE(ann)); 34 | 35 | printf("Writing to file...\n"); 36 | 37 | fp = fopen("result.txt", "w"); 38 | 39 | 40 | fprintf(fp, "RowId,ImageId,FeatureName,Location\n"); 41 | 42 | struct fann *ann = fann_create_from_file("facial.net"); 43 | 44 | struct fann_train_data *data = fann_read_train_from_file("ftest.txt"); 45 | printf("Mean Square Error: %f\n", fann_get_MSE(ann)); 46 | 47 | 48 | for(i = 0; i < fann_length_train_data(data); i++) { 49 | 50 | 51 | calc_out = fann_run(ann, data->input[i] ); 52 | 53 | 54 | 55 | for (int n=0; n<30; n++) { 56 | counter++; 57 | float output; 58 | 59 | //output = (calc_out[n]*6 + calc_out2[n]*6) / 2; 60 | //printf (" %i# %.2f/%.2f > %.2f \n", i+1 , calc_out[n]*(2*96), calc_out2[n]*(2*96), output ); 61 | 62 | output = (float)calc_out[n]*(2*96); 63 | 64 | if ( output > 96) { 65 | output = 96; 66 | } 67 | 68 | if (output < 0 ) { 69 | output = 0 ; 70 | } 71 | 72 | 73 | 74 | fprintf(fp, "%i,%i,%s,%f\n",counter,i+1,features[n], output); 75 | 76 | } 77 | 78 | counter++; 79 | 80 | 81 | 82 | } 83 | 84 | fclose(fp); 85 | 86 | 87 | fann_destroy_train(data); 88 | fann_destroy(ann); 89 | 90 | 91 | 92 | return 0; 93 | } --------------------------------------------------------------------------------