AttributeError: 'TensorSliceDataset' object has no attribute 'get_shape' - python

I'm trying to load images into a model using datasets. However, I keep getting an error that my tensor slices don't have the get_shape() attribute. I have confirmed that they don't by trying to call it within my code. What am I doing wrong?
I'm using:
Spyder 4.1.5 on Anaconda |
Keras 2.3.1 |
Tensorflow 2.1.0
# load dataset
dataset = h5py.File('3dshapes.h5', 'r')
print(dataset.keys())
images = dataset['images'] # array shape [480000,64,64,3], uint8 in range(256)
labels = dataset['labels'] # array shape [480000,6], float64
train_dataset = tf.data.Dataset.from_tensor_slices((images[1:10], labels[1:10]))
test_dataset = tf.data.Dataset.from_tensor_slices((images[10:20], labels[10:20]))
print("train_dataset", train_dataset)
print("test_dataset", test_dataset)
train_dataset <TensorSliceDataset shapes: ((64, 64, 3), (6,)), types:
(tf.uint8, tf.float64)>
test_dataset <TensorSliceDataset shapes: ((64, 64, 3), (6,)), types: (tf.uint8, tf.float64)>
File "C:\Users\Administration
User.conda\envs\Keras\lib\site-packages\tensorflow_core\python\keras\layers\convolutional.py",
line 192, in call
call_input_shape = inputs.get_shape()
AttributeError: 'TensorSliceDataset' object has no attribute
'get_shape'

Turns out I just needed to setup a new Python environment on Anaconda and install Tensorflow and Keras. My existing environment was already setup with these, but various other posts mentioned that doing this can help, and it did.

Related

how to save and load custom siamese bert model

I am following this tutorial on how to train a siamese bert network:
https://keras.io/examples/nlp/semantic_similarity_with_bert/
all good, but I am not sure what is the best way to save the model after train it and save it.
any suggestion?
I was trying with
model.save('models/bert_siamese_v1')
which creates a folder with save_model.bp keras_metadata.bp and two subfolders (variables and assets)
then I try to load it with:
model.load_weights('models/bert_siamese_v1/')
and it gives me this error:
2022-03-08 14:11:52.567762: W tensorflow/core/util/tensor_slice_reader.cc:95] Could not open models/bert_siamese_v1/: Failed precondition: models/bert_siamese_v1; Is a directory: perhaps your file is in a different file format and you need to use a different restore operator?
what is the best way to proceed?
Try using tf.saved_model.save to save your model:
tf.saved_model.save(model, 'models/bert_siamese_v1')
model = tf.saved_model.load('models/bert_siamese_v1')
The warning you get during saving can apparently be ignored. After loading your model, you can use it for inference f(test_data):
f = model.signatures["serving_default"]
x1 = tf.random.uniform((1, 128), maxval=100, dtype=tf.int32)
x2 = tf.random.uniform((1, 128), maxval=100, dtype=tf.int32)
x3 = tf.random.uniform((1, 128), maxval=100, dtype=tf.int32)
print(f)
print(f(attention_masks = x1, input_ids = x2, token_type_ids = x3))
ConcreteFunction signature_wrapper(*, token_type_ids, attention_masks, input_ids)
Args:
attention_masks: int32 Tensor, shape=(None, 128)
input_ids: int32 Tensor, shape=(None, 128)
token_type_ids: int32 Tensor, shape=(None, 128)
Returns:
{'dense': <1>}
<1>: float32 Tensor, shape=(None, 3)
{'dense': <tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[0.40711606, 0.13456087, 0.45832306]], dtype=float32)>}
It seems you have two options
manually save weights
model.save_weights('./checkpoints/my_checkpoint')
model = create_model()
model.load_weights('./checkpoints/my_checkpoint')
save the entire model
Call model.save to save a model's architecture, weights, and training configuration in a single file/folder. This allows you to export a model so it can be used without access to the original Python code*. Since the optimizer-state is recovered, you can resume training from exactly where you left off.
Save model
# Create and train a new model instance.
model = create_model()
model.fit(train_images, train_labels, epochs=5)
# Save the entire model as a SavedModel.
!mkdir -p saved_model
model.save('saved_model/my_model')
load model
new_model = tf.keras.models.load_model('saved_model/my_model')
It seems that you are mixing both approaches, saving model and loading weights.

Cannot convert tf.keras.preprocessing.image_dataset_from_directory to np.array

I am trying to create a image classification model using CNN. For that I am reading the data using the tf.keras.preprocessing.image_dataset_from_directory function.
This is the code:
train_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir_train,seed=123,validation_split = 0.2,subset = 'training',image_size=(img_height, img_width),batch_size=batch_size)
Then I am trying to convert the dataset in np.array object. My code is
x_train = np.array(train_ds)
But when I print x_train, I am getting
array(<BatchDataset shapes: ((None, 180, 180, 3), (None,)), types: (tf.float32, tf.int32)>, dtype=object)
The object train_ds is of shape (2000,180,180,3). I am not sure what is wrong in my code.
When using image_dataset_from_directory:
... image_dataset_from_directory(main_directory, labels='inferred') will return a tf.data.Dataset that yields batches of images from the subdirectories ...
One option to get the data you want, is to use take to create a Dataset with at most count elements from this dataset.
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
img = np.empty((6000,180,180,3), dtype=np.float32)
label = np.empty((6000,), dtype=np.int32)
train_ds = tf.data.Dataset.from_tensor_slices((img,label)).batch(2000)
print(train_ds) # <BatchDataset shapes: ((None, 180, 180, 3), (None,)), types: (tf.float32, tf.int32)>
for imgs, labels in train_ds.take(1):
print(imgs.shape) # (2000, 180, 180, 3)
print(labels.shape) # (2000,)
for img in imgs:
plt.imshow(img.numpy().astype(np.uint8)) # print imgs in the batch
Depending on how you're structuring your code, you may not even need to convert to a numpy.array, since tf.keras.Model fit accepts tf.data datasets.
model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)

How can I change a tensor to NumPy?

I want to exchange Tensor a to a NumPy two-dimensional array for getting a heat map.
(Tensor(1, 64, 64, 1) -> numpy (64, 64))
I tried x.numpy(), but it doesn't work. The error message is this:
AttributeError: in user code: :187 call * x_np=x.numpy() /usr/local/lib/python3.7/dist packages/tensorflow/python/framework/ops.py:401 getattr self.getattribute(name) AttributeError: 'Tensor' object has no attribute 'numpy'
This is the tensor information and type of the tensor:
Tensor("ExpandDims:0", shape=(1, 64, 64, 1), dtype=float32)
<class 'tensorflow.python.framework.ops.Tensor'>
and I don't know what ExpandDims:0 means (what is this argv?).
Tensorflow:2.6.0
Numpy:1.21.2
I made the test code that has the same Tensor type, shape, and env, and it works.
What should I do?
import tensorflow as tf
import numpy
print(tf.__version__)
print(numpy.__version__)
a = tf.constant([[[[0.1]*1]*64]*64])
print(a)
print(a.numpy())

ds_train has shape (2, 224, 224, 3) instead of (None, 224, 224, 3)

I have created my own custom dataset (with 2 classes) with the following code:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
ds_train = tf.keras.preprocessing.image_dataset_from_directory(
'C:/Users/mydir/Source_Images/',
labels = 'inferred', # from subfolders in alphabetical order
label_mode = "int",
class_names = ["CVS", "No_CVS"],
color_mode = 'rgb',
batch_size = 2,
image_size = (224, 224),
shuffle = True, # randomized order of images
seed = 123, #set the seed if train, valid images are the same when you run again
validation_split = 0.1,
subset = "training"
)
df_train results in:
<BatchDataset shapes: ((None, 224, 224, 3), (None,)), types: (tf.float32, tf.int32)>
Now, I want to visualize my data by looking at 9 images:
for i, (image, label) in enumerate(ds_train.take(9)):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image.numpy().astype("uint8"))
plt.axis("off")
However, I get the following error:
line 61, in
plt.imshow(image.numpy().astype("uint8"))
TypeError: Invalid shape (2, 224, 224, 3) for image data
I'm looking for a way to resolve this, and be able to plot my images with matplotlib.
EDIT:
More importantly, it seems that the data of the data cannot be used when training the model either as I get this error:
ValueError: Input 0 is incompatible with layer EfficientNet: expected shape=(None, 224, 224, 3), found shape=(2, None, 224, 224, 3)
After running the Keras example code I found here (where I created ds_train with the image_dataset_from_directory instead of the tdsf.load() function).
So I think there is something going wrong in the way I created the ds_train. Any resolutions are very welcome.
It seems like you are leaving the batch_size in, when you do:
plt.imshow(image.numpy().astype("uint8"))
With your original code you still won't be able to see 9 images because of your batch_size. I think it will be fine if you do it like:
No errors should be thrown like TypeError: Invalid shape...:
plt.imshow(image[i].numpy().astype("uint8"))
Furthermore you can do following to see batch_size:
for img_batch_size, labels_batch_size in train_df:
print(img_batch_size.shape)
print(labels_batch_size.shape)
For your case img_batch_size.shape should print (2,224,224,3) where this tuple corresponds to image tensor.
For input_shape problem, you need to add your model so we can see what's wrong with input_shape.

reshape.cc:55 stretch_dim != -1. Node number X (RESHAPE) failed to prepare

I'm new to all this, and I need some help with running inference using a custom tflite yolov3 tiny model.
The error I am getting is:
File "/usr/local/lib/python3.6/dist-packages/tensorflow/lite/python/interpreter.py", line 524, in invoke
self._interpreter.Invoke()
RuntimeError: tensorflow/lite/kernels/reshape.cc:55 stretch_dim != -1 (0 != -1)Node number 35 (RESHAPE) failed to prepare.
What have I done to get here:
trained a custom yolov3 tiny model for object detection to detect just 1 class using this project
https://github.com/pythonlessons/TensorFlow-2.x-YOLOv3.git
used default hyperparameters:
https://github.com/pythonlessons/TensorFlow-2.x-YOLOv3/blob/master/yolov3/configs.py
used tf-nightly
the model is here:
https://github.com/vladimirhorvat/y/blob/master/app/src/main/assets/converted_model.tflite
When the model was trained I tested the SavedModel by running inference and it worked.
Converted the SavedModel to tflite, run inference on it using the following code, and received the error from the title:
interpreter = tf.lite.Interpreter(model_path="converted_model.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
input_shape = input_details[0]['shape']
input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
(this code is from here, btw
https://www.tensorflow.org/lite/guide/inference#load_and_run_a_model_in_python )
Data for node 35:
type: Reshape
location: 35
inputs
data: name: functional_1/tf_op_layer_Tile_3/Tile_3;StatefulPartitionedCall/functional_1/tf_op_layer_Tile_3/Tile_3
shape: name: functional_1/tf_op_layer_strided_slice_6/strided_slice_6;StatefulPartitionedCall/functional_1/tf_op_layer_strided_slice_6/strided_slice_6
outputs
reshaped: name: functional_1/tf_op_layer_strided_slice_16/strided_slice_16;StatefulPartitionedCall/functional_1/tf_op_layer_strided_slice_16/strided_slice_16
Please help. I am out of ideas.
I was able to solve the exact same problem by following this similar post:
https://stackoverflow.com/a/62552677/11334316
In essence you would have to do the following when converting your model:
batch_size = 1
model = tf.keras.models.load_model('./yolo_model')
input_shape = model.inputs[0].shape.as_list()
input_shape[0] = batch_size
func = tf.function(model).get_concrete_function(tf.TensorSpec(input_shape, model.inputs[0].dtype))
model_converter = tf.lite.TFLiteConverter.from_concrete_functions([func])
model_lite = model_converter.convert()
f = open("./yolo_model.tflite", "wb")
f.write(model_lite)
f.close()

Categories

Resources