sq_fann.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. #include <stdio.h>
  2. #include "squirrel.h"
  3. #include <string.h>
  4. #include <inttypes.h>
  5. #include <math.h>
  6. #include <stdlib.h>
  7. #include <sys/time.h>
  8. //#include <pthread.h>
  9. SQ_OPT_STRING_STRLEN();
  10. #include "floatfann.h"
  11. struct SQFannTrainData
  12. {
  13. fann_train_data *data;
  14. };
  15. static const SQChar sq_fann_training_data_TAG[] = _SC("SQFannTrainData");
  16. #define SQ_GET_FANN_TRAINING_DATA_INSTANCE_NAME_AT(v, at, vname) \
  17. SQ_GET_INSTANCE_VAR(v, at, SQFannTrainData, vname, sq_fann_training_data_TAG)
  18. #define SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, at) \
  19. SQ_GET_FANN_TRAINING_DATA_INSTANCE_NAME_AT(v, at, self)
  20. static SQRESULT sq_fann_training_data_release_hook(SQUserPointer p, SQInteger size, void */*ep*/) {
  21. SQFannTrainData *self = (SQFannTrainData *)p;
  22. if(self->data) fann_destroy_train(self->data);
  23. return 0;
  24. }
  25. /*
  26. ** Creates a new fann_train_data.
  27. */
  28. static SQRESULT sq_fann_training_data_constructor (HSQUIRRELVM v) {
  29. SQ_FUNC_VARS_NO_TOP(v);
  30. fann_train_data *data = NULL;
  31. SQObjectType otype = sq_gettype(v, 2);
  32. if(otype == OT_STRING)
  33. {
  34. SQ_GET_STRING(v, 2, data_fname);
  35. data = fann_read_train_from_file(data_fname);
  36. }
  37. else if(otype == OT_INTEGER)
  38. {
  39. SQ_GET_INTEGER(v, 2, num_data);
  40. SQ_GET_INTEGER(v, 3, num_input);
  41. SQ_GET_INTEGER(v, 4, num_output);
  42. if(num_data <= 0 || num_input <= 0 || num_output <= 0)
  43. return sq_throwerror(v, _SC("expect only dimensions > 0"));
  44. data = fann_create_train(num_data, num_input, num_output);
  45. }
  46. if(!data) return sq_throwerror(v, _SC("could not create train data"));
  47. SQFannTrainData *self = (SQFannTrainData*)sq_malloc(sizeof(*self));
  48. self->data = data;
  49. sq_setinstanceup(v, 1, self);
  50. sq_setreleasehook(v, 1, sq_fann_training_data_release_hook);
  51. return 1;
  52. }
  53. static SQRESULT sq_fann_training_data_shuffle(HSQUIRRELVM v)
  54. {
  55. SQ_FUNC_VARS_NO_TOP(v);
  56. SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, 1);
  57. if(self->data) fann_shuffle_train_data(self->data);
  58. else return sq_throwerror(v, _SC("train data not initialized"));
  59. return 0;
  60. }
  61. static SQRESULT sq_fann_training_data_get_errstr(HSQUIRRELVM v)
  62. {
  63. SQ_FUNC_VARS_NO_TOP(v);
  64. SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, 1);
  65. sq_pushstring(v, fann_get_errstr((struct fann_error *)self->data), -1);
  66. return 1;
  67. }
  68. static SQRESULT sq_fann_training_data_get_errno(HSQUIRRELVM v)
  69. {
  70. SQ_FUNC_VARS_NO_TOP(v);
  71. SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, 1);
  72. sq_pushinteger(v, fann_get_errno((struct fann_error *)self->data));
  73. return 1;
  74. }
  75. static SQRESULT sq_fann_training_data_reset_errno(HSQUIRRELVM v)
  76. {
  77. SQ_FUNC_VARS_NO_TOP(v);
  78. SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, 1);
  79. fann_reset_errno((struct fann_error *)self->data);
  80. return 0;
  81. }
  82. static SQRESULT sq_fann_training_data_save(HSQUIRRELVM v)
  83. {
  84. SQ_FUNC_VARS_NO_TOP(v);
  85. SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, 1);
  86. SQ_GET_STRING(v, 2, fname);
  87. sq_pushinteger(v, fann_save_train(self->data, fname));
  88. return 1;
  89. }
  90. #define SQ_FANN_TRAINING_DATA_GET_INT(field)\
  91. static SQRESULT sq_fann_training_data_##field(HSQUIRRELVM v)\
  92. {\
  93. SQ_FUNC_VARS_NO_TOP(v);\
  94. SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, 1);\
  95. sq_pushinteger(v, self->data->field);\
  96. return 1;\
  97. }
  98. SQ_FANN_TRAINING_DATA_GET_INT(num_data);
  99. SQ_FANN_TRAINING_DATA_GET_INT(num_input);
  100. SQ_FANN_TRAINING_DATA_GET_INT(num_output);
  101. static SQRESULT sq_fann_training_data_set_input_at(HSQUIRRELVM v)
  102. {
  103. SQ_FUNC_VARS_NO_TOP(v);
  104. SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, 1);
  105. SQ_GET_INTEGER(v, 2, row);
  106. if(row < 0 || row >= self->data->num_data) return sq_throwerror(v, _SC("index out fo bounds"));
  107. SQInteger cols = sq_getsize(v, 3);
  108. if(cols != self->data->num_input) return sq_throwerror(v, _SC("cols mismatch"));
  109. //fill input
  110. fann_type **input = self->data->input;
  111. for(SQInteger i=0; i < cols; ++i)
  112. {
  113. sq_arrayget(v, 3, i);
  114. SQ_GET_FLOAT(v, -1, value);
  115. input[row][i] = value;
  116. sq_poptop(v);
  117. }
  118. return 0;
  119. }
  120. static SQRESULT sq_fann_training_data_set_output_at(HSQUIRRELVM v)
  121. {
  122. SQ_FUNC_VARS_NO_TOP(v);
  123. SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, 1);
  124. SQ_GET_INTEGER(v, 2, row);
  125. if(row < 0 || row >= self->data->num_data) return sq_throwerror(v, _SC("index out fo bounds"));
  126. SQInteger cols = sq_getsize(v, 3);
  127. if(cols != self->data->num_output) return sq_throwerror(v, _SC("cols mismatch"));
  128. //fill input
  129. fann_type **output = self->data->output;
  130. for(SQInteger i=0; i < cols; ++i)
  131. {
  132. sq_arrayget(v, 3, i);
  133. SQ_GET_FLOAT(v, -1, value);
  134. output[row][i] = value;
  135. sq_poptop(v);
  136. }
  137. return 0;
  138. }
  139. #define SCALE_ALL 0
  140. #define SCALE_INPUT 1
  141. #define SCALE_OUTPUT 2
  142. static SQRESULT sq_fann_training_data_scale_iot(HSQUIRRELVM v, int iot)
  143. {
  144. SQ_FUNC_VARS_NO_TOP(v);
  145. SQ_GET_FANN_TRAINING_DATA_INSTANCE(v, 1);
  146. SQ_GET_FLOAT(v, 2, new_min);
  147. SQ_GET_FLOAT(v, 3, new_max);
  148. switch(iot)
  149. {
  150. case SCALE_ALL:
  151. fann_scale_train_data(self->data, new_min, new_max);
  152. break;
  153. case SCALE_INPUT:
  154. fann_scale_input_train_data(self->data, new_min, new_max);
  155. break;
  156. case SCALE_OUTPUT:
  157. fann_scale_output_train_data(self->data, new_min, new_max);
  158. break;
  159. }
  160. return 0;
  161. }
  162. static SQRESULT sq_fann_training_data_scale(HSQUIRRELVM v)
  163. {
  164. return sq_fann_training_data_scale_iot(v, SCALE_ALL);
  165. }
  166. static SQRESULT sq_fann_training_data_scale_input(HSQUIRRELVM v)
  167. {
  168. return sq_fann_training_data_scale_iot(v, SCALE_INPUT);
  169. }
  170. static SQRESULT sq_fann_training_data_scale_output(HSQUIRRELVM v)
  171. {
  172. return sq_fann_training_data_scale_iot(v, SCALE_OUTPUT);
  173. }
  174. #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_fann_training_data_##name,nparams,tycheck}
  175. static SQRegFunction sq_fann_training_data_methods[] =
  176. {
  177. _DECL_FUNC(constructor, -2,_SC("x s|i ii")),
  178. _DECL_FUNC(shuffle, 1,_SC("x")),
  179. _DECL_FUNC(get_errstr, 1,_SC("x")),
  180. _DECL_FUNC(get_errno, 1,_SC("x")),
  181. _DECL_FUNC(reset_errno, 1,_SC("x")),
  182. _DECL_FUNC(num_data, 1,_SC("x")),
  183. _DECL_FUNC(num_input, 1,_SC("x")),
  184. _DECL_FUNC(num_output, 1,_SC("x")),
  185. _DECL_FUNC(save, 2,_SC("xs")),
  186. _DECL_FUNC(set_input_at, 3,_SC("xia")),
  187. _DECL_FUNC(set_output_at, 3,_SC("xia")),
  188. _DECL_FUNC(scale, 3,_SC("xnn")),
  189. _DECL_FUNC(scale_input, 3,_SC("xnn")),
  190. _DECL_FUNC(scale_output, 3,_SC("xnn")),
  191. {0,0}
  192. };
  193. #undef _DECL_FUNC
  194. struct SQFann
  195. {
  196. fann *ann;
  197. };
  198. struct SQFannCallback
  199. {
  200. HSQUIRRELVM v;
  201. HSQOBJECT cb;
  202. HSQOBJECT udata;
  203. };
  204. static const SQChar sq_fann_TAG[] = _SC("SQFann");
  205. #define SQ_GET_FANN_INSTANCE_NAME_AT(v, at, vname) SQ_GET_INSTANCE_VAR(v, at, SQFann, vname, sq_fann_TAG)
  206. #define SQ_GET_FANN_INSTANCE(v, at) SQ_GET_FANN_INSTANCE_NAME_AT(v, at, self)
  207. static void release_sq_fann_callback(SQFannCallback *cb)
  208. {
  209. sq_release(cb->v, &cb->cb);
  210. sq_release(cb->v, &cb->udata);
  211. sq_free(cb, sizeof(*cb));
  212. }
  213. static SQRESULT sq_fann_release_hook(SQUserPointer p, SQInteger size, void */*ep*/) {
  214. SQFann *self = (SQFann *)p;
  215. if(self->ann)
  216. {
  217. SQFannCallback *cb = (SQFannCallback*)fann_get_user_data(self->ann);
  218. if(cb) release_sq_fann_callback(cb);
  219. fann_destroy(self->ann);
  220. }
  221. return 0;
  222. }
  223. /*
  224. ** Creates a new fann.
  225. */
  226. static SQRESULT sq_fann_constructor (HSQUIRRELVM v) {
  227. SQ_FUNC_VARS(v);
  228. fann *ann;
  229. SQObjectType otype = sq_gettype(v, 2);
  230. if(otype == OT_STRING)
  231. {
  232. SQ_GET_STRING(v, 2, net_fname);
  233. ann = fann_create_from_file(net_fname);
  234. }
  235. else
  236. {
  237. int create_type = FANN_NETTYPE_LAYER;
  238. if(_top_ > 2)
  239. {
  240. SQ_GET_INTEGER(v, 3, nt);
  241. create_type = nt;
  242. }
  243. switch(create_type)
  244. {
  245. case FANN_NETTYPE_LAYER:
  246. case FANN_NETTYPE_SHORTCUT:
  247. break;
  248. default:
  249. return sq_throwerror(v, _SC("invalid net type"));
  250. }
  251. SQFloat connection_rate;
  252. SQInteger array_pos = 2;
  253. if(otype == OT_FLOAT)
  254. {
  255. ++array_pos;
  256. SQ_GET_FLOAT(v, 2, cr);
  257. connection_rate = cr;
  258. }
  259. SQInteger num_layers = sq_getsize(v, array_pos);
  260. unsigned int *layers = (unsigned int *)
  261. sq_getscratchpad(v, num_layers*sizeof(unsigned int));
  262. for(SQInteger i=0; i < num_layers; ++i)
  263. {
  264. sq_arrayget(v, array_pos, i);
  265. SQ_GET_INTEGER(v, -1, value);
  266. layers[i] = value;
  267. sq_poptop(v);
  268. }
  269. if(array_pos == 2)
  270. {
  271. if(create_type == FANN_NETTYPE_LAYER)
  272. ann = fann_create_standard_array(num_layers, layers);
  273. else if(create_type == FANN_NETTYPE_SHORTCUT)
  274. ann = fann_create_shortcut_array(num_layers, layers);
  275. }
  276. else ann = fann_create_sparse_array(connection_rate, num_layers, layers);
  277. }
  278. if(ann)
  279. {
  280. SQFann *self = (SQFann*)sq_malloc(sizeof(*self));
  281. self->ann = ann;
  282. sq_setinstanceup(v, 1, self);
  283. sq_setreleasehook(v, 1, sq_fann_release_hook);
  284. return 1;
  285. }
  286. return sq_throwerror(v, _SC("failed to create SQFann"));
  287. }
  288. static SQRESULT sq_fann_copy(HSQUIRRELVM v)
  289. {
  290. SQ_FUNC_VARS_NO_TOP(v);
  291. SQ_GET_FANN_INSTANCE(v, 1);
  292. fann *ann = fann_copy(self->ann);
  293. if(ann)
  294. {
  295. SQFann *new_self = (SQFann*)sq_malloc(sizeof(*self));
  296. new_self->ann = ann;
  297. sq_pushstring(v, sq_fann_TAG, -1);
  298. sq_getonroottable(v);
  299. sq_createinstance(v, -1);
  300. sq_setinstanceup(v, 1, new_self);
  301. sq_setreleasehook(v, 1, sq_fann_release_hook);
  302. return 1;
  303. }
  304. return sq_throwerror(v, _SC("failed to create SQFann"));
  305. }
  306. static int sq_fann_callback_c(fann *ann, fann_train_data *train,
  307. unsigned int max_epochs, unsigned int epochs_between_reports,
  308. float desired_error, unsigned int epochs)
  309. {
  310. SQFannCallback *cb = (SQFannCallback*)fann_get_user_data(ann);
  311. if(cb)
  312. {
  313. /* ensure there is enough space in the stack */
  314. sq_reservestack(cb->v, 20);
  315. SQInteger top = sq_gettop(cb->v);
  316. sq_pushobject(cb->v, cb->cb);
  317. sq_pushroottable(cb->v);
  318. sq_pushobject(cb->v, cb->udata);
  319. sq_pushinteger(cb->v, max_epochs);
  320. sq_pushinteger(cb->v, epochs_between_reports);
  321. sq_pushfloat(cb->v, desired_error);
  322. sq_pushinteger(cb->v, epochs);
  323. /* call squilu function */
  324. SQInteger rc = 0;
  325. if (sq_call(cb->v, 6, SQTrue, SQFalse) == SQ_OK)
  326. sq_getinteger(cb->v, -1, &rc);
  327. sq_settop(cb->v, top);
  328. return rc;
  329. }
  330. return 0;
  331. }
  332. static SQRESULT sq_fann_set_callback(HSQUIRRELVM v)
  333. {
  334. SQ_FUNC_VARS(v);
  335. SQ_GET_FANN_INSTANCE(v, 1);
  336. SQFannCallback *cb = (SQFannCallback*)fann_get_user_data(self->ann);
  337. if(cb) release_sq_fann_callback(cb);
  338. cb = (SQFannCallback*)sq_malloc(sizeof(*cb));
  339. cb->v = v;
  340. sq_resetobject(&cb->cb);
  341. sq_getstackobj(v, 2, &cb->cb);
  342. sq_addref(v, &cb->cb);
  343. sq_resetobject(&cb->udata);
  344. if(_top_ > 2)
  345. {
  346. sq_getstackobj(v, 3, &cb->udata);
  347. sq_addref(v, &cb->udata);
  348. }
  349. fann_set_user_data(self->ann, cb);
  350. fann_set_callback(self->ann, sq_fann_callback_c);
  351. return 0;
  352. }
  353. static SQRESULT sq_fann_learning_rate(HSQUIRRELVM v)
  354. {
  355. SQ_FUNC_VARS(v);
  356. SQ_GET_FANN_INSTANCE(v, 1);
  357. if(_top_ > 1)
  358. {
  359. SQ_GET_FLOAT(v, 2, learn_rate);
  360. fann_set_learning_rate(self->ann, learn_rate);
  361. return 0;
  362. }
  363. sq_pushfloat(v, fann_get_learning_rate(self->ann));
  364. return 1;
  365. }
  366. static SQRESULT sq_fann_learning_momentum(HSQUIRRELVM v)
  367. {
  368. SQ_FUNC_VARS(v);
  369. SQ_GET_FANN_INSTANCE(v, 1);
  370. if(_top_ > 1)
  371. {
  372. SQ_GET_FLOAT(v, 2, value);
  373. fann_set_learning_momentum(self->ann, value);
  374. return 0;
  375. }
  376. sq_pushfloat(v, fann_get_learning_momentum(self->ann));
  377. return 1;
  378. }
  379. static SQRESULT sq_fann_training_algorithm(HSQUIRRELVM v)
  380. {
  381. SQ_FUNC_VARS(v);
  382. SQ_GET_FANN_INSTANCE(v, 1);
  383. if(_top_ > 1)
  384. {
  385. SQ_GET_INTEGER(v, 2, value);
  386. fann_set_training_algorithm(self->ann, (fann_train_enum)value);
  387. return 0;
  388. }
  389. sq_pushinteger(v, fann_get_training_algorithm(self->ann));
  390. return 1;
  391. }
  392. static SQRESULT sq_fann_train_error_function(HSQUIRRELVM v)
  393. {
  394. SQ_FUNC_VARS(v);
  395. SQ_GET_FANN_INSTANCE(v, 1);
  396. if(_top_ > 1)
  397. {
  398. SQ_GET_INTEGER(v, 2, value);
  399. fann_set_train_error_function(self->ann, (fann_errorfunc_enum)value);
  400. return 0;
  401. }
  402. sq_pushinteger(v, fann_get_train_error_function(self->ann));
  403. return 1;
  404. }
  405. static SQRESULT sq_fann_train_stop_function(HSQUIRRELVM v)
  406. {
  407. SQ_FUNC_VARS(v);
  408. SQ_GET_FANN_INSTANCE(v, 1);
  409. if(_top_ > 1)
  410. {
  411. SQ_GET_INTEGER(v, 2, value);
  412. fann_set_train_stop_function(self->ann, (fann_stopfunc_enum)value);
  413. return 0;
  414. }
  415. sq_pushinteger(v, fann_get_train_stop_function(self->ann));
  416. return 1;
  417. }
  418. static SQRESULT sq_fann_activation_steepness(HSQUIRRELVM v)
  419. {
  420. SQ_FUNC_VARS(v);
  421. SQ_GET_FANN_INSTANCE(v, 1);
  422. if(_top_ > 3)
  423. {
  424. SQ_GET_FLOAT(v, 2, value);
  425. SQ_GET_INTEGER(v, 3, layer);
  426. SQ_GET_INTEGER(v, 4, neuron);
  427. fann_set_activation_steepness(self->ann, (fann_type)value, layer, neuron);
  428. return 0;
  429. }
  430. SQ_GET_INTEGER(v, 2, layer);
  431. SQ_GET_INTEGER(v, 3, neuron);
  432. sq_pushfloat(v, fann_get_activation_steepness(self->ann, layer, neuron));
  433. return 1;
  434. }
  435. #define SQFANN_GET_FLOAT_OR_INT(stype, func_name) \
  436. static SQRESULT sq_fann_##func_name(HSQUIRRELVM v) \
  437. { \
  438. SQ_FUNC_VARS_NO_TOP(v); \
  439. SQ_GET_FANN_INSTANCE(v, 1); \
  440. sq_push##stype(v, fann_##func_name(self->ann)); \
  441. return 1; \
  442. }
  443. #define SQFANN_GET_FLOAT(func_name) \
  444. SQFANN_GET_FLOAT_OR_INT(float, func_name)
  445. #define SQFANN_GET_INTEGER(func_name) \
  446. SQFANN_GET_FLOAT_OR_INT(integer, func_name)
  447. #define SQFANN_SET_FLOAT_OR_INT(stype, func_name, cast_type) \
  448. static SQRESULT sq_fann_##func_name(HSQUIRRELVM v) \
  449. { \
  450. SQ_FUNC_VARS_NO_TOP(v); \
  451. SQ_GET_FANN_INSTANCE(v, 1); \
  452. SQ_GET_##stype(v, 2, value); \
  453. fann_##func_name(self->ann, (cast_type)value); \
  454. return 0; \
  455. }
  456. #define SQFANN_SET_FLOAT(func_name, cast_type) \
  457. SQFANN_SET_FLOAT_OR_INT(FLOAT, func_name, cast_type)
  458. #define SQFANN_SET_INTEGER(func_name, cast_type) \
  459. SQFANN_SET_FLOAT_OR_INT(INTEGER, func_name, cast_type)
  460. SQFANN_SET_FLOAT(set_activation_steepness_hidden, fann_type);
  461. SQFANN_SET_FLOAT(set_activation_steepness_output, fann_type);
  462. SQFANN_SET_FLOAT(set_quickprop_decay, fann_type);
  463. SQFANN_SET_FLOAT(set_quickprop_mu, fann_type);
  464. SQFANN_SET_FLOAT(set_rprop_increase_factor, fann_type);
  465. SQFANN_SET_FLOAT(set_rprop_decrease_factor, fann_type);
  466. SQFANN_SET_FLOAT(set_rprop_delta_min, fann_type);
  467. SQFANN_SET_FLOAT(set_rprop_delta_max, fann_type);
  468. SQFANN_SET_FLOAT(set_cascade_output_change_fraction, fann_type);
  469. SQFANN_SET_INTEGER(set_cascade_output_stagnation_epochs, unsigned);
  470. SQFANN_SET_FLOAT(set_cascade_candidate_change_fraction, fann_type);
  471. SQFANN_SET_INTEGER(set_cascade_candidate_stagnation_epochs, unsigned);
  472. SQFANN_SET_FLOAT(set_cascade_weight_multiplier, fann_type);
  473. SQFANN_SET_FLOAT(set_cascade_candidate_limit, fann_type);
  474. SQFANN_SET_INTEGER(set_cascade_max_out_epochs, unsigned);
  475. SQFANN_SET_INTEGER(set_cascade_max_cand_epochs, unsigned);
  476. SQFANN_SET_INTEGER(set_cascade_num_candidate_groups, unsigned);
  477. SQFANN_SET_INTEGER(set_activation_function_hidden, fann_activationfunc_enum);
  478. SQFANN_SET_INTEGER(set_activation_function_output, fann_activationfunc_enum);
  479. static SQRESULT sq_fann_randomize_weights(HSQUIRRELVM v)
  480. {
  481. SQ_FUNC_VARS_NO_TOP(v);
  482. SQ_GET_FANN_INSTANCE(v, 1);
  483. SQ_GET_FLOAT(v, 2, min_weight);
  484. SQ_GET_FLOAT(v, 3, max_weight);
  485. fann_randomize_weights(self->ann, min_weight, max_weight);
  486. return 0;
  487. }
  488. static SQRESULT sq_fann_reset_MSE(HSQUIRRELVM v)
  489. {
  490. SQ_FUNC_VARS_NO_TOP(v);
  491. SQ_GET_FANN_INSTANCE(v, 1);
  492. fann_reset_MSE(self->ann);
  493. return 0;
  494. }
  495. SQFANN_GET_FLOAT(get_MSE);
  496. static SQRESULT sq_fann_get_errstr(HSQUIRRELVM v)
  497. {
  498. SQ_FUNC_VARS_NO_TOP(v);
  499. SQ_GET_FANN_INSTANCE(v, 1);
  500. sq_pushstring(v, fann_get_errstr((struct fann_error *)self->ann), -1);
  501. return 1;
  502. }
  503. static SQRESULT sq_fann_get_errno(HSQUIRRELVM v)
  504. {
  505. SQ_FUNC_VARS_NO_TOP(v);
  506. SQ_GET_FANN_INSTANCE(v, 1);
  507. sq_pushinteger(v, fann_get_errno((struct fann_error *)self->ann));
  508. return 1;
  509. }
  510. static SQRESULT sq_fann_reset_errno(HSQUIRRELVM v)
  511. {
  512. SQ_FUNC_VARS_NO_TOP(v);
  513. SQ_GET_FANN_INSTANCE(v, 1);
  514. fann_reset_errno((struct fann_error *)self->ann);
  515. return 0;
  516. }
  517. SQFANN_GET_INTEGER(get_num_input);
  518. SQFANN_GET_INTEGER(get_num_output);
  519. SQFANN_GET_INTEGER(get_bit_fail);
  520. static SQRESULT sq_fann_train_on_data_type(HSQUIRRELVM v, bool isCascade)
  521. {
  522. SQ_FUNC_VARS_NO_TOP(v);
  523. SQ_GET_FANN_INSTANCE(v, 1);
  524. SQ_GET_FANN_TRAINING_DATA_INSTANCE_NAME_AT(v, 2, data);
  525. SQ_GET_INTEGER(v, 3, max_epochs);
  526. SQ_GET_INTEGER(v, 4, epochs_between_reports);
  527. SQ_GET_FLOAT(v, 5, desired_error);
  528. if(isCascade)
  529. fann_cascadetrain_on_data(self->ann, data->data, max_epochs,
  530. epochs_between_reports, desired_error);
  531. else
  532. fann_train_on_data(self->ann, data->data, max_epochs,
  533. epochs_between_reports, desired_error);
  534. return 0;
  535. }
  536. static SQRESULT sq_fann_train_on_data(HSQUIRRELVM v)
  537. {
  538. return sq_fann_train_on_data_type(v, false);
  539. }
  540. static SQRESULT sq_fann_cascadetrain_on_data(HSQUIRRELVM v)
  541. {
  542. return sq_fann_train_on_data_type(v, true);
  543. }
  544. static SQRESULT sq_fann_train_on_file(HSQUIRRELVM v)
  545. {
  546. SQ_FUNC_VARS_NO_TOP(v);
  547. SQ_GET_FANN_INSTANCE(v, 1);
  548. SQ_GET_STRING(v, 2, data_fn);
  549. SQ_GET_INTEGER(v, 3, max_epochs);
  550. SQ_GET_INTEGER(v, 4, epochs_between_reports);
  551. SQ_GET_FLOAT(v, 5, desired_error);
  552. fann_train_on_file(self->ann, data_fn, max_epochs,
  553. epochs_between_reports, desired_error);
  554. return 0;
  555. }
  556. static SQRESULT sq_fann_test_data(HSQUIRRELVM v)
  557. {
  558. SQ_FUNC_VARS_NO_TOP(v);
  559. SQ_GET_FANN_INSTANCE(v, 1);
  560. SQ_GET_FANN_TRAINING_DATA_INSTANCE_NAME_AT(v, 2, data);
  561. sq_pushfloat(v, fann_test_data(self->ann, data->data));
  562. return 1;
  563. }
  564. static SQRESULT sq_fann_test(HSQUIRRELVM v)
  565. {
  566. SQ_FUNC_VARS_NO_TOP(v);
  567. SQ_GET_FANN_INSTANCE(v, 1);
  568. SQInteger isize = sq_getsize(v, 2);
  569. SQInteger ann_num_input = fann_get_num_input(self->ann);
  570. if(isize != ann_num_input) return sq_throwerror(v, _SC("wrong number of inputs"));
  571. SQInteger osize = sq_getsize(v, 3);
  572. SQInteger ann_num_output = fann_get_num_output(self->ann);
  573. if(osize != ann_num_output) return sq_throwerror(v, _SC("wrong number of outputs"));
  574. fann_type *data = (fann_type*)sq_getscratchpad(v, (osize+isize)*sizeof(fann_type));
  575. fann_type *input = data;
  576. fann_type *output = data+isize;
  577. for(SQInteger i=0; i < isize; ++i)
  578. {
  579. sq_arrayget(v, 2, i);
  580. SQ_GET_FLOAT(v, -1, value);
  581. input[i] = value;
  582. sq_poptop(v);
  583. }
  584. for(SQInteger i=0; i < osize; ++i)
  585. {
  586. sq_arrayget(v, 3, i);
  587. SQ_GET_FLOAT(v, -1, value);
  588. output[i] = value;
  589. sq_poptop(v);
  590. }
  591. fann_type *calc_output = fann_test(self->ann, input, output);
  592. sq_newarray(v, ann_num_output);
  593. for(SQInteger i=0; i < ann_num_output; ++i)
  594. {
  595. sq_pushfloat(v, calc_output[i]);
  596. sq_arrayset(v, -2, i);
  597. }
  598. return 1;
  599. }
  600. static SQRESULT sq_fann_run(HSQUIRRELVM v)
  601. {
  602. SQ_FUNC_VARS_NO_TOP(v);
  603. SQ_GET_FANN_INSTANCE(v, 1);
  604. SQInteger isize = sq_getsize(v, 2);
  605. SQInteger ann_num_input = fann_get_num_input(self->ann);
  606. if(isize != ann_num_input) return sq_throwerror(v, _SC("wrong number of inputs"));
  607. SQInteger ann_num_output = fann_get_num_output(self->ann);
  608. fann_type *input = (fann_type*)sq_getscratchpad(v, isize*sizeof(fann_type));
  609. fann_type *calc_output;
  610. for(SQInteger i=0; i < isize; ++i)
  611. {
  612. sq_arrayget(v, 2, i);
  613. SQ_GET_FLOAT(v, -1, value);
  614. input[i] = value;
  615. sq_poptop(v);
  616. }
  617. calc_output = fann_run(self->ann, input);
  618. if(!calc_output) return sq_throwerror(v, _SC("error running ann"));
  619. sq_newarray(v, ann_num_output);
  620. for(SQInteger i=0; i < ann_num_output; ++i)
  621. {
  622. sq_pushfloat(v, calc_output[i]);
  623. sq_arrayset(v, -2, i);
  624. }
  625. return 1;
  626. }
  627. static SQRESULT sq_fann_set_scaling_params(HSQUIRRELVM v)
  628. {
  629. SQ_FUNC_VARS_NO_TOP(v);
  630. SQ_GET_FANN_INSTANCE(v, 1);
  631. SQ_GET_FANN_TRAINING_DATA_INSTANCE_NAME_AT(v, 2, data);
  632. SQ_GET_FLOAT(v, 3, new_input_min);
  633. SQ_GET_FLOAT(v, 4, new_input_max);
  634. SQ_GET_FLOAT(v, 5, new_output_min);
  635. SQ_GET_FLOAT(v, 6, new_output_max);
  636. fann_set_scaling_params(self->ann, data->data,
  637. new_input_min, new_input_max, new_output_min, new_output_max);
  638. return 0;
  639. }
  640. static SQRESULT sq_fann_set_input_ouput_scaling_params(HSQUIRRELVM v, bool isInput)
  641. {
  642. SQ_FUNC_VARS_NO_TOP(v);
  643. SQ_GET_FANN_INSTANCE(v, 1);
  644. SQ_GET_FANN_TRAINING_DATA_INSTANCE_NAME_AT(v, 2, data);
  645. SQ_GET_FLOAT(v, 3, new_min);
  646. SQ_GET_FLOAT(v, 4, new_max);
  647. if(isInput) fann_set_input_scaling_params(self->ann, data->data, new_min, new_max);
  648. else fann_set_output_scaling_params(self->ann, data->data, new_min, new_max);
  649. return 0;
  650. }
  651. static SQRESULT sq_fann_set_input_scaling_params(HSQUIRRELVM v)
  652. {
  653. return sq_fann_set_input_ouput_scaling_params(v, true);
  654. }
  655. static SQRESULT sq_fann_set_output_scaling_params(HSQUIRRELVM v)
  656. {
  657. return sq_fann_set_input_ouput_scaling_params(v, false);
  658. }
  659. static SQRESULT sq_fann_init_weights(HSQUIRRELVM v)
  660. {
  661. SQ_FUNC_VARS_NO_TOP(v);
  662. SQ_GET_FANN_INSTANCE(v, 1);
  663. SQ_GET_FANN_TRAINING_DATA_INSTANCE_NAME_AT(v, 2, data);
  664. fann_init_weights(self->ann, data->data);
  665. return 0;
  666. }
  667. static SQRESULT sq_fann_scale_train(HSQUIRRELVM v)
  668. {
  669. SQ_FUNC_VARS_NO_TOP(v);
  670. SQ_GET_FANN_INSTANCE(v, 1);
  671. SQ_GET_FANN_TRAINING_DATA_INSTANCE_NAME_AT(v, 2, data);
  672. fann_scale_train(self->ann, data->data);
  673. return 0;
  674. }
  675. static SQRESULT sq_fann_scale_input(HSQUIRRELVM v)
  676. {
  677. SQ_FUNC_VARS_NO_TOP(v);
  678. SQ_GET_FANN_INSTANCE(v, 1);
  679. SQ_GET_FLOAT(v, 2, value);
  680. fann_type fv = value;
  681. fann_scale_input(self->ann, &fv);
  682. sq_pushfloat(v, fv);
  683. return 1;
  684. }
  685. static SQRESULT sq_fann_descale_output(HSQUIRRELVM v)
  686. {
  687. SQ_FUNC_VARS_NO_TOP(v);
  688. SQ_GET_FANN_INSTANCE(v, 1);
  689. SQ_GET_FLOAT(v, 2, value);
  690. fann_type fv = value;
  691. fann_descale_input(self->ann, &fv);
  692. sq_pushfloat(v, fv);
  693. return 1;
  694. }
  695. static SQRESULT sq_fann_save(HSQUIRRELVM v)
  696. {
  697. SQ_FUNC_VARS_NO_TOP(v);
  698. SQ_GET_FANN_INSTANCE(v, 1);
  699. SQ_GET_STRING(v, 2, net_fname);
  700. fann_save(self->ann, net_fname);
  701. return 0;
  702. }
  703. static SQRESULT sq_fann_print_connections(HSQUIRRELVM v)
  704. {
  705. SQ_FUNC_VARS_NO_TOP(v);
  706. SQ_GET_FANN_INSTANCE(v, 1);
  707. fann_print_connections(self->ann);
  708. return 0;
  709. }
  710. static SQRESULT sq_fann_print_parameters(HSQUIRRELVM v)
  711. {
  712. SQ_FUNC_VARS_NO_TOP(v);
  713. SQ_GET_FANN_INSTANCE(v, 1);
  714. fann_print_parameters(self->ann);
  715. return 0;
  716. }
  717. #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_fann_##name,nparams,tycheck}
  718. static SQRegFunction sq_fann_methods[] =
  719. {
  720. _DECL_FUNC(constructor, -2,_SC("x s|f|a i")),
  721. _DECL_FUNC(copy, 1,_SC("x")),
  722. _DECL_FUNC(save, 2,_SC("xs")),
  723. _DECL_FUNC(learning_rate, -1,_SC("xf")),
  724. _DECL_FUNC(learning_momentum, -1,_SC("xf")),
  725. _DECL_FUNC(training_algorithm, -1,_SC("xi")),
  726. _DECL_FUNC(train_error_function, -1,_SC("xi")),
  727. _DECL_FUNC(train_stop_function, -1,_SC("xi")),
  728. _DECL_FUNC(set_activation_function_hidden, 2,_SC("xi")),
  729. _DECL_FUNC(set_activation_function_output, 2,_SC("xi")),
  730. _DECL_FUNC(activation_steepness, -3,_SC("xnnn")),
  731. _DECL_FUNC(set_activation_steepness_hidden, 2,_SC("xn")),
  732. _DECL_FUNC(set_activation_steepness_output, 2,_SC("xn")),
  733. _DECL_FUNC(set_quickprop_decay, 2,_SC("xn")),
  734. _DECL_FUNC(set_quickprop_mu, 2,_SC("xn")),
  735. _DECL_FUNC(set_rprop_increase_factor, 2,_SC("xn")),
  736. _DECL_FUNC(set_rprop_decrease_factor, 2,_SC("xn")),
  737. _DECL_FUNC(set_rprop_delta_min, 2,_SC("xn")),
  738. _DECL_FUNC(set_rprop_delta_max, 2,_SC("xn")),
  739. _DECL_FUNC(set_cascade_output_change_fraction, 2,_SC("xn")),
  740. _DECL_FUNC(set_cascade_output_stagnation_epochs, 2,_SC("xi")),
  741. _DECL_FUNC(set_cascade_candidate_change_fraction, 2,_SC("xn")),
  742. _DECL_FUNC(set_cascade_candidate_stagnation_epochs, 2,_SC("xi")),
  743. _DECL_FUNC(set_cascade_weight_multiplier, 2,_SC("xn")),
  744. _DECL_FUNC(set_cascade_candidate_limit, 2,_SC("xn")),
  745. _DECL_FUNC(set_cascade_max_out_epochs, 2,_SC("xi")),
  746. _DECL_FUNC(set_cascade_max_cand_epochs, 2,_SC("xi")),
  747. _DECL_FUNC(set_cascade_num_candidate_groups, 2,_SC("xi")),
  748. _DECL_FUNC(randomize_weights, 3,_SC("xnn")),
  749. _DECL_FUNC(reset_MSE, 1,_SC("x")),
  750. _DECL_FUNC(get_MSE, 1,_SC("x")),
  751. _DECL_FUNC(get_errstr, 1,_SC("x")),
  752. _DECL_FUNC(get_errno, 1,_SC("x")),
  753. _DECL_FUNC(reset_errno, 1,_SC("x")),
  754. _DECL_FUNC(get_num_input, 1,_SC("x")),
  755. _DECL_FUNC(get_num_output, 1,_SC("x")),
  756. _DECL_FUNC(get_bit_fail, 1,_SC("x")),
  757. _DECL_FUNC(print_connections, 1,_SC("x")),
  758. _DECL_FUNC(print_parameters, 1,_SC("x")),
  759. _DECL_FUNC(train_on_data, 5,_SC("xxiif")),
  760. _DECL_FUNC(cascadetrain_on_data, 5,_SC("xxiif")),
  761. _DECL_FUNC(train_on_file, 5,_SC("xsiif")),
  762. _DECL_FUNC(test, 3,_SC("xaa")),
  763. _DECL_FUNC(test_data, 2,_SC("xx")),
  764. _DECL_FUNC(run, 2,_SC("xa")),
  765. _DECL_FUNC(set_scaling_params, 6,_SC("xxnnnn")),
  766. _DECL_FUNC(set_input_scaling_params, 4,_SC("xxnn")),
  767. _DECL_FUNC(set_output_scaling_params, 4,_SC("xxnn")),
  768. _DECL_FUNC(init_weights, 2,_SC("xx")),
  769. _DECL_FUNC(scale_train, 2,_SC("xx")),
  770. _DECL_FUNC(scale_input, 2,_SC("xn")),
  771. _DECL_FUNC(descale_output, 2,_SC("xn")),
  772. _DECL_FUNC(set_callback, -2,_SC("xc.")),
  773. {0,0}
  774. };
  775. #undef _DECL_FUNC
  776. typedef struct {
  777. const SQChar *Str;
  778. SQInteger Val;
  779. } KeyIntType, * KeyIntPtrType;
  780. static KeyIntType module_constants[] = {
  781. #define MK_CONST(c) {_SC(#c), FANN_##c}
  782. MK_CONST(LINEAR),
  783. MK_CONST(THRESHOLD),
  784. MK_CONST(THRESHOLD_SYMMETRIC),
  785. MK_CONST(SIGMOID),
  786. MK_CONST(SIGMOID_STEPWISE),
  787. MK_CONST(SIGMOID_SYMMETRIC),
  788. MK_CONST(SIGMOID_SYMMETRIC_STEPWISE),
  789. MK_CONST(GAUSSIAN),
  790. MK_CONST(GAUSSIAN_STEPWISE),
  791. MK_CONST(ELLIOT),
  792. MK_CONST(ELLIOT_SYMMETRIC),
  793. MK_CONST(GAUSSIAN_SYMMETRIC),
  794. MK_CONST(LINEAR_PIECE),
  795. MK_CONST(LINEAR_PIECE_SYMMETRIC),
  796. MK_CONST(SIN_SYMMETRIC),
  797. MK_CONST(COS_SYMMETRIC),
  798. MK_CONST(SIN),
  799. MK_CONST(COS),
  800. MK_CONST(TRAIN_INCREMENTAL),
  801. MK_CONST(TRAIN_BATCH),
  802. MK_CONST(TRAIN_RPROP),
  803. MK_CONST(TRAIN_QUICKPROP),
  804. MK_CONST(TRAIN_SARPROP),
  805. MK_CONST(ERRORFUNC_LINEAR),
  806. MK_CONST(ERRORFUNC_TANH),
  807. MK_CONST(STOPFUNC_MSE),
  808. MK_CONST(STOPFUNC_BIT),
  809. MK_CONST(NETTYPE_LAYER),
  810. MK_CONST(NETTYPE_SHORTCUT),
  811. {0,0}
  812. };
  813. #ifdef __cplusplus
  814. extern "C" {
  815. #endif
  816. /* This defines a function that opens up your library. */
  817. SQRESULT sqext_register_fann (HSQUIRRELVM v) {
  818. sq_pushstring(v,sq_fann_training_data_TAG,-1);
  819. sq_newclass(v,SQFalse);
  820. sq_settypetag(v,-1,(void*)sq_fann_training_data_TAG);
  821. sq_insert_reg_funcs(v, sq_fann_training_data_methods);
  822. sq_newslot(v,-3,SQTrue);
  823. sq_pushstring(v,sq_fann_TAG,-1);
  824. sq_newclass(v,SQFalse);
  825. sq_settypetag(v,-1,(void*)sq_fann_TAG);
  826. sq_insert_reg_funcs(v, sq_fann_methods);
  827. //add constants
  828. KeyIntPtrType KeyIntPtr;
  829. for (KeyIntPtr = module_constants; KeyIntPtr->Str; KeyIntPtr++) {
  830. sq_pushstring(v, KeyIntPtr->Str, -1); //first the key
  831. sq_pushinteger(v, KeyIntPtr->Val); //then the value
  832. sq_newslot(v, -3, SQFalse); //store then
  833. }
  834. sq_newslot(v,-3,SQTrue);
  835. return SQ_OK;
  836. }
  837. #ifdef __cplusplus
  838. }
  839. #endif