how to label a three dimensional data in tensorflow.js - tensorflow.js

I have a three dimensional data to fit a tensorflow.js model on it. But the code I have tried is not showing any value nor any error. I don't know how to exactly assign a label to a feature. How I am supposed to do this with three dimensional data ? The complete code with model is attached below
Update
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
import * as tf from '#tensorflow/tfjs';
import '#tensorflow/tfjs-react-native';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isTfReady: false,
};
}
init() {
const model = tf.sequential({
layers: [
tf.layers.dense({
inputShape: [784],
units: 32,
activation: "relu"
}),
tf.layers.dense({
units: 10,
activation: "softmax"
})
]
});
model.compile({
optimizer: "sgd",
loss: "categoricalCrossentropy",
metrics: ["accuracy"]
});
featureTensor = tf.tensor2d([[1],[2],[4]])
featureTensor1 = tf.tensor2d([[2],[1],[3]])
featureTensor2 = tf.tensor2d([[3],[2],[1]])
featuresTensor = tf.stack([featureTensor, featureTensor1, featureTensor2])
const labelArray = ["standing", "sitting"]
// {standing: 0, sitting: 1}
const mapIndexLabel = Object.fromEntries(Object.entries({...labelArray}).map(([a, b]) => [b, +a]))
labelsTensor = tf.onehot([0, 1, 1], numberOfUniqueLabels) // numberOfUniqueLabels = 2 in this case
function onBatchEnd(batch, logs) {
logs.acc = parseFloat((logs.acc * 100).toFixed(2));
logs.loss = parseFloat((logs.loss * 100).toFixed(3));
console.log("Accuracy", logs.acc);
}
// Train for 5 epochs with batch size of 32.
model
.fit(featuresTensor, labelsTensor, {
epochs: 10,
batchSize: 32,
callbacks: {
onBatchEnd
}
})
.then(info => {
this.setState({info: info })
history = model.fit(featuresTensor, labelsTensor, {
});
console.log("Final accuracy", info.history.acc);
});
}
async componentDidMount() {
await tf.ready();
this.init()
// Signal to the app that tensorflow.js can now be used.
this.setState({
isTfReady: true,
});
}
render() {
const {info} = this.state;
return (
<View style={styles.output}>
{info && info.history.acc.map(i=>(<Text>{i}</Text>))}
</View>
)
}
}
const styles = StyleSheet.create({
output: {
flexDirection: 'column',
// alignItems: 'center',
marginTop: 50,
},
})

I have a three dimensional data to fit a tensorflow.js
It is not a three dimensional data, it is a two dimensional data. tf.tensor3d([[1],[2],[4]]) will fail in constructing a 3d tensor, thus throwing an error. To constructor the feature tensors, tf.tensor can be used - it will infer the shape from the data itself; alternatively you can use tf.tensor2d for easy readability.
featureTensor = tf.tensor2d([[1],[2],[4]])
The second thing to mention is that there needs to be a flatten layer before the last layer to allow the model output to be of one dimension.
As for the callBack, it needs to be called given a certain event.
const model = tf.sequential({
layers: [
tf.layers.dense({
inputShape: [3, 1],
units: 32,
activation: "relu"
}),
tf.layers.flatten(),
tf.layers.dense({
units: 2,
activation: "softmax"
})
]
});
model.compile({
optimizer: "sgd",
loss: "categoricalCrossentropy",
metrics: ["accuracy"]
});
featureTensor = tf.tensor2d([[1],[2],[4]])
featureTensor1 = tf.tensor2d([[2],[1],[3]])
featureTensor2 = tf.tensor2d([[3],[2],[1]])
featuresTensor = tf.stack([featureTensor, featureTensor1, featureTensor2])
const labelArray = ["standing", "sitting"]
// {standing: 0, sitting: 1}
const mapIndexLabel = {standing: 0, sitting: 1}
labelsTensor = tf.oneHot([0, 1, 1], 2) // numberOfUniqueLabels = 2 in this case
function onBatchEnd(batch, logs) {
logs.acc = parseFloat((logs.acc * 100).toFixed(2));
logs.loss = parseFloat((logs.loss * 100).toFixed(3));
console.log("Accuracy", logs.acc);
}
model.summary()
// Train for 5 epochs with batch size of 32.
featuresTensor.print()
labelsTensor.print()
hist = await model
.fit(featuresTensor, labelsTensor, {
callbacks: {onEpochEnd: onBatchEnd }
})
console.log(hist)

Related

React - Map single field from array to array issue

I found this nice implementation for a basic card game
It is based on this (however slightly different):
https://react-spring.io/hooks/use-springs#usesprings < doc
https://codesandbox.io/s/github/pmndrs/react-spring/tree/master/demo/src/sandboxes/cards-stack < doc example code
So here's the issue:
It has two arrays
cards which stores the index of cards (hardcoded)
cardData which stores the contents of cards (hardcoded)
What I'm trying to do is bind array 1 dynamically based on cardData.id
This does semi-works, it compiles and you can swipe the cards. However when all cards have cleared the board it wont reset as it would with the card-coded cards.
import React, { useState, useEffect } from "react";
import { useSprings } from "react-spring";
import { useGesture } from "react-with-gesture";
import Card from "./Card";
const cardData = [
{
id: 1,
question: "Islamic finance doesnt have different requirements",
pic:"https://images.unsplash.com/photo-1519817650390-64a93db51149?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=627&q=80",
text:
"Check out week 5 documents",
correct: false,
value: 15
},
{
id: 2,
question: "CEO requirements",
pic:
"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fdoerlife.com%2Fwp-content%2Fuploads%2F2020%2F03%2FSP.png&f=1&nofb=1",
text: "They must decide high-level policy and strategy",
correct: true,
value: 6
},
{
id: 3,
question: "The sky is green",
text: "Make sure to look outside!",
correct: false,
value: 2
}
,
{
id: 4,
question: "This signifies British currency",
pic: "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.kindpng.com%2Fpicc%2Fm%2F112-1123896_black-pound-sterling-symbol-clipart-pound-sign-hd.png&f=1&nofb=1",
text:
"Maybe check in your wallet",
correct: true,
value: 17
}
];
const cards = [1, 2, 3, 4];
const to = i => ({
x: 0,
y: i * -12,
scale: 1,
rot: -10 + Math.random() * 20,
delay: i * 150
});
const from = i => ({ rot: 0, scale: 1.5, y: -1000 });
const trans = (r, s) =>
`perspective(1500px) rotateX(15deg) rotateY(${r /
10}deg) rotateZ(${r}deg) scale(${s})`;
function Swipe() {
console.log(cardData)
// const [cards, setCards] = useState([]);
// useEffect( () => {
// cardData.map(({id}) => {
// setCards(prev => [...prev, id]) // this doesnt reset cards after sorting all
// })
// },[])
const [gone] = useState(() => new Set());
const [props, set] = useSprings(cards.length, i => ({
...to(i),
from: from(i)
}));
const bind = useGesture(
(
{
args: [index],
down,
delta: [xDelta],
distance,
direction: [xDir],
velocity
}) => {
const trigger = velocity > 0.2;
const dir = xDir < 0 ? -1 : 1;
if (!down && trigger) gone.add(index);
set(i => {
if (index !== i) return;
const isGone = gone.has(index);
if (isGone){
console.log("index",i)
console.log("isgone",isGone) // grab by is gone
console.log("cards",cards)
// set()
}
const x = isGone ? (200 + window.innerWidth) * dir : down ? xDelta : 0;
const rot = xDelta / 100 + (isGone ? dir * 10 * velocity : 0);
const scale = down ? 1.1 : 1;
return {
x,
rot,
scale,
delay: undefined,
config: { friction: 50, tension: down ? 800 : isGone ? 200 : 500 }
};
});
if (!down && gone.size === cards.length)
setTimeout(() => gone.clear() || set(i => to(i)), 600);
// insert game end here
}
);
return (
<div className="swipe">
{props.map(({ x, y, rot, scale }, i) => (
<Card i={i} x={x} y={y} rot={rot} scale={scale} trans={trans} cardData={cardData} bind={bind} key={i}/>
))};
</div>);
}
export default Swipe;
Here is a live example to make it more legible: https://codesandbox.io/s/wandering-lake-iwzns5?file=/src/App.js
Any suggestions are welcome!
Turns out the impl I found which was a little different from the docs, for some reason had two separate arrays when it was unneeded. Changing instances ofcards into cardData seems to work fine.

Issue rendering react charts

I am dynamically changing the values that are displayed on the areachart. But for some reason the chart is only displayed if I change one of the dynamic variable with a hard coded number in the array. For example
const data = [
["Year", "Free Cash Flow", "Revenue"],
[this.props.date1, this.props.cashFlow1, this.props.revenue1],
[this.props.date2, this.props.cashFlow2, this.props.revenue2],
[this.props.date3, this.props.cashFlow3, this.props.revenue3],
[this.props.date4, this.props.cashFlow4, this.props.revenue4],
[this.props.date5, this.props.cashFlow5, this.props.revenue5],
];
that is how I structured my data array, but it doesn't renders and give the following error All series on a given axis must be of the same data type. However, if I replace this.props.revenue1 with let say 100 the area chart renders
const data = [
["Year", "Free Cash Flow", "Revenue"],
[this.props.date1, this.props.cashFlow1, 100],
[this.props.date2, this.props.cashFlow2, this.props.revenue2],
[this.props.date3, this.props.cashFlow3, this.props.revenue3],
[this.props.date4, this.props.cashFlow4, this.props.revenue4],
[this.props.date5, this.props.cashFlow5, this.props.revenue5],
];
I have looked at other examples and I can't seem to find a mistake I could've made.
import React, {Component} from "react";
import { Chart } from "react-google-charts";
class AreaChart extends Component {
render () {
const chartEvents = [
{
callback: ({ chartWrapper, google }) => {
const chart = chartWrapper.getChart();
chart.container.addEventListener("click", (ev) => console.log(ev))
},
eventName: "ready"
}
];
const rev1 = this.props.revenue1;
const FCF1 = this.props.cashFlow1;
const data = [
["Year", "Free Cash Flow", "Revenue"],
[this.props.date1, this.props.cashFlow1, this.props.revenue1],
[this.props.date2, this.props.cashFlow2, this.props.revenue2],
[this.props.date3, this.props.cashFlow3, this.props.revenue3],
[this.props.date4, this.props.cashFlow4, this.props.revenue4],
[this.props.date5, this.props.cashFlow5, this.props.revenue5],
];
const options = {
isStacked: true,
height: 300,
legend: { position: "top", maxLines: 3 },
vAxis: { minValue: 0 },
};
return (
<Chart
chartType="AreaChart"
width="75%"
height="400px"
data={data}
options={options}
chartEvents={chartEvents}
/>
);
}
}
export default AreaChart;

How to fix map is not function even there is already set data in the useState using React Hook

Right now I am creating a chart and the chart data is based on the backend api created. Now I have problem where I need to push all the amounts in the array. So by doing this I need of course map the state and push it on the array however there is error happen it says that
TypeError: receiveGroupCount.map is not a function. I don't know why this happen.
Error:
Response:
State:
const [receiveCheckCount, setReceiveCheckCount] = useState();
const [receiveGroupCount, setReceiveGroupCount] = useState({
});
API:
let list_filter_countings_url = process.env.BASEURL+"chart_filter_range/"+moment(selectionRange.startDate).format("YYYY-MM-DD")+"/"+moment(selectionRange.endDate).format("YYYY-MM-DD");
axios.get(list_filter_countings_url, { headers: { 'Authorization': AuthToken, 'Accept': 'application/json', 'Content-Type': 'application/json' } })
.then(res => {
console.log(res);
if(res) {
const count_receive_check = res.data.data.receive;
const count_receive_grouped = res.data.data.data_receive_grouped;
setReceiveCheckCount(count_receive_check);
setReceiveGroupCount(count_receive_grouped);
}
})
.catch((error) => {
});
Chart Parameters:
useEffect(() => {
setChartData({
labels: dataDate(selectionRange),
datasets: [
{
label: 'Receive Check',
backgroundColor: 'rgb(195 218 251 / 35%)',
borderColor: '#70a8f3',
pointBackgroundColor: "#fff",
pointBorderWidth: '2',
fill: true,
lineTension: 0.0,
pointRadius: 7,
borderWidth: 1,
data: randomVal(),
//data:[12, 19, 3, 5, 2, 3]
}
]
})
},[selectionRange,receiveGroupCount,receiveCheckCount])
const randomVal = () => {
var randomArr = []
var from = new Date(selectionRange.startDate);
var to = new Date(selectionRange.endDate);
console.log(receiveGroupCount)
if(receiveGroupCount != null) {
for (var day = from; day <= to; day.setDate(day.getDate() + 1)) {
receiveGroupCount.map((rows) => {
randomArr.push(rows.amount)
})
}
return randomArr
}
}
It looks like you're initializing that state to an empty object:
const [receiveGroupCount, setReceiveGroupCount] = useState({});
Objects don't have a .map property. Try initializing to an empty array instead.
receiveGroupCount is not null initially, it is {}(an empty object) because of this statement:
const [receiveGroupCount, setReceiveGroupCount] = useState({ });
.map() is a method for arrays, and although you might have an array like data later in receiveGroupCount, the first time your randomVal() is run, it will fail.
You are already trying to mitigate the issue by checking for null but if you do not want to change your initial state you can change your if check like this:
if(receiveGroupCount != {}) {
for (var day = from; day <= to; day.setDate(day.getDate() + 1)) {
receiveGroupCount.map((rows) => {
randomArr.push(rows.amount)
})
}
return randomArr
}
Note: Your useEffect will run the first time and after every render where any of the selectionRange,receiveGroupCount,receiveCheckCount changes.
You just simply have to create a state with the default variable
try:
const [receiveGroupCount, setReceiveGroupCount] = useState({
labels: // your code here,
datasets: []
});

Wav sound is not playing in react

I'm getting the error "Uncaught (in promise) DOMException: The media resource indicated by the src attribute or assigned media provider object was not suitable.", while trying to play a wav sound file using react-sound and "Uncaught (in promise) DOMException: The buffer passed to decodeAudioData contains an unknown content type." in a three.js scene using a positionalAudio. It works when I use mp3 files. I already tried to fix it by importing the wav file through file-loader and a webpack config. On the dev and build server everything works also using wav files but after deplyoing to a cloudflare server I'm getting this error when I try to use wav.
Now my second guess is, that I somehow have to set to code up using a promise but I am struggling as how to do it.
Code for react-sound
import Sound from 'react-sound'
import wavURL from '../../../public/sounds/ambientStereoSound.wav'
export default function AmbientSound(props) {
let state = ''
if(props.state){
state = Sound.status.PLAYING
}else{
state = Sound.status.PAUSED
}
return (
<Sound
url={wavURL}
autoLoad={true}
playStatus={state}
loop={true}
volume={100}
/>
)
}
Code for three.js (react-three-fiber)
import * as THREE from 'three'
import React, { Suspense, useMemo, useEffect, useState } from 'react'
import { useThree, useLoader } from '#react-three/fiber'
import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper.js'
import { useControls } from 'leva'
function PositionalAudio({ refs, url, volume, rolloffFactor, coneOuterGain, state }) {
const sound = refs
const { camera } = useThree()
const [listener] = useState(() => new THREE.AudioListener())
const buffer = useLoader(THREE.AudioLoader, url)
useEffect(() => {
sound.current.setBuffer(buffer)
sound.current.setRefDistance(1)
sound.current.setRolloffFactor(1)
sound.current.setDirectionalCone(180, 260, 0)
sound.current.setLoop(true)
sound.current.setVolume(volume)
sound.current.play()
const helper = new PositionalAudioHelper(sound.current)
sound.current.add(helper)
camera.add(listener)
return () => camera.remove(listener)
}, [])
useEffect(() => {
sound.current.setDirectionalCone(180, 260, coneOuterGain)
sound.current.setRolloffFactor(rolloffFactor)
sound.current.setVolume(volume)
}, [rolloffFactor, volume, coneOuterGain])
if(state) {
useEffect(() => {
sound.current.play()
}, [state])
}else{
useEffect(() => {
sound.current.pause()
}, [state])
}
return <positionalAudio ref={sound} args={[listener]} />
}
type SoundObject = {
id: number
x: number
y: number
z: number
position: number[]
filePath: string
name: string
rotation: number
}
type SoundObjectProps = {
soundObjects: SoundObject[]
}
export default function SoundObject(props: SoundObjectProps) {
const audioRefs = useMemo(
() =>
Array(props.soundObjects.length)
.fill(0)
.map(() => React.createRef()),
[]
)
const PositionalSoundObject = props.soundObjects.map((soundObject, index) => {
const name = soundObject.name
const { Rotation, Volume, Rolloff, X, Y, Z, ConeOuterGain } = useControls( name, {
Rotation: {
value: soundObject.rotation,
min: 0,
max: Math.PI * 2,
step: Math.PI * 0.25
},
Volume: {
value: 1,
min: 0,
max: 1,
step: 0.05
},
Rolloff: {
value: 1,
min: 0,
max: 1,
step: 0.05
},
ConeOuterGain: {
value: 0,
min: 0,
max: 1
},
X: {
value: soundObject.x,
},
Y: {
value: soundObject.y,
},
Z: {
value: soundObject.z,
}
})
return (
<mesh position={[X, Y, Z]} rotation={[0, Rotation, 0]}>
<sphereGeometry args={[0.1, 8, 8]} />
<meshStandardMaterial color='hotpink' wireframe />
<PositionalAudio
refs={audioRefs[index]}
volume={Volume}
rolloffFactor={Rolloff}
url={soundObject.filePath}
key={soundObject.id}
coneOuterGain={ConeOuterGain}
state={props.state}
/>
</mesh>
)
})
return <Suspense fallback={null}>{PositionalSoundObject}</Suspense>
}
Not exactly sure why, but hosting the wav files on the server and requesting it through https fixed the problem. My guess is that next.js (which runs node.js) can't handle loading wav files from the public folder out of the box and that it is not a problem related to react.

React useEffect doesn't change data displayed on map

I'm playing with uber's react-map-gl and deck-gl libraries to try to display data dynamically.I've got 2 components in my react little app.A navigation bar and a Mapbox map.So here is my pipeline.When the page first loads,only the map is displayed without any marker or visual data.But when i click on one of navigation bar link,an action creator gets called,when i make an ajax call to fetch some data,and from the action that is dispatched a pass my response data as payload and the reducer is reached so that i have a new version of the store.the data that i would like to visualize in they stor key : mainProjects that contains an array of geojson.My click on a navbar link succefully updates that value,and in the actual Map component,i can load the new values but useEffect does not update my localstate.Here is my map code:
import React, { useState, useEffect, useContext } from "react";
import { StaticMap } from "react-map-gl";
import { MapContext } from "./contexts/MapProvider";
import DeckGL, { GeoJsonLayer } from "deck.gl";
import chroma from "chroma-js";
import { connect } from "react-redux";
const MAPBOX_TOKEN =
"pk.mykey";
const mapStyle = "mapbox://mymapstyle";
function getEnergyFillColor(regime) {
const ENERGY_COLORS = {
naturalGaz: "#FF8500",
coal: "#99979A",
nuclear: "#E0399E",
hydroelectric: "#0082CB",
Wind: "#00B53B",
solar: "#DBCA00",
oil: "#FF0009",
other: "#FFEFD3"
};
let color;
switch (regime) {
case "Hydraulique":
color = ENERGY_COLORS.hydroelectric;
break;
case "Thermique":
color = ENERGY_COLORS.nuclear;
break;
default:
color = ENERGY_COLORS.other;
break;
}
color = chroma(color)
.alpha(0.667)
.rgba();
color[3] *= 255;
return color;
}
function _onClick(info) {
if (info.object) {
// eslint-disable-next-line
alert(
`${info.object.properties.NOM} (${info.object.properties.PROVINCE}) - ${
info.object.properties.PUISSANCE
}MW`
);
}
}
function Map({ mainProjects }) {
const { viewport, setViewport, onLoad } = useContext(MapContext);
const [airports, setAireports] = useState();
const [electricalEnergy, setElectricalEnergy] = useState();
const [hospitals, setHospitals] = useState();
const [roads, setRoads] = useState();
useEffect(() => {
if (mainProjects.length) {
setHospitals(mainProjects[0].hospitals);
setAireports(mainProjects[1].aeroports);
setElectricalEnergy(mainProjects[2].electricite);
setRoads(mainProjects[2].routes);
}
}, [airports, electricalEnergy, hospitals, roads]);
const layers = [
//ENERGIE ELECTRIQUE
new GeoJsonLayer({
id: "energy",
data: electricalEnergy,
// Styles
filled: true,
pointRadiusMinPixels: 20,
opacity: 1,
pointRadiusScale: 2000,
getRadius: energyItem => energyItem.properties.puissance * 3.14,
getFillColor: energyItem =>
getEnergyFillColor(energyItem.properties.regime),
// Interactive props
pickable: true,
autoHighlight: true,
onClick: _onClick
}),
//AEROPORTS
new GeoJsonLayer({
id: "airports",
data: airports,
// Styles
filled: true,
pointRadiusMinPixels: 20,
opacity: 1,
pointRadiusScale: 2000,
getRadius: energyItem => energyItem.properties.PUISSANCE * 3.14,
getFillColor: energyItem =>
getEnergyFillColor(energyItem.properties.REGIME),
// Interactive props
pickable: true,
autoHighlight: true,
onClick: _onClick
}),
//HOSPITALS
new GeoJsonLayer({
id: "hospitals",
data: hospitals,
// Styles
filled: true,
pointRadiusMinPixels: 20,
opacity: 1,
pointRadiusScale: 2000,
getRadius: energyItem => energyItem.properties.PUISSANCE * 3.14,
getFillColor: energyItem =>
getEnergyFillColor(energyItem.properties.REGIME),
// Interactive props
pickable: true,
autoHighlight: true,
onClick: _onClick
}),
//ROUTES
new GeoJsonLayer({
id: "roads",
data: roads,
pickable: true,
stroked: false,
filled: true,
extruded: true,
lineWidthScale: 20,
lineWidthMinPixels: 2,
getFillColor: [160, 160, 180, 200],
getLineColor: d => [255, 160, 20, 200],
// getLineColor: d => colorToRGBArray(d.properties.color),
getRadius: 100,
getLineWidth: 1,
getElevation: 30,
onHover: ({ object, x, y }) => {
// const tooltip = object.properties.name || object.properties.station;
/* Update tooltip
http://deck.gl/#/documentation/developer-guide/adding-interactivity?section=example-display-a-tooltip-for-hovered-object
*/
},
onClick: _onClick
})
];
return (
<>
<link
href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.css"
rel="stylesheet"
/>
<DeckGL
initialViewState={viewport}
viewState={viewport}
controller={true}
layers={layers}
onLoad={onLoad}
onViewportChange={nextViewport => setViewport(nextViewport)}
>
<StaticMap mapboxApiAccessToken={MAPBOX_TOKEN} mapStyle={mapStyle} />
</DeckGL>
</>
);
}
const mapStateToProps = ({
selectedLinks: { sectorSelected, provinceSelected, subSectorSelected },
mainProjects
}) => {
if (sectorSelected || provinceSelected || subSectorSelected) {
return {
mainProjects
};
} else {
return {
mainProjects: []
};
}
};
export default connect(mapStateToProps)(Map);
In the above code,i try to update my local state values by is setters,but useEffect doesn't seem to work.And it looks like it's only called once,at when the component renders for the first time.How can i solve this problem?
Thank you!!
Your useEffect has a set of dependencies that donˋt match those, which are actually used.
You are setting your local state with elements of mainProjects, so useEffect will only do something when mainProjects changes.
You donˋt seem to be doing anything with your useState-Variables, so you donˋt change state, so react doesnˋt rerender.
Update: it is really important to check, that the dependency-array (2nd argument to useEffect) and the used variables inside the function (1st argument) correspond, else bad things will happen ;-)
There is an eslint-rule for that: https://www.npmjs.com/package/eslint-plugin-react-hooks

Resources