I'm trying to predict some data using a neural network in javascript. For that I found convnetjs that seems easy to use.
In the example, they use one thing that they call MagicNet, so you don't need to know about NN to work with it. This is the example of use:
// toy data: two data points, one of class 0 and other of class 1
var train_data = [new convnetjs.Vol([1.3, 0.5]), new convnetjs.Vol([0.1, 0.7])];
var train_labels = [0, 1];
// create a magic net
var magicNet = new convnetjs.MagicNet(train_data, train_labels);
magicNet.onFinishBatch(finishedBatch); // set a callback a finished evaluation of a batch of networks
// start training MagicNet. Every call trains all candidates in current batch on one example
setInterval(function(){ magicNet.step() }, 0});
// once at least one batch of candidates is evaluated on all folds we can do prediction!
function finishedBatch() {
// prediction example. xout is Vol of scores
// there is also predict_soft(), which returns the full score volume for all labels
var some_test_vol = new convnetjs.Vol([0.1, 0.2]);
var predicted_label = magicNet.predict(some_test_vol);
}
What I don't understand is this:
They create train data like [new convnetjs.Vol([1.3, 0.5]), new convnetjs.Vol([0.1, 0.7])] and then use 2 labels. Those labels, are one for each position of array or for each element of subarray in those positions??
Here is a visual example:
It's like [new 0, new 1] or like [new convnetjs.Vol([0, 1]), new convnetjs.Vol([0, 1])]?
The sample new convnetjs.Vol([1.3, 0.5]) has label 0.
The sample new convnetjs.Vol([0.1, 0.7]) has label 1.
In general, in machine learning, you'd usually have samples which can be quite high-dimensional (here they are only two-dimensional), but you'd have a single label per sample which tells you which "class" it belongs in. What the classes actually mean depends on the problem you are trying to solve; for instance, they could be the digits that are represented by images of hand-written digits.
Related
I am wondering how should I implement KCL using JavaScript. I have several current meter that to detect the value of current along a line.
I came out with a simple program but was unable to think about how to implement KCL efficiently.
var currentPointsDBA = new Array(); // Data from electricity meter will be captured and store in this array
var totalCurrentMDB = new Array(); // Total current from adding will be stored in array. Each index represents 1 distribution board.
const totalBusBar = 5;
for (z=0; z<currentPointsDBA.length(); z++){
totalCurrent += currentPoints[z];
}
totalCurrentMDB[0] = totalCurrent;
var currentCheck = [
{
name: DBA, number: 0, threshold: 0
}];
for(i=0; i<totalBusBar; i++){
var totalCurrentCheck = currentCheck[i];
if(totalCurrentMDB[totalCurrentCheck.number] != 0){
//DO SOMETHING
}
}
I realized with this, the condition will never be met as I am adding the current without using the concept of current entering the node is equals to current exiting a node.
Another difficulty that I was facing was to have an algorithm that can be used to calculate positively and negatively for KCL.
Inputs would be a power line that will be connected to a transducer(meter to measure current). Output is also current that is connected to a meter.
For the Point 1,2,3,4,5 it will be replaced with the meters. Basically, I would want an algorithm to have Sum of DBA = Point 1+2+3+4+5. However, point 1 is bi-directional. It can act as input or output. The issue will be to figure out how the current direction is and use that to determine as input or output.
I am new to machine and new to tensorflow. As a method of learning, I have been following along with Dan Shiffman of the Coding Train as he shows how to create a color classifier.
I, however, wanted to do something different, so I collected data of hand-drawn shapes. Each shape has a label (square, circle, or triangle) and also has an array of 400 pixels (each picture was draw in a 20x20 grid). The data is stored in an object, which is contained within a JSON file.
Using p5.js's 'loadJSON' function, I can access the JSON file, iterate the entries, and create two arrays: 'shapes,' which is a an array of an array of pixels, and 'labels,' which is an array of the corresponding labels.
Below is the code, which utilizes p5's 'preload' and 'setup' functions.
let data;
let model;
// list of labels from which you can get the oneHot index
let labelList = [
"square",
"circle",
"triangle"
];
// function that is ran before setup
function preload() {
data = loadJSON('shapeData.json'); // loads the json file
}
// called after preload
function setup() {
let shapes = []; // an array of the pixels of hand-drawn shapes
let labels = []; // the corresponding label of each hand-drawn shape
// iterates over all of the entries in data
for (let record of data.entries) {
let pixels = record.pixels;
shapes.push(pixels);
labels.push(labelList.indexOf(record.label));
}
// ---------------- ERROR ------------------------
let xs = tf.tensor2d(shapes);
// these tensors work great
let labelsTensor = tf.tensor1d(labels, 'int32');
let ys = tf.oneHot(labelsTensor, 3);
}
The problem arises when I try to create the 'xs' as a tensor2d.
I get the error:
Error: Constructing tensor of shape (120800) should match the length of values (121881)
at assert (tfjs#0.11.7:2)
at new e (tfjs#0.11.7:2)
at Function.e.make (tfjs#0.11.7:2)
at Function.e.tensor (tfjs#0.11.7:2)
at Object.e.tensor2d (tfjs#0.11.7:2)
at setup (sketch.js:27)
at p5.<anonymous> (p5.js:46551)
at _runIfPreloadsAreDone (p5.js:46499)
at p5._decrementPreload (p5.js:46509)
at p5.js:59586
I have a total of 302 data points, each of which is an array of 400 binary numbers. Therefore the shape of the tensor should be [302, 400], and when I change the shape to something that is wrong (like [303, 401]) it gives an error saying that it should be [302, 400].
I am new to this whole process, so any help will be appreciated.
Thanks
I have found the fix! The separate script which downloads the data had an error. This created data of different lengths...
For instance, one shape had 400 pixels and another had 410 pixels. This difference created a problem within tensorflow. After removing the data points that did not have 400 pixels, the program worked just fine!
I'm creating a gantt-like chart (configuration really) and need to calculate total duration and validate configurable durations. The goal is that users can build the gantt chart without knowing dates, but by knowing tasks and how they (loosely) relate. In a previous step, users add tasks and select start & end steps for those tasks. Steps have a fixed order. Actual dates are not known (or relevant) but will be mapped to steps later.
Most gantt tools I've seen rely on knowing the start/end dates and don't do calculations.
How should I calculate the total duration and also validate when a duration is invalid? Obviously in some cases a total can't be calculated: if there is an unused step between activities. A simple invalid duration would occur when 2 tasks share the same start and end date but have different values. A more complicated one would occur when 2 or more activities have different start/end steps and overlap.
I'm not looking for a complete solution (it would probably be of little use with my current code anyway), but more a general algorithm or approach. I would think a recursive solution would make sense, but because I'm doing this with JS/jQuery/DOM, I'm concerned about performance of a recursive solution that has to repeatedly look up elements. Should I start calculating from the end or the beginning? should I follow each step's start/end until I go no further or re-evaluate which step to add to total duration mid-way through?
Here is a picture of the current markup:
I'll try to explain what I wound up doing.
I think to follow you have to know a bit about the requirements.
This interactive/configurable gantt/schedule is being used as a template to estimate production timelines.
There are 3 pieces:
Steps
Activities
Durations of activities, which are different depending on the type of item the schedule is applied to.
Since this is a template used for estimation, initially there are no dates - just arbitrary durations tied to activities mapped to steps. However eventually steps get mapped to dates from an imported report (or manually entered).
There are 3 pages where the user incrementally builds up the schedule:
Add/Edit Steps: Steps are rows which are created with a sort order value (inferred)
Add/Edit Activities: A matrix with Steps as columns, Activities as rows. Every intersection is a checkbox. A Start and End Step must be selected for each Activity.
Add/Edit Durations: An item type is selected and durations are added for each activity.
Classes
Step [ Name, StepOrder, ..]
Activity [ Name, StartStepID, StartStepOrder, EndStepID, EndStepOrder, ..]
ActivityDuration : Activity [ Duration, ItemType, ..]
In MVC Controller/Repository:
// start by ordering the durations by the order of the steps
var sortedActivities = durations
.OrderBy(x => x.StartStepOrder)
.ThenBy(x => x.EndStepOrder);
// create func to get the path name from the old + new activity
var getActivityPath = new Func<string, string, string>(
(prevPath, activityID) =>
{
return string.IsNullOrEmpty(prevPath)
? string.Format("{0}", activityID)
: string.Format("{0}.{1}", prevPath, activityID);
});
// create the recursive func we'll call to do all the work
Action<List<ActivityDuration>, string, long?, IEnumerable<ActivityDuration>> buildPaths = null;
buildPaths = (activities, path, startStepID, starts) =>
{
// activities will be null until we are joining gapped paths,
// so grab the activities with the provided startStepID
if (starts == null)
starts = activities.Where(x => x.StartStepID == startStepID);
// each activity represents a new branch in the path
foreach (var activity in starts)
{
var newPath = getActivityPath(path, activity.Id.ToString());
// add the new path and it's ordered collection
// of activities to the collection
if (string.IsNullOrEmpty(path))
{
paths.Add(newPath, new ActivityDuration[] { activity });
}
else
{
paths.Add(newPath, paths[path].Concat(new ActivityDuration[] { activity }));
}
// do this recursively providing the EndStepID as the new Start
buildPaths(activities, newPath, activity.EndStepID, null);
}
// if there were any new branches, remove the previous
// path from the collection
if (starts.Any() && !string.IsNullOrEmpty(path))
{
paths.Remove(path);
}
};
// since the activities are in step order, the first activity's
// StartStepID will be where all paths start.
var firstStepID = sortedActivities.FirstOrDefault().StartStepID;
// call the recursive function starting with the first step
buildPaths(sortedActivities.ToList(), null, firstStepID, null);
// handle gaps in the paths after all the first connected ones have been pathed.
// :: ie - step 1,2 & 4,5 are mapped, but not step 3
// these would be appended to the longest path with a step order < start step of the gapped activity's start step (!!!)
// :: ie - the path should be 1-2,2-4,4-5)
// because the list of paths can grow, we need to keep track of the count
// and loop until there are no more paths added
var beforeCount = paths.Count;
var afterCount = beforeCount + 1;
while (beforeCount < afterCount)
{
foreach (var path in paths.ToArray())
{
var lastActivity = path.Value.Last();
// check for activities that start after the last one in each path ..
// .. that don't start on another activity's end step (because that would be a part of a path already)
var gapped = sortedActivities
.Where(x => x.StartStepOrder > lastActivity.EndStepOrder)
.Where(thisAct =>
!sortedActivities
.Select(otherAct => otherAct.EndStepID)
.Contains(thisAct.StartStepID)
);
beforeCount = paths.Count;
// for each new gapped path, build paths as if it was specified by the previous activity
buildPaths(sortedActivities.ToList(), path.Key, null, gapped);
afterCount = paths.Count;
}
}
// build up an object that can be returned to
// JS with summations and ordering already done.
rValue = new ActivityPaths()
{
Paths = paths
.Select(x => new ActivityPath()
{
Path = x.Key,
ActivityDurations = x.Value,
TotalDuration = x.Value.Sum(y => y.Duration)
})
.OrderByDescending(x => x.TotalDuration)
};
There are admittedly some shortcomings of this design, but the use cases allow for it. Specifically:
- An activity can't directly have more than one dependent step - or in other words - 2 steps can't have the same step order.
- If 2 paths have the same total duration, only one will show as the critical path.
Since the dates which are mapped to steps are ultimately used to calculate back/forward to the end of a path from a given point of time, this is OK. Once all dates are provided, a more accurate critical path can be calculated if needed.
The entire set of paths is returned so that some validation can be implemented in the javascript. The first path will be the critical 'one', and this path gets highlighted in the UI, with the total duration of the critical path shown as well:
Picture of problem: http://puu.sh/5spfQ.png
My first question here. I hope I can explain it to a decent extent, to give you an idea of what I'm trying to do.
I am working on a small javascript game, where the only objective is to make money. One of the methods to make money is by hiring workers. However, there's a problem. For instance we have Worker A and Worker B. For some odd reason, whenever Worker B mines something, Worker A also receives the mined ore (so both seem to always have the same amount of ore). I can't seem to figure out why this is; they should not be receiving each others ore.
Note: >hired< workers are stored in the "employed" variable.
The fun part, the code:
*This function fills in placeholders to the employed variable for each possible worker for hire. *
//add "placeholder data" to prevent future undefined/errors
//and makes future modification easier, specially in workerMain()
var o = [];
for(ore in ores){o[ore] = 0;}
for(w in workers){
employed[w] = [0, o];
}
So our employed variable may look something along the lines of:
('miner a' => [0, ['coal_ore' => 0,'diamond_ore' => 0]], 'miner b' => [0, ['coal_ore' => 0, 'diamond_ore' => 0]])
Now once they are hired, a loop that is ran every second will determine how much ore they have mined, and it should put any worker's mined ore in their respective spot.
function workerMain(){
setTimeout(function(){
for(e in employed){
var wObj = workers[e];
var orePerSecond = Math.ceil(wObj.opm/60)*employed[e][0];
var oresMined = generateOres(orePerSecond, wObj.pickaxe);
//add newly mined ore count to worker's ore
for(ore in oresMined){
employed[e][1][ore] += oresMined[ore];
//we aren't storing the ore, so let's go ahead and sell it
money += ores[ore].worth*oresMined[ore];
}
}
updateValues();
workerMain();
}, 1000);
}
But again, somehow if Miner A mines a coal ore, somehow Miner B will also get that coal ore.
Hope I've explained my problem thoroughly. If you can't seem to find the problem within this code, it may lie within these sibling functions:
http://pastebin.com/2WgT8Acg
Arrays and objects in Javascript are passed by reference so in this code:
var o = [];
for(ore in ores){o[ore] = 0;}
for(w in workers){
employed[w] = [0, o];
}
You're creating one variable o and assigning references to it to every miner. Ergo, every miner is updating the same set of ores.
You need to create a new array for each miner:
var o;
for(w in workers){
o = [];
for(ore in ores){o[ore] = 0;}
employed[w] = [0, o];
}
I dare say some Javascript guru could make a more efficient version!
I am trying to insert a Float32Array in the middle of anther Float32Array. I am currently creating a new Float32Array and using 3 for loops to insert elements into this new Float32Array (1 for before the insertion, 1 for inserting the new Float32Array, and 1 for after the insertion).
This is taking a long time. Is there a faster way to insert a Float32Array into another? For instance, is there functionality akin to
// Suppose originalArray and insertedArray are 2 Float32Arrays of
// lengths 100000 and 5000 respectively, and I want to insert
// insertedArray into originalArray at element 50000.
var combinedArray = new Float32Array(105000);
combinedArray.set(originalArray.subarray(0, 50000));
combinedArray.subarray(50000, 55000).set(insertedArray);
combinedArray.subarray(55000, 105000).set(originalArray.subarray(50000, 100000));
Currently, the above code does not work because the subarray method does not return a value with a set method pertinent to the entire Float32Array.
There's something you can do in just a bunch of instructions:
var combinedArray = new Float32Array(105000);
combinedArray.set(originalArray);
[].splice.apply(combinedArray, [50000, 0].concat([].slice.call(insertedArray, 0)));
I don't really know about its performances, though. I fear that combinedArray is somehow converted into an Array, thus taking a lot of memory and maybe CPU occupation. It shouldn't, but I'm not sure.
Anyway, the set method has a second optional argument, i.e. is the offset of the array from where the new elements must be set. So, your last two lines would become:
combinedArray.set(insertedArray, 50000);
combinedArray.set(originalArray.subarray(50000, 100000), 55000);
Maybe this is more efficient.
Edit: it is, according to this test. So, you have your way.