I am trying to learn how to do simple convolution. I only want to see whether this matrix can detect v lines in images. Like in wikipedia.
This is my MWE
import * as tf from "#tensorflow/tfjs-node"
import { readFile, writeFile } from "node:fs/promises"
async function mainModule() {
const img = tf.node.decodeImage(await readFile("./numberOneGreyColor.png"), 1) as tf.Tensor3D;
const tensor4d = tf.tensor4d(
[-1, 2, -1,
-1, 2, -1,
-1, 2, -1,
], [1, 1, 3, 3])
.cast("float32")
.div(6)
const result = img.div(255).conv2d(
tensor4d as tf.Tensor4d, 1, "same") as tf.Tensor3D
const data = await tf.node.encodePng(result)
await writeFile("./result.png", data)
}
mainModule()
Which I wrote mostly by eye, so I appreciate some corrections.
Can not get this going. Any help?
I think finally got it.
This is original image
And the code:
import * as tf from "#tensorflow/tfjs-node"
import { tensor3d } from "#tensorflow/tfjs-node"
import { readFile, writeFile } from "node:fs/promises"
async function mainModule() {
let img = tf.node.decodeImage(await readFile("./images.png"), 1)
const tensor4d = tf.tensor4d([-1, 2, -1,
-1, 2, -1,
-1, 2, -1,
], [3, 3, 1, 1]).cast("float32")
const result = img.div(255).conv2d(tensor4d.div(6) as tf.Tensor4D, 1, "same")
const data = await tf.node.encodePng(result.abs().mul(255))
await writeFile("./result.png", data)
}
mainModule()
And the result
Not fully sure why is so dark but should inspect it later. Similar result in wikipedia by the way.
What's the best way to do the following in Ramda:
_.range(0, 3, 0);
// => [0, 0, 0]
Thank you.
If you need to repeat the same number n times, then Ori Drori already provided a good answer with repeat.
However if you need to support step, you would have to build a function yourself. (Ramda has a range function but it does not support step.)
So where Lodash would return:
_.range(1, 10, 2);
//=> [1, 3, 5, 7, 9]
You can achieve a similar functionality with Ramda unfold function:
const rangeStep = curry((start, end, step) =>
unfold(n => n < end ? [n, n + step] : false, start));
rangeStep(1, 10, 2);
//=> [1, 3, 5, 7, 9]
You can use R.repeat to create an array of multiple instances of a single item:
const result = R.repeat(0, 3)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
I am using lodash and have grouped an array of objects on a key that they shared; I then do calculations to these objects in these groups but now I need to ungroup.
Is there any way to do this in lodash?
Thanks
You can use _.flatMap() to "ungroup", but it won't restore the original order:
const arr = [2, 3, 4, 2, 3, 4]
const grouped = _.groupBy(arr)
console.log(JSON.stringify(grouped))
const ungrouped = _.flatMap(grouped)
console.log(JSON.stringify(ungrouped))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
I'm trying to animate the X value from 0 to PI, and the Y value from 0 to sin(x).
Something like:
this.positionX = new Animated.Value(0);
Animated.timing(
this.positionX, {
toValue: Math.PI,
duration: 1000,
}
).start();
// this obviously won't work
this.positionY = Math.sin(this.positionX);
I tried interpolating the X value with:
this.positionX.interpolate({
inputRange: [0, ..., PI],
outputRange: [0, ..., sin(PI)],
});
but I still get a linear approximation and slows down the animation drastically.
How can I compose an Animated.Value from a custom function the same way Animated.add or Animated.divide work?
I am trying to implement a median pooling layer in tensorflow.
However there is neither tf.nn.median_pool and neither tf.reduce_median.
Is there a way to implement such pooling layer with the python api ?
You could use something like:
patches = tf.extract_image_patches(tensor, [1, k, k, 1], ...)
m_idx = int(k*k/2+1)
top = tf.top_k(patches, m_idx, sorted=True)
median = tf.slice(top, [0, 0, 0, m_idx-1], [-1, -1, -1, 1])
To accommodate even sized median kernels and multiple channels, you will need to extend this, but this should get you most of the way.
As of March 2017, an easier answer (that under the hood works similarly to how Alex suggested) is to do this:
patches = tf.extract_image_patches(x, [1, k, k, 1], [1, k, k, 1], 4*[1], 'VALID')
medians = tf.contrib.distributions.percentile(patches, 50, axis=3)
For me, Alex's answer is not working for tf 1.4.1.
tf.top_k should be tf.nn.top_k
and should get values of tf.nn.top_k
Also, if the input is [1, H, W, C], either answer could not only work on height and width and neglect the channel.
Channel-wise median-pooling can be done by some addition reshapes on top of other answers:
# assuming NHWC layout
strides = rates = [1, 1, 1, 1]
patches = tf.extract_image_patches(x, [1, k, k, 1], strides, rates, 'VALID')
batch_size = tf.shape(x)[0]
n_channels = tf.shape(x)[-1]
n_patches_h = (tf.shape(x)[1] - k) // strides[1] + 1
n_patches_w = (tf.shape(x)[2] - k) // strides[2] + 1
n_patches = tf.shape(patches)[-1] // n_channels
patches = tf.reshape(patches, [batch_size, k, k, n_patches_h * n_patches_w, n_channels])
medians = tf.contrib.distributions.percentile(patches, 50, axis=[1,2])
medians = tf.reshape(medians, (batch_size, n_patches_h, n_patches_w, n_channels))
Not very efficient though.
I was looking for a median filter for tensorflowjs but can't seem to find one. tfa has a median filter now I think but for tf.js you can use this. Not sure if it would work on nodegpu.
function medianFilter(x, filter, strides, pad) {
//make Kernal
//todo allow for filter as array or number
let filterSize = filter ** 2;
let locs = tf.range(0, filterSize, filterSize );
//makes a bunc of arrays each one reprensentin one of the valuesin the median window ie 2x2 filter i in chanle and 4 out chanles
let f = tf.oneHot(tf.range(0,filterSize,1, 'int32'), filterSize).reshape([filter, filter, 1, filterSize]);
let y = tf.conv2d(x,f,strides,pad);
let m_idx = Math.floor(filterSize/2)+1;
let top = tf.topk(y, m_idx, true);
//note that thse are 3d tensors and if you use 4d ones add a 0 and -1 infron like in above ansowers
let median = tf.slice(top.values, [0,0,m_idx-1], [-1,-1,1] );
return median;
}