<html>
<body id='body'>
<button onclick="StartData(event)"> Start</button>
<button onclick="getStopCordinates(event)">Stop</button>
<script>
let inputs = [];
let labels = [];
function Mouse(event) {
inputs.push({ x: event.clientX, y: event.clientY })
}
function StartData() {
document.getElementById('body').addEventListener("mouseover", Mouse())
}
function getStopCordinates(event) {
labels.push({ x: event.clientX, y: event.clientY })
document.getElementById('body').removeEventListener("mouseover", Mouse())
}
</script>
</body>
</html>
I am using above code to capture all the x y coordinates of the mouse in the body . When the user moves the pointer towards the stop button i am capturing all the x,y coordinates for this . and when user clicks stop i am capturing stop coordinates also . now i want to train the tensorflow js model from the captured points so that when user moves the mouse with same trajectory i can predict that he will click the stop button .
tensorflow code :
const model = tf.sequential();
// Add a single hidden layer
model.add(tf.layers.dense({inputShape: [2], units: 1, useBias: true}));
// Add an output layer
model.add(tf.layers.dense({units: 1, useBias: true}));
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
trainModel(model,inputs,labels)
async function trainModel(model, inputs, labels) {
// Prepare the model for training.
model.compile({
optimizer: tf.train.adam(),
loss: tf.losses.meanSquaredError,
metrics: ['mse'],
});
const batchSize = 32;
const epochs = 50;
return await model.fit(inputs, labels, {
batchSize,
epochs,
shuffle: true,
callbacks: tfvis.show.fitCallbacks(
{ name: 'Training Performance' },
['loss', 'mse'],
{ height: 200, callbacks: ['onEpochEnd'] }
)
});
}
but this code gives error as the inputs and labels are not the same so how to correct this code for the above result ?
The inputs and labels should be an array of array and not an array of object. The inputs should rather be
[[1, 2], [4, 6], ...]
The same thing holds for the labels.
Since your are predicting 2 values, the last layer should have as number of units 2
const model = tf.sequential();
// Add a single hidden layer
model.add(tf.layers.dense({inputShape: [2], units: 1, useBias: true}));
// Add an output layer
model.add(tf.layers.dense({units: 1, useBias: true}));
The last thing - surely not the least - is to add activation in order to add non linearity to the model
Related
In my scenario, i create a ship according to player's preferences. The ship consists of the flag and the hull.
An example view
PROBLEM-1
Ship is an Arcade.Group and i want to prevent this group from going outside the borders of the world.
create(){
// Create a group for ship
this.shipGroup = this.physics.add.group()
// Add hull to shipGroup
this.shipGroup.create(400, 500, "1021")
// Add flag to shipGroup
const mainFlag = this.shipGroup.create(400, 500, "FA1")
mainFlag.setOrigin(0.5, 0.8)
// Set collision property to true of every object in shipGroup
this.shipGroup.children.each((item: any) =>
item.setCollideWorldBounds(true)
)
}
update(t: number, dt: number){
if (this.cursor.up.isDown) {
this.shipGroup.setVelocity(...)
}
else {
this.shipGroup.setVelocity(0, 0)
}
}
With this approach every object in group calculated seperately. After hitting the world boundary, the position of the objects is distorted.
PROBLEM-2
To avoid this i tried another approach. I add bounding box to group. Instead of check collision for every object, i will only check collision for bounding box.
create(){
// Create a group for ship
this.shipGroup = this.physics.add.group()
// Add bounding box for shipGroup
this.shipBox = this.shipGroup.create(400, 500, "bbox")
this.shipBox.setCollideWorldBounds(true)
this.shipBox.body.onWorldBounds = true
// Add hull to shipGroup
this.shipGroup.create(400, 500, "1021")
// Add flag to shipGroup
const mainFlag = this.shipGroup.create(400, 500, "FA1")
mainFlag.setOrigin(0.5, 0.8)
/*this.shipGroup.children.each((item: any) =>
item.setCollideWorldBounds(true)
)*/
}
update(t: number, dt: number){
if (this.cursor.up.isDown && !this.shipBox.body.checkWorldBounds()) {
this.shipGroup.setVelocity(...)
}
else {
this.shipGroup.setVelocity(0, 0)
}
}
The problem is checkWorldBounds() returns false even if shipBox hits world boundaries. But collision for shipBox is work.
checkWorldBounds()
Description: Checks for collisions between this Body and the world
boundary and separates them.
Returns: True if this Body is colliding with the world boundary.
How can i implement collision for group and world boundary?
P.S. : phaser version is 3.55.2
There are a few ways to solve/work around this issue, I personally would just use only one image why one physics-body (hull and flag combined) and just move that single image/texture, and switch the image, when needed.
That said, if you need to use the separate images, the easy way is to use a phaser container. (link to the documentation)
create a container
add the images to the container
set the size for the container (default size is width=0 height=0)
create a physics body for the container
done
A short demo:
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
gravity:{ y: 0 },
debug: true
}
},
scene: {
create
},
banner: false
};
function create () {
this.add.text(10,10, 'Ship with physics')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let graphics = this.make.graphics();
graphics.fillStyle(0xffffff);
graphics.fillRect(0, 0, 10, 40);
graphics.generateTexture('ship', 10, 40);
graphics.fillStyle(0xff0000);
graphics.fillRect(0, 0, 30, 10);
graphics.generateTexture('flag', 30, 10);
graphics.generateTexture('flag2', 20, 6);
let hull = this.add.image(0, 0, 'ship')
let flag = this.add.image(0, -5, 'flag')
let flag2 = this.add.image(0, 10, 'flag2')
this.ship = this.add.container(100, 80, [ hull, flag, flag2]);
this.ship.setAngle(-90)
this.ship.setSize(40, 30)
this.physics.world.enable(this.ship);
this.ship.body.setVelocity(100, 0).setBounce(1, 1).setCollideWorldBounds(true);
}
new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
Info: this demo is based partly from this official example
If my server tells the clients when and what tile to reload/update, how can reload/update the tile sent from the server? I'm using the L.CRS.Simple CRS. And I have no zoom levels on a custom game map.
Here is my code:
var map = L.map('map', {
crs: L.CRS.Simple,
attributionControl: false
}).setView([0, 0], 2)
L.tileLayer('/chunks/{x}.{y}.png', {
maxNativeZoom: 1,
minNativeZoom: 1,
}).addTo(map)
function ReloadTile(x,y){
// UPDATE TILE HERE Request for example /chunks/{1}.{1}.png depending on input
}
First, listen to the tileload and tileunload events of the L.TileLayer to grab references to tiles as they load (and free those references as they unload), e.g.
let myTileLayer = L.tileLayer(...);
let tileRefs = {};
myTileLayer.on('tileload', function(ev) {
tileRefs[ ev.coords.x + ',' + ev.coords.y ] = ev.tile;
});
myTileLayer.on('tileunload', function(ev) {
delete tileRefs[ ev.coords.x + ',' + ev.coords.y ];
});
...so whenever you want to update a tile, you just have to search for it in the data structure.
Remember that in order to reload a HTMLImageElement, you've got to change its src property, e.g.:
function ReloadTile(x,y){
const tile = tileRefs[x + ',' + y];
if (!tile) {
// Tile is not currently loaded on the screen
return;
}
tile.src = "/chunks/{1}.{1}.png";
}
Beware of requesting a URL that your browser has cached. Do your homework regarding cache busting and relevant HTTP headers.
Note that I'm using a javascript Object as key-value data structure, and string concatenation to build up a unique key per tile. You're free to use other data structures (such a Map) and any other method to index the tiles (such as a double-depth data structure for x-y, or triple-depth for x-y-z, or indexing by tile URL). Also note that the sample code is usign only the X and Y coordinates of the tile since your TileLayer seems to have only one zoom level.
lThanks for the help!
My final code:
var map = L.map('map', {
crs: L.CRS.Simple,
attributionControl: false
}).setView([0, 0], 2)
const path = '/chunks/{x}.{y}.png?cash={time}'
const layer = L.tileLayer(path, {
maxNativeZoom: 1,
minNativeZoom: 1,
time: 0
}).addTo(map)
function VectorToString(vector) {
return vector.x + "." + vector.y
}
class TileHandler {
constructor(layer){
this.layer = layer
this.layers = {}
this.layer.on('tileload', (tile) => {
this.layers[VectorToString(tile.coords)] = tile
})
this.layer.on('tileunload', (tile) => {
delete this.layers[VectorToString(tile.coords)]
})
}
update(position){
const tile = this.layers[VectorToString(position)]
const url = L.Util.template(tile.target._url, {
...position,
time: new Date().getTime()
})
if (!tile) return
tile.tile.src = url
}
}
I was playing around with some tensorflow code I got from a youtube tutorial that predicts data of flowers. Here is the script (the training data is assigned to variable "iris" and the testing data is assigned to variable "irisTesting":
const trainingData = tf.tensor2d(iris.map(item => [
item.sepal_length, item.petal_length, item.petal_width,
]));
const outputData = tf.tensor2d(iris.map(item => [
item.species === "setosa" ? 1 : 0,
item.species === "virginica" ? 1 : 0,
item.species === "versicolor" ? 1 : 0,
item.sepal_width
]));
const testingData = tf.tensor2d(irisTesting.map(item => [
item.sepal_length, item.petal_length, item.petal_width
]));
const model = tf.sequential();
model.add(tf.layers.dense({
inputShape: [3],
activation: "sigmoid",
units: 5,
}));
model.add(tf.layers.dense({
inputShape: [5],
activation: "sigmoid",
units: 4,
}));
model.add(tf.layers.dense({
activation: "sigmoid",
units: 4,
}));
model.compile({
loss: "meanSquaredError",
optimizer: tf.train.adam(.06),
});
const startTime = Date.now();
model.fit(trainingData, outputData, {epochs: 100})
.then((history) => {
//console.log(history);
console.log("Done training in " + (Date.now()-startTime) / 1000 + " seconds.");
model.predict(testingData).print();
});
When the console prints the predicted sepal_width, it seems to have an upper limit of 1. The training data has sepal_width values of well over 1, but here is the data that is logged:
Tensor
[[0.9561102, 0.0028415, 0.0708825, 0.9997129],
[0.0081552, 0.9410981, 0.0867947, 0.999761 ],
[0.0346453, 0.1170913, 0.8383155, 0.9999373]]
The last (fourth) column would be the predicted sepal_width value. The predicted values should be larger than 1 however it seems that something is preventing it from being larger than 1.
This is the original code:
https://gist.github.com/learncodeacademy/a96d80a29538c7625652493c2407b6be
You're using a sigmoid activation function in the final layer to predict the sepal_width. Sigmoid is continuous function bounded between 0 and 1. See Wikipedia for a more thorough explanation.
You should try to use a different activation function if you want to predict the sepal_width. For a list of available activation functions you can check Tensorflow's API page (this is for the Python version, but the it should be similar for the JavaScript version). You can try 'softplus', 'relu' or even 'linear', but I cannot say if any of these are suitable for your application. Try and experiment to see which is best.
The original code from here addresses a classification problem. It is not meaningful to add item.sepal_width in your outputData because it is not another class.
The activation function of your last layer is sigmoid.
The Sigmoid function looks like this:
source
And as you can see it is restricted in the range of 0 to 1. So if you want other output values you need to adjust your last activation function accordingly.
I'm trying to get some linear regression for a project.
As I'm used to Javascript, I decided to try and use TensorFlowJS.
I'm following the tutorial from their website and have watched some videos explaining how it works, but I still can't understand why my algorithm doesn't return the result I expect.
Here is what I'm doing:
// Define a model for linear regression.
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
// Prepare the model for training: Specify the loss and the optimizer.
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
// Generate some synthetic data for training.
const xs = tf.tensor1d([1, 2, 3, 4]);
const ys = tf.tensor1d([1, 2, 3, 4]);
// Train the model using the data.
model.fit(xs, ys).then(() => {
// Use the model to do inference on a data point the model hasn't seen before:
// Open the browser devtools to see the output
const output = model.predict(tf.tensor2d([5], [1,1]));
console.log(Array.from(output.dataSync())[0]);
});
I'm trying here to have a linear graph, where the input should always be equal to the output.
I'm trying to predict what I would get with an input of 5, however it seems that the output is random.
Here it is on codepen so you can try: https://codepen.io/anon/pen/RJJNeO?editors=0011
Your model is making prediction after only one epoch (one cyle of training). As a result the loss is still big which leads to unaccurate prediction.
The weights of the model are initialized randomly. So with only one epoch, the prediction is very random. That's why, one needs to train for more than one epoch, or update weights after each batch (here you have only one batch also).
To have a look at the loss during training, you can change your fit method that way:
model.fit(xs, ys, {
callbacks: {
onEpochEnd: (epoch, log) => {
// display loss
console.log(epoch, log.loss);
}
}}).then(() => {
// make the prediction after one epoch
})
To get accurate prediction, you can increase the number of epochs
model.fit(xs, ys, {
epochs: 50,
callbacks: {
onEpochEnd: (epoch, log) => {
// display loss
console.log(epoch, log.loss);
}
}}).then(() => {
// make the prediction after one epoch
})
Here is a snippet which shows how increasing the number of epochs will help the model to perform well
// Define a model for linear regression.
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
// Prepare the model for training: Specify the loss and the optimizer.
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
// Generate some synthetic data for training.
const xs = tf.tensor1d([1, 2, 3, 4]);
const ys = tf.tensor1d([1, 2, 3, 4]);
// Train the model using the data.
model.fit(xs, ys, {
epochs: 50,
callbacks: {
onEpochEnd: (epoch, log) => {
console.log(epoch, log.loss);
}
}}).then(() => {
// Use the model to do inference on a data point the model hasn't seen before:
// Open the browser devtools to see the output
const output = model.predict(tf.tensor2d([6], [1,1]));
output.print();
});
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/0.12.4/tf.js"> </script>
</head>
<body>
</body>
</html>
Your training data needs to be one more dimension, than your model shape to reflect training batches. So x and y need to be at least 2D.
Okay this is going to be hard to explain. So bear with me.
Im having less of a problem with the programming, and more a problem with the idea behind what Im trying to do.
I have a grid of triangles. Ref: http://i.imgur.com/08BPHiD.png [1]
Each triangle is it's own polygon on a canvas element that I have set as an object within the code. The only difference between the objects is the coordinates that I pass through as parameters of a function like so:
var triCoordX = [1, 2, 3, ...];
var triCoordY = [1, 2, 3, ...];
var triCoordFlipX = [1, 2, 3, ...];
var triCoordFlipY = [1, 2, 3, ...];
var createTri = function(x, y, z) {
return {
x: x,
y: y,
sides: 3,
radius: 15,
rotation: z,
fillRed: 17,
fillGreen: 17,
fillBlue: 17,
closed: true,
shadowColor: '#5febff',
shadowBlur: 5,
shadowOpacity: 0.18
}
};
for (i = 0; i < triCoordX.length; i++){
var tri = new Kinetic.RegularPolygon(createTri(triCoordX[i], triCoordY[i], 0));
}
for (i = 0; i < triCoordFlipX.length; i++){
var triFlip = new Kinetic.RegularPolygon(createTri(triCoordFlipX[i], triCoordFlipY[i], 180));
}
Now what Im trying to do exactly is have each object polygon be able to 'recognise' its neighbors for various graphical effects.
How I propose to do this is pass a 4th parameter into the function that I push from another array using the for loop that sets a kind of "index" for each polygon. Also in the for loop I will define a function that points to the index 'neighbors' of the object polygon.
So for instance, if I want to select a random triangle from the grid and make it glow, and on completion of a tween want to make one of it's neighbors glow I will have the original triangle use it's object function to identify a 'neighbor' index and pick at random one of its 3 'neighbors'.
The problem is with this model, Im not entirely sure how to do it without large amounts of bloat in my programming, or when I set the function for the loop, to set a way for the loop to intuitively pick the correct index numbers for what are actually the triangle's neighbors.
If all of that made sense, Im looking for any and all suggestions.
Think of your triangles as being laid out in a grid with the triangle in the top left corner being col==0, row==0.
Then you can find the row/col coordinates of the 3 neighbors of any triangle with the following function.
Ignore any neighbors with the following coordinates because the neighbors would be off the grid.
col<0
row<0
col>ColumnCount-1
row>RowCount-1
Example code (warning...untested code--you may have to tweak it):
function findNeighbors(t){
// determine if this triangle's row/col are even or odd
var evenRow=(t.col%2==0);
var evenCol=(t.row%2==0;
// left neighbor is always the same
n1={ col:t.col-1, row:t.row };
// right neighbor is always the same
n2={ col:t.col+1, row:t.row };
// third neighbor depends on row/col being even or odd
if(evenRow && evenCol){
n3={ col:t.col, row:t.row+1 };
}
if(evenRow && !evenCol){
n3={ col:t.col, row:t.row-1 };
}
if(!evenRow && evenCol){
n3={ col:t.col, row:t.row-1 };
}
if(!evenRow && !evenCol){
n3={ col:t.col, row:t.row+1 };
}
// return an array with the 3 neighbors
return([n1,n2,n3]);
}