import { default as M, Cloud } from "./m.ts"; export type N = Array>> const Forward = (inData:Cloud.M, inLayers:N):N => { let i:number; let stages:N = [inData]; let nonLinear = (inIndex:number):any=> inIndex >= inLayers.length-1 ? M.Batch.Sig : M.Batch.Rec; let process = (index:number):Cloud.M => nonLinear(index)(M.Batch.Affine(stages[index], inLayers[index])); for(i=0; i { let i:number; let errorBack:Cloud.M = M.Batch.Subtract(inStages[inStages.length-1], inGoals); let nonLinear = (inIndex:number):any=> inIndex >= inLayers.length-1 ? M.Batch.SigDeriv : M.Batch.RecDeriv; for(i=inLayers.length-1; i>=0; i--) { let errorScaled:Cloud.M = M.Batch.Multiply(errorBack, nonLinear(i)(inStages[i+1])); errorBack = M.Batch.Affine(errorScaled, M.Create.Transpose(inLayers[i])); errorScaled.forEach((inScaledError:Cloud.V, inIndex:number)=> { inLayers[i] = M.Batch.Subtract( inLayers[i], M.Batch.Scale(M.Create.Outer(inStages[i][inIndex], inScaledError), inRate) ); }); } return inLayers; }; const Split = (inTrainingSet:Cloud.M, inHeaderLabel:Cloud.V, inHeaderKeep:Cloud.V = []):N => { let data:Cloud.M = []; let label:Cloud.M = []; if(!inHeaderKeep.length) { inTrainingSet[0].forEach( (item:number, index:number)=> inHeaderLabel.includes(index) ? false : inHeaderKeep.push(index) ); } inTrainingSet.forEach((row:Cloud.V):void => { data.push( inHeaderKeep.map((i:number)=>row[i]) ); label.push( inHeaderLabel.map((i:number)=>row[i]) ); }); return [ data, label ]; }; const Build = (...inLayers:Array):N => { let i:number; let output:N = []; let rand = (inDimensions:number, inCount:number):Cloud.M => M.Create.Box( new Array(inDimensions).fill(-1), new Array(inDimensions).fill(1), inCount); for(i=0; i { let stages:N = Forward(M.Create.Padded(inData), inLayers); return stages[stages.length-1]; }; const Learn = (inData:Cloud.M, inLayers:N, inLabels:Cloud.M, inIterations:number, inRate:number):Cloud.M => { let stages:N = []; for(let i=0; i Learn(inData, inLayers, inLabels, 1, 0); export { Split, Build, Label, Learn, Check, Forward, Backward };