From 93d4bd43034b6b51d8641e780f54dad15bdfb6b6 Mon Sep 17 00:00:00 2001 From: sbosse Date: Mon, 21 Jul 2025 23:07:30 +0200 Subject: [PATCH] Mon 21 Jul 22:43:21 CEST 2025 --- js/ml/cnn.js | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 js/ml/cnn.js diff --git a/js/ml/cnn.js b/js/ml/cnn.js new file mode 100644 index 0000000..61baa81 --- /dev/null +++ b/js/ml/cnn.js @@ -0,0 +1,102 @@ +/** + ** ============================== + ** O O O OOOO + ** O O O O O O + ** O O O O O O + ** OOOO OOOO O OOO OOOO + ** O O O O O O O + ** O O O O O O O + ** OOOO OOOO O O OOOO + ** ============================== + ** Dr. Stefan Bosse http://www.bsslab.de + ** + ** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED + ** BY THE AUTHOR(S). + ** THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED, + ** MODIFIED, OR OTHERWISE USED IN A CONTEXT + ** OUTSIDE OF THE SOFTWARE SYSTEM. + ** + ** $AUTHORS: Stefan Bosse + ** $CREATED: (C) 2006-2019 bLAB by sbosse + ** $VERSION: 1.1.1 + ** + ** $INFO: + ** + ** Convolutional neural network ML Algorithm + ** + ** Incremental learner using ml.update! Initial training data via ml.learn (or empty data set) + ** + ** $ENDOFINFO + */ +'use strict'; +var Io = Require('com/io'); +var Comp = Require('com/compat'); +var current=none; +var Aios=none; + +var convnetjs = Require('ml/convnet') +var that; + +that = module.exports = { + // typeof options = {x:[][],y:[],width,height,depth,normalize?:[a,b],layers:{}[]..} + // format x = [ [row1=[col1=[z1,z2,..],col2,..],row2,..] ] + create : function (options) { + var net = new convnetjs.Net(); + if (options.layers) + net.makeLayers(options.layers); + if (!options.iterations) options.iterations=10; + if (!options.depth) options.depth=1; + if (!options.width) options.width=options.x[0].length,options.height=1; + var trainer = new convnetjs.SGDTrainer(net, options.trainer|| + {method: 'adadelta', + l2_decay: 0.001, + batch_size: 10}); + // convert matrix (2dim/3dim) to volume elements + var x = options.x; + if (options.normalize) { + var a,b, + c=options.normalize[0], + d=options.normalize[1]; + x.forEach(function (row) { + var min=Math.min.apply(null,row), + max=Math.max.apply(null,row); + if (a==undefined) a=min; else a=Math.min(a,min); + if (b==undefined) b=max; else b=Math.max(b,max); + }) + x=x.map(function (row) { + return row.map(function (col) { return (((col-a)/(b-a))*(d-c))+c }) // scale [0,1] -> [c,d] + }) + } + x=x.map(function (row) { + var vol = new convnetjs.Vol(options.width, options.height, options.depth, 0.0); //input volume (image) + vol.w = row; + return vol; + }); + x.forEach (function (row) { + //net.forward(row); + }) + var y = options.y; + if (!options.targets) { + options.targets=that.ml.stats.unique(y); + } + for(var iters=0;iters