No connection between any variable and the result of the loss function - tensorflow.js

The optimizer I'm using isn't finding a connection between my variables and the loss function.
I'm new to machine learning in general and I'm trying to build a curve fitting application for the equation y = a * 2^(t/b). The trainable variables being "a" and "b". Right now I'm testing it with some synthetic data.
// Declare variables
const a = tf.variable(tf.scalar(Math.random()));
const b = tf.variable(tf.scalar(Math.random()));
const year = tf.tensor1d([1,2,3,4]);
//Declare optimizer
var optimizer = tf.train.sgd(learningRate);
// y = a * 2^(t/b)
function Moore(t){
var Moore_results = [];
aPrime = a.dataSync();
bPrime = b.dataSync();
tPrime = t.dataSync();
for(i = 0; i < tPrime.length; i++){
Moore_results.push(aPrime * Math.pow(2,(tPrime[i]/bPrime)) );}
const tensorMoore = tf.variable(tf.tensor1d(Moore_results));
return tensorMoore;}
// Define loss function
function loss(predictions, labels) {
const meanSquareError = predictions.sub(labels).square().mean();
return meanSquareError;}
//Optimize loss function
optimizer.minimize(() => loss(Moore(year),year));
When I run the optimizer I get the error.
Cannot find a connection between any variable and the result of the loss >function y=f(x). Please make sure the operations that use variables are inside >the function f passed to minimize().
Any help is greatly appreciated.

The optimizer tries to optimize a variable tensor created with tf.variable given the loss between the prediction and the expected value. You have to pass a prediction value as the following :
function predict(t) {
// y = a * 2 ^ (t / b)
return tf.tidy(() => {
return a.mul(tf.scalar(2)) // a * 2
.pow(t.div(b)) // ^ (t / b)
});
}
for (let iter = 0; iter < numIterations; iter++) {
optimizer.minimize(() => {
const predsYs = predict(xs);
return loss(predsYs, ys);
});
}
The optimizer will then compute the value of a and b that best predict your model

Related

Make multiple assignments more optimal

I have one simple function that memorize a couple of previous values. Can someone help me to make this function more compact. More exactly I want to do all the assignments in a more optimal way. If it is someone to help me I will be very thankfully.
xy snake_body(int x,int y)
{
xy body;
body.x = x_loop_16;
body.y = y_loop_16;
x_loop_16 = x_loop_15;
y_loop_16 = y_loop_15;
x_loop_15 = x_loop_14;
y_loop_15 = y_loop_14;
x_loop_14 = x_loop_13;
y_loop_14 = y_loop_13;
x_loop_13 = x_loop_12;
y_loop_13 = y_loop_12;
x_loop_12 = x_loop_11;
y_loop_12 = y_loop_11;
x_loop_11 = x_loop_10;
y_loop_11 = y_loop_10;
x_loop_10 = x_loop_9;
y_loop_10 = y_loop_9;
x_loop_9 = x_loop_8;
y_loop_9 = y_loop_8;
x_loop_8 = x_loop_7;
y_loop_8 = y_loop_7;
x_loop_7 = x_loop_6;
y_loop_7 = y_loop_6;
x_loop_6 = x_loop_5;
y_loop_6 = y_loop_5;
x_loop_5 = x_loop_4;
y_loop_5 = y_loop_4;
x_loop_4 = x_loop_3;
y_loop_4 = y_loop_3;
x_loop_3 = x_loop_2;
y_loop_3 = y_loop_2;
x_loop_2 = x_loop_1;
y_loop_2 = y_loop_1;
x_loop_1 = x;
y_loop_1 = y;
return body;
}
"xy" is a structure variable. I use it to store the data that comes from "x" and "y", and also to have multiple returns from "snake_body" function. I hope I was enough specific and if there are any questions, I will respond them as quick as I can. Thank you.
Instead of using 2x16 variables just use two arrays and loop over it.
You roughly want this:
int x_loop[16];
int y_loop[16];
xy snake_body(int x, int y)
{
xy body;
body.x = x_loop]15];
body.y = y_loop[15];
for (int i = 15; i > 0; i--)
{
x_loop[i] = x_loop[i - 1];
y_loop[i] = y_loop[i - 1];
}
x_loop[0] = x;
y_loop[0] = y;
return body;
}
But there are more elegant ways to solve this problem, especially using a circular buffer.

cocos2dx : Change Array to Vector

I need to change Array to Vector as it is being depracted in cocos2dx.
Earlier it was running but after deprecation its giving error.
As I am quite new to cocos2dx I am not able to resolve this issue.
Here is my code:
int BaseScene::generateRandom()
{
//int rn = arc4random()%6+1;
int rn = rand() % 6 + 1;
Array * balls = (Array*)this->getChildren();
Array * ballsTypeLeft = Array::create();
// if(balls->count() <= 7)
{
for (int j=0; j<balls->count(); j++)
{
Node * a = (Node*)balls->objectAtIndex(j);
if(a->getTag() >= Tag_Ball_Start)
{
Ball * currentBall = (Ball*)balls->objectAtIndex(j);
bool alreadyHas = false;
for(int k=0;k<ballsTypeLeft->count();k++)
{
if(strcmp(((String*)ballsTypeLeft->objectAtIndex(k))->getCString(), (String::createWithFormat("%d",currentBall->type))->getCString()) == 0)
{
alreadyHas = true;
}
}
if(alreadyHas)
{
}
else
{
ballsTypeLeft->addObject(String::createWithFormat("%d",currentBall->type));
}
}
}
}
// CCLog("%d",ballsTypeLeft->count());
if(ballsTypeLeft->count() <=2)
{
// int tmp = arc4random()%ballsTypeLeft->count();
int tmp = rand() % ballsTypeLeft->count();
return ((String*)ballsTypeLeft->objectAtIndex(tmp))->intValue();
}
return rn;
}
How can I make this method working?
Please convert this method using Vector.
Thanks
To change cocos2d::Array to cocos2d::Vector, you must first understand it. cocos2d::Vector is implemented to mimick std::vector. std::vector is part of the STL in c++. cocos2d::Vector is built specifically to handle cocos2d::Ref. Whenever you add a Ref type to Vector it automatically retained and then released on cleanup.
Now to change Array to Vector in your code:
Store children this way:
Vector <Node*> balls = this->getChildren();
Access ball at index i this way:
Ball* ball = (Ball*)balls.at (i);
Add elements to vector this way:
balls.pushBack (myNewBall);
EDIT -
From what I understand, you want to get a random ball from the scene/layer. You can perform this by simply returning the Ball object:
Ball* BaseScene::generateRandom()
{
Vector <Node*> nodeList = this->getChildren();
Vector <Ball*> ballList;
for (int i = 0; i<nodeList.size(); i++)
{
if (ball->getTag() >= Tag_Ball_Start)
{
Ball * ball = (Ball*)nodeList.at(i);
ballList.pushBack(ball);
}
}
if (ballList.size() > 0)
{
return ballList[rand() % ballList.size()];
}
return nullptr;
}
If there is no ball it will return NULL which you can check when you call the function. The code you have linked below seems to make use of Arrays outside the function. You need to make the changes to accommodate that. I suggest studying the documentation for Vector.

MATLAB Coder dynamically sized array of structs

I'm trying to use a dynamically growing array of structs in a piece of code that is supposed to be converted to C with Coder:
I initialize the struct and then declare its fields variable size for coder, then i proceed to grow the struct. Note that i have simplified this example to aid in readability of the generated code, so the reason for me using an array of structs is not obvious from this example.
MATLAB:
function [ events ] = testArraysOfStructs( data)
//%#codegen
ii=1;
events = struct('typ' ,int32(0),...
'title' ,int32(1),...
'value' ,double(0),...
'sta' ,int32(2),...
'end' ,int32(3));
coder.varsize('events','events.typ','events.title','events.value','events.sta','events.end','events.title')
for n=1:length(data.temperatur_spikes_daily)
events(ii).typ = int32(101);
events(ii).title = int32(1234);
events(ii).value = double(1234);
events(ii).sta = int32(4321);
events(ii).end = int32(3412);
ii = length(events)+1;
end
end
The problem is, in the generated code, the variable ii disappears and the data is continuously written onto the same array elements of the struct without any regard for the number of iterations of the loop that is supposed to grow it.
C:
void testArraysOfStructs(const struct0_T *data, struct1_T events_data[], int
events_size[2])
{
struct1_T r0;
int n;
r0.typ.size[0] = 1;
r0.typ.size[1] = 1;
r0.typ.data[0] = 0;
r0.title.size[0] = 1;
r0.title.size[1] = 1;
r0.title.data[0] = 1;
r0.value.size[0] = 1;
r0.value.size[1] = 1;
r0.value.data[0] = 0.0;
r0.sta.size[0] = 1;
r0.sta.size[1] = 1;
r0.sta.data[0] = 2;
r0.end.size[0] = 1;
r0.end.size[1] = 1;
r0.end.data[0] = 3;
events_size[0] = 1;
events_size[1] = 1;
events_data[0] = r0;
for (n = 0; n < data->temperatur_spikes_daily->size[0]; n++) {
events_data[0].typ.size[0] = 1;
events_data[0].typ.size[1] = 1;
events_data[0].typ.data[0] = 101;
events_data[0].title.size[0] = 1;
events_data[0].title.size[1] = 1;
events_data[0].title.data[0] = 1234;
events_data[0].value.size[0] = 1;
events_data[0].value.size[1] = 1;
events_data[0].value.data[0] = 1234.0;
events_data[0].sta.size[0] = 1;
events_data[0].sta.size[1] = 1;
events_data[0].sta.data[0] = 4321;
events_data[0].end.size[0] = 1;
events_data[0].end.size[1] = 1;
events_data[0].end.data[0] = 3412;
}
}
I suppose i have an error in declaring the struct dynamic, but unfortunately the documentation only contains examples for declaring either standard arrays dynamic or preallocating the size of the array of structs, even though dynamic sizing is mentioned as being supported. Any help in getting this to work would be appreciated.
Short answer: growing an array by indexing one beyond the end is not supported using Coder.
So your loop that increases the size of events on every iteration is not supported for Coder. You could use:
function [ events ] = foo(data)
%#codegen
events = struct('typ' ,int32(0),...
'title' ,int32(1),...
'value' ,double(0),...
'sta' ,int32(2),...
'end' ,int32(3));
for n = 1:length(data.temperatur_spikes_daily)
events = [events, struct('typ' ,int32(101),...
'title' ,int32(1234),...
'value' ,double(1234),...
'sta' ,int32(4321),...
'end' ,int32(3412))];
end
or:
function [ events ] = foo(data)
%#codegen
% Allocate events
s = struct('typ' ,int32(0),...
'title' ,int32(1),...
'value' ,double(0),...
'sta' ,int32(2),...
'end' ,int32(3));
events = coder.nullcopy(repmat(s, 1, length(data.temperatur_spikes_daily)));
% Populate values of events
for n = 1:numel(events)
events(n).typ = int32(101);
events(n).title = int32(1234);
events(n).value = double(1234);
events(n).sta = int32(4321);
events(n).end = int32(3412);
end
instead.
If you generate a MEX function from your original code rather than standalone code and run this MEX function in MATLAB you'll get an error:
Index exceeds matrix dimensions. Index value 2 exceeds valid range [1-1] of array events.
Error in foo (line 15)
events(ii).typ = int32(101);
Generating and running a MEX function is the best way to verify that your MATLAB code is using constructs which are supported for Coder.

as3 random array - randomize array - actionscript 3

How do you randomize an array using actionscript 3?
There is a short version using Array.sort() function:
var arr : Array = [0,1,2,3,4,5,6,7,8,9];
function randomize ( a : *, b : * ) : int {
return ( Math.random() > .5 ) ? 1 : -1;
}
trace( arr.sort( randomize ) );
If you don't get "enough" randomness you can sort twice :)
EDIT - explanation line by line:
For Array class method sort() you can pass not only sort options like Array.CASEINSENSITIVE, Array.DESCENDING and so on but also your own custom compare function reference (a callback) that accepts two parameters (two elements from array to compare). From AS3 documentation:
A comparison function should take two arguments to compare. Given the elements A and B, the result of compareFunction can have a negative, 0, or positive value:
A negative return value specifies that A appears before B in the sorted sequence.
A return value of 0 specifies that A and B have the same sort order.
A positive return value specifies that A appears after B in the sorted sequence.
Note: compare function parameters might be typed (if your array is typed) and have any name you want eg.:
function compareElements ( elementA : SomeClass, elementB : SomeClass ) : int;
This method is very useful when you need to sort array elements by their special properties. In randomization case compareFunction randomly returns -1, 0 or 1 and makes array elements to switch their places (indices). I have found that better randomization (in my subjective and mathematically untested opinion) is when method returns only -1 and 1. Also have in mind that sorting function with custom compare function doesn't compare elements sequentially so in some special cases randomization results may differ from what you might expect.
There's a better way that will also allow you to randomize the array in place, if you need that, and it will not make you create more then a single copy of your original array.
package
{
import flash.display.Sprite;
public class RandomizeArrayExample extends Sprite
{
public function RandomizeArrayExample()
{
super();
testDistribution();
}
private function testDistribution():void
{
var hash:Object = { };
var tester:Array = [1, 2, 3, 4];
var key:String;
for (var i:int; i < 1e5; i++)
{
randomize(tester);
key = tester.join("");
if (key in hash) hash[key]++;
else hash[key] = 1;
}
for (var p:String in hash) trace(p, "=>", hash[p]);
}
private function randomize(array:Array):Array
{
var temp:Object;
var tempOffset:int;
for (var i:int = array.length - 1; i >= 0; i--)
{
tempOffset = Math.random() * i;
temp = array[i];
array[i] = array[tempOffset];
array[tempOffset] = temp;
}
return array;
}
}
}
I had an alternative requirement where i wanted to randomly insert lots of source arrays into a target array randomly. Like Rytis i'm a big fan of the forEach, map and sort functions on Arrays.
var randomInsert:Function = function callback(item:*, index:int, array:Vector.<MyItem>):void
{
var j:Number = Math.floor(Math.random() * targetArray.length);
targetArray.splice(j,0,item);
}
targetArray = new Vector.<MyItem>();
sourceArray1.forEach(randomInsert, this);
sourceArray2.forEach(randomInsert, this);
here's an easier function. Works also on multidimensional arrays
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
var mn=Math.floor(Math.random()*array.length)
newArray[newArray.length]=array[mn]
array.splice(mn,1)
}
return newArray;
}
I found this very helpful. I hope it can help you too.
// Array to Randomize
var firstArray:Array = ["One","Two","Three","Four","Five","six","seven","eight","nine","ten"];
trace(firstArray); // Prints in order
var newArray:Array = new Array();
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
newArray.push(array.splice(Math.floor(Math.random()*array.length), 1));
}
return newArray;
}
var randomArray:Array = randomizeArray(firstArray);
trace(randomArray); // Prints out randomized :)
If you need your array to be shuffled (your elements can not repeat). You could use this function:
/**
* Shuffles array into new array with no repeating elements. Simple swap algorithm is used.
*/
public function shuffleArray(original:Array):Array
{
// How many swaps we will do
// Increase this number for better results (more shuffled array, but slower performance)
const runs:int = original.length * 3;
var shuffled:Array = new Array(original.length);
var i:int;
var a:int;
var b:int;
var temp:Object;
// Copy original array to shuffled
for(i=0; i<shuffled.length; i++){
shuffled[i] = original[i];
}
// Run random swap cycle 'runs' times
for(i=0; i<runs; i++){
// There is a chance that array element will swap with itself,
// and there is always small probability it will make your shuffle
// results not that good, hence try to experiment with
// different runs count as stated above
a = Math.floor(Math.random() * original.length);
b = Math.floor(Math.random() * original.length);
// Swap messages
temp = shuffled[a];
shuffled[a] = shuffled[b];
shuffled[b] = temp;
}
return shuffled;
}
Usage:
var testArray:Array = ["Water", "Fire", "Air", "Earth"];
trace(shuffleArray(testArray).concat());
this is how I randomize my array of 36 cards for a memory game
const QUANT_CARTAS: int = 36;
//get the 36 numbers into the array
for (var i: int = 0; i < QUANT_CARTAS; i++)
{
cartas.push(i);
}
//shuffles them =)
for (var moeda: int = QUANT_CARTAS - 1; moeda > 0; moeda--)
{
var pos: int = Math.floor(Math.random() * moeda);
var carta: int = cartas[moeda];
cartas[moeda] = cartas[pos];
cartas[pos] = carta;
}
// and add them using the random order...
for (i = 0; i < QUANT_CARTAS; i++)
{
var novaCarta: Carta = new Carta();
novaCarta.tipoCarta = cartas[i];
etcetcetc.............
}
choose random string from array
function keyGenerator(len:Number):String
{
function randomRange(minNum:Number, maxNum:Number):Number
{
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
}
var hexArray = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
var key = "";
for (var i=0; i<len; i++)
{
key += hexArray[randomRange(0,hexArray.length-1)];
}
return key;
}
usage:
trace(keyGenerator(16));

ActionScript - Array.sortOn() For Non-English Data?

this is an array of objects that i want to alphabetize:
var streets:Array = new Array();
streets.push({name:"Édouard-Montpetit"});
streets.push({name:"Alexandre de Sève"});
streets.push({name:"Van Horne"});
streets.push({name:"Atwater"});
now i'll sort my array:
streets.sortOn("name", Array.CASEINSENSITIVE);
//Sorted
Alexandre de Sève
Atwater
Van Horne
Édouard-Montpetit
the accent above the E in Édouard-Montpetit, and any other first letter with a non-english accent is sorted after Z.
any ideas how i can sort this correctly? i do not have access to the named data.
I know this is late, but for anyone going through this answer, you could pass a Collator
object to the Array.sort() method. A simple example from the documentation:
var words:Array = new Array("coté", "côte");
var sorter:Collator = new Collator("fr-FR", CollatorMode.SORTING);
words.sort(sorter.compare);
trace(words);// côte,coté
Hope this helps
I don't think you can do it with sortOn, as there's no way to tell flash to use a particular collaction for sorting text (at least, not that I'm aware of).
However, you could use sort and a custom sort function.
In this sort function, basically you want to strip all accents and do a case insensitive comparation. Replacing diacritics is easy and after that, you can safely use < and > for comparing the strings. A sort function is called by sort with two of the items to be sorted at a time. It should return a negative number if the first passed items sorts first , a possitive number if the second comes first and 0 if they sort equal.
function sortText(obj1:Object,obj2:Object):int {
var a:String = replaceDiacritics(obj1.name);
var b:String = replaceDiacritics(obj2.name);
if(a < b) {
return -1;
} else if(b < a) {
return 1;
} else {
return 0;
}
}
function replaceDiacritics(str:String):String {
str = str.toLowerCase();
str = str.replace(/á/g,"a");
str = str.replace(/é/g,"e");
str = str.replace(/í/g,"i");
str = str.replace(/ó/g,"o");
str = str.replace(/ú/g,"u");
str = str.replace(/à/g,"a");
str = str.replace(/è/g,"e");
str = str.replace(/ì/g,"i");
str = str.replace(/ò/g,"o");
str = str.replace(/ù/g,"u");
return str;
}
streets.sort(sortText);
A couple of notes about this. I know this method won't work for Spanish, as you have ñ, which is considered a letter on its own (not a regular n with a funny mark) and comes after n and before o. So, it's not possible to just replace accents and do a < / > compare. I think this is not a problem in French, but I could be wrong (not sure how Ç / ç is considered for sort purposes, for instance). Also, note that I haven't replaced all possible diacritics, so you'd want to add circumflexes (^) and umlauts (¨) to replaceDiacritics as necessary.
Edit
For a table based approach you could try something like the following. Each letter is assigned a number that reflects the sort order. As long as you can assume that any letter will have an absolute sort order (that is, context won't change how this works, which is not the case on some languages), it should give you good results.
Out of laziness, I built the table with a loop and just did what was neccesary to put "Ñ" between "n" and "o". I'm not considering any diacritics for sorting purposes, so they have the same value than their unaccented counterpart. But you could change this table as neccesary. Also, this table probably should be hardcoded for the required locale, but this code is just to give you an idea of how you could do this, not a full implementation (and it's probably not entirely correct from a purist perspective, but I think it could do the job). Also, in case we find a character that is not mapped, I'm falling back to its code point to determine how it sorts.
var sortTable:Object = buildSortTable();
function buildSortTable():Object {
var sortTable:Object = {};
var char:String;
var offset:int = 0;
for(var i:int = 1; i < 256; i++) {
char = String.fromCharCode(i);
if(char == "Ñ" || char == "ñ") {
offset--;
continue;
}
sortTable[char] = i + offset;
if(char == "N") {
sortTable["Ñ"] = sortTable["N"] + 1;
offset++;
}
if(char == "n") {
sortTable["ñ"] = sortTable["n"] + 1;
offset++;
}
}
sortTable["Á"] = sortTable["À"] = sortTable["Ä"] = sortTable["Â"] = sortTable["A"];
sortTable["É"] = sortTable["È"] = sortTable["Ë"] = sortTable["Ê"] = sortTable["E"];
sortTable["Í"] = sortTable["Ì"] = sortTable["Ï"] = sortTable["Î"] = sortTable["I"];
sortTable["Ó"] = sortTable["Ò"] = sortTable["Ö"] = sortTable["Ô"] = sortTable["O"];
sortTable["Ú"] = sortTable["Ì"] = sortTable["Ü"] = sortTable["Û"] = sortTable["U"];
sortTable["á"] = sortTable["à"] = sortTable["ä"] = sortTable["â"] = sortTable["a"];
sortTable["é"] = sortTable["è"] = sortTable["ë"] = sortTable["ê"] = sortTable["e"];
sortTable["í"] = sortTable["ì"] = sortTable["ï"] = sortTable["î"] = sortTable["i"];
sortTable["ó"] = sortTable["ò"] = sortTable["ö"] = sortTable["ô"] = sortTable["o"];
sortTable["ú"] = sortTable["ù"] = sortTable["ü"] = sortTable["û"] = sortTable["u"];
return sortTable;
}
function sortText(obj1:Object,obj2:Object):int {
var a:String = obj1.name.toLowerCase();
var b:String = obj2.name.toLowerCase();
var len_a:int = a.length;
var len_b:int = b.length;
var char_a:String;
var char_b:String;
var val_a:Number;
var val_b:Number;
for(var i = 0; i < len_a && i < len_b; i++) {
char_a = a.charAt(i);
char_b = b.charAt(i);
val_a = sortTable[char_a];
val_b = sortTable[char_b];
// this is just in case we have a letter that we haven't mapped...
// let's fall back to using its code point
if(isNaN(val_a)) {
val_a = char_a.charCodeAt(0);
}
if(isNaN(val_b)) {
val_b = char_b.charCodeAt(0);
}
if(val_a < val_b) {
return -1;
} else if(val_a > val_b) {
return 1;
}
}
// both strings are equal so far; so the sorter one (if any) must sort first
if(len_a < len_b) {
return -1;
} else if(len_a > len_b) {
return 1;
} else {
return 0;
}
}

Resources