⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 facenet.cpp

📁 Gaussian Mixture Algorithm
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "facenet.h"#include <stdio.h>#include <string.h>#include <math.h>using namespace std;using namespace ebl;///////////////////////////////////////////////////////////////////////////////////////////////////////////////Idx<intg> custom_table(int in, int out){	int out2 = out-2;	Idx<intg> tbl((3.5 * out2)+(2*in), 2);    for(int i = 0; i < out2/2; i++){    	for(int j = 0; j <= 2; j++){    		tbl.set(i, (3*i)+j, 1);    		tbl.set((i+j)% in, 3*i +j, 0);    	}    }    for(int i = out2/2; i < out2; i++){    	for(int j = 0; j <= 3; j++){    		tbl.set(i, i*4 - out2/2 + j, 1);    		tbl.set((i+j)% in,  i*4 - out2/2 + j, 0);    	}    }    for(int j = 0; j < in; j++){    	tbl.set(j, 3.5*out2 + j, 0);    	tbl.set(out2,  3.5*out2 + j, 1);    }    for(int j = 0; j < in; j++){    	tbl.set(j, 3.5*out2 + j + in, 0);    	tbl.set(out-1,  3.5*out2 + j + in, 1);    }    return tbl;}Idx<double> mexican_hat(double s, int n){	Idx<double> m(n, n);	double vinv = 1/(s*s);	double total = 0;	int cx = n/2;	int cy = n/2;	for(int x = 0; x < n; x++){		for(int y = 0; y < n; y++){			int dx = x - cx;			int dy = y - cy;			m.set( -exp(-sqrt(vinv*(dx*dx + dy*dy))) , x, y);			total += m.get(x, y);		}	}	//! set center valus so it's zero sum	m.set( m.get(cx, cy) - total, cx, cy);	//! normalize so that energy is 1	double energy = sqrt(idx_sumsqr(m));	idx_dotc(m, 1/energy, m);	return m;}//////////////////////////////////////////////////////////////////facenet_datasource::facenet_datasource(Idx<double> *inputs, Idx<ubyte> *labels, double m, double d, bool pretreatment) :	LabeledDataSource<double, ubyte>(inputs, labels)	{		height = data->dim(1);		width = data->dim(2);		mymean = m;		mydeviation = d;		if(pretreatment){			mexican_filter(2, 5);			mymean = idx3_mean(data);			mydeviation = idx3_coef(data, mymean);			normalize();		}	}void facenet_datasource::mexican_filter(double s, int n){	Idx<double> filter = mexican_hat(s, n);	for(int layer = 0; layer < data->dim(0); layer++){		Idx<double> big(height + floor(n/2), width + floor(n/2));		idx_fill(big, 0.0);		Idx<double> bla = data->select(0, layer);		Idx<double> bla2 = big.narrow(0, height, floor(n/2)).narrow(1, width, floor(n/2));		idx_copy( bla, bla2);		idx_2dconvol(big, filter, bla);	}	printf("High-pass filtering performed \n");}void facenet_datasource::save(string dir, string name){	string s1 = dir + "/" + name + "_inputs.mat";	save_matrix(*data, s1.c_str());	string s2 = dir + "/" + name + "_labels.mat";	save_matrix(*labels, s2.c_str());}void facenet_datasource::normalize(){	for(int layer = 0; layer < data->dim(0); layer++){		Idx<double> bla = data->select(0, layer);		Idx<double> bla2(height, width);		idx_addc(bla, -mymean, bla2);		idx_dotc(bla2, 1/mydeviation, bla);	}	printf("Normalization performed \n");}/////////////////////////////////////////////////////////////////facenet::facenet(const char *paramfile){	theparam = new parameter(60000);	int nclasses = 2;	//! the target values for mean-squared error training	//! are +target for the output corresponding to the class	//! being shown and -target for the other outputs.	double target = 1;	labels = new Idx<ubyte>(nclasses);	targets = new Idx<double>(nclasses, nclasses);	idx_fill( *targets, -target);	for(int i = 0; i < nclasses; i++){	     targets->set(target, i, i);	     labels->set(i, i);	}	idx_dotc(*targets, 1.5, *targets);	table0 = full_table(1, 6);	table1 = custom_table(6, 16);	table2 = custom_table(16, 80);	//! initializes the net (cscscf) and charges the weights if needed	init(theparam, 42, 42, 7, 7, &table0, 2, 2, 7, 7, &table1, 2, 2, 6, 6, &table2, 2);	if((paramfile != NULL) && (theparam->load(paramfile))){		printf("Weights loaded. \n");	}	else{		printf("Weights loaded \n");	}	//! creates the kernels for smoothing and high-pass filtering	double sker[3][3] = {{0.3, 0.5, 0.3}, {0.5, 1, 0.5}, {0.3, 0.5, 0.3}};	smoothing_kernel = Idx<double>(3, 3);	memcpy(smoothing_kernel.idx_ptr(), sker, sizeof (sker));	highpass_kernel = mexican_hat(2, 5);}facenet::~facenet() {	delete theparam;	{ idx_bloop3(in, inputs, void*, out, outputs, void*, r, results, void*) {		delete((state_idx*) in.get());		delete((state_idx*) out.get());		delete((Idx<double>*) r.get());	}}	delete labels;	delete targets;}void facenet::build_databases( int sz, const string directory, float ratio){	Idx<double> dataface(1,1,1), datanonface(1,1,1);	Idx<ubyte> lblface(1), lblnonface(1);	//! loads the various images idxs	string s1 = directory + "/data_face.mat";	load_matrix( dataface, s1.c_str());	string s2 = directory + "/labels_face.mat";	load_matrix( lblface, s2.c_str());	string s3 = directory + "/data_nonface.mat";	load_matrix( datanonface, s3.c_str());	string s4 = directory + "/labels_nonface.mat";	load_matrix( lblnonface, s4.c_str());	//! initializes the various sets of images and according labels	Idx<double> training_data( dataface.dim(0)+ datanonface.dim(0), sz, sz);	Idx<double> validation_data( dataface.dim(0)+ datanonface.dim(0), sz, sz);	Idx<ubyte> training_lbl( lblface.dim(0)+ lblnonface.dim(0));	Idx<ubyte> validation_lbl( lblface.dim(0)+ lblnonface.dim(0));	int n_train = 0, n_valid = 0;	int imax = min(dataface.dim(0)-1, datanonface.dim(0) - 1);	//! distributes randomly the images into the training and validation datasets, according to the ratio	dseed(0);	for(int i = 0; i <= imax; i++){		if(drand() < ratio){			Idx<double> bla = datanonface.select(0,i);			Idx<double> bla2 = training_data.select(0, n_train);			idx_copy( bla, bla2);			training_lbl.set( lblnonface.get(i) , n_train);			n_train++;			bla = dataface.select(0,i);			bla2 = training_data.select(0, n_train);			idx_copy( bla, bla2);			training_lbl.set( lblface.get(i) , n_train);			n_train++;		} else {			Idx<double> bla = datanonface.select(0,i);			Idx<double> bla2 = validation_data.select(0, n_valid);			idx_copy( bla, bla2);			validation_lbl.set( lblnonface.get(i) , n_valid);			n_valid++;			bla = dataface.select(0,i);			bla2 = validation_data.select(0, n_valid);			idx_copy( bla, bla2);			validation_lbl.set( lblface.get(i) , n_valid);			n_valid++;		}	}	training_data = training_data.narrow(0, n_train, 0);	training_lbl = training_lbl.narrow(0, n_train, 0);	validation_data = validation_data.narrow(0, n_valid, 0);	validation_lbl = validation_lbl.narrow(0, n_valid, 0);	//! saves the idxs for future use	facenet_datasource* trainingdb = new facenet_datasource( &training_data, &training_lbl, 0, 0, true);	facenet_datasource* testingdb = new facenet_datasource( &validation_data, &validation_lbl, 0, 0, true);	trainingdb->save(directory, "training");	testingdb->save(directory, "testing");	printf("Databases built \n");}void facenet::train(const string directory){	//! create the network	idx3_supervised_module* thenet = new idx3_supervised_module(this, new edist_cost(labels, 1, 1, targets), new max_classer(labels));	//! create the trainer	supervised_gradient* thetrainer = new supervised_gradient( thenet, theparam);	//! a classifier-meter measures classification errors	classifier_meter* trainmeter = new classifier_meter();	classifier_meter* testmeter = new classifier_meter();	//! initialize the network weights	forget_param_linear forgetparam(1, 1/2);	init_drand(0);	thenet->machine->forget(forgetparam);	//! load the training and testing databases	Idx<double> training_input(1,1,1);	Idx<ubyte> training_label(1);	Idx<double> testing_input(1,1,1);	Idx<ubyte> testing_label(1);	string s1 = directory + "/training_inputs.mat";	load_matrix(training_input, s1.c_str());	string s2 = directory + "/training_labels.mat";	load_matrix(training_label, s2.c_str());	string s3 = directory + "/testing_inputs.mat";	load_matrix(testing_input, s3.c_str());	string s4 = directory + "/testing_labels.mat";	load_matrix(testing_label, s4.c_str());	facenet_datasource* trainingdb = new facenet_datasource(&training_input, &training_label);	facenet_datasource* testingdb = new facenet_datasource( &testing_input, &testing_label);	printf("Databases loaded \n");	//! do training iterations (here only one)	printf("training with %d training samples and %d test samples\n", trainingdb->size(), testingdb->size());	gd_param* gdp = new gd_param(0.0001, 0, 0, 0, 0, 0, 0, 0, 0);	//! perform only one pass to check that the training is working	train_online(thetrainer, trainingdb, testingdb, trainmeter, testmeter, 1, gdp, 0, directory);	//! basic training scheme	//train_online(thetrainer, trainingdb, testingdb, trainmeter, testmeter, 3, gdp, 0, directory);	//gdp->eta = 0.00003;	//train_online(thetrainer, trainingdb, testingdb, trainmeter, testmeter, 2, gdp, 1, directory);	//gdp->eta = 0.00001;	//train_online(thetrainer, trainingdb, testingdb, trainmeter, testmeter, 2, gdp, 2, directory);}void facenet::train_online(supervised_gradient* trainer, facenet_datasource* trainingdb, facenet_datasource* testingdb, classifier_meter* trainmeter, classifier_meter* testmeter, int n, gd_param* eta, int pass, const string directory){	int i = 0;	for(int j = 0; j < n; j++){		time_t t = clock();	    //! estimate second derivative on 100 iterations, using mu=0.02 and set individual espilons	    printf("computing diagonal hessian and learning rates\n");	    trainer->compute_diaghessian(trainingdb, 100, 0.02);	    trainer->train(trainingdb, trainmeter, eta, 0);	    time_t t2 = clock() - t;	    printf("time : %li \n", (int)t2/CLOCKS_PER_SEC);	    printf("training: ");	    trainer->test(trainingdb, trainmeter);	    trainmeter->display();	    printf(" testing: ");	    trainer->test(testingdb, testmeter);	    testmeter->display();		//! save the generated weights	    std::stringstream ss;	    ss << pass << i;	    string s = directory + "/weights" + ss.str() + ".mat";	    save_matrix( theparam->x, s.c_str());	    i++;	}}Idx<double> facenet::detect(Idx<ubyte> *img, int h, int w, Idx<int> &sz, float zoom, double threshold, int objsize) {	height = h;	width = w;	grabbed = Idx<ubyte>(height, width);	sizes = sz;	//! initialize input and output states and result matrices for each size	inputs = Idx<void*>(sizes.nelements());	outputs = Idx<void*>(sizes.nelements());	results = Idx<void*>(sizes.nelements());	{ idx_bloop4(size, sizes, int, in, inputs, void*, out, outputs, void*, r, results, void*) {		in.set((void*) new state_idx(2, 38 + (size.get() * 4), 38 + (size.get() * 4)));		out.set((void*) new state_idx(labels->nelements(), size.get(), size.get()));		r.set((void*) new Idx<double>(size.get(), size.get(), 2)); // (class,score)	}}	//! prepares the multiple scales	Idx<ubyte> display = this->multi_res_prep(img, 0.5);	//! performs the fprop	Idx<double> res = this->multi_res_fprop(threshold, objsize);	//! draws the rectangles around the hot spots detected	{ idx_bloop1(re, res, double) {		image_draw_box(display, (ubyte)255,				(unsigned int) (zoom * (re.get(3) - (0.5 * re.get(5)))),				(unsigned int) (zoom * (re.get(2) - (0.5 * re.get(4)))),				(unsigned int) (zoom * re.get(5)),				(unsigned int) (zoom * re.get(4)));	}}	idx_copy(grabbed, *img);	return res;}void facenet::mark_maxima(Idx<double> &in, Idx<double> &inc, Idx<double> &res, double threshold) {	idx_clear(res);	int tr[] = { 1, 2, 0 };	Idx<double> s(inc.transpose(tr));	Idx<double> z(in.transpose(tr));	z = z.unfold(0, 3, 1);	z = z.unfold(1, 3, 1);	{ idx_bloop3(se, s, double, ze, z, double, re, res, double) {		{ idx_bloop3(see, se, double, zee, ze, double, ree, re, double)  {			// find winning class			intg w = 1;			double c = see.get(w);			// look if above threshold and local maximum			ree.set(-1.0, 0),			ree.set(-100.0, 1);			if ((c > threshold) &&					(c > zee.get(w, 0, 0)) && (c > zee.get(w, 0, 1)) && (c > zee.get(w, 0, 2)) &&					(c > zee.get(w, 1, 0)) && (c > zee.get(w, 1, 2)) &&					(c > zee.get(w, 2, 0)) && (c > zee.get(w, 2, 1)) && (c > zee.get(w, 2, 2))) {				ree.set(w, 0);				ree.set(c, 1);			}		}}	}}}//! produce a score between 0 and 1 for each class at each locationIdx<double> facenet::postprocess_output(double threshold, int objsize) {	//! find candidates at each scale	{ idx_bloop2(out, outputs, void*, resu, results, void*) {		Idx<double> outx = ((state_idx*) out.get())->x;		int c = outx.dim(0);		int h = outx.dim(1);		int w = outx.dim(2);		Idx<double> in(c, 2 + w, 2 + h);		Idx<double> inc(in);		inc = inc.narrow(1, w, 1);		inc = inc.narrow(2, h, 1);		Idx<double> m(c, h, w);		idx_fill(in, 0.0);		idx_clip(outx, 0.0, inc);		//! smooth		{ idx_bloop2(ie, in, double, me, m, double) {			idx_2dconvol(ie, smoothing_kernel, me);		}}		idx_copy(m, inc);		//! find points that are local maxima spatial and class-wise		//! write result in m. rescale result to [0 1]		mark_maxima(in, inc, *((Idx<double>*) resu.get()), threshold);	}}	//! now prune by scale and make a list	Idx<double> rlist(1, 6);	rlist.resize(0, rlist.dim(1));	Idx<double> in0x(((state_idx*) inputs.get(0))->x);	intg s0j = in0x.dim(2);	{ idx_bloop3(input, inputs, void*, output, outputs, void*, r, results, void*) {		Idx<double> inx(((state_idx*) input.get())->x);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -