How to load images in batches in tensorflow? - python

I have been using pytorch and is new to tensorflow.
In pytorch we create loader class to which return single tuple of dataset and then pass the instance of the class to torch.data.Dataloader and define the batch-size and worker.
How do we do the same process in tensorflow?
class Dataset_Tuple_Loader(data.Dataset):
def __init__(self,img_root, csv_label_address, transforms,img_source ='local'):
add = img_root
if(img_source=='network'):
add,csv_label_address,status = DataDownload(img_root,csv_label_address)
self.imgs_address_list = glob.glob(add + '/*')
labels_csv = pd.read_csv(csv_label_address)
labels_csv.set_index('image_name', inplace=True)
self.labels_csv = labels_csv
self.transforms = transforms
def __len__(self):
return len(self.imgs_address_list)
def get_filename(self,filename):
base = os.path.basename(filename)
return (os.path.splitext(base)[0])
def __getitem__(self,index):
img_add = self.imgs_address_list[index]
img = Image.open(img_add)
img = self.transforms(np.asarray(img))
filename = self.get_filename(img_add)
label = int(self.labels_csv.loc[filename][0])
return img,label
params = {'batch_size': 2,
'shuffle': True,
'num_workers': 1}
csv = 'label_address'
image_root = 'img_add'
just_set = Dataset('local',image_root,csv)
generator = data.DataLoader(just_set,**params)
for tup in generator:
img = tup[0]
lb = tup[1]
print(img.shape,' ',lb)

Related

Coco_eval - Average Precision and Recall

I trained my model with maskrcnn and now I need to test it. How can I extract AP and AR and plot the graph, ok I know how to plot with matplotlib, but I need to plot Precision-recall curve but for that don't know how to access AP and AR values. Where are they saved?
I'm using this coco_eval script, and from here I see in function summarize there are print("IoU metric: {}".format(iou_type)) and this I got in output and under that AP and AR results, but I can't find it here in code. Where is this calculation?
coco_eval.py
import json
import tempfile
import numpy as np
import copy
import time
import torch
import torch._six
from pycocotools.cocoeval import COCOeval
from pycocotools.coco import COCO
import pycocotools.mask as mask_util
from collections import defaultdict
import utils
class CocoEvaluator(object):
def __init__(self, coco_gt, iou_types):
assert isinstance(iou_types, (list, tuple))
coco_gt = copy.deepcopy(coco_gt)
self.coco_gt = coco_gt
self.iou_types = iou_types
self.coco_eval = {}
for iou_type in iou_types:
self.coco_eval[iou_type] = COCOeval(coco_gt, iouType=iou_type)
self.img_ids = []
self.eval_imgs = {k: [] for k in iou_types}
def update(self, predictions):
img_ids = list(np.unique(list(predictions.keys())))
self.img_ids.extend(img_ids)
for iou_type in self.iou_types:
results = self.prepare(predictions, iou_type)
coco_dt = loadRes(self.coco_gt, results) if results else COCO()
coco_eval = self.coco_eval[iou_type]
coco_eval.cocoDt = coco_dt
coco_eval.params.imgIds = list(img_ids)
img_ids, eval_imgs = evaluate(coco_eval)
self.eval_imgs[iou_type].append(eval_imgs)
def synchronize_between_processes(self):
for iou_type in self.iou_types:
self.eval_imgs[iou_type] = np.concatenate(self.eval_imgs[iou_type], 2)
create_common_coco_eval(self.coco_eval[iou_type], self.img_ids, self.eval_imgs[iou_type])
def accumulate(self):
for coco_eval in self.coco_eval.values():
coco_eval.accumulate()
def summarize(self):
for iou_type, coco_eval in self.coco_eval.items():
print("IoU metric: {}".format(iou_type))
coco_eval.summarize()
def prepare(self, predictions, iou_type):
if iou_type == "bbox":
return self.prepare_for_coco_detection(predictions)
elif iou_type == "segm":
return self.prepare_for_coco_segmentation(predictions)
elif iou_type == "keypoints":
return self.prepare_for_coco_keypoint(predictions)
else:
raise ValueError("Unknown iou type {}".format(iou_type))
def prepare_for_coco_detection(self, predictions):
coco_results = []
for original_id, prediction in predictions.items():
if len(prediction) == 0:
continue
boxes = prediction["boxes"]
boxes = convert_to_xywh(boxes).tolist()
scores = prediction["scores"].tolist()
labels = prediction["labels"].tolist()
coco_results.extend(
[
{
"image_id": original_id,
"category_id": labels[k],
"bbox": box,
"score": scores[k],
}
for k, box in enumerate(boxes)
]
)
return coco_results
def prepare_for_coco_segmentation(self, predictions):
coco_results = []
for original_id, prediction in predictions.items():
if len(prediction) == 0:
continue
scores = prediction["scores"]
labels = prediction["labels"]
masks = prediction["masks"]
masks = masks > 0.5
scores = prediction["scores"].tolist()
labels = prediction["labels"].tolist()
rles = [
mask_util.encode(np.array(mask[0, :, :, np.newaxis], dtype=np.uint8, order="F"))[0]
for mask in masks
]
for rle in rles:
rle["counts"] = rle["counts"].decode("utf-8")
coco_results.extend(
[
{
"image_id": original_id,
"category_id": labels[k],
"segmentation": rle,
"score": scores[k],
}
for k, rle in enumerate(rles)
]
)
return coco_results
def prepare_for_coco_keypoint(self, predictions):
coco_results = []
for original_id, prediction in predictions.items():
if len(prediction) == 0:
continue
boxes = prediction["boxes"]
boxes = convert_to_xywh(boxes).tolist()
scores = prediction["scores"].tolist()
labels = prediction["labels"].tolist()
keypoints = prediction["keypoints"]
keypoints = keypoints.flatten(start_dim=1).tolist()
coco_results.extend(
[
{
"image_id": original_id,
"category_id": labels[k],
'keypoints': keypoint,
"score": scores[k],
}
for k, keypoint in enumerate(keypoints)
]
)
return coco_results
def convert_to_xywh(boxes):
xmin, ymin, xmax, ymax = boxes.unbind(1)
return torch.stack((xmin, ymin, xmax - xmin, ymax - ymin), dim=1)
def merge(img_ids, eval_imgs):
all_img_ids = utils.all_gather(img_ids)
all_eval_imgs = utils.all_gather(eval_imgs)
merged_img_ids = []
for p in all_img_ids:
merged_img_ids.extend(p)
merged_eval_imgs = []
for p in all_eval_imgs:
merged_eval_imgs.append(p)
merged_img_ids = np.array(merged_img_ids)
merged_eval_imgs = np.concatenate(merged_eval_imgs, 2)
# keep only unique (and in sorted order) images
merged_img_ids, idx = np.unique(merged_img_ids, return_index=True)
merged_eval_imgs = merged_eval_imgs[..., idx]
return merged_img_ids, merged_eval_imgs
def create_common_coco_eval(coco_eval, img_ids, eval_imgs):
img_ids, eval_imgs = merge(img_ids, eval_imgs)
img_ids = list(img_ids)
eval_imgs = list(eval_imgs.flatten())
coco_eval.evalImgs = eval_imgs
coco_eval.params.imgIds = img_ids
coco_eval._paramsEval = copy.deepcopy(coco_eval.params)
#################################################################
# From pycocotools, just removed the prints and fixed
# a Python3 bug about unicode not defined
#################################################################
# Ideally, pycocotools wouldn't have hard-coded prints
# so that we could avoid copy-pasting those two functions
def createIndex(self):
# create index
# print('creating index...')
anns, cats, imgs = {}, {}, {}
imgToAnns, catToImgs = defaultdict(list), defaultdict(list)
if 'annotations' in self.dataset:
for ann in self.dataset['annotations']:
imgToAnns[ann['image_id']].append(ann)
anns[ann['id']] = ann
if 'images' in self.dataset:
for img in self.dataset['images']:
imgs[img['id']] = img
if 'categories' in self.dataset:
for cat in self.dataset['categories']:
cats[cat['id']] = cat
if 'annotations' in self.dataset and 'categories' in self.dataset:
for ann in self.dataset['annotations']:
catToImgs[ann['category_id']].append(ann['image_id'])
# print('index created!')
# create class members
self.anns = anns
self.imgToAnns = imgToAnns
self.catToImgs = catToImgs
self.imgs = imgs
self.cats = cats
maskUtils = mask_util
def loadRes(self, resFile):
"""
Load result file and return a result api object.
Args:
self (obj): coco object with ground truth annotations
resFile (str): file name of result file
Returns:
res (obj): result api object
"""
res = COCO()
res.dataset['images'] = [img for img in self.dataset['images']]
# print('Loading and preparing results...')
# tic = time.time()
if isinstance(resFile, torch._six.string_classes):
anns = json.load(open(resFile))
elif type(resFile) == np.ndarray:
anns = self.loadNumpyAnnotations(resFile)
else:
anns = resFile
assert type(anns) == list, 'results in not an array of objects'
annsImgIds = [ann['image_id'] for ann in anns]
assert set(annsImgIds) == (set(annsImgIds) & set(self.getImgIds())), \
'Results do not correspond to current coco set'
if 'caption' in anns[0]:
imgIds = set([img['id'] for img in res.dataset['images']]) & set([ann['image_id'] for ann in anns])
res.dataset['images'] = [img for img in res.dataset['images'] if img['id'] in imgIds]
for id, ann in enumerate(anns):
ann['id'] = id + 1
elif 'bbox' in anns[0] and not anns[0]['bbox'] == []:
res.dataset['categories'] = copy.deepcopy(self.dataset['categories'])
for id, ann in enumerate(anns):
bb = ann['bbox']
x1, x2, y1, y2 = [bb[0], bb[0] + bb[2], bb[1], bb[1] + bb[3]]
if 'segmentation' not in ann:
ann['segmentation'] = [[x1, y1, x1, y2, x2, y2, x2, y1]]
ann['area'] = bb[2] * bb[3]
ann['id'] = id + 1
ann['iscrowd'] = 0
elif 'segmentation' in anns[0]:
res.dataset['categories'] = copy.deepcopy(self.dataset['categories'])
for id, ann in enumerate(anns):
# now only support compressed RLE format as segmentation results
ann['area'] = maskUtils.area(ann['segmentation'])
if 'bbox' not in ann:
ann['bbox'] = maskUtils.toBbox(ann['segmentation'])
ann['id'] = id + 1
ann['iscrowd'] = 0
elif 'keypoints' in anns[0]:
res.dataset['categories'] = copy.deepcopy(self.dataset['categories'])
for id, ann in enumerate(anns):
s = ann['keypoints']
x = s[0::3]
y = s[1::3]
x1, x2, y1, y2 = np.min(x), np.max(x), np.min(y), np.max(y)
ann['area'] = (x2 - x1) * (y2 - y1)
ann['id'] = id + 1
ann['bbox'] = [x1, y1, x2 - x1, y2 - y1]
# print('DONE (t={:0.2f}s)'.format(time.time()- tic))
res.dataset['annotations'] = anns
createIndex(res)
return res
def evaluate(self):
'''
Run per image evaluation on given images and store results (a list of dict) in self.evalImgs
:return: None
'''
# tic = time.time()
# print('Running per image evaluation...')
p = self.params
# add backward compatibility if useSegm is specified in params
if p.useSegm is not None:
p.iouType = 'segm' if p.useSegm == 1 else 'bbox'
print('useSegm (deprecated) is not None. Running {} evaluation'.format(p.iouType))
# print('Evaluate annotation type *{}*'.format(p.iouType))
p.imgIds = list(np.unique(p.imgIds))
if p.useCats:
p.catIds = list(np.unique(p.catIds))
p.maxDets = sorted(p.maxDets)
self.params = p
self._prepare()
# loop through images, area range, max detection number
catIds = p.catIds if p.useCats else [-1]
if p.iouType == 'segm' or p.iouType == 'bbox':
computeIoU = self.computeIoU
elif p.iouType == 'keypoints':
computeIoU = self.computeOks
self.ious = {
(imgId, catId): computeIoU(imgId, catId)
for imgId in p.imgIds
for catId in catIds}
evaluateImg = self.evaluateImg
maxDet = p.maxDets[-1]
evalImgs = [
evaluateImg(imgId, catId, areaRng, maxDet)
for catId in catIds
for areaRng in p.areaRng
for imgId in p.imgIds
]
# this is NOT in the pycocotools code, but could be done outside
evalImgs = np.asarray(evalImgs).reshape(len(catIds), len(p.areaRng), len(p.imgIds))
self._paramsEval = copy.deepcopy(self.params)
# toc = time.time()
# print('DONE (t={:0.2f}s).'.format(toc-tic))
return p.imgIds, evalImgs
#################################################################
# end of straight copy from pycocotools, just removing the prints
#################################################################
And this is my code for evaluation:
def evaluate(model, data_loader, device):
n_threads = torch.get_num_threads()
# FIXME remove this and make paste_masks_in_image run on the GPU
torch.set_num_threads(1)
cpu_device = torch.device("cpu")
model.eval()
metric_logger = utils.MetricLogger(delimiter=" ")
header = 'Test:'
coco = get_coco_api_from_dataset(data_loader.dataset)
iou_types = _get_iou_types(model)
coco_evaluator = CocoEvaluator(coco, iou_types)
for images, targets in metric_logger.log_every(data_loader, 100, header):
images = list(img.to(device) for img in images)
if torch.cuda.is_available():
torch.cuda.synchronize()
model_time = time.time()
outputs = model(images)
outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
model_time = time.time() - model_time
res = {target["image_id"].item(): output for target, output in zip(targets, outputs)}
evaluator_time = time.time()
coco_evaluator.update(res)
evaluator_time = time.time() - evaluator_time
metric_logger.update(model_time=model_time, evaluator_time=evaluator_time)
# gather the stats from all processes
metric_logger.synchronize_between_processes()
print("Averaged stats:", metric_logger)
coco_evaluator.synchronize_between_processes()
# accumulate predictions from all images
coco_evaluator.accumulate()
coco_evaluator.summarize()
torch.set_num_threads(n_threads)
return coco_evaluator
This is my results what I got:

Values for custom Tensorflow Optimization Algorithm not converging

I wanted to create an implementation of the Swarm Optimization Algorithm for deep neural networks that is the Fireworks Algorithm.
I was finally able to create a TensorFlow optimizer class that implements the same using THIS repository.
But even after implementation, my accuracy seems to be around ~11% during training. (please refer to THIS collab notebook for code)
To test out the code SEE MY IMPLEMENTATION ON A COLLAB NOTEBOOK
How can I resolve this issue.
also my main optimizer code is,
# https://github.com/cilatpku/firework-algorithm/blob/master/fwa/BBFWA.py
class Firework(optimizer.Optimizer):
def __init__(self,
# params for prob
evaluator = None,
dim = 2,
upper_bound = 100,
lower_bound = -100,
max_iter = 10000,
max_eval = 20000,
# params for method
sp_size = 200,
init_amp = 200,
name="Firework", use_locking=False, **kwargs):
super(Firework, self).__init__(use_locking, name)
## Parameters
# params of method
self.sp_size = sp_size # total spark size
self.init_amp = init_amp # initial dynamic amplitude
# load params
self.evaluator = evaluator
self.dim = dim
self.upper_bound = upper_bound
self.lower_bound = lower_bound
self.max_iter = max_iter
self.max_eval = max_eval
## States
# private init states
self._num_iter = 0
self._num_eval = 0
self._dyn_amp = init_amp
# public states
self.best_idv = None # best individual found
self.best_fit = None # best fitness found
self.trace = [] # trace of best individual in each generation
## Fireworks
self.fireworks = np.random.uniform(self.lower_bound, self.upper_bound, [1, self.dim])
self.fireworks = self.fireworks.tolist()
self.fits = self.evaluator(self.fireworks)
## Tensor versions of the constructor arguments, created in _prepare().
self.dim_t = None
self.upper_bound_t = None
self.lower_bound_t = None
self.max_iter_t = None
self.max_eval_t = None
self.sp_size_t = None
self.init_amp_t = None
self.fireworks_t = None
self.fits_t = None
def _create_slots(self, var_list):
"""For each model variable, create the optimizer variable associated with it.
TensorFlow calls these optimizer variables "slots"."""
# Create slots for the first and second moments.
for v in var_list:
self._zeros_slot(v, "fireworks", self._name)
for v in var_list:
self._zeros_slot(v, "fits", self._name)
def _prepare(self):
# self.evaluator_t = ops.convert_to_tensor(self.evaluator, name="evaloator")
self.dim_t = ops.convert_to_tensor(self.dim, name="dimention")
self.upper_bound_t = ops.convert_to_tensor(self.upper_bound, name="upper_bound")
self.lower_bound_t = ops.convert_to_tensor(self.lower_bound, name="lower_bound")
self.max_iter_t = ops.convert_to_tensor(self.max_iter, name="max_iterations")
self.max_eval_t = ops.convert_to_tensor(self.max_eval, name="max_eval")
self.sp_size_t = ops.convert_to_tensor(self.sp_size, name="sp_size")
self.init_amp_t = ops.convert_to_tensor(self.init_amp, name="init_amp")
self.fireworks_t = ops.convert_to_tensor(self.fireworks, name="fireworks")
self.fits_t = ops.convert_to_tensor(self.fits, name="fits")
print(self.fireworks_t)
def _resource_apply_dense(self, grad, var):
evaluator = self.evaluator
dim_t = math_ops.cast(self.dim_t, var.dtype.base_dtype)
upper_bound_t = math_ops.cast(self.upper_bound_t, var.dtype.base_dtype)
lower_bound_t = math_ops.cast(self.lower_bound_t, var.dtype.base_dtype)
max_iter_t = math_ops.cast(self.max_iter_t, var.dtype.base_dtype)
max_eval_t = math_ops.cast(self.max_eval_t, var.dtype.base_dtype)
sp_size_t = math_ops.cast(self.sp_size_t, var.dtype.base_dtype)
init_amp_t = math_ops.cast(self.init_amp_t, var.dtype.base_dtype)
fits = self.get_slot(grad, "fits")
fireworks = self.get_slot(var, "fireworks")
fireworks_update, fits_update = self.iter(self.fireworks, self.fits)
self.fireworks = fireworks_update
self.fits = fits_update
fireworks_update_t = math_ops.cast(fireworks_update, var.dtype.base_dtype)
fits_update_t = math_ops.cast(fits_update, var.dtype.base_dtype)
self.fireworks_t = fireworks_update_t
self.fits_t = fits_update_t
print("fireworks_update : ", fireworks_update)
print("fits_update : ", fits_update)
#Create an op that groups multiple operations
#When this op finishes, all ops in input have finished
return control_flow_ops.group(*[fireworks_update_t, fits_update_t])
## Helper functions
def iter(self, fireworks, fits):
print("...\n")
e_sparks, e_fits = self._explode(fireworks, fits)
n_fireworks, n_fits = self._select(fireworks, fits, e_sparks, e_fits)
# update states
if n_fits[0] < fits[0]:
self._dyn_amp *= 1.2
else:
self._dyn_amp *= 0.9
self._num_iter += 1
self._num_eval += len(e_sparks)
self.best_idv = n_fireworks[0]
self.best_fit = n_fits[0]
self.trace.append([n_fireworks[0], n_fits[0], self._dyn_amp])
fireworks = n_fireworks
fits = n_fits
return fireworks, fits
def _explode(self, fireworks, fits):
bias = np.random.uniform(-self._dyn_amp, self._dyn_amp, [self.sp_size, self.dim])
rand_samples = np.random.uniform(self.lower_bound, self.upper_bound, [self.sp_size, self.dim])
e_sparks = fireworks + bias
in_bound = (e_sparks > self.lower_bound) * (e_sparks < self.upper_bound)
e_sparks = in_bound * e_sparks + (1 - in_bound) * rand_samples
e_sparks = e_sparks.tolist()
e_fits = self.evaluator(e_sparks)
return e_sparks, e_fits
def _select(self, fireworks, fits, e_sparks, e_fits):
idvs = fireworks + e_sparks
fits = fits + e_fits
idx = np.argmin(fits)
return [idvs[idx]], [fits[idx]]
##################################################
##################################################
def get_config(self):
base_config = super().get_config()
return {
**base_config,
"learning_rate": self._serialize_hyperparameter("learning_rate"),
"decay": self._serialize_hyperparameter("decay"),
"momentum": self._serialize_hyperparameter("momentum"),
}
def _apply_dense(self, grad, var):
raise NotImplementedError("Dense gradient updates are not supported.")
def _apply_sparse(self, grad, var):
raise NotImplementedError("Sparse gradient updates are not supported.")
def _resource_apply_sparse(self, grad, var):
raise NotImplementedError("Sparse Resource gradient updates are not supported.")

How to deal with None in a PyTorch custom dataset class?

I have an object detection dataset with RGB images and annotations in Json. I use a custom DataLoader class to read the images and the labels. One issue that I’m facing is that I would like to skip images when training my model if/when labels don’t contain certain objects.
For example, If one image doesn’t contain any target labels belonging to the class ‘Cars’, I would like to skip them. When parsing my Json annotation, I tried checking for labels that don’t contain the class ‘Cars’ and returned None. Subsequently, I used a collate function to filter the None but unfortunately, It is not working.
import torch
from torch.utils.data.dataset import Dataset
import json
import os
from PIL import Image
from torchvision import transforms
#import cv2
import numpy as np
general_classes = {
# Cars
"Toyota Corolla" : 0,
"VW Golf" : 0,
"VW Beetle" : 0,
# Motor-cycles
"Harley Davidson" : 1,
"Yamaha YZF-R6" : 1,
}
car_classes={
"Toyota Corolla" : 0,
"VW Golf" : 0,
"VW Beetle" : 0
}
def get_transform(train):
transforms = []
# converts the image, a PIL image, into a PyTorch Tensor
transforms.append(T.ToTensor())
if train:
# during training, randomly flip the training images
# and ground-truth for data augmentation
transforms.append(T.RandomHorizontalFlip(0.5))
return T.Compose(transforms)
def my_collate(batch):
batch = list(filter(lambda x: x is not None, batch))
return torch.utils.data.dataloader.default_collate(batch)
class FilteredDataset(Dataset):
# The dataloader will skip the image and corresponding labels based on the dictionary 'car_classes'
def __init__(self, data_dir, transforms):
self.data_dir = data_dir
img_folder_list = os.listdir(self.data_dir)
self.transforms = transforms
imgs_list = []
json_list = []
self.filter_count=0
self.filtered_label_list=[]
for img_path in img_folder_list:
#img_full_path = self.data_dir + img_path
img_full_path=os.path.join(self.data_dir,img_path)
json_file = os.path.join(img_full_path, 'annotations-of-my-images.json')
img_file = os.path.join(img_full_path, 'Image-Name.png')
json_list.append(json_file)
imgs_list.append(img_file)
self.imgs = imgs_list
self.annotations = json_list
total_count=0
for one_annotation in self.annotations:
filtered_obj_id=[]
with open(one_annotation) as f:
img_annotations = json.load(f)
parts_list = img_annotations['regions']
for part in parts_list:
current_obj_id = part['tags'][0] # bbox label
check_obj_id = general_classes[current_obj_id]
if(check_obj_id==0):
subclass_id=car_classes[current_obj_id]
filtered_obj_id.append(subclass_id)
total_count=total_count+1
if(len(filtered_obj_id)>0):
self.filter_count=self.filter_count+1
self.filtered_label_list.append(one_annotation)
print("The total number of the objects in all images: ",total_count)
# get one image and the bboxes,img_id, labels of parts, etc in the image as target.
def __getitem__(self, idx):
img_path = self.imgs[idx]
image_id = torch.tensor([idx])
with open(self.annotations[idx]) as f:
img_annotations = json.load(f)
parts_list = img_annotations['regions']
obj_ids = []
boxes = []
for part in parts_list:
obj_id = part['tags'][0]
check_obj_id = general_classes[obj_id]
if(check_obj_id==0):
obj_id=car_classes[obj_id]
obj_ids.append(obj_id)
#print("---------------------------------------------------")
if(len(obj_ids)>0):
img = Image.open(img_path).convert("RGB")
labels = torch.as_tensor(obj_ids, dtype = torch.int64)
target = {}
target['labels'] = labels
if self.transforms is not None:
img, target = self.transforms(img, target)
return img, target
else:
return None
def __len__(self):
return len(self.filtered_label_list)
train_data_path = "path-to-my-annotation"
# Generators
train_dataset = FilteredDataset(train_data_path,get_transform(train=True))
print("Total files in the train_dataset: ",len(train_dataset))
#print("The first instance in the train dataset : ",train_dataset[0])
#training_generator = torch.utils.data.DataLoader(train_dataset)
training_generator = torch.utils.data.DataLoader(train_dataset,collate_fn=my_collate)
print("\n\n Iterator in action! ")
print("---------------------------------------------------------")
count=0
for img,target in training_generator:
#print("The img name : ",img[0])
count=count+1
print("target name : ",target)
print("count : ",count)
print("**************************************************")
However, I get the following error,
Could anyone please suggest a way to skip the images that do not contain a particular categorical label?

Tensorflow dataset generator inverted colors

I have a problem with TF dataset generator. I do not why, but when I get picture from dataset by running it through session, it returns Tensors where colors are inverted. I tried to changed BGR to RGB, but this is not the problem.
It is partially solved by inverting the image array (img = 1 - img ), but I would like not this problem to occur in first place. Does somebody know what could be the cause?
import os
import glob
import random
import tensorflow as tf
from tensorflow import Tensor
class PairGenerator(object):
person1 = 'img'
person2 = 'person2'
label = 'same_person'
#def __init__(self, lfw_path='./tf_dataset/resources' + os.path.sep + 'lfw'):
def __init__(self, lfw_path='/home/tom/Devel/ai-dev/tensorflow-triplet-loss/data/augmentor'):
self.all_people = self.generate_all_people_dict(lfw_path)
print(self.all_people.keys())
def generate_all_people_dict(self, lfw_path):
# generates a dictionary between a person and all the photos of that person
all_people = {}
for person_folder in os.listdir(lfw_path):
person_photos = glob.glob(lfw_path + os.path.sep + person_folder + os.path.sep + '*.jpg')
all_people[person_folder] = person_photos
return all_people
def get_next_pair(self):
all_people_names = list(self.all_people.keys())
while True:
# draw a person at random
person1 = random.choice(all_people_names)
# flip a coin to decide whether we fetch a photo of the same person vs different person
same_person = random.random() > 0.5
if same_person:
person2 = person1
else:
# repeatedly pick random names until we find a different name
person2 = person1
while person2 == person1:
person2 = random.choice(all_people_names)
person1_photo = random.choice(self.all_people[person1])
yield ({self.person1: person1_photo,
self.label: same_person})
class Inputs(object):
def __init__(self, img: Tensor, label: Tensor):
self.img = img
self.label = label
def feed_input(self, input_img, input_label=None):
# feed the input images that are necessary to make a prediction
feed_dict = {self.img: input_img}
# optionally also include the label:
# if we're just making a prediction without calculating loss, that won't be necessary
if input_label is not None:
feed_dict[self.label] = input_label
return feed_dict
class Dataset(object):
img_resized = 'img_resized'
label = 'same_person'
def __init__(self, generator=PairGenerator()):
self.next_element = self.build_iterator(generator)
def build_iterator(self, pair_gen: PairGenerator):
batch_size = 10
prefetch_batch_buffer = 5
dataset = tf.data.Dataset.from_generator(pair_gen.get_next_pair,
output_types={PairGenerator.person1: tf.string,
PairGenerator.label: tf.bool})
dataset = dataset.map(self._read_image_and_resize)
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(prefetch_batch_buffer)
iter = dataset.make_one_shot_iterator()
element = iter.get_next()
return Inputs(element[self.img_resized],
element[PairGenerator.label])
def _read_image_and_resize(self, pair_element):
target_size = [224, 224]
# read images from disk
img_file = tf.read_file(pair_element[PairGenerator.person1])
print("////")
print(PairGenerator.person1)
img = tf.image.decode_image(img_file, channels=3)
# let tensorflow know that the loaded images have unknown dimensions, and 3 color channels (rgb)
img.set_shape([None, None, 3])
# resize to model input size
img_resized = tf.image.resize_images(img, target_size)
#img_resized = tf.image.flip_up_down(img_resized)
#img_resized = tf.image.rot90(img_resized)
pair_element[self.img_resized] = img_resized
pair_element[self.label] = tf.cast(pair_element[PairGenerator.label], tf.float32)
return pair_element
generator = PairGenerator()
iter = generator.get_next_pair()
for i in range(10):
print(next(iter))
ds = Dataset(generator)
import matplotlib.pyplot as plt
imgplot = plt.imshow(out)
imgplot = plt.imshow(1 - out)
Ok so the solution was
imgplot = plt.imshow(out/255)

weird python object attribute error

I have encountered a very weird problem.
Please see the below code. In the class there is an attribute 'weird' that is defined like all other attributes. (problem area of the code marked by
========================
========================)
But when i train to access it in one of the functions it will raise an error saying the attribute does not exist.
However if I remove the line accessing that attribute in the function, and then create an object, that attribute of the object can be accessed...
Could you please have a look at the code and see what is going wrong, i am at my wit's end here... :'(
class img_iter(DataIter):
def __init__(self, dir_train,
dir_label,
data_name = "data",
label_name = "softmax_label",
last_batch_handle = 'pad',
batch_size = 1,
#===================================================
#===================================================
color_mean = (117, 117, 117),
#===================================================
#===================================================
cut_off_size = None):
super().__init__()
# directories as attributes
self.dir_train = dir_train
self.dir_label = dir_label
# names
self.data_name = data_name
self.label_name = label_name
# read data and label files into list
self.img_data_lst = [s for s in os.listdir(dir_train) if '.jpg' in s]
self.img_data_iter = iter(self.img_data_lst)
if self.dir_label is not None:
self.img_label_lst = [s for s in os.listdir(dir_label) if '.gif' in s]
# number of data files
self.num_data = len(self.img_data_lst)
# read data when initialising
self.data, self.label = self._read()
# size limiter
self.cut_off_size = cut_off_size
# batch size
self.batch_size = batch_size
# data cursor
self.cursor = -batch_size
#===================================================
#===================================================
self.weird = np.array(color_mean)
#===================================================
#===================================================
self.last_batch_handle = last_batch_handle
def _read(self):
"""get two list, each list contains two elements: name and nd.array
value"""
data = {}
label = {}
data[self.data_name], label[self.label_name] = self._read_img()
return list(data.items()), list(label.items())
def _read_img(self):
# get next data file from the file name iterator
img_name = self.img_data_iter.__next__()
# open image file
img = Image.open(os.path.join(self.dir_train, img_name))
# find corresponding label image and open [s for s in self.img_label_lst if img_name in s][0]
label_name = img_name.split('.')[0] + '_mask.gif'
label = Image.open(os.path.join(self.dir_label, label_name))
# check image file size match
assert img.size == label.size
# convert into numpy array and manipulate, resulting 3d array: height, width, color
img = np.array(img, dtype = np.float32)
#===================================================
#===================================================
#img = img - self.weird.reshape(1,1,3)
test = self.weird
#===================================================
#===================================================
img = np.swapaxes(img, 0, 2)
# (c, h, w)
img = np.swapaxes(img, 1, 2)
# (1, c, h, w)
img = np.expand_dims(img, axis=0)
# resulting 2d array: height, width
label = np.array(label)
# (h, w)
label = np.array(label)
# (1, h, w)
label = np.expand_dims(label, axis=0)
return (img, label)
def reset(self):
self.cursor = -1
self.img_data_iter = iter(self.img_data_lst)
def iter_next(self):
self.cursor += 1
if (self.cursor < self.num_data - 1):
return True
else:
return False
def next(self):
if self.iter_next():
'''
try:
self.data, self.label = self._read()
return {self.data_name : self.data[0][1],
self.label_name : self.label[0][1]}
except:
raise
'''
self.data, self.label = self._read()
return DataBatch(data = self.data, label = self.label, \
pad=self.getpad(), index=None)
else:
raise StopIteration
#property
def provide_data(self):
"""The name and shape of data provided by this iterator"""
return [(k, tuple([1] + list(v.shape[1:]))) for k, v in self.data]
#property
def provide_label(self):
"""The name and shape of label provided by this iterator"""
return [(k, tuple([1] + list(v.shape[1:]))) for k, v in self.label]
def get_batch_size(self):
return 1
screenshots:
with call to the class attribute in the function.
remove call to the class attribute, create an object and access the same attribte directly.
You are trying to access self.weird before it is defined.
self.data, self.label = self._read()
# self._read() calls self. _read_img()
# which tries to access self.weird
# => AttributeError...
#...
# move this line above `self.data...`,
# and all should be well!
self.weird = np.array(color_mean)
Hope this helps!

Categories