Error converting shape to a TensorShape: Dimension value must be integer or None or have an __index__ method, got value '

Viewed 3311

I am coding a simple Convolutional Network for a regression using RGB images but i am having a problem with the input shape. The shape is (8,96,96,3) but the error tells me that it's not an integer which is normal because it's a tuple. I have a relatively small dataset. This is the code and the bug.

The Code:


import kerastuner
from keras.models import load_model
from kerastuner.tuners import RandomSearch
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Activation
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import Adam
from imutils import paths
import numpy as np
import argparse
import cv2
import os
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from tensorflow.keras.models import Sequential
from keras.utils.vis_utils import plot_model
from keras.layers import Input
from keras.models import Model
from tensorflow import keras
from google.colab.patches import cv2_imshow
from google.colab import drive
drive.mount('/content/drive')

LABELS = set(["56", "76", "72", "110"])

print("[INFO] loading images...")
imagePaths = list(paths.list_images('/content/drive/My Drive/train'))
data = []
labels = []

for imagePath in imagePaths:
    label = imagePath.split(os.path.sep)[-2]

    if label not in LABELS:
        continue
    # load the image and resize it to be a fixed 96x96 pixels,
    # ignoring aspect ratio
    image = cv2.imread(imagePath)
    image = cv2.resize(image, (96, 96))
    # update the data and labels lists, respectively
    data.append(image)
    labels.append(label)
labels=list(set(labels))


data = np.array(data, dtype="float") / 250
labels = np.array(labels, dtype="int") 

(X, Y) = (data, labels)

LABELS = set(["59"])

imagePaths = list(paths.list_images('/content/drive/My Drive/test'))
data = []
labels = []

for imagePath in imagePaths:
    label = imagePath.split(os.path.sep)[-2]

    if label not in LABELS:
        continue
    image = cv2.imread(imagePath)
    image = cv2.resize(image, (96, 96))
    data.append(image)
    labels.append(label)

labels=list(set(labels))

data = np.array(data, dtype="float") / 250
labels = np.array(labels, dtype="int") 

(Z,T) =(data,labels)

import numpy as np
from sklearn.preprocessing import StandardScaler


aug = ImageDataGenerator(rotation_range=20, zoom_range=0.15,
    width_shift_range=0.2, height_shift_range=0.2, shear_range=0.15,
    horizontal_flip=True, fill_mode="nearest")

import tensorflow as tf
X.reshape(8,96,96,3)
input_shape =Input(batch_shape=[8,96,96,3])
Z.reshape(2,96,96,3)
X=np.array(X, dtype="int")
Z=np.array(Z, dtype="int")
def create_model(hp):
 model = Sequential()

 model.add(keras.layers.Conv2D(hp.Int('a',32,256,step=1), (3,3), input_shape=input_shape,activation='relu'))
 
 model.add(MaxPooling2D(pool_size=(2, 2)))

 
 model.add(keras.layers.Conv2D(hp.Int('c',32,256,step=1), (3,3), activation='relu'))
 model.add(MaxPooling2D(pool_size=(2, 2)))

 model.add(keras.layers.Conv2D(hp.Int('w',32,256,step=1), (3,3), activation='relu'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Flatten())
 opt = Adam(lr=1e-3, decay=1e-3 / 200)
 model.compile(loss="mean_absolute_percentage_error", optimizer=opt)

 model.fit(x=aug.flow(X, Y, batch_size=5),validation_data=(Z, T), steps_per_epoch=5, epochs=hp.Int('n',30,31,step=1))

 return model

np.set_printoptions(precision=2,suppress=True)
my_dir ='/content/drive/My Drive/'
tuner= RandomSearch(create_model,objective= 'val_loss',  max_trials =1, executions_per_trial = 1, directory = 'my_dir' )

tuner.search(x=X, y=Y,epochs=30,batch_size=5,validation_data=(Z, T))

create_model(tuner.get_best_hyperparameters()[0]).save('model1.h5')

model1=keras.models.load_model('model1.h5')
for i in range(len(Z)):
    print("Prediction: " + str(model1.predict(Z[i] )) + " | True: " + str(T[i]))

scores=model1.evaluate(Z,T,batch_size=5)
print(scores)
tf.keras.utils.plot_model(model1, to_file='model_plot.png', show_shapes=True, show_layer_names=True)
print(tuner.get_best_hyperparameters()[0].values)

The Error:

  File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/execute.py", line 213, in make_shape
    raise TypeError("Error converting %s to a TensorShape: %s." % (arg_name, e))
TypeError: Error converting shape to a TensorShape: Dimension value must be integer or None or have an __index__ method, got value '<tf.Tensor 'strided_slice_40:0' shape=(96, 96, 3) dtype=float32>' with type '<class 'tensorflow.python.framework.ops.Tensor'>'.
[Warning] Invalid model 5/5
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/execute.py in make_shape(v, arg_name)
    210   try:
--> 211     shape = tensor_shape.as_shape(v)
    212   except TypeError as e:

22 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/tensor_shape.py in as_shape(shape)
   1234   else:
-> 1235     return TensorShape(shape)
   1236 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/tensor_shape.py in __init__(self, dims)
    755     if isinstance(dims, (tuple, list)):  # Most common case.
--> 756       self._dims = [Dimension(d) for d in dims]
    757     elif dims is None:

/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/tensor_shape.py in <listcomp>(.0)
    755     if isinstance(dims, (tuple, list)):  # Most common case.
--> 756       self._dims = [Dimension(d) for d in dims]
    757     elif dims is None:

/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/tensor_shape.py in __init__(self, value)
    203                       "an __index__ method, got value '{0!r}' with type '{1!r}'"
--> 204                       .format(value, type(value))), None)
    205       if self._value < 0:

/usr/local/lib/python3.6/dist-packages/six.py in raise_from(value, from_value)

TypeError: Dimension value must be integer or None or have an __index__ method, got value '<tf.Tensor 'strided_slice_40:0' shape=(96, 96, 3) dtype=float32>' with type '<class 'tensorflow.python.framework.ops.Tensor'>'

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/kerastuner/engine/hypermodel.py in build(self, hp)
    104                 with maybe_distribute(self.distribution_strategy):
--> 105                     model = self.hypermodel.build(hp)
    106             except:

<ipython-input-16-7d8b77f7488e> in create_model(hp)
    114 
--> 115  model.add(keras.layers.Conv2D(hp.Int('a',32,256,step=1), (3,3), input_shape=input_shape,activation='relu'))
    116 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/training/tracking/base.py in _method_wrapper(self, *args, **kwargs)
    456     try:
--> 457       result = method(self, *args, **kwargs)
    458     finally:

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/sequential.py in add(self, layer)
    201           x = input_layer.Input(
--> 202               batch_shape=batch_shape, dtype=dtype, name=layer.name + '_input')
    203           # This will build the current layer

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/input_layer.py in Input(shape, batch_size, name, dtype, sparse, tensor, ragged, **kwargs)
    310         {'batch_size': batch_size, 'input_shape': shape})
--> 311   input_layer = InputLayer(**input_layer_config)
    312 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/input_layer.py in __init__(self, input_shape, batch_size, dtype, input_tensor, sparse, name, ragged, **kwargs)
    159             sparse=sparse,
--> 160             ragged=ragged)
    161 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py in placeholder(shape, ndim, dtype, sparse, name, ragged)
   1222       else:
-> 1223         x = array_ops.placeholder(dtype, shape=shape, name=name)
   1224 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/array_ops.py in placeholder(dtype, shape, name)
   3099 
-> 3100   return gen_array_ops.placeholder(dtype=dtype, shape=shape, name=name)
   3101 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/gen_array_ops.py in placeholder(dtype, shape, name)
   6806     shape = None
-> 6807   shape = _execute.make_shape(shape, "shape")
   6808   _, _, _op, _outputs = _op_def_library._apply_op_helper(

/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/execute.py in make_shape(v, arg_name)
    212   except TypeError as e:
--> 213     raise TypeError("Error converting %s to a TensorShape: %s." % (arg_name, e))
    214   except ValueError as e:

TypeError: Error converting shape to a TensorShape: Dimension value must be integer or None or have an __index__ method, got value '<tf.Tensor 'strided_slice_40:0' shape=(96, 96, 3) dtype=float32>' with type '<class 'tensorflow.python.framework.ops.Tensor'>'.

During handling of the above exception, another exception occurred:

RuntimeError                              Traceback (most recent call last)
<ipython-input-16-7d8b77f7488e> in <module>()
    133 np.set_printoptions(precision=2,suppress=True)
    134 my_dir ='/content/drive/My Drive/'
--> 135 tuner= RandomSearch(create_model,objective= 'val_loss',  max_trials =1, executions_per_trial = 1, directory = 'my_dir' )
    136 
    137 tuner.search(x=X, y=Y,epochs=30,batch_size=5,validation_data=(Z, T))

/usr/local/lib/python3.6/dist-packages/kerastuner/tuners/randomsearch.py in __init__(self, hypermodel, objective, max_trials, seed, hyperparameters, tune_new_entries, allow_new_entries, **kwargs)
    173             oracle,
    174             hypermodel,
--> 175             **kwargs)

/usr/local/lib/python3.6/dist-packages/kerastuner/engine/multi_execution_tuner.py in __init__(self, oracle, hypermodel, executions_per_trial, **kwargs)
     56                  **kwargs):
     57         super(MultiExecutionTuner, self).__init__(
---> 58             oracle, hypermodel, **kwargs)
     59         if isinstance(oracle.objective, list):
     60             raise ValueError(

/usr/local/lib/python3.6/dist-packages/kerastuner/engine/tuner.py in __init__(self, oracle, hypermodel, max_model_size, optimizer, loss, metrics, distribution_strategy, directory, project_name, logger, tuner_id, overwrite)
    101                                     project_name=project_name,
    102                                     logger=logger,
--> 103                                     overwrite=overwrite)
    104 
    105         self.distribution_strategy = distribution_strategy

/usr/local/lib/python3.6/dist-packages/kerastuner/engine/base_tuner.py in __init__(self, oracle, hypermodel, directory, project_name, logger, overwrite)
     89         self._display = tuner_utils.Display()
     90 
---> 91         self._populate_initial_space()
     92 
     93         if not overwrite and tf.io.gfile.exists(self._get_tuner_fname()):

/usr/local/lib/python3.6/dist-packages/kerastuner/engine/base_tuner.py in _populate_initial_space(self)
    104         """
    105         hp = self.oracle.get_space()
--> 106         self.hypermodel.build(hp)
    107         self.oracle.update_space(hp)
    108 

/usr/local/lib/python3.6/dist-packages/kerastuner/engine/hypermodel.py in _build_wrapper(self, hp, *args, **kwargs)
     63             # to the search space.
     64             hp = hp.copy()
---> 65         return self._build(hp, *args, **kwargs)
     66 
     67 

/usr/local/lib/python3.6/dist-packages/kerastuner/engine/hypermodel.py in build(self, hp)
    113                 if i == self._max_fail_streak:
    114                     raise RuntimeError(
--> 115                         'Too many failed attempts to build model.')
    116                 continue
    117 

RuntimeError: Too many failed attempts to build model.
1 Answers

You assign to input shape a tf.layer.Input() object, not a tuple.

input_shape = Input(batch_shape=[8,96,96,3])

You can fix this by instead doing the following, which gets the shape of the first input of the Input layer:

input_shape = Input(batch_shape=[8, 96, 96, 3]).input_shape()[0]

Of course, since you know your shape I think you could specify input_shape=(96, 96, 3). You omit the first dimension because batch size is inferred. See this TF tutorial for an example.

Related