I'm trying to figure out how the actor-critic method works. And implement it in tensorflow.js
I have designed a small environment where you need a board to catch a falling ball. If caught +1 reward point, if not -1 reward point.
My implementation https://codepen.io/redrickShuhart/pen/popKmRj
The model is implemented with one body and two heads.
I am trying to train the model, but it seems to me that I have implemented the training process incorrectly.
Please help. Where am I wrong.
I would be glad to get a link to a tfjs example to help me figure it out.
train() {
this.memory.reverse()
let V_next = 0
for (let s of this.memory) {
let V_current = s.reward + V_next * this.gamma
s['V'] = V_current
s['V_next'] = V_next
V_next = V_current
}
this.memory.reverse()
for (let mem of this.memory) {
let f = () => tf.tidy(() => {
let {state, action, reward, next_state, V, V_next} = mem
state = tf.tensor(state, [1, this.env.state_size])
let [probs, value] = this.model.predict(state)
let target_V = tf.tensor(V, [1, 1])
let value_loss = tf.losses.meanSquaredError(target_V, value).asScalar()
let advantages = new Array(this.action_size).fill(0)
advantages[action] = V_next - V
advantages = tf.tensor(advantages, [1, this.action_size])
let policy_loss = tf.log(probs).mul(advantages).sum().mul(tf.scalar(-1)).asScalar()
return policy_loss.add(value_loss)
})
let grads = tf.variableGrads(f).grads
this.ALL_GRADIENTS.push(grads)
}
tf.tidy(() => {
/* grads names */
let keys = Object.keys(this.ALL_GRADIENTS[0])
const new_grad = {}
for (let key of keys) {
new_grad[key] = null
}
for (let key in new_grad) {
let grad_by_key = this.ALL_GRADIENTS.map(grad => grad[key])
let mean = grad_by_key.reduce((prev_grad, cur_grad) => prev_grad.add(cur_grad)).div(tf.scalar(grad_by_key.length))
new_grad[key] = mean
tf.dispose(grad_by_key)
}
this.model.optimizer.applyGradients(new_grad)
})
// for (let grad of this.ALL_GRADIENTS) {
// this.model.optimizer.applyGradients(grad)
// }
this.memory = []
tf.dispose(this.ALL_GRADIENTS)
this.ALL_GRADIENTS = []
// console.log(tf.memory())
}
Related
On the front end of my app I wanted to parse some data related to a CSV they upload. Through the file upload tool, I first get a FileList object and then pull the 1 file out of it.
I want to turn it into a json object which I could then iterate. I was thinking to user csv-parser from node, but I dont see a way to leverage a File object stored in memory.
How Can I accomplish this?
At first I was doing:
let f = fileList.item(0);
let decoder = new window.TextDecoder('utf-8');
f.arrayBuffer().then( data => {
let _data = decoder.decode(data)
console.log("Dataset", data, _data)
});
And that was passing the array buffer, and decoding the string. While I Could write a generic tool which process this string data based on \n and ',' I wanted this to be a bit more easier to read.
I wanted to do something like:
let json = csvParser(f)
is there a way to user csv-parser from node, (3.0.0) or is there another tool i should leverage? I was thinking that levering modules based on the browser ( new window.TextDecoder(...) ) is poor form since it has the opportunity to fail.
Is there a tool that does this? im trying to create some sample data and given a File picked from an input type="file" i would want to have this be simple and straight forward.
This example below works, but i feel the window dependancy and a gut feeling makes me think this is naive.
const f : File = fileList.item(0)
console.log("[FOO] File", f)
let decoder = new window.TextDecoder('utf-8');
f.arrayBuffer().then( data => {
let _data = decoder.decode(data)
console.log("Dataset", data, _data)
let lines = _data.split("\n")
let headers = lines[0].split(',')
let results = []
for ( let i = 1; i < lines.length; i++) {
let line = lines[i]
let row = {}
line.split(",").forEach( (item, idx) => {
row[headers[idx]] = item;
})
results.push(row)
}
console.log("JSON ARRAY", results)
})
The issue i run when i stop and do: ng serve is that it does not like using the arrayBuffer function and accessing TextDecoder from window, since that thost functions/classes are not a part of File and window respectively during build.
Any thoughts?
This is what I ended up doing, given the file input being passed into this function:
updateTranscoders(project: Project, fileList: FileList, choice: string = 'replace') {
const f: File = fileList.item(0)
//Reads a File into a string.
function readToString(file) : Promise<any> {
const reader = new FileReader();
const future = new Promise( (resolve,reject) => {
reader.addEventListener("load", () => {
resolve(reader.result);
}, false)
reader.addEventListener("error", (event) => {
console.error("ERROR", event)
reject(event)
}, false)
reader.readAsText(file)
});
return future;
}
readToString(f).then( data => {
let lines = data.split("\n")
let headers = lines[0].split(',')
let results = []
for (let i = 1; i < lines.length; i++) {
let line = lines[i]
let row = {}
line.split(",").forEach((item, idx) => {
row[headers[idx]] = item;
})
results.push(row)
}
if (choice.toLowerCase() === 'replace'){
let rows = project.csvListContents.toJson().rows.filter( row => row.isDeployed)
rows.push( ...results)
project.csvListContents = CsvDataset.fromJson({ rows: rows })
}else if (choice.toLowerCase() === 'append') {
let r = project.csvListContents.toJson();
r.rows.push(...results);
project.csvListContents = CsvDataset.fromJson(r);
}else {
alert("Invalid option for Choice.")
}
this.saveProject(project)
})
}
Now the CHOICE portion of the code is where I have a binary option to do a hard replace on CSV contents or just append to it. I would then save the project accordingly. This is also understanding that the first row contains column headers.
I'm using Angular 6.
I have an array of links and a variable to store fetched information in same order as of array one by one.
Here is what I'm trying to do using for loop.
products: any;
processedItems: Array<any> = [];
private _processItem() {
for (let i = 0; i < this.products.length; i++) {
this.scraperService.scrapSingle(this.products[i].url).subscribe(
res => {
if (res.status.http_code === 200) {
const properties = this.scraperService.processSingleProduct(res.contents);
const p_item = {};
p_item['info'] = this.products[i];
p_item['properties'] = properties;
this.processedItems.push(p_item);
}
console.log(res);
}
);
}
console.log(this.products.length);
}
But how to wait for subscribe before moving to next index in the loop?
Just splice the p_item into your array at the required index given i.
For example instead of doing,
this.processedItems.push(p_item);
do this,
this.processedItems.splice(p_item, 0, i);
That solves your problem :)
Use promises instead of rx.js subscriptions via using toPromise method. You might need to map the res to json. res.map(item => item.json());
products: any;
processedItems: Array < any > =[];
private _processItem() {
this.products.array.forEach(async (element) => {
const res = await this.scraperService.scrapSingle(element.url).toPromise();
if (res.status.http_code === 200) {
const properties = this.scraperService.processSingleProduct(res.contents);
const p_item = {};
p_item['info'] = element
p_item['properties'] = properties;
this.processedItems.push(p_item);
}
console.log(res);
});
console.log(this.products.length);
}
I have the following code:
UPDATE:
const showEvent = (eventLink) => {
let {events
} = database
let staffMembers = ""
let scenesList = ""
const staffMembersContainer = $('.staff-members')
const scenesContainer = $('.scenes')
const eventsGrid = $('#events-grid')
const eventHeader = $('#events-grid h2')
const eventKey = eventLink.getAttribute('data-key')
const {
name,
staff,
scenes
} = events[eventKey]
eventHeader.innerText = name
eventsGrid.classList.toggle("hidden")
Object.keys(staff).forEach(role => {
const staffMember = staff[role]
staffMembers += Staff(role, staffMember)
})
staffMembersContainer.innerHTML = staffMembers
Object.keys(scenes).forEach(scene => {
scenesList += Scene(scenes[scene])
})
scenesContainer.innerHTML = scenesList
}
const Staff = (role, staffMember) => {
const {
name
} = database.profiles[staffMember[0]]
return `
<li>
<p>${role}:</p>
<p>${name}</p>
</li>
`
}
const Scene = (id) => {
let promises = []
const {
name,
concerts
} = database.scenes[id]
let concertList = ""
concerts.forEach(concert => {
promises.push(
Concert(concert).then(bandName => {
concertList += `<li><p>${bandName}</p></li>`
})
)
})
return Promise.all(promises).then(() => {
return `
<li class="scene">
<p>Scene ${name}:</p>
<ul>
${concertList}
</ul>
</li>
`
})
}
const Concert = (id) => {
const bandId = database.concerts[id].band
return firebase.database().ref(`/bands/${bandId}/name`).once('value').then(snap => {
return snap.val()
})
}
So I would like to generate two lists, one containing the Staff members, the other one is containing lists of scenes, where scenes themselves are lists of Band names. I only could get plain HTML elements until I found out, that I should probably wait until the data is fetched from Firebase. As this is my first try with promises, the code is a bit messy, and probably is broken on several points.
If someone would have the time to help, I would extremely appreciate it!
Thanks
When I pass an array of dbIds to be turned off the viewer is turning every node off in my model.
Autodesk.Viewing.Viewer3D.prototype.turnOff = function(dbIds) {
var node;
$(dbIds)
.each(function(index, item) {
node = viewer.model.getData().instanceTree.nodeAccess.nodes[item];
viewer.impl.visibilityManager.setNodeOff(node, true);
});
}
If you pass the id of a parent, it will turn off all its children, which is probably what happens in your case. Turning nodes off definitely works fine, you can take a look at my demo at https://forge-rcdb.autodesk.io.
Select a row in the database view or a segment in the pie chart:
What you need to do is to get the leaf node ids, only leaf nodes are represented by geometry in the viewer.
Here is some ES6 code sample, extracted from there:
static getLeafNodes (model, dbIds) {
return new Promise((resolve, reject)=>{
try {
const instanceTree = model.getData().instanceTree
dbIds = dbIds || instanceTree.getRootId()
const dbIdArray = Array.isArray(dbIds) ? dbIds : [dbIds]
let leafIds = []
const getLeafNodesRec = (id) => {
var childCount = 0;
instanceTree.enumNodeChildren(id, (childId) => {
getLeafNodesRec(childId)
++childCount
})
if (childCount == 0) {
leafIds.push(id)
}
}
for (var i = 0; i < dbIdArray.length; ++i) {
getLeafNodesRec(dbIdArray[i])
}
return resolve(leafIds)
} catch(ex){
return reject(ex)
}
})
}
static async isolateFull (viewer, dbIds = [], model = null) {
try {
model = model || viewer.activeModel || viewer.model
viewer.isolate(dbIds)
const targetIds = Array.isArray(dbIds) ? dbIds : [dbIds]
const targetLeafIds = await ViewerToolkit.getLeafNodes(
model, targetIds)
const leafIds = await ViewerToolkit.getLeafNodes (model)
const leafTasks = leafIds.map((dbId) => {
return new Promise((resolveLeaf) => {
const show = !targetLeafIds.length ||
targetLeafIds.indexOf(dbId) > -1
viewer.impl.visibilityManager.setNodeOff(
dbId, !show)
resolveLeaf()
})
})
return Promise.all(leafTasks)
} catch (ex) {
return Promise.reject(ex)
}
}
I have an iterator (actually a Source.getLines) that's reading an infinite stream of data from a URL. Occasionally the iterator throws a java.io.IOException when there is a connection problem. In such situations, I need to re-connect and re-start the iterator. I want this to be seamless so that the iterator just looks like a normal iterator to the consumer, but underneath is restarting itself as necessary.
For example, I'd like to see the following behavior:
scala> val iter = restartingIterator(() => new Iterator[Int]{
var i = -1
def hasNext = {
if (this.i < 3) {
true
} else {
throw new IOException
}
}
def next = {
this.i += 1
i
}
})
res0: ...
scala> iter.take(6).toList
res1: List[Int] = List(0, 1, 2, 3, 0, 1)
I have a partial solution to this problem, but it will fail on some corner cases (e.g. an IOException on the first item after a restart) and it's pretty ugly:
def restartingIterator[T](getIter: () => Iterator[T]) = new Iterator[T] {
var iter = getIter()
def hasNext = {
try {
iter.hasNext
} catch {
case e: IOException => {
this.iter = getIter()
iter.hasNext
}
}
}
def next = {
try {
iter.next
} catch {
case e: IOException => {
this.iter = getIter()
iter.next
}
}
}
}
I keep feeling like there's a better solution to this, maybe some combination of Iterator.continually and util.control.Exception or something like that, but I couldn't figure one out. Any ideas?
This is fairly close to your version and using scala.util.control.Exception:
def restartingIterator[T](getIter: () => Iterator[T]) = new Iterator[T] {
import util.control.Exception.allCatch
private[this] var i = getIter()
private[this] def replace() = i = getIter()
def hasNext: Boolean = allCatch.opt(i.hasNext).getOrElse{replace(); hasNext}
def next(): T = allCatch.opt(i.next).getOrElse{replace(); next}
}
For some reason this is not tail recursive but it that can be fixed by using a slightly more verbose version:
def restartingIterator2[T](getIter: () => Iterator[T]) = new Iterator[T] {
import util.control.Exception.allCatch
private[this] var i = getIter()
private[this] def replace() = i = getIter()
#annotation.tailrec def hasNext: Boolean = {
val v = allCatch.opt(i.hasNext)
if (v.isDefined) v.get else {replace(); hasNext}
}
#annotation.tailrec def next(): T = {
val v = allCatch.opt(i.next)
if (v.isDefined) v.get else {replace(); next}
}
}
Edit: There is a solution with util.control.Exception and Iterator.continually:
def restartingIterator[T](getIter: () => Iterator[T]) = {
import util.control.Exception.allCatch
var iter = getIter()
def f: T = allCatch.opt(iter.next).getOrElse{iter = getIter(); f}
Iterator.continually { f }
}
There is a better solution, the Iteratee:
http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/
Here is for example an enumerator that restarts on encountering an exception.
def enumReader[A](r: => BufferedReader, it: IterV[String, A]): IO[IterV[String, A]] = {
val tmpReader = r
def loop: IterV[String, A] => IO[IterV[String, A]] = {
case i#Done(_, _) => IO { i }
case Cont(k) => for {
s <- IO { try { val x = tmpReader.readLine; IO(x) }
catch { case e => enumReader(r, it) }}.join
a <- if (s == null) k(EOF) else loop(k(El(s)))
} yield a
}
loop(it)
}
The inner loop advances the Iteratee, but the outer function still holds on to the original. Since Iteratee is a persistent data structure, to restart you just have to call the function again.
I'm passing the Reader by name here so that r is essentially a function that gives you a fresh (restarted) reader. In practise you will want to bracket this more effectively (close the existing reader on exception).
Here's an answer that doesn't work, but feels like it should:
def restartingIterator[T](getIter: () => Iterator[T]): Iterator[T] = {
new Traversable[T] {
def foreach[U](f: T => U): Unit = {
try {
for (item <- getIter()) {
f(item)
}
} catch {
case e: IOException => this.foreach(f)
}
}
}.toIterator
}
I think this very clearly describes the control flow, which is great.
This code will throw a StackOverflowError in Scala 2.8.0 because of a bug in Traversable.toStream, but even after the fix for that bug, this code still won't work for my use case because toIterator calls toStream, which means that it will store all items in memory.
I'd love to be able to define an Iterator by just writing a foreach method, but there doesn't seem to be any easy way to do that.