I am studying electrical engineering and doing some ML-stuff on hardware level.
I downloaded the Imagenet_subset using tensorflowdataset:
ds = tfds.load('imagenet2012_subset',
data_dir=os.path.join(write_dir, 'data'),
#split='validation',
shuffle_files=False,
download=True,
as_supervised=True,
download_and_prepare_kwargs=download_and_prepare_kwargs,
with_info=False)
Currently I am preparing the data like that:
def resize_with_crop(image, label):
i = image
i = tf.cast(i, tf.float32)
#i = tf.image.resize_with_crop_or_pad(i, 224, 224)
i = tf.image.resize(i, size=(224, 224))
#i = tf.expand_dims(i, axis=0)
i = tf.keras.applications.mobilenet_v2.preprocess_input(i)
return (i, label)
train = ds['train']
val = ds['validation']
# Preprocess the images
ds_train = train.map(resize_with_crop)
ds_val = val.map(resize_with_crop)
Now comes the filthy part. The way I extract the images and labels:
label= []
img = []
for element in ds_val.take(10000).as_numpy_iterator():
img.append(element[0])
label.append(element[1])
img = np.asarray(img)
label = np.asarray(label)
This approach is working but kind of ugly and killing my RAM.
Does some of you know how to extract the labels and images in a clean way?
The model I used is the MobileNetV2 pretrained on Imagenet:
model = keras.applications.MobileNetV2()
Thank you!
I have trained the model, now i would like to use it to detect objects in many images. I saw that the defaultpredictor allows you to detect only on an image, what can I do?
I am really new to this world. The approach I tried was to use a for loop but it doesn't work. Are there any other methods?
%cd /kaggle/working/detectron2
import glob
cfg.MODEL.WEIGHTS = os.path.join("/kaggle/working/detectron2/output", "model_final.pth") # path to the model we trained
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.0001 # set a testing threshold
pred = DefaultPredictor(cfg)
os.chdir("/kaggle/working/detectron2/images")
for img in glob.glob('.jpg'):
inputs = cv2.imread(img)
outputs = pred(inputs)
print(outputs)
Ok, i solved in this way:
%cd /kaggle/working/detectron2
import glob
cfg.MODEL.WEIGHTS = os.path.join("/kaggle/working/detectron2/output", "model_final.pth") # path to the model we trained
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.0001 # set a testing threshold
pred = DefaultPredictor(cfg)
for img in glob.glob('/kaggle/working/detectron2/images/*.jpg'):
inputs = cv2.imread(img)
outputs = pred(inputs)
print(outputs)
i deleted os.chdir()
I trained an autoencoder model in Keras to generate denoised images given noisy images. The predicted images are stored in the "result" directory, with the individual filenames appended with the "denoised" tag. When I run the code, nothing is stored in the "result" folder. When I ran for an individual image, the final cv2.imwrite throws this error: "TypeError: Expected Ptr<cv::UMat> for argument 'img'". Is there a different way to write the predicted files to the destination folder without using openCV in this case?
import glob
from keras.preprocessing import image
test = glob.glob("data/test1/*.png") #all test data that needs to be denoised
test.sort()
result = "data/result" #the folder that contains predicted denoised images
#load model
model = load_model('autoencoder_model.h5')
model.summary()
#compile the model
model.compile(loss='mean_squared_error', optimizer = RMSprop())
for f in test:
img = image.load_img(f,grayscale=True,target_size=(128,128),interpolation="nearest")
img_name = f.split(os.sep)[-1]
#preprocess the image
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x /= 255
#predict on the image
preds = model.predict(x)
pred_norm = 255 * (preds - preds.min()) / (preds.max() - preds.min())
pred_normed = np.array(pred_norm, np.int)
cv2.imwrite(os.path.join(result,f[:-4]+'_removed.png'), pred_normed)
I am trying to implement the Neural Image Caption generator with visual attention proposed in the "Show, Attend and Tell" paper. For validation, I want to compute the Bleu score. For this, I need to get all the captions for a particular image. I thought of approaching the problem as shown below:
data_path = './processed_data'
split_type = 'val'
encoded_captions = np.load(data_path + '/{}/captions_{}.npy'.format(split_type, split_type))
image_paths = json.load(open(data_path + '/{}/img_paths_{}.json'.format(split_type, split_type), 'r'))
encoded_captions, image_paths = shuffle(encoded_captions, image_paths, random_state=0)
dataset = tf.data.Dataset.from_tensor_slices((image_paths, encoded_captions))
dataset = dataset.map(lambda img_path, cap: map_func(img_path, cap, image_paths, encoded_captions))
def map_func(img_path, caption, image_paths, encoded_captions):
matching_captions = [caption for i, caption in enumerate(encoded_captions) if image_paths[i] == img_path]
img = tf.io.read_file(img_path)
img = tf.image.decode_jpeg(img, channels=3)
img = tf.image.resize(img, (299, 299))
img = tf.keras.applications.inception_v3.preprocess_input(img)
return img, caption, matching_captions
When running the above code, I am getting the following error:
OperatorNotAllowedInGraphError: using a tf.Tensor as a Python bool is not allowed in Graph execution. Use Eager execution or decorate this function with #tf.function.
How do I resolve this issue? Alternatively, is there a more efficient way of getting captions that map to a particular image?
Thank you very much!
I am new to TensorFlow. I am looking for the help on the image recognition where I can train my own image dataset.
Is there any example for training the new dataset?
If you are interested in how to input your own data in TensorFlow, you can look at this tutorial.
I've also written a guide with best practices for CS230 at Stanford here.
New answer (with tf.data) and with labels
With the introduction of tf.data in r1.4, we can create a batch of images without placeholders and without queues. The steps are the following:
Create a list containing the filenames of the images and a corresponding list of labels
Create a tf.data.Dataset reading these filenames and labels
Preprocess the data
Create an iterator from the tf.data.Dataset which will yield the next batch
The code is:
# step 1
filenames = tf.constant(['im_01.jpg', 'im_02.jpg', 'im_03.jpg', 'im_04.jpg'])
labels = tf.constant([0, 1, 0, 1])
# step 2: create a dataset returning slices of `filenames`
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
# step 3: parse every image in the dataset using `map`
def _parse_function(filename, label):
image_string = tf.read_file(filename)
image_decoded = tf.image.decode_jpeg(image_string, channels=3)
image = tf.cast(image_decoded, tf.float32)
return image, label
dataset = dataset.map(_parse_function)
dataset = dataset.batch(2)
# step 4: create iterator and final input tensor
iterator = dataset.make_one_shot_iterator()
images, labels = iterator.get_next()
Now we can run directly sess.run([images, labels]) without feeding any data through placeholders.
Old answer (with TensorFlow queues)
To sum it up you have multiple steps:
Create a list of filenames (ex: the paths to your images)
Create a TensorFlow filename queue
Read and decode each image, resize them to a fixed size (necessary for batching)
Output a batch of these images
The simplest code would be:
# step 1
filenames = ['im_01.jpg', 'im_02.jpg', 'im_03.jpg', 'im_04.jpg']
# step 2
filename_queue = tf.train.string_input_producer(filenames)
# step 3: read, decode and resize images
reader = tf.WholeFileReader()
filename, content = reader.read(filename_queue)
image = tf.image.decode_jpeg(content, channels=3)
image = tf.cast(image, tf.float32)
resized_image = tf.image.resize_images(image, [224, 224])
# step 4: Batching
image_batch = tf.train.batch([resized_image], batch_size=8)
Based on #olivier-moindrot's answer, but for Tensorflow 2.0+:
# step 1
filenames = tf.constant(['im_01.jpg', 'im_02.jpg', 'im_03.jpg', 'im_04.jpg'])
labels = tf.constant([0, 1, 0, 1])
# step 2: create a dataset returning slices of `filenames`
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
def im_file_to_tensor(file, label):
def _im_file_to_tensor(file, label):
path = f"../foo/bar/{file.numpy().decode()}"
im = tf.image.decode_jpeg(tf.io.read_file(path), channels=3)
im = tf.cast(image_decoded, tf.float32) / 255.0
return im, label
return tf.py_function(_im_file_to_tensor,
inp=(file, label),
Tout=(tf.float32, tf.uint8))
dataset = dataset.map(im_file_to_tensor)
If you are hitting an issue similar to:
ValueError: Cannot take the length of Shape with unknown rank
when passing tf.data.Dataset tensors to model.fit, then take a look at https://github.com/tensorflow/tensorflow/issues/24520. A fix for the code snippet above would be:
def im_file_to_tensor(file, label):
def _im_file_to_tensor(file, label):
path = f"../foo/bar/{file.numpy().decode()}"
im = tf.image.decode_jpeg(tf.io.read_file(path), channels=3)
im = tf.cast(image_decoded, tf.float32) / 255.0
return im, label
file, label = tf.py_function(_im_file_to_tensor,
inp=(file, label),
Tout=(tf.float32, tf.uint8))
file.set_shape([192, 192, 3])
label.set_shape([])
return (file, label)
2.0 Compatible Answer using Tensorflow Hub: Tensorflow Hub is a Provision/Product Offered by Tensorflow, which comprises the Models developed by Google, for Text and Image Datasets.
It saves Thousands of Hours of Training Time and Computational Effort, as it reuses the Existing Pre-Trained Model.
If we have an Image Dataset, we can take the Existing Pre-Trained Models from TF Hub and can adopt it to our Dataset.
Code for Re-Training our Image Dataset using the Pre-Trained Model, MobileNet, is shown below:
import itertools
import os
import matplotlib.pylab as plt
import numpy as np
import tensorflow as tf
import tensorflow_hub as hub
module_selection = ("mobilenet_v2_100_224", 224) ##param ["(\"mobilenet_v2_100_224\", 224)", "(\"inception_v3\", 299)"] {type:"raw", allow-input: true}
handle_base, pixels = module_selection
MODULE_HANDLE ="https://tfhub.dev/google/imagenet/{}/feature_vector/4".format(handle_base)
IMAGE_SIZE = (pixels, pixels)
print("Using {} with input size {}".format(MODULE_HANDLE, IMAGE_SIZE))
BATCH_SIZE = 32 ##param {type:"integer"}
#Here we need to Pass our Dataset
data_dir = tf.keras.utils.get_file(
'flower_photos',
'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
untar=True)
model = tf.keras.Sequential([
hub.KerasLayer(MODULE_HANDLE, trainable=do_fine_tuning),
tf.keras.layers.Dropout(rate=0.2),
tf.keras.layers.Dense(train_generator.num_classes, activation='softmax',
kernel_regularizer=tf.keras.regularizers.l2(0.0001))
])
model.build((None,)+IMAGE_SIZE+(3,))
model.summary()
Complete Code for Image Retraining Tutorial can be found in this Github Link.
More information about Tensorflow Hub can be found in this TF Blog.
The Pre-Trained Modules related to Images can be found in this TF Hub Link.
All the Pre-Trained Modules, related to Images, Text, Videos, etc.. can be found in this TF HUB Modules Link.
Finally, this is the Basic Page for Tensorflow Hub.
If your dataset consists of subfolders, you can use ImageDataGenerator it has flow_from_directory it helps to load data from a directory,
train_batches = ImageDataGenerator().flow_from_directory(
directory=train_path, target_size=(img_height,img_weight), batch_size=32 ,color_mode="grayscale")
The structure of the folder hierarchy can be as follows,
train
-- cat
-- dog
-- moneky