Tensorflow, how to preserve the intermediate node value and reuse them - tensorflow

Assuming I have the following graph.
- X3 and Z are the values I care about.
- X and Y are inputs. In each different. iteration, the coming values and shapes of X and Y are different, so I think they much be placeholder
- The circumstance is that I need to run this graph twice in different time point to get X3 and Z asynchronously.
+---+ op: +1 op: *3
| X +------------> X_1 +-----------> X3 +---+
+---+ + + | Y |
| | +-+-+
| op:add |
| | |
| | |
| op: add v op:add |
+-------------> <------------+
Z
At early time point, I get an input X(say X=7 and I don't know what's Y is at this moment). I want to see the value of X3. So I execute sess.run([X3], {X:7}), then it returns 24 as expected.
At later time point, I get another input Y(say Y=8), and this time I only want to take a look at node Z. But the point is that I have to execute sess.run([Z], {X:7, Y:8}) to get the result.
The problem is, for the later run, I have to feed X again to recalculate the intermediate node X_1 and X3. It calculates flow X--> X_1 --> X3 twice which hurts the efficiency.
My idea is that X_1 and X3 will contain values(X_1=8,X3=24) after the early run until the graph is destroyed, then I can directly leverage the instead of recalculating.
Is there a way to achieve the goal?

The following doesn't solve your problem completely, but it gets away with feeding X again:
X_temp = tf.Variable(0, dtype=tf.int32)
X = tf.placeholder_with_default(X_temp, shape=())
Y = tf.placeholder(tf.int32, shape=())
X_temp = tf.assign(X_temp, X)
X_1 = X_temp + 1
X3 = X_1 * 3
Z = X_1 + X3 + Y
sess = tf.InteractiveSession()
print(sess.run(X3, {X:7}))
print(sess.run(Z, {Y:8}))
#24
#40

One option I would recommend is:
temp_X1, temp_X3 = sess.run([X_1, X3], feed_dict={X:7})
sess.run(Z, feed_dict={X_1:temp_X1, X3:temp_X3, Y: 8}
You don't need to store everything inside the tf graph.
See the tensorflow doc for other options (like using a Saver, etc.)
Note: Feeding into placeholder is recommended by the doc, but feeding into an intermediate Tensor achieves your requirement the easiest.

Related

Python to fit a linear-plateau curve

I have curve that initially Y increases linearly with X, then reach a plateau at point C.
In other words, the curve can be defined as:
if X < C:
Y = k * X + b
else:
Y = k * C + b
The training data is a list of X ~ Y values. I need to determine k, b and C through a machine learning approach (or similar), since the data is noisy and refection point C changes over time. I want something more robust than get C through observing the current sample data.
How can I do it using sklearn or maybe scipy?
WLOG you can say the second equation is
Y = C
looks like you have a linear regression to fit the line and then a detection point to find the constant.
You know that in the high values of X, as in X > C you are already at the constant. So just check how far back down the values of X you get the same constant.
Then do a linear regression to find the line with value of X, X <= C
Your model is nonlinear
I think the smartest way to solve this is to do these steps:
find the maximum value of Y which is equal to k*C+b
M=max(Y)
drop this maximum value from your dataset
df1 = df[df.Y != M]
and then you have simple dataset to fit your X to Y and you can use sklearn for that

Tensorflow: ignore a specific dependency during tf.gradients()

Given variables y and z, both of which depend on a tensor x. By product rule, if I do tf.gradients(yz,x), it would give me y'(x)z(x) + z'(x)y(x). Is there a way I can specify y as a constant with respect to x such that tf.gradients(yz,x) only gives me z'(x)y(x)?
I know y_=tf.constant(sess.run(y)) will give me y as a constant, but I cannot use that solution in my code.
You can use tf.stop_gradient() to block backpropagation. To block gradients in your example:
y = function1(x)
z = function2(x)
blocked_y = tf.stop_gradient(y)
product = blocked_y * z
After you backpropagate through product, the backpropagation will continue to z and not y.

Clustering method. Choice variables when sum of variables is 1 on each observation

There are 3 variables are x, and z=1-(x+y). ( x>=0, y>=0, z>=0 )
Data are like below.
O(1)= (x1,y1,z1)
O(2)= (x2,y2,z2)
...
O(n)= (xn,yn,zn)
I thought that z is not necessary to express each observation because z is determined by x and y.
So, I did clustering this data with x and y.
And also did clustering same data with x, y and z, too.
The results are different.
Because the distances in 2D and 3D are not equal. (It changed.)
(Yes, Of course, the distances 2D and 3D are not equivalent.)
But, What is the right way do clustering in this case?
Do I have to use x and y? Or, do I have to use x, y and z? Why?
Please someone help me. Thank you in advance!
Below is R code.
############
x <- sample(c(0:100), 100, replace = T)
y <- sample(c(0:100), 100, replace = T)
z <- 200 - (x+y)
xyz <- cbind(x,y,z)
xyz <- xyz/200 # z=1-(x+y)
xy <- zyz[,-3]
require(fpc)
(xy.pamk <- pamk(xy))
plot(xy,col=xy.pamk$pamobject$clustering)
(xyz.pamk <- pamk(xyz))
require(rgl)
plot3d(xyz,col=xyz.pamk$pamobject$clustering,xlim=c(0,1), ylim=c(0,1), zlim=c(0,1))
##############
Your theory that you don't need z, because it can be computed from x and y is flawed.
If it were that way, then x,y and x,z and y,z would all give the same result.
But the algorithms don't assume x+y+z=1. They won't assume x*x+y*y+z*z=1 either or other dependencies of features.

How to rename a variable which respects the name scope?

Given x, y are tensors, I know I can do
with tf.name_scope("abc"):
z = tf.add(x, y, name="z")
So that z is named "abc/z".
I am wondering if there exists a function f which assign the name directly in the following case:
with tf.name_scope("abc"):
z = x + y
f(z, name="z")
The stupid f I am using now is z = tf.add(0, z, name="z")
If you want to "rename" an op, there is no way to do that directly, because a tf.Operation (or tf.Tensor) is immutable once it has been created. The typical way to rename an op is therefore to use tf.identity(), which has almost no runtime cost:
with tf.name_scope("abc"):
z = x + y
z = tf.identity(z, name="z")
Note however that the recommended way to structure your name scope is to assign the name of the scope itself to the "output" from the scope (if there is a single output op):
with tf.name_scope("abc") as scope:
# z will get the name "abc". x and y will have names in "abc/..." if they
# are converted to tensors.
z = tf.add(x, y, name=scope)
This is how the TensorFlow libraries are structured, and it tends to give the best visualization in TensorBoard.
It seems it works also without tf.name_scope only with z = tf.identity(z, name="z_name"). If you run additionally z = tf.identity(z, name="z_name_new") then you can access the same tensor using both names: tf.get_default_graph().get_tensor_by_name("z_name:0") or tf.get_default_graph().get_tensor_by_name("z_name_new:0")

Formatting a txt file of equations into the same format and then manipulating them for linear algebra calculations in Python

I'm looking for an universal way of transforming equations in Python 3.2. I've only recently begun playing around with it and stumbled upon some of my old MATLAB homework. I'm able to calculate this in MATLAB but pylab is still a bit of a mystery to me.
So, I have a text file of equations that I'm trying to convert into the the same form of A x = b and then solve some linear algebra problems associated with them in PYLAB.
The text file, "equations.txt",contains collections of linear equations in the following format:
-38 y1  +  35 y2  +  31 y3  = -3047
11 y1  + -13 y2  + -34 y3  = 784
34 y1  + -21 y2  +  19 y3  = 2949
etc.
The file contains the equations for four sets of equations, each set with a different number of variables. Each set of equations is of the exact form shown (3 examples above) with one empty line between each set.
I want to write a program to read all the sets of equations in the files, convert sets of equations into a matrix equation A x = b, and solve the set of equations for the vector x.
My approach has been very "MATLABy", which is a problem because I want to be able to write a program that will solve for all of the variables.
I've tried reading a single equation as a text line, stripped of the carriage return at the end, and splitting line at the = sign because as we know the 2nd element in the split is the right hand side of the equation, that goes into the vector b.
The first element in the split is the part you have to get the coefficients that go in the A matrix.  If you split this at white space ' ', you will get a list like
['-38', 'y1', '+', '35', 'y2', '+', '31', 'y3']
Note now that you can pull every 3rd element and get the coefficients that go into the matrix A.
Partial answers would be:
y1 = 90; c2 = 28; x4 = 41; z100 = 59
I'm trying to manipulate them to give me the sum of the entries of the solutions y1, ..., y3 for the first block of equations, the sum of the entries of the solutions c1, ..., c6 for the second block of equations, the sum of the entries of the solutions x1, ..., x13 for the third block of equations, and the sum of the entries of the solutions z1, ..., z100 for the fourth block of equations.
Like, I said - I'm able to do this in MATLAB but not in Python so I'm probably approaching this from the wrong way but this is what I have so far:
import pylab
f = open('equations.txt', 'r')
L=f.readlines()
list_final = []
for line in L:
line_l = line.rstrip()
list_l = line_l.split(";")
list_l = filter(None, list_l)
for expression in list_l:
and ending it with
f.close()
This was just my go at trying to format the equations to all look the same. I realise it's not a lot but I was really hoping someone could get my started because even though I know some python I normally don't use it for math because I have MATLAB for that.
I think this could be useful for many of us who have prior MATLAB experience but not pylab.
How would you go around this? Thank you!
For your example format, it's very easy to process it by numpy.loadtxt():
import numpy as np
data = np.loadtxt("equations.txt", dtype=str)[:, ::3].astype(np.float)
a = data[:, :-1]
b = data[:, -1]
x = np.linalg.solve(a, b)
The steps are:
An alternative approach that is possibly more robust to unstructured input is to use a combination of the Python symbolic math package (sympy), and a few parsing tricks. This scales to the variables in the equations being written in an arbitrary order.
Although sympy has some tools for parsing, (your input is very close in appearance to Mathematica), it appears that the sympy.parsing.mathematica module can't deal with some of the input (particularly leading minus signs).
import sympy
from sympy.parsing.sympy_parser import parse_expr
import re
def text_to_equations(text):
lines = text.split('\n')
lines = [line.split('=') for line in lines]
eqns = []
for lhs, rhs in lines:
# clobber all the spaces
lhs = lhs.replace(' ','')
# *assume* that a number followed by a letter is an
# implicit multiplication
lhs = re.sub(r'(\d)([a-z])', r'\g<1>*\g<2>', lhs)
eqns.append( (parse_expr(lhs), parse_expr(rhs)) )
return eqns
def get_all_symbols(eqns):
symbs = set()
for lhs, rhs in eqns:
for sym in lhs.atoms(sympy.Symbol):
symbs.add(sym)
return symbs
def text_to_eqn_matrix(text):
eqns = text_to_equations(text)
symbs = get_all_symbols(eqns)
n = len(eqns)
m = len(symbs)
A = numpy.zeros((m, n))
b = numpy.zeros((m, 1))
for i, (lhs, rhs) in enumerate(eqns):
d = lhs.as_coefficients_dict()
b[i] = int(rhs)
for j, s in enumerate(symbs):
A[i, j] = d[s]
x = sympy.Matrix([list(symbs)]).T
return sympy.Matrix(A), x, sympy.Matrix(b)
s = '''-38 y1 + 35 y2 + 31 y3 = -3047
11 y1 + -13 y2 + -34 y3 = 784
34 y1 + -21 y2 + 19 y3 = 2949'''
A, x, b = text_to_eqn_matrix(s)
print A
print x
print b