Trying to implement experience replay in Tensorflow - tensorflow

I am trying to implement experience replay in Tensorflow. The problem I am having is in storing outputs for the models trial and then updating the gradient simultaneously. A couple approaches I have tried are to store the resulting values from sess.run(model), however, these are not tensors and cannot be used for gradient descent as far as tensorflow is concerned. I am currently trying to use tf.assign(), however, The difficulty I am having is best shown through this example.
import tensorflow as tf
import numpy as np
def get_model(input):
return input
a = tf.Variable(0)
b = get_model(a)
d = tf.Variable(0)
for i in range(10):
assign = tf.assign(a, tf.Variable(i))
b = tf.Print(b, [assign], "print b: ")
c = b
d = tf.assign_add(d, c)
e = d
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(e))
The issue I have with the above code is as follows:
-It prints different values on each run which seems odd
-It does not correctly update at each step in the for loop
Part of why I am confused is the fact that I understand you have to run the assign operation to update the prior reference, however, I just can't figure out how to correctly do that in each step of the for loop. If there is an easier way I am open to suggestions. This example is the same as how I am currently trying to feed in an array of inputs and get a sum based on each prediction the model makes. If clarification on any of the above would help I will be more than happy to provide it.
The following is the results from running the code above three times.
$ python test3.py
2018-07-03 13:35:08.380077: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
80
$ python test3.py
2018-07-03 13:35:14.055827: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
print b: [7]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
60
$ python test3.py
2018-07-03 13:35:20.120661: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
90
The result I am expecting is as follows:
print b: [0]
print b: [1]
print b: [2]
print b: [3]
print b: [4]
print b: [5]
print b: [6]
print b: [7]
print b: [8]
print b: [9]
45
The main reason I am confused is that sometimes it provides all nines which makes me think that it loads the last value assigned 10 times, however, sometimes it loads different values which seems to contrast this theory.
What I would like to do is to feed in an array of input examples and compute the gradient for all examples at the same time. It needs to be concurrently because the reward used is dependent on the outputs of the model, so if the model changes the resulting rewards would also change.

When you call tf.assign(a, tf.Variable(i)) this does not actually immediately assign the value of the second variable to the first one. It just create an operation in the NN to do the assignment when sess.run(...) is called.
When it is called all 10 assignments try to do their assignment at the same time. One of them randomly wins and then gets passed to the 10 assign_add operations which in effect multiplies it 10 times.
As to your motivating problem of implementing experience replay, most approaches I came across use tf.placeholder() to feed the experience buffer content into the network on training.

Related

Tensorflow graph execution ignores equality condition in earger execution mode

I stumbled on some weird tensorflow behaviour. After tf.print everywhere, it led me to the cause as shown in the following code but don't know why it happened unless either threading race condition or graph construction omitted the code segment. Don't see either of them should happen.
# Ragged tensor may have empty rows. So, for tensor arithmetic operation,
# we need to create zero-padded tensors to replace them.
# This implementation only keeps the first entry of each row.
# So, the output tensor is a normal tensor.
def pad_empty_ragged_tensor(ragtensor):
tf.print("Ragged tensor padding empty tensor...", output_stream=sys.stdout)
batch_size = ragtensor.shape[0]
n_rows = ragtensor.row_lengths()
tf.print("row_lengths(): ", n_rows, output_stream=sys.stdout)
new_tensor = []
for i in range(batch_size):
tf.print("n_rows[i]: ", n_rows[i], output_stream=sys.stdout)
if tf.equal(n_rows[i], 0): # Tried n_rows[i] == 0 too
tf.print("Create zero padded tensor...", output_stream=sys.stdout)
num_zeros = ragtensor.shape[-1]
tensor = tf.tile([[0]], [1, num_zeros])
tensor = tf.cast(tensor, dtype=ragtensor.dtype)
else:
tf.print("Take first entry from the row", output_stream=sys.stdout)
tensor = ragtensor[i,0:1]
new_tensor.append(tensor)
tensor = tf.stack(new_tensor, axis=0) # [batch, 1, [y, x, h, w]]
tensor.set_shape([batch_size, 1, ragtensor.shape[-1]])
tf.print("The padded tensor shape: ", tensor.shape, output_stream=sys.stdout)
return tensor
Here is a segment of the print trace:
row_lengths(): [1 1 0 ... 1 1 1]
n_rows[i]: 1
Take first entry from the row
n_rows[i]: 1
Take first entry from the row
n_rows[i]: 0
Take first entry from the row
n_rows[i]: 1
Take first entry from the row
As shown, if tf.equal(n_rows[i], 0): # Tried n_rows[i] == 0 too condition block was never called. It falls into 'else' condition every time even if the equality condition was met. Could anyone hint me what went wrong?
BTW, debugging tensorflow runtime is difficult too. Breakpoint in VSCode didn't hit once graph execution runs. tfdbg is not working with eager execution either. A suggestion on this is very beneficial to me too.
My dev env:
OS: Ubuntu18.04
Python: 3.6
Tensorflow-gpu: 1.14
GPU: RTX2070
Cuda: 10.1
cudnn: 7.6
IDE: VS code
Tensorflow mode: Eager execution
Thanks in advance

Read parquet file compressed with zstd

I am new to Julia and I am trying to port some stuff I did in Python.
I have a file I wrote in Python, with a DataFrame to a parquet file using the zstd compression lib (supported by both pandas and fastparquet, parquet file writing).
It gives an error since ParquetFiles or FileIO (not sure which one is responsible for the decompression), doesn't support zstd.
Any ideas on how to read this file in Julia?
using DataFrames
using ParquetFiles
using FileIO
test = DataFrame(load("test.parquet"))
Unknown compression codec for column chunk: 6
Stacktrace:
[1] error(::String) at ./error.jl:33
[2] bytes at /home/morgado/.julia/packages/Parquet/qSvbc/src/reader.jl:149 [inlined]
[3] bytes at /home/morgado/.julia/packages/Parquet/qSvbc/src/reader.jl:140 [inlined]
[4] values(::ParFile, ::Parquet.Page) at /home/morgado/.julia/packages/Parquet/qSvbc/src/reader.jl:232
[5] values(::ParFile, ::Parquet.PAR2.ColumnChunk) at /home/morgado/.julia/packages/Parquet/qSvbc/src/reader.jl:178
[6] setrow(::ColCursor{Int64}, ::Int64) at /home/morgado/.julia/packages/Parquet/qSvbc/src/cursor.jl:144
[7] ColCursor(::ParFile, ::UnitRange{Int64}, ::String, ::Int64) at /home/morgado/.julia/packages/Parquet/qSvbc/src/cursor.jl:115
[8] (::getfield(Parquet, Symbol("##11#12")){ParFile,UnitRange{Int64},Int64})(::String) at ./none:0
[9] collect(::Base.Generator{Array{AbstractString,1},getfield(Parquet, Symbol("##11#12")){ParFile,UnitRange{Int64},Int64}}) at ./generator.jl:47
[10] RecCursor(::ParFile, ::UnitRange{Int64}, ::Array{AbstractString,1}, ::JuliaBuilder{ParquetFiles.RCType361}, ::Int64) at /home/morgado/.julia/packages/Parquet/qSvbc/src/cursor.jl:269 (repeats 2 times)
[11] getiterator(::ParquetFiles.ParquetFile) at /home/morgado/.julia/packages/ParquetFiles/cLLFb/src/ParquetFiles.jl:74
[12] nondatavaluerows(::ParquetFiles.ParquetFile) at /home/morgado/.julia/packages/Tables/IT0t3/src/tofromdatavalues.jl:16
[13] columns at /home/morgado/.julia/packages/Tables/IT0t3/src/fallbacks.jl:173 [inlined]
[14] #DataFrame#393(::Bool, ::Type, ::ParquetFiles.ParquetFile) at /home/morgado/.julia/packages/DataFrames/VrZOl/src/other/tables.jl:34
[15] DataFrame(::ParquetFiles.ParquetFile) at /home/morgado/.julia/packages/DataFrames/VrZOl/src/other/tables.jl:25
[16] top-level scope at In[25]:8

Julia #eval world age missmatch

I'm trying to use the julia #eval functionality to only load the PyPlot package on demand. However I verry often run into world age missmatch.
Here is a minimal example where i try and plot on demand
function CreateMatrix(Ncount;Plot=true)
TheMatrix = fill(0.0,Ncount,Ncount)
if Plot
#eval using PyPlot
###"Plot the Matrix"
PyPlot.figure()
PyPlot.imshow(abs.(TheMatrix))
PyPlot.colorbar()
end
return TheMatrix
end
CreateMatrix(10;Plot=false)
CreateMatrix(10;Plot=true)
With the output
ERROR: LoadError: MethodError: no method matching figure()
The applicable method may be too new: running in world age 25063, while current world is 25079.
Closest candidates are:
figure(!Matched::Any...; kws...) at ~/.julia/packages/PyPlot/fZuOQ/src/PyPlot.jl:148 (method too new to be called from this world context.)
Stacktrace:
[1] #CreateMatrix#3(::Bool, ::Function, ::Int64) at myfile.jl:7
[2] (::getfield(Main, Symbol("#kw##CreateMatrix")))(::NamedTuple{(:Plot,),Tuple{Bool}}, ::typeof(CreateMatrix), ::Int64) at ./none:0
[3] top-level scope at none:0
[4] include at ./boot.jl:317 [inlined]
[5] include_relative(::Module, ::String) at ./loading.jl:1044
[6] include(::Module, ::String) at ./sysimg.jl:29
[7] exec_options(::Base.JLOptions) at ./client.jl:231
[8] _start() at ./client.jl:425
in expression starting at myfile.jl:16
Does anyone know how uses the #eval functionality properly?
EDIT
One of the comments suggested wrapping the plotting command and annotating with #noinline as below, but this does not work.
function CreateMatrix(Ncount;Plot=false)
TheMatrix = fill(0.0,Ncount,Ncount)
if Plot
#eval using PyPlot
###"Plot the Matrix"
ThePlotting(TheMatrix)
end
return TheMatrix
end
#noinline function ThePlotting(TheMatrix)
PyPlot.figure()
PyPlot.imshow(abs.(TheMatrix))
PyPlot.colorbar()
end
CreateMatrix(10;Plot=false)
CreateMatrix(10;Plot=true)
I'm running julia version 1.0.2
You can implement it like this:
function CreateMatrix(Ncount;Plot=true)
TheMatrix = fill(0.0,Ncount,Ncount)
if Plot
if isdefined(Main, :PyPlot)
println("PyPlot already loaded")
PyPlot.figure()
PyPlot.imshow(abs.(TheMatrix))
PyPlot.colorbar()
else
println("PyPlot loading PyPlot")
#eval using PyPlot
Base.invokelatest(PyPlot.figure)
Base.invokelatest(PyPlot.imshow, abs.(TheMatrix))
Base.invokelatest(PyPlot.colorbar)
end
end
return TheMatrix
end
I have used conditional to allow you to see which branch gets executed on repeated call to the function.
Initially I thought that when calling non-inlined function Julia allows world age change (but it turns out that it is strict).
Finally - in general it is probably safer not to write code like this but simply load the module in top-level scope (possibly conditionally).

tensorflow tf.Print not printing anything in Jupyter

Trying debug statements in Python/tensorflow1.0 using jupyter , but does not get any output printed from tf.Print
Thought sess.run(during training in below code) should have evaluated db1 tensor and print output which did not happen
However db1.eval in evaluate phase , printing entire tensor X with out "message X:".
def combine_inputs(X):
db1=tf.Print(X,[X],message='X:')
return (tf.matmul(X, W) + b,db1)
<<training code>>
_,summary=sess.run([train_op,merged_summaries])
## merged_summaries tensor triggers combine_inputs function. There are
## other tensor functions/coding in between , not giving entire code to keep
## it simple; code works as expected except tf.Print
<<evaluate code>>
print(db1.eval())
Confused on following
a) Why tf.Print is not printing during sess.run during training?
b) Why explicit db1.eval is necessary , expected tf.Print to trigger with
sess.run. If eval is required , could copy tensor X in my code to db1
and evaluate it with out tf.Print. Correct?
Tried going through other questions (like below one). Suggested to implement memory_util or predefined function. As learner could not understand why tf.Print does not work in my scenario
If anyone encountered similar issues , please assist. Thanks!
Similar question in stackoverflow
According to the documentation, tf.Print prints to standard error (as of version 1.1), and it's not compatible with jupyter notebook. That's why you can't see any output.
Check here:
https://www.tensorflow.org/api_docs/python/tf/Print
You can check the terminal where you launched the jupyter notebook to see the message.
import tensorflow as tf
tf.InteractiveSession()
a = tf.constant(1)
b = tf.constant(2)
opt = a + b
opt = tf.Print(opt, [opt], message="1 + 2 = ")
opt.eval()
In the terminal, I can see:
2018-01-02 23:38:07.691808: I tensorflow/core/kernels/logging_ops.cc:79] 1 + 2 = [3]

How can I copy a variable in tensorflow

In numpy I can create a copy of the variable with numpy.copy. Is there a similar method, that I can use to create a copy of a Tensor in TensorFlow?
You asked how to copy a variable in the title, but how to copy a tensor in the question. Let's look at the different possible answers.
(1) You want to create a tensor that has the same value that is currently stored in a variable that we'll call var.
tensor = tf.identity(var)
But remember, 'tensor' is a graph node that will have that value when evaluated, and any time you evaluate it, it will grab the current value of var. You can play around with control flow ops such as with_dependencies() to see the ordering of updates to the variable and the timing of the identity.
(2) You want to create another variable and set its value to the value currently stored in a variable:
import tensorflow as tf
var = tf.Variable(0.9)
var2 = tf.Variable(0.0)
copy_first_variable = var2.assign(var)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
print sess.run(var2)
sess.run(copy_first_variable)
print sess.run(var2)
(3) You want to define a variable and set its starting value to the same thing you already initialized a variable to (this is what nivwu.. above answered):
var2 = tf.Variable(var.initialized_value())
var2 will get initialized when you call tf.initialize_all_variables. You can't use this to copy var after you've already initialized the graph and started running things.
You can do this in a couple of ways.
this will create you a copy: v2 = tf.Variable(v1)
you can also use identity op: v2 = tf.identity(v1) (which I think is a proper way of doing it.
Here is a code example:
import tensorflow as tf
v1 = tf.Variable([[1, 2], [3, 4]])
v_copy1 = tf.Variable(v1)
v_copy2 = tf.identity(v1)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
a, b = sess.run([v_copy1, v_copy2])
sess.close()
print a
print b
Both of them would print the same tensors.
This performs a deep copy
copied_variable = tf.Variable(source_variable.initialized_value())
It also handles intialization properly, i.e.
tf.intialize_all_variables()
will properly initialize source_variable first and then copy that value to copied_variable
In TF2 :
tf.identity() will do the good deed for you. Recently I encountered some problems using the function in google colab. In case that's why you're here, this will be helping you.
Error : Failed copying input tensor from /job:localhost/replica:0/task:0/device:CPU:0 to /job:localhost/replica:0/task:0/device:GPU:0 in order to run Identity: No unary variant device copy function found for direction: 1 and Variant type_index: tensorflow::data::(anonymous namespace)::DatasetVariantWrapper [Op:Identity]
#Erroneous code
tensor1 = tf.data.Dataset.from_tensor_slices([[[1], [2]], [[3], [4]]])
tensor2 = tf.identity(tensor1)
#Correction
tensor1 = tf.data.Dataset.from_tensor_slices([[[1], [2]], [[3], [4]]])
with tf.device('CPU'): tensor2 = tf.identity(tensor1)