I am trying to define a log loss function for a multi class classification problem as:
self.loss = tf.losses.log_loss(
labels=self.sampled_actions,
predictions= [self.probability[i][self.sampled_actions[i]] for i in range(tf.shape(self.sampled_actions)[0])],
weights=self.discounted_rewards)
Here, self.sampled_actions is a 1D tensor of 0/1/2 (e.g: [0,1,2,1,0,2]) which corresponds to which action is the ground truth. self.probability is defined as:
h = tf.layers.dense(
self.observations,
units=hidden_layer_size,
activation=tf.nn.relu,
kernel_initializer=tf.contrib.layers.xavier_initializer())
self.probability = tf.layers.dense(
h,
units=3,
activation=tf.sigmoid,
kernel_initializer=tf.contrib.layers.xavier_initializer())
As the probabilities of all three actions, 0,1,2 for any given observation in the input.
However, when I run this program, I get the error:
Traceback (most recent call last):
File "spaceinvaders.py", line 68, in <module>
hidden_layer_size, learning_rate, checkpoints_dir='checkpoints')
File "/home/elfarouk/Desktop/opengym/policy_network_space_invaders.py", line 49, in __init__
predictions= [self.probability[i][self.sampled_actions[i]] for i in range(tf.shape(self.sampled_actions)[0])],
TypeError: range() integer end argument expected, got Tensor.
Is there a way to specify that my prediction in the loss function should be dependent on the sampled_actions?
Related
I am working on a model that trains on simulation data, which should ideally be able to predict N timesteps forward from a given state in a simulation. I have attempted to model this by feeding the output of the model back into itself N times, where N is a hyperparameter of the model. I have done this in the call function of the tensorflow.keras.Model() class.
The relevant code:
def call(self, inputs):
x = inputs[0]
outputs = tf.TensorArray(
dtype=tf.float32, size=0, dynamic_size=True, infer_shape=False
)
window = inputs[1]
for i in tf.range(window):
x = self.model(x)
outputs = outputs.write(i, x)
outputs = tf.transpose(outputs.stack(), [1, 2, 3, 0, 4])
return outputs
This works, and the model trains, but i want to save the model using the tensorflow.keras.Model.save() function. Trying this leads to the following error:
Traceback (most recent call last):
File "/zhome/22/4/118839/Masters_Thesis/Model_files/Unet.py", line 562, in <module>
model_.save(savepath + "/saved_model/Model")
File "/zhome/22/4/118839/Masters_Thesis/Menv/lib/python3.9/site-packages/keras/utils/traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/appl/python/3.9.11/lib/python3.9/contextlib.py", line 126, in __exit__
next(self.gen)
File "/zhome/22/4/118839/Masters_Thesis/Model_files/Unet.py", line 485, in call
for i in tf.range(4):
tensorflow.python.framework.errors_impl.OperatorNotAllowedInGraphError: Iterating over a symbolic `tf.Tensor` is not allowed: AutoGraph did convert this function. This might indicate you are trying to use an unsupported feature.
Is there a better way of doing what I'm trying to do? Any other threads I have found recommend using the tf.map_fn() function, but this does not work for me due to the sequential nature of the model. Any help is appreciated!
This is a toy model I am trying to implement with tensorflow. The input is a set (10) of real number pairs. And the underlying function I want to approximate is . The implemented model should look like this:
I also need to mention that "Hidden Layer" is the same layer (same parameters) for all X_i.
What I implemented so far:
import tensorflow as tf
import numpy as np
def tf_model():
# Define the inputs
inputs = tf.keras.Input(shape=[10, 2])
# Define common hidden layer
hidden_layer = tf.keras.layers.Dense(64, activation="relu")(inputs)
# Propagate and average
outputs = tf.keras.layers.Dense(1, activation="sigmoid")(hidden_layer)
outputs = tf.keras.layers.Average()(outputs)
return tf.keras.Model(inputs=inputs, outputs=output)
X = np.random.rand(1000,10,2) * 100
y = 1 / (1 + X[...,0]**2 + X[...,1]**4)
y = np.average(y, axis=1)
model = tf_model()
model.fit(X, y)
What I get from running this:
Traceback (most recent call last):
File "model_test.py", line 21, in <module>
model = tf_model()
File "model_test.py", line 13, in tf_model
outputs = tf.keras.layers.Average()(outputs)
File "/home/redbull/.local/lib/python3.8/site-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/home/redbull/.local/lib/python3.8/site-packages/keras/layers/merge.py", line 88, in build
raise ValueError(
ValueError: A merge layer should be called on a list of inputs. Received: input_shape=(None, 10, 1) (not a list of shapes)
I think the issue is that tf.keras.layers.Average() only works with a list of inputs, but not a tf layer/ tensor.
Since tf.keras.layers.Average() does not seem to be suitable in this scenario, how can I implement the wished functionality?
You can use tf.reduce_mean as below.
outputs = tf.reduce_mean(outputs, axis=1)
Traceback (most recent call last):
File "c:/Users/levin/Desktop/programming/nn.py", line 208, in <module>
agent.train(BATCHSIZE)
File "c:/Users/levin/Desktop/programming/nn.py", line 147, in train
output = F.mse_loss(prediction, target)
File "C:\Users\levin\Anaconda3\lib\site-packages\torch\nn\functional.py", line 2203, in mse_loss
if not (target.size() == input.size()):
AttributeError: 'NoneType' object has no attribute 'size'
This above is the Error that I'm constantly getting and I really don't know how to fix it.
This some code that might be important
def train(self, BATCHSIZE):
trainsample = random.sample(self.memory, BATCHSIZE)
for state, action, reward, new_state, gameovertemp in trainsample:
if gameovertemp:
target = torch.tensor(reward).grad_fn
else:
target = reward + self.gamma * torch.max(self.dqn.forward(new_state))
self.dqn.zero_grad()
prediction = torch.max(self.dqn.forward(state))
#print(prediction, "prediction")
#print(target, "target")
output = F.mse_loss(prediction, target)
output.backward()
self.optimizer.step()
As stated in a comment the error due to either target of input to be None and is not related to the size() attribute.
The problem is probably at this line:
target = torch.tensor(reward).grad_fn
Here you convert reward to a new Tensor. However, a Tensor created by the user always has a grad_fn equal to None (as explained in Pytorch Autograd).
To have a grad_fn a Tensor must be the result of some computation, not a static value.
The thing is that mse_loss does not expect target to be differentiable, as the name suggest it is just the value to be compared.
Try to remove the grad_fn from this line the raw Tensor should be sufficient.
I am new to tensorflow, I have a class that describes my neural network and all the methods i need for the network. I have a specific method to feed a neuron value. I have declared the neuron initially as a placeholder, hoping to use get_neuron method to feed the value to neuron when available. When I am running , I am having a runtime error saying RuntimeError: The Session graph is empty. Add operations to the graph before calling run(). Can anyone help me how to solve it ? and what exactly it means ? I dont understand what exactly it means by add operations as I have been using feed_dict operation and running the session. Also does it bring any disadvantages if i run sessions for every computation to my tensor or should the session only be run at the end when having the final output. I am asking this because i am wondering whether this effects the effectiveness of tensorflow as it follows the graph to optimize while using optimizer.
def get_neuron(self, a, b):
#'while a being the name of the neuron and b being the value of that neuron'
with tf.Session() as sess_n:
sess_n.run(a, feed_dict={a: b})
return
EDIT:
this is how I am calling that above function i.e.
knowledge_out = knowledge.run(carollis_inp)
knowledge is a object created from class knowledge_transfer which has a method run, and the very first line of the function is
self.get_neuron(self.neuron_input, carollis_input)
The error displayed exactly is
[ERROR] [1566241992.292524, 15.300000]: bad callback: <function joint_callback at 0x7f42221982f0>
Traceback (most recent call last):
File "/opt/ros/melodic/lib/python2.7/dist-packages/rospy/topics.py", line 748, in _invoke_callback
cb(msg, cb_args)
File "/home/microbot/catkin_ws/src/spider/spider_control/control1.py", line 60, in joint_callback
knowledge_out = knowledge.run(carollis_inp)
File "/home/microbot/catkin_ws/src/spider/spider_control/knowledge_transfer.py", line 99, in run
self.get_neuron(self.neuron_input, carollis_input)
File "/home/microbot/catkin_ws/src/spider/spider_control/knowledge_transfer.py", line 81, in get_neuron
sess_n.run(a, feed_dict={a: b})
File "/home/microbot/.local/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 950, in run
run_metadata_ptr)
File "/home/microbot/.local/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1098, in _run
raise RuntimeError('The Session graph is empty. Add operations to the '
RuntimeError: The Session graph is empty. Add operations to the graph before calling run().
EDIT2:
I have a neural network with name knowledge_transfer, it takes 8 inputs and gives four outputs which are then soft maxed , kind of like multi-classification problem. There is this class method run which accepts the input array of size 8 and then returns the output array of size four. Inside the run method it feeds the given input arguments to input placeholder of a size 8 and then does some processing through the layers and weights and finally gives the output.
example:
I want to create a class member method which takes two inputs and feed_dict first second input argument to the first argument considering the first argument is a placeholder and both the arguments are of same size.
Edit3:
I am feeding an input to the input layer, and then using an input function to calculate the output of input layer, later feeding it to input function of hidden layer and then using the output of input function to hidden layer to pass through leaky_rectified linear output , the output of which is then passed to input function of output layer folowed by passing the output of it through softmax function and giving that softmax output as an output of NN.
The code is as follows:
self.neuron_input = tf.compat.v1.placeholder(tf.float32, shape=(self.neurons, 1))
self.weight_in = tf.get_variable(name="Weight_input", dtype=tf.float32, shape=[self.neurons, 1], initializer=self.weight_initer)
self.neuron_hid = tf.compat.v1.placeholder(tf.float32, shape=(int(self.neurons/2), 1))
self.weight_initer1 = tf.truncated_normal_initializer(mean=1.0, stddev=0.01)
self.weight_hid = tf.get_variable(name="Weight_hidden", dtype=tf.float32, shape=[self.neurons, 1], initializer=self.weight_initer1)
self.neuron_out = tf.compat.v1.placeholder(tf.float32, shape=(4, 1))
self.weight_initer2 = tf.truncated_normal_initializer(mean=2.0, stddev=0.01)
self.weight_out = tf.get_variable(name="Weight_output", dtype=tf.float32, shape=[4, 2], initializer=self.weight_initer2)
self.bias_initer =tf.truncated_normal_initializer(mean=0-1, stddev=0.01)
self.bias_in =tf.get_variable(name="Bias_input", dtype=tf.float32, shape=[self.neurons, 1], initializer=self.bias_initer)
self.bias_initer1 =tf.truncated_normal_initializer(mean=0-2, stddev=0.01)
self.bias_hid = tf.get_variable(name="Bias_hidden", dtype=tf.float32, shape=[self.neurons, 1], initializer=self.bias_initer1)
self.bias_initer2 =tf.truncated_normal_initializer(mean=0-3, stddev=0.01)
self.bias_out = tf.get_variable(name="Bias_output", dtype=tf.float32, shape=[4, 1], initializer=self.bias_initer2)
and then the run() function is as follows:
def run(self, carollis_input):
self.normalization(carollis_input)
#'finding the output of the input layer'
knowledge_input = tf.add(tf.multiply(self.neuron_input, self.weight_in), self.bias_in)
#'calculating the input for the hidden layer'
knowledge_hidden = tf.add(tf.multiply(knowledge_input, self.weight_in), self.bias_hid)
#'calculating the output of hidden layer'
knowledge_hidden_output = 3.14*(tf.add(tf.multiply(knowledge_hidden, self.weight_hid), self.bias_hid))#input function of hidden layer
knowledge_hidden_out = tf.nn.leaky_relu(self.neuron_hid, alpha=0.01, name='leaky_relu')
with tf.Session() as sess1_2:
sess1_2.run(knowledge_hidden_out, feed_dict={self.neuron_input: carollis_input, self.neuron_hid: knowledge_hidden_output})
#'calculating the input of output layer'
tf.reshape(knowledge_hidden_out, [4, 2])#for quadrant method
in_out = tf.add(tf.multiply(knowledge_hidden_out, self.weight_out), self.bias_out)
with tf.Session as s:
s.run(in_out)
#'finding the softmax output of the neurons'
softmax_output = np.array(4)
softmax_output = self.out_softmax(in_out) # this gives the softmax output and stores it in the newly created array
return softmax_output
The error is as follows :
sess1_2.run(knowledge_hidden_out, feed_dict={self.neuron_input: carollis_input, self.neuron_hid: knowledge_hidden_output})
File "/home/microbot/.local/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 950, in run
run_metadata_ptr)
File "/home/microbot/.local/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1098, in _run
raise RuntimeError('The Session graph is empty. Add operations to the '
RuntimeError: The Session graph is empty. Add operations to the graph before calling run().
I am trying to implement a custom loss function in Keras with TF backend based on the Laplacian of two images.
def blur_loss(y_true, y_pred):
#weighting of blur loss
alpha = 1
mae = losses.mean_absolute_error(y_true, y_pred)
lapKernel = K.constant([0, 1, 0, 1, -4, 1, 0, 1, 0],shape = [3, 3])
trueLap = K.conv2d(y_true, lapKernel)
predLap = K.conv2d(y_pred, lapKernel)
trueBlur = K.var(trueLap)
predBlur = K.var(predLap)
blurLoss = alpha * K.abs(trueBlur - predBlur)
loss = (1-alpha) * mae + alpha * blurLoss
return loss
When I try to compile the model I get this error
Traceback (most recent call last):
File "kitti_train.py", line 65, in <module>
model.compile(loss='mean_absolute_error', optimizer='adam', metrics=[blur_loss])
File "/home/ubuntu/.virtualenvs/dl4cv/lib/python3.5/site-packages/keras/engine/training.py", line 924, in compile
handle_metrics(output_metrics)
File "/home/ubuntu/.virtualenvs/dl4cv/lib/python3.5/site-packages/keras/engine/training.py", line 921, in handle_metrics
mask=masks[i])
File "/home/ubuntu/.virtualenvs/dl4cv/lib/python3.5/site-packages/keras/engine/training.py", line 450, in weighted
score_array = fn(y_true, y_pred)
File "/home/ubuntu/prednet/blur_loss.py", line 14, in blur_loss
trueLap = K.conv2d(y_true, lapKernel)
File "/home/ubuntu/.virtualenvs/dl4cv/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py", line 3164, in conv2d
data_format='NHWC')
File "/home/ubuntu/.virtualenvs/dl4cv/lib/python3.5/site-packages/tensorflow/python/ops/nn_ops.py", line 655, in convolution
num_spatial_dims, strides, dilation_rate)
File "/home/ubuntu/.virtualenvs/dl4cv/lib/python3.5/site-packages/tensorflow/python/ops/nn_ops.py", line 483, in _get_strides_and_dilation_rate
(len(dilation_rate), num_spatial_dims))
ValueError: len(dilation_rate)=2 but should be 0
After reading other questions, my understanding is that this problem stems from the compilation using placeholder tensors for y_true and y_pred. I've tried checking if the inputs are placeholders and replacing them with zero tensors, but this gives me other errors.
How do I use a convolution (the image processing function, not a layer) in my loss function without getting these errors?
The problem here was a misunderstanding of the conv2d function which is not simply a 2-dimensional convolution. It is a batched 2-d convolution of multiple channels. So while you might expect a *2d function to accept 2-dimensional tensors, the input should actually 4 dimensions (batch_size, height, width, channels) and the filter should also be 4 dimensions (filter_height, filter_width, input_channels, output_channels). Details can be found in the TF docs