/** * @method rspamd_fann:train(inputs, outputs) * Trains neural network with samples. Inputs and outputs should be tables of * equal size, each row in table should be N inputs and M outputs, e.g. * {0, 1, 1} -> {0} * @param {table} inputs input samples * @param {table} outputs output samples * @return {number} number of samples learned */ static gint lua_fann_train (lua_State *L) { #ifndef WITH_FANN return 0; #else struct fann *f = rspamd_lua_check_fann (L, 1); guint ninputs, noutputs, j; fann_type *cur_input, *cur_output; gboolean ret = FALSE; if (f != NULL) { /* First check sanity, call for table.getn for that */ ninputs = rspamd_lua_table_size (L, 2); noutputs = rspamd_lua_table_size (L, 3); if (ninputs != fann_get_num_input (f) || noutputs != fann_get_num_output (f)) { msg_err ("bad number of inputs(%d, expected %d) and " "output(%d, expected %d) args for train", ninputs, fann_get_num_input (f), noutputs, fann_get_num_output (f)); } else { cur_input = g_malloc (ninputs * sizeof (fann_type)); for (j = 0; j < ninputs; j ++) { lua_rawgeti (L, 2, j + 1); cur_input[j] = lua_tonumber (L, -1); lua_pop (L, 1); } cur_output = g_malloc (noutputs * sizeof (fann_type)); for (j = 0; j < noutputs; j++) { lua_rawgeti (L, 3, j + 1); cur_output[j] = lua_tonumber (L, -1); lua_pop (L, 1); } fann_train (f, cur_input, cur_output); g_free (cur_input); g_free (cur_output); ret = TRUE; } } lua_pushboolean (L, ret); return 1; #endif }
template<bool msg> AnnDef *Ann_GetAnnDef( int i, unsigned int inc, unsigned int outc ) { AnnDef *def = getAnnDef(i); if(!def) { if(msg) Print("Could not get ANN at index %i\n", i); return 0; } struct fann *ann = def->_ann; if( inc != fann_get_num_input(ann) ) { if(msg) Print( "Error: Input count mismatch ugen: %i / ann: %i\n", inc, fann_get_num_input(ann) ); return 0; } if( outc != fann_get_num_output(ann) ) { if(msg) Print( "Error: Output count mismatch ugen: %i / ann: %i\n", outc, fann_get_num_output(ann) ); return 0; } return def; }
/*! ann:__tostring() *# Converts a neural net to a string for Lua's virtual machine *x print(ann) *- */ static int ann_tostring(lua_State *L) { struct fann **ann; ann = luaL_checkudata(L, 1, FANN_METATABLE); luaL_argcheck(L, ann != NULL, 1, "'neural net' expected"); lua_pushfstring(L, "[[FANN neural network: %d %d %d]]", fann_get_num_input(*ann), fann_get_num_output(*ann), fann_get_total_neurons(*ann)); return 1; }
/** * @method rspamd_fann:test(inputs) * Tests neural network with samples. Inputs is a single sample of input data. * The function returns table of results, e.g.: * {0, 1, 1} -> {0} * @param {table} inputs input sample * @return {table/number} outputs values */ static gint lua_fann_test (lua_State *L) { #ifndef WITH_FANN return 0; #else struct fann *f = rspamd_lua_check_fann (L, 1); guint ninputs, noutputs, i, tbl_idx = 2; fann_type *cur_input, *cur_output; if (f != NULL) { /* First check sanity, call for table.getn for that */ if (lua_isnumber (L, 2)) { ninputs = lua_tonumber (L, 2); tbl_idx = 3; } else { ninputs = rspamd_lua_table_size (L, 2); if (ninputs == 0) { msg_err ("empty inputs number"); lua_pushnil (L); return 1; } } cur_input = g_malloc0 (ninputs * sizeof (fann_type)); for (i = 0; i < ninputs; i++) { lua_rawgeti (L, tbl_idx, i + 1); cur_input[i] = lua_tonumber (L, -1); lua_pop (L, 1); } cur_output = fann_run (f, cur_input); noutputs = fann_get_num_output (f); lua_createtable (L, noutputs, 0); for (i = 0; i < noutputs; i ++) { lua_pushnumber (L, cur_output[i]); lua_rawseti (L, -2, i + 1); } g_free (cur_input); } else { lua_pushnil (L); } return 1; #endif }
int main(int argc , char **argv) { fann_type *calc_out; int i; if (argc==1) { printf("usage : eval testFile.txt network.net\n"); return 0; } struct fann_train_data *testData = fann_read_train_from_file(argv[1]); struct fann *ann = ann = fann_create_from_file(argv[2]); int output_size = fann_get_num_output(ann); for(i=0;i<testData->num_data ;i++) { // calcul du résultat de la prédiction calc_out = fann_run(ann, testData->input[i]); // interprétation et affichage du résultat switch (maxIndex(calc_out,output_size)){ case 0 : printf ("fr\n"); break; case 1 : printf ("en\n"); break; case 2 : printf ("de\n"); break; case 3 : printf ("es\n"); break; case 4 : printf ("pt\n"); break; case 5 : printf ("it\n"); break; case 6 : printf ("tr\n"); break; } } fann_destroy(ann); return 0; }
/*** * @method rspamd_fann:get_outputs() * Returns number of outputs for neural network * @return {number} number of outputs */ static gint lua_fann_get_outputs (lua_State *L) { #ifndef WITH_FANN return 0; #else struct fann *f = rspamd_lua_check_fann (L, 1); if (f != NULL) { lua_pushnumber (L, fann_get_num_output (f)); } else { lua_pushnil (L); } return 1; #endif }
/*! ann:run(input1, input2, ..., inputn) *# Evaluates the neural network for the given inputs. *x xor = ann:run(-1, 1) *- */ static int ann_run(lua_State *L) { struct fann **ann; int nin, nout, i; fann_type *input, *output; ann = luaL_checkudata(L, 1, FANN_METATABLE); luaL_argcheck(L, ann != NULL, 1, "'neural net' expected"); nin = lua_gettop(L) - 1; if(nin != fann_get_num_input(*ann)) luaL_error(L, "wrong number of inputs: expected %d, got %d", fann_get_num_input(*ann), nin); nout = fann_get_num_output(*ann); #ifdef FANN_VERBOSE printf("Evaluating neural net: %d inputs, %d outputs\n", nin, nout); #endif input = lua_newuserdata(L, nin*(sizeof *input)); for(i = 0; i < nin; i++) { input[i] = luaL_checknumber(L, i + 2); #ifdef FANN_VERBOSE printf("Input %d's value is %f\n", i, input[i]); #endif } output = fann_run(*ann, input); for(i = 0; i < nout; i++) { #ifdef FANN_VERBOSE printf("Output %d's value is %f\n", i, output[i]); #endif lua_pushnumber(L, output[i]); } return nout; }
NeuralNetwork::NeuralNetwork(int argc, char **argv, int cellArea, int mapWidth, int mapHeight) : BaseRosNode(argc, argv, "NeuralNetwork") { std::string neuralNetowrkFile = get_current_dir_name(); neuralNetowrkFile = neuralNetowrkFile.erase(neuralNetowrkFile.find("catkin_ws") + 9) .append("/src/neural_network/rna.net"); ann = fann_create_from_file(neuralNetowrkFile.c_str()); output = NULL; outputSize= fann_get_num_output(ann); this->occupancyGrid.info.resolution = cellArea; this->occupancyGrid.info.width = mapWidth; this->occupancyGrid.info.height = mapHeight; this->occupancyGrid.header.frame_id = "LaserScannerBody_2D"; for(int i = 0; i < (mapWidth * mapHeight) / cellArea; i++) { this->occupancyGrid.data.insert(this->occupancyGrid.data.begin(),unknownCell); } updateWorld = true; for(int i = 0; i <100; i++) { freeCellVector[i] = 0; occupiedCellVector[i] = 0; visitedCell[i] = 0; } }
/** * @method rspamd_fann:train_threaded(inputs, outputs, callback, event_base, {params}) * Trains neural network with batch of samples. Inputs and outputs should be tables of * equal size, each row in table should be N inputs and M outputs, e.g. * {{0, 1, 1}, ...} -> {{0}, {1} ...} * @param {table} inputs input samples * @param {table} outputs output samples * @param {callback} function that is called when train is completed */ static gint lua_fann_train_threaded (lua_State *L) { #ifndef WITH_FANN return 0; #else struct fann *f = rspamd_lua_check_fann (L, 1); guint ninputs, noutputs, ndata, i, j; struct lua_fann_train_cbdata *cbdata; struct event_base *ev_base = lua_check_ev_base (L, 5); GError *err = NULL; const guint max_epochs_default = 1000; const gdouble desired_mse_default = 0.0001; if (f != NULL && lua_type (L, 2) == LUA_TTABLE && lua_type (L, 3) == LUA_TTABLE && lua_type (L, 4) == LUA_TFUNCTION && ev_base != NULL) { /* First check sanity, call for table.getn for that */ ndata = rspamd_lua_table_size (L, 2); ninputs = fann_get_num_input (f); noutputs = fann_get_num_output (f); cbdata = g_malloc0 (sizeof (*cbdata)); cbdata->L = L; cbdata->f = f; cbdata->train = rspamd_fann_create_train (ndata, ninputs, noutputs); lua_pushvalue (L, 4); cbdata->cbref = luaL_ref (L, LUA_REGISTRYINDEX); if (rspamd_socketpair (cbdata->pair, 0) == -1) { msg_err ("cannot open socketpair: %s", strerror (errno)); cbdata->pair[0] = -1; cbdata->pair[1] = -1; goto err; } for (i = 0; i < ndata; i ++) { lua_rawgeti (L, 2, i + 1); if (rspamd_lua_table_size (L, -1) != ninputs) { msg_err ("invalid number of inputs: %d, %d expected", rspamd_lua_table_size (L, -1), ninputs); goto err; } for (j = 0; j < ninputs; j ++) { lua_rawgeti (L, -1, j + 1); cbdata->train->input[i][j] = lua_tonumber (L, -1); lua_pop (L, 1); } lua_pop (L, 1); lua_rawgeti (L, 3, i + 1); if (rspamd_lua_table_size (L, -1) != noutputs) { msg_err ("invalid number of outputs: %d, %d expected", rspamd_lua_table_size (L, -1), noutputs); goto err; } for (j = 0; j < noutputs; j++) { lua_rawgeti (L, -1, j + 1); cbdata->train->output[i][j] = lua_tonumber (L, -1); lua_pop (L, 1); } } cbdata->max_epochs = max_epochs_default; cbdata->desired_mse = desired_mse_default; if (lua_type (L, 5) == LUA_TTABLE) { rspamd_lua_parse_table_arguments (L, 5, NULL, "max_epochs=I;desired_mse=N", &cbdata->max_epochs, &cbdata->desired_mse); } /* Now we can call training in a separate thread */ rspamd_socket_nonblocking (cbdata->pair[0]); event_set (&cbdata->io, cbdata->pair[0], EV_READ, lua_fann_thread_notify, cbdata); event_base_set (ev_base, &cbdata->io); /* TODO: add timeout */ event_add (&cbdata->io, NULL); cbdata->t = rspamd_create_thread ("fann train", lua_fann_train_thread, cbdata, &err); if (cbdata->t == NULL) { msg_err ("cannot create training thread: %e", err); if (err) { g_error_free (err); } goto err; } } else { return luaL_error (L, "invalid arguments"); } return 0; err: if (cbdata->pair[0] != -1) { close (cbdata->pair[0]); } if (cbdata->pair[1] != -1) { close (cbdata->pair[1]); } fann_destroy_train (cbdata->train); luaL_unref (L, LUA_REGISTRYINDEX, cbdata->cbref); g_free (cbdata); return luaL_error (L, "invalid arguments"); #endif }
FANN_EXTERNAL void FANN_API fann_print_connections(struct fann *ann) { struct fann_layer *layer_it; struct fann_neuron *neuron_it; unsigned int i; int value; char *neurons; unsigned int num_neurons = fann_get_total_neurons(ann) - fann_get_num_output(ann); neurons = (char *) fann_malloc(num_neurons + 1); if(neurons == NULL) { fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM); return; } neurons[num_neurons] = 0; printf("Layer / Neuron "); for(i = 0; i < num_neurons; i++) { printf("%d", i % 10); } printf("\n"); for(layer_it = ann->first_layer + 1; layer_it != ann->last_layer; layer_it++) { for(neuron_it = layer_it->first_neuron; neuron_it != layer_it->last_neuron; neuron_it++) { memset(neurons, (int) '.', num_neurons); for(i = neuron_it->first_con; i < neuron_it->last_con; i++) { if(ann->weights[i] < 0) { #ifdef FIXEDFANN value = (int) ((ann->weights[i] / (double) ann->multiplier) - 0.5); #else value = (int) ((ann->weights[i]) - 0.5); #endif if(value < -25) value = -25; neurons[ann->connections[i] - ann->first_layer->first_neuron] = (char)('a' - value); } else { #ifdef FIXEDFANN value = (int) ((ann->weights[i] / (double) ann->multiplier) + 0.5); #else value = (int) ((ann->weights[i]) + 0.5); #endif if(value > 25) value = 25; neurons[ann->connections[i] - ann->first_layer->first_neuron] = (char)('A' + value); } } printf("L %3d / N %4d %s\n", layer_it - ann->first_layer, neuron_it - ann->first_layer->first_neuron, neurons); } } fann_free(neurons); }
void MyMoveServer::recognizeWithNN() { qDebug("MyMoveServer::recognizeWithNN: finger vectors 1 %d 2 %d 3 %d", m_gesture[0].length(),m_gesture[1].length(),m_gesture[2].length()); // Check if the user has been doing a two-finger gesture but // has accidentally touched the screen with a third finger if (m_fingerAmount == 3 && m_gesture[2].length() < 5) { m_fingerAmount = 2; } // Also check the same for 3-finger gesture if (m_fingerAmount == 4 && m_gesture[3].length() < 5) { m_fingerAmount = 3; } if (m_gesture[0].length() + m_gesture[1].length() <= MIN_GESTURE_LENGTH) { qDebug("Gesture vector is too short"); m_state = OBSERVING; return; } formFeatureVector(); struct fann* network = NULL; QMap<int, Gesture>* gestureList = NULL; switch(m_fingerAmount) { case 2: network = m_gestureNN2; gestureList = &m_gesturesDouble; break; case 3: network = m_gestureNN3; gestureList = &m_gesturesTriple; break; default: qDebug("Amount of fingers not supported, returning"); m_state = OBSERVING; return; break; } qDebug("Using neural network %d", m_fingerAmount); fann_type* results = NULL; results = fann_run(network, m_featureVector); int outputs = fann_get_num_output(network); int matchingIdx = -1; int matches = 0; bool falseRecognitions = false; for (int i = 0; i < outputs; i++) { if (results[i] >= GESTURE_RECOGNITION_THRESHOLD) { matches++; matchingIdx = i; } else if (results[i] >= FALSE_RECOGNITION_THRESHOLD) { falseRecognitions = true; } qDebug("Gesture %d, result: %.2f", i, results[i]); } QString command = ""; if (matches == 1 && !falseRecognitions) { qDebug("Found a single match: %d", matchingIdx); if (matchingIdx < gestureList->size()) { qDebug() << "Command to execute: " << (*gestureList)[matchingIdx].command; command = (*gestureList)[matchingIdx].command; } } m_state = OBSERVING; if (command.length() > 0) { command = command + " &"; system(command.toLatin1()); } qDebug("MyMoveServer::recognizeWithNN out"); }