Tensorflow HammingLoss gives ValueError with keras.utils.Sequence - python-3.x

I am working on a multi-label image classification problem with 13 labels. I want to use Hamming Loss to evaluate the performance of the model. So I specified tfa.metrics.HammingLoss(mode = 'multilabel') in the metrics parameter during model compilation. This worked when I provided both X_train and y_train to model.fit(), but it threw a ValueError when I used a Sequence object (described below) for training.
Data Generator description
I used a keras.utils.Sequence input object similar to what is present here. The generator returns 2 numpy arrays for each batch - the first array consists of the input images of shape (128, 128, 3) and the second array consists of labels each of shape (13,).
This is what my code looks like:
model.compile(
loss='binary_crossentropy',
optimizer='rmsprop',
metrics=[tfa.metrics.HammingLoss(mode = 'multilabel')]
)
model.fit(
train_datagen,
epochs = 5,
batch_size = BATCH_SIZE,
steps_per_epoch = TOTAL // BATCH_SIZE
)
And this is the error that I obtained:
Epoch 1/5
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-140-978987a2bbaa> in <module>
3 epochs=5,
4 batch_size=BATCH_SIZE,
----> 5 steps_per_epoch = 2000 // BATCH_SIZE
6 # validation_data=validation_generator,
7 )
4 frames
/usr/local/lib/python3.7/dist-packages/tensorflow_addons/metrics/hamming.py in else_body_2()
64 try:
65 do_return = True
---> 66 retval_ = (ag__.ld(nonzero) / ag__.converted_call(ag__.ld(y_true).get_shape, (), None, fscope)[(- 1)])
67 except:
68 do_return = False
ValueError: in user code:
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1051, in train_function *
return step_function(self, iterator)
File "/usr/local/lib/python3.7/dist-packages/tensorflow_addons/metrics/utils.py", line 66, in update_state *
matches = self._fn(y_true, y_pred, **self._fn_kwargs)
File "/usr/local/lib/python3.7/dist-packages/tensorflow_addons/metrics/hamming.py", line 133, in hamming_loss_fn *
return nonzero / y_true.get_shape()[-1]
ValueError: None values not supported.
How do I correct this? Is there any issue with the format of the labels?

Related

Unexpected ValueError after training Keras NN a few times

I am working on time series prediction using RNNs implemented in Keras on Google Colaboratory. I implemented the RNN as follows:
from tensorflow import keras
mae = keras.losses.MeanAbsoluteError()
hidden_neurons = 50
output_neurons = 1
epoch_size = 50
batch_size = 72
# x_train has shape (500, 1, 23)
LSTM_layer = keras.layers.LSTM(hidden_neurons, input_shape = (x_train.shape[1], x_train.shape[2]), dropout = 0.05)
output_layer = keras.layers.Dense(1)
test_model = keras.Sequential(layers = (LSTM_layer, output_layer))
test_model.reset_states()
test_model.compile(optimizer = 'adam', loss = mae)
test_model.summary()
history = test_model.fit(tf.expand_dims(x_train, axis=-1), y_train, epochs = epoch_size, batch_size = batch_size, validation_data=(x_test, y_test), shuffle = False)
# y_train has shape (500, 1)
# x_test has shape (500, 1, 23)
# y_test has shape (500, 1)
I have the above code (except the import) in a single code cell. When I start a fresh runtime, the network trains fine as expected. But after executing the code cell for around 3-4 times, Colab throws the following error:
ValueError Traceback (most recent call last)
<ipython-input-23-3ac5cc808611> in <module>
12 test_model.compile(optimizer = 'adam', loss = mae)
13 test_model.summary()
---> 14 history = test_model.fit(tf.expand_dims(x_train, axis=-1), y_train, epochs = epoch_size, batch_size = batch_size, validation_data=(x_test, y_test), shuffle = False)
...
/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in autograph_handler(*args, **kwargs)
1145 except Exception as e: # pylint:disable=broad-except
1146 if hasattr(e, "ag_error_metadata"):
-> 1147 raise e.ag_error_metadata.to_exception(e)
1148 else:
1149 raise
ValueError: Input 0 of layer "sequential_2" is incompatible with the layer: expected shape=(None, 1, 23), found shape=(None, 23)
The error persists if tf.expand_dims(x_train, axis=-1)) is omitted in test_model.fit() while fitting the Sequential model.
I guess this has something to do with the layer inputs somehow being changed during execution. I have tried using test_model.reset_states() and running
keras.backend.clear_session()
del test_model
in a separate code cell, but only forcibly killing the Colab runtime seems to work:
import os
os.kill(os.getpid(), 9)
What could cause the layer inputs to change midway during program run?
EDIT: I got the same error when I tried running the cells on Jupyter Notebook on my PC rather than on Colab.

Convert tflearn to keras

Since tflearn is outdated and I am watching a chatbot tutorial that uses tflearn, I want to write the neural network model in keras. However, I got this error right here:
WARNING:tensorflow:Model was constructed with shape (None, 58) for input KerasTensor(type_spec=TensorSpec(shape=(None, 58), dtype=tf.float32, name='input_22'), name='input_22', description="created by layer 'input_22'"), but it was called on an input with incompatible shape (None,).
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-164-1a494613d0d2> in <module>()
1 convert_input("Hello")
----> 2 chat()
2 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in autograph_handler(*args, **kwargs)
1145 except Exception as e: # pylint:disable=broad-except
1146 if hasattr(e, "ag_error_metadata"):
-> 1147 raise e.ag_error_metadata.to_exception(e)
1148 else:
1149 raise
ValueError: in user code:
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1801, in predict_function *
return step_function(self, iterator)
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1790, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1783, in run_step **
outputs = model.predict_step(data)
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1751, in predict_step
return self(x, training=False)
File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/usr/local/lib/python3.7/dist-packages/keras/engine/input_spec.py", line 228, in assert_input_compatibility
raise ValueError(f'Input {input_index} of layer "{layer_name}" '
ValueError: Exception encountered when calling layer "sequential_24" (type Sequential).
Input 0 of layer "dense_59" is incompatible with the layer: expected min_ndim=2, found ndim=1. Full shape received: (None,)
Call arguments received:
• inputs=('tf.Tensor(shape=(None,), dtype=int64)',)
• training=False
• mask=None
I have tried to set up the keras model myself
model = keras.Sequential()
# model.add(keras.layers.InputLayer(input_shape = len(words)))
model.add(keras.Input(shape=len(training[0])))
model.add(keras.layers.Dense(8, activation = "relu"))
model.add(keras.layers.Dense(8, activation = "relu"))
model.add(keras.layers.Dense(len(output[0]), activation= "softmax"))
model.compile(optimizer = "adam", loss = "categorical_crossentropy", metrics=['accuracy'])
# convert_input(inp) -> return a 1D numpy array filled with 1 and 0
prediction = model.predict([convert_input(inp)])
versus the tflearn model
network = tflearn.input_data(shape=[None, len(training[0])])
network = tflearn.fully_connected(network, 8)
network = tflearn.fully_connected(network, 8)
network = tflearn.fully_connected(network, len(output[0]), activation = "softmax")
network = tflearn.regression(network)
model = tflearn.DNN(network)
model.fit(training, output, n_epoch = 1000, batch_size=8, show_metric=True)
# convert_input(inp) -> return a 1D numpy array filled with 1 and 0
prediction = model.predict([convert_input(inp)])
However, when I call model.predict only the tflearn model works and not the keras. Please help!
I was in a similar predicament. However I was finally able to resolve my problem with the following code:
import numpy as np
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
model=Sequential()
model.add(Dense(8,input_shape=(len(train_x[0]),),kernel_initializer='normal'))
model.add(Dense(8,kernel_initializer='normal'))
model.add(Dense(len(train_y[0]),activation='softmax',kernel_initializer='normal'))
model.compile(optimizer='adam', loss='mean_squared_error', metrics=['accuracy'])
model.fit(np.array(train_x),np.array(train_y), epochs=1000, batch_size=8, verbose=1)
During prediction,
model.predict(np.array([p]))
Basically converting the list into an array using np.array() helped me solve the problem.

Reshape layer after a dense layer in Keras

I am trying to understand why there is a mismatch dimensionality between a Dense Layer and a Reshape Layer. Shouldn't this snippet code be correct? The dimensionality of the Dense Layer output will be image_resize^2 * 128, why is there a conflict in the reshape?
input_shape = (28,28,1)
inputs = Input(shape=input_shape)
image_size = 28
image_resize = image_size // 4
x = Dense(image_resize * image_resize * 128)(inputs)
x = Reshape((image_resize, image_resize, 128))(x)
This is the error that shows up:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/venv/lib/python3.7/site-packages/keras/engine/base_layer.py", line 474, in __call__
output_shape = self.compute_output_shape(input_shape)
File "/Users/venv/lib/python3.7/site-packages/keras/layers/core.py", line 398, in compute_output_shape
input_shape[1:], self.target_shape)
File "/Users/venv/lib/python3.7/site-packages/keras/layers/core.py", line 386, in _fix_unknown_dimension
raise ValueError(msg)
ValueError: total size of new array must be unchanged
Dense layers act on the last dimension of the input data, if you want to give image input to a Dense layer, you should first flatten it:
x = Flatten()(x)
x = Dense(image_resize * image_resize * 128)(x)
x = Reshape((image_resize, image_resize, 128))(x)
Then the Reshape will work.
Your input is 784 and enters Dense layer with 7*7*128
So you will have and output of 784*7*7*128 in Reshape, not 7*7*128

Input Dimensions Tensorflow v1.8 ConvLSTMCell

ConvLSTMCell Official Docs
GitHub _conv where the error occurs
Issue
I'm experimenting with the ConvLSTMCell in tensorflow r1.8. The error I'm continuing to generate occurs in the __call__ method of ConvLSTMCell. The _conv method is invoked and the error is raised.
ValueError: Conv Linear Expects 3D, 4D, 5D
The error is raised from the unstacked inputs. unstacked (in this example) has dimensions of [BATCH_SIZE, N_INPUTS] = [2,5]. I am using tf.unstack to generate the required sequence that the ConvLSTMCell requires.
Why use tf.unstack?
If the input array is not unstacked, the TypeError below is raised.
TypeError: inputs must be a sequence
Question
What am I missing on the formatting? I've read through related issues but have not found anything that has guided me into a working implementation.
Are the placeholder dimensions correct?
Should I be unstacking or is there a better way?
Am I providing the proper input dimension into the ConvLSTMCell?
Code
# Parameters
TIME_STEPS = 28
N_INPUT = 5
N_HIDDEN = 128
LEARNING_RATE = 0.001
NUM_UNITS = 28
CHANNEL = 1
tf.reset_default_graph()
# Input placeholders
x = tf.placeholder(tf.float32, [BATCH_SIZE, TIME_STEPS, N_INPUT])
y = tf.placeholder(tf.float32, [None, 1])
# Format input as a sequence for LSTM Input
unstacked = tf.unstack(x, TIME_STEPS, 1) # shape=(timesteps, batch, inputs)
# Convolutional LSTM Layer
lstm_layer = tf.contrib.rnn.ConvLSTMCell(
conv_ndims=1,
input_shape=[BATCH_SIZE, N_INPUT],
output_channels=5,
kernel_shape=[7,5]
)
# Error is generated when the lstm_layer is invoked
outputs, _ = tf.contrib.rnn.static_rnn(
lstm_layer,
unstacked,
dtype=tf.float32)
Error Message
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-83-3568a097e4ea> in <module>()
10 lstm_layer,
11 unstacked,
---> 12 dtype=tf.float32)
~/miniconda3/envs/MultivariateTimeSeries/lib/python3.6/site-packages/tensorflow/python/ops/rnn.py in static_rnn(cell, inputs, initial_state, dtype, sequence_length, scope)
1322 state_size=cell.state_size)
1323 else:
-> 1324 (output, state) = call_cell()
1325
1326 outputs.append(output)
~/miniconda3/envs/MultivariateTimeSeries/lib/python3.6/site-packages/tensorflow/python/ops/rnn.py in <lambda>()
1309 varscope.reuse_variables()
1310 # pylint: disable=cell-var-from-loop
-> 1311 call_cell = lambda: cell(input_, state)
1312 # pylint: enable=cell-var-from-loop
1313 if sequence_length is not None:
~/miniconda3/envs/MultivariateTimeSeries/lib/python3.6/site-packages/tensorflow/python/ops/rnn_cell_impl.py in __call__(self, inputs, state, scope)
230 setattr(self, scope_attrname, scope)
231 with scope:
--> 232 return super(RNNCell, self).__call__(inputs, state)
233
234 def _rnn_get_variable(self, getter, *args, **kwargs):
~/miniconda3/envs/MultivariateTimeSeries/lib/python3.6/site-packages/tensorflow/python/layers/base.py in __call__(self, inputs, *args, **kwargs)
715
716 if not in_deferred_mode:
--> 717 outputs = self.call(inputs, *args, **kwargs)
718 if outputs is None:
719 raise ValueError('A layer\'s `call` method should return a Tensor '
~/miniconda3/envs/MultivariateTimeSeries/lib/python3.6/site-packages/tensorflow/contrib/rnn/python/ops/rnn_cell.py in call(self, inputs, state, scope)
2110 cell, hidden = state
2111 new_hidden = _conv([inputs, hidden], self._kernel_shape,
-> 2112 4 * self._output_channels, self._use_bias)
2113 gates = array_ops.split(
2114 value=new_hidden, num_or_size_splits=4, axis=self._conv_ndims + 1)
~/miniconda3/envs/MultivariateTimeSeries/lib/python3.6/site-packages/tensorflow/contrib/rnn/python/ops/rnn_cell.py in _conv(args, filter_size, num_features, bias, bias_start)
2184 if len(shape) not in [3, 4, 5]:
2185 raise ValueError("Conv Linear expects 3D, 4D "
-> 2186 "or 5D arguments: %s" % str(shapes))
2187 if len(shape) != len(shapes[0]):
2188 raise ValueError("Conv Linear expects all args "
ValueError: Conv Linear expects 3D, 4D or 5D arguments: [[2, 5], [2, 2, 5]]
Here's an example with a couple tweaks, which at least passes static shape checking:
import tensorflow as tf
# Parameters
TIME_STEPS = 28
N_INPUT = 5
N_HIDDEN = 128
LEARNING_RATE = 0.001
NUM_UNITS = 28
CHANNEL = 1
BATCH_SIZE = 16
# Input placeholders
x = tf.placeholder(tf.float32, [BATCH_SIZE, TIME_STEPS, N_INPUT])
y = tf.placeholder(tf.float32, [None, 1])
# Format input as a sequence for LSTM Input
unstacked = tf.unstack(x[..., None], TIME_STEPS, 1) # shape=(timesteps, batch, inputs)
# Convolutional LSTM Layer
lstm_layer = tf.contrib.rnn.ConvLSTMCell(
conv_ndims=1,
input_shape=[N_INPUT, 1],
output_channels=5,
kernel_shape=[7]
)
# Error is generated when the lstm_layer is invoked
outputs, _ = tf.contrib.rnn.static_rnn(
lstm_layer,
unstacked,
dtype=tf.float32)
Notes:
input_shape does not include the batch dimension (see docstring)
The input needs a channels dimension. Fine for it to be one in the input (that's what I've done).
Not sure what more than one dimension on kernel_shape would mean for a 1-D convolution.

keras multi dimensions input to simpleRNN: dimension mismatch

The input element has 3 rows each having 199 columns and the output has 46 rows and 1 column
Input.shape, output.shape
((204563, 3, 199), (204563, 46, 1))
When the input is given the following error is thrown:
from keras.layers import Dense
from keras.models import Sequential
from keras.layers.recurrent import SimpleRNN
model = Sequential()
model.add(SimpleRNN(100, input_shape = (Input.shape[1], Input.shape[2])))
model.add(Dense(output.shape[1], activation = 'softmax'))
model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
model.fit(Input, output, epochs = 20, batch_size = 200)
error thrown:
Epoch 1/20
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-134-378dd431cf45> in <module>()
3 model.add(Dense(y_target.shape[1], activation = 'softmax'))
4 model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
----> 5 model.fit(X_input, y_target, epochs = 20, batch_size = 200)
.
.
.
ValueError: Error when checking model target: expected dense_6 to have 2 dimensions, but got array with shape (204563, 46, 1)
Please explain the reason for the problem and possible soution
The problem is that SimpleRNN(100) returns a tensor of shape (204563, 100), hence, the Dense(46) (since output.shape[1]=46) will return a tensor of shape (204563, 46), but your y_target have shape (204563, 46, 1). You need to remove the last dimension with, for example, y_target = np.squeeze(y_target), so that the dimension are consistent

Resources