Tensorflow.js print() and dataSync methods on model.predict not working - tensorflow.js

I've distilled this down to as few lines of code as I could to get to the bottom of this issue.
currently these are the config constants below (I'm using a array of length 1 to represent tokenised words I'm doing semantic analysis on.
export const top_words = 10000;
export const max_review_length = 1
export const embedding_vector_length = 32
Here is the code, I've substituted the tensors with mock tokens or one word length for now. I'm getting typescript linting errors showing that .print() or .dataSync()[0] will fail on the basis that they do not exist. the line of code in question (.predict) is returning a tensor which has no print or datasync method
const x_train = tf.tensor([[80], [86], [10], [1], [2]]);
const y_train = tf.tensor([[1],[1],[1],[0],[0]])
const x_val = tf.tensor([[1], [3], [102], [100], [104]]);
const y_val = tf.tensor([[0],[0],[1],[1],[1]])
const model = tf.sequential();
model.add(tf.layers.embedding({ inputDim: dictionary.size, inputLength: max_review_length, outputDim: 1 }))
model.add(tf.layers.lstm({units: 200, dropout: 0.2, recurrentDropout: 0.2}))
model.add(tf.layers.dense({units: 1, activation:'sigmoid'}))
model.compile({ loss:'binaryCrossentropy', optimizer:'rmsprop', metrics:['accuracy'] })
const history=model.fit(x_train, y_train,{epochs: 12, batchSize: 5})
history.then(hist => console.log(hist.history.loss)) // Show error loss vs epoch
const predictOut = model.predict(tf.tensor2d([10]))
predictOut.print() or predictOut.dataSync()[0]
returns

If you are using TypeScript you need to specify what predict() returns in such way:
(model.predict(...) as tf.Tensor).print()
since predict() can return either a Tensor or Tensor[]

Ok, so one thing thats easy to forget if you're not used to dealing with Python. Python is syncronous!
the model is async so to solve this problem in this code.
history (the result)
history.then(result => {
model.predict(tftensor2d([10)).print()
console.log('loss ', result.history.loss)
}
otherwise the model doesnt yet have a predict method as it is still calculating.
Gotta love async.

Related

insertAt using fp-ts to insert element at specific index

Trying to simply insert some element at specific index using insertAt util function from fp-ts but insertAt returns Option<T[]> | NonEmptyArray which returns object like
const x = insertAt(1, 100)([0, 10]) => { _tag: "someTag", value: [0, 100, 10] }
and I can't just print x.value because Option or NonEmptyArray type have no 'value' key. How can I get access to the whole array to for example render it in a view? How can I iterate through them? fp-ts documentation gives me absolutely 0 knowledge about how it works.
It's not easy to get started with fp-ts and the answer doesn't mean to deeply explain it, but in short: you need a way to get the value from that option, if there's any.
Here's an example with a brief explanation:
import { insertAt } from 'fp-ts/lib/Array';
import { pipe } from 'fp-ts/lib/function';
import { option as O } from 'fp-ts';
const x = pipe( // 1
[0, 10],
insertAt(1, 100),
O.getOrElse(() => []) // 2
);
I used pipe to transform the initial value and apply all the needed functions.
You could also use flow, which returns a function instead and you must pass your array as an argument.
const x = flow(
insertAt(1, 100),
O.getOrElse(() => [])
)([0, 10]);
Here you can see an example on how to retrieve the value. Since the value in option can be "none" or "some", you need a way to get a fallback value.
An example for the "none" case:
const x = pipe(
[0, 10],
insertAt(4, 100), // NOTE: cannot insert at index 4 since the array has 2 items
O.getOrElse(() => [1000])
);
// x === [1000]

Best practice testing return value from a function with Jest + React Testing Library

I have a very simple salary calculator function that receives as parameters input values ​​inside a form and that in the end returns the result with its calculations.
Logic Function
export function calcAnnualSalary(
monthlySalary: string,
healthPlan?: string,
transpostationTicket?: string,
mealTicket?: string,
valueSaturday?: boolean
) {
const annualSalary =
parseFloat(monthlySalary.replace(/\./g, '').replace(',', '.')) * 12
const thirteenth = parseFloat(
monthlySalary.replace(/\./g, '').replace(',', '.')
)
const extraHoliday =
parseFloat(monthlySalary.replace(/\./g, '').replace(',', '.')) / 3
const totalAnnualCrude = annualSalary + thirteenth + extraHoliday
return {
annualSalary,
thirteenth,
extraHoliday,
totalAnnualCrude,
}
}
Testing
With that, I created a very simple test with hardcoded values, I would like to know if this is the best practice to test function calculation logic. To avoid hardcoded for example, I should get the value inside the form, what would it suggest?
import {CalcAnnualSalary} from '~src/components/app/Calculators/CalcAnnualSalary'
import * as Calc from '~src/utils/calculators/'
import * as Lib from '~src/utils/testing-library'
describe('CalculatorAnnualSalary', () => {
it('expect return gross annual salary', () => {
const {annualSalary} = Calc.calcAnnualSalary('1.000,00')
expect(annualSalary).toEqual(12000)
})
})
In the test, you should provide the test double and test data as simply as possible. That reduces the complexity and facilitates testing.
Whether you use static data or dynamically generated test data, keep it simple. With simple test data, you can also more easily predict the desired results.
The test is predictable, when writing test cases, you should provide the desired result before running the test cases, if your input is complicated, the desired result is difficult to calculate, you need to execute the code in your brain with this data.
Use simple test data to test every code branch, the logical fragment of a function.

TestCafe loop over elements and check if class exists within Set

I have a table with a column of icons. Each Icon has a class of "test" and then "test" + [some rating]. The rating could be A, B, C, XX, YY. I'd like to select the group of icons and loop over them, pop off the last class (the one with the rating) and then expect that my Set of classConsts contains the class in question. I've done a bunch of research but can only find examples of interacting with each of the elements, I'm not sure what I'm doing wrong when trying to check the classes on each instead. Any help is appreciated, thanks.
The below code blows up when i call mrArray.nth saying it's not a function (sorry its a bit messy, had to change some variable names around)
test('Sers are verified', async t => {
const IconArr = Selector('#testtable .test');
var count = await IconArr().count;
var myArray = await IconArr();
const classConsts = ["testClassA", "testClassB", "testClassC", "testClassXX", "testClassYY"]
let mySet = new Set(classConsts);
for(let i = 1; i <= count; i++){
console.log(mySet.has(myArray.nth(i).classNames.pop()));
};
});
myArray is no longer a Selector object after you execute it as an asynchronous function. Please refer to the following help article for more information DOMNodeState.
Also, the index starts with 0, not 1. Your code may look as follows:
for(let i = 0; i \< count; i++){
let classes = await IconArr().nth(i).classNames;
console.log(mySet.has(classes.pop()));
};
You can always debug your test cases to see what goes wrong:
https://devexpress.github.io/testcafe/documentation/recipes/debugging/chrome-dev-tools.html

Typescript and fixed array length (array.slice)

I am trying to fix my arguments array to a length of 2 so that it can be spread into a function that requires 2 arguments. However, the array comes from a slice of another array that returns the type number[].
const twoArgs: [number, number] = [2,3,4].slice(0, 2));
//Type 'number[]' is missing the following properties from type '[number, number]': 0, 1
functionThatRequiresTwoArgs(...twoArgs);
//Expected 2 arguments, but got 0 or more.
I have found a solution but I wasn't able to clearly do it in a neat fashion. Perhaps a typescript user can enlighten me with a better way of doing this?
const myWorkaround = (t: number[]) => {
let result: [number, number] = [0, 0];
t.forEach((value, index) => (result[index] = value));
return result;
};
const twoArgs: [number, number] = myWorkaround([2,3,4].slice(0, 2));
functionThatRequiresTwoArgs(...twoArgs);
This should do the trick
const twoArgs = [2,3,4].slice(0, 2) as [number, number];
functionThatRequiresTwoArgs(...twoArgs);
The slice function returns an array of undefined length (event if you know it will become a certain length), so you can't define twoArgs to be of a defined length. However, you can typecast it with the as keyword.

Unable to create array of SKActions

I'm experimenting with SpriteKit in Swift but somehow seem unable to create an array of actions to use in a sequence. I've split it up to try and pin-point the problem, but no luck so far.
func animateBackground(){
let moveLeft = SKAction.moveByX(100, y: 0, duration: 3)
moveLeft.timingMode = SKActionTimingMode.EaseInEaseOut
let moveRight = SKAction.reversedAction(moveLeft)
let actions = [moveLeft, moveRight] // <--- here there be dragons/trouble
let sequence = SKAction.sequence(actions)
let repeat = SKAction.repeatActionForever(sequence)
}
When trying to create the actions-array I get the error "Cannot convert the expression's type 'Array' to type 'ArrayLiteralConvertible' " So, I thought I might need to be more explicit and attempted to change it to
var actions: SKAction[] = [moveLeft, moveRight]
This seemed to bring down the house, and not in a good way, resulting in the SourceKit terminated bug...
You're adding a function to the array for moveRight, not the SKAction itself. Try using this instead:
let moveRight = SKAction.reversedAction(moveLeft)()
When you create moveRight you're actually generating a function. You can call the function with "()" to get the actual SKAction. I added explicit types to the two SKAction's so it's clear that they can be put in an SKAction[]:
let moveLeft:SKAction = SKAction.moveByX(100, y: 0, duration: 3)
moveLeft.timingMode = SKActionTimingMode.EaseInEaseOut
let moveRight:SKAction = moveLeft.reversedAction()
let actions = [moveLeft, moveRight]
let sequence = SKAction.sequence(actions)
let repeat = SKAction.repeatActionForever(sequence)

Resources