Module 3_mxrcnn.lib.mx-rcnn.symdata.loader
Expand source code
import mxnet as mx
import numpy as np
from symdata.anchor import AnchorGenerator, AnchorSampler
from symdata.image import imdecode, resize, transform, get_image, tensor_vstack
def load_test(filename, short, max_size, mean, std):
# read and transform image
im_orig = imdecode(filename)
im, im_scale = resize(im_orig, short, max_size)
height, width = im.shape[:2]
im_info = mx.nd.array([height, width, im_scale])
# transform into tensor and normalize
im_tensor = transform(im, mean, std)
# for 1-batch inference purpose, cannot use batchify (or nd.stack) to expand dims
im_tensor = mx.nd.array(im_tensor).expand_dims(0)
im_info = mx.nd.array(im_info).expand_dims(0)
# transform cv2 BRG image to RGB for matplotlib
im_orig = im_orig[:, :, (2, 1, 0)]
return im_tensor, im_info, im_orig
def generate_batch(im_tensor, im_info):
"""return batch"""
data = [im_tensor, im_info]
data_shapes = [('data', im_tensor.shape), ('im_info', im_info.shape)]
data_batch = mx.io.DataBatch(data=data, label=None, provide_data=data_shapes, provide_label=None)
return data_batch
class TestLoader(mx.io.DataIter):
def __init__(self, roidb, batch_size, short, max_size, mean, std):
super(TestLoader, self).__init__()
# save parameters as properties
self._roidb = roidb
self._batch_size = batch_size
self._short = short
self._max_size = max_size
self._mean = mean
self._std = std
# infer properties from roidb
self._size = len(self._roidb)
self._index = np.arange(self._size)
# decide data and label names (only for training)
self._data_name = ['data', 'im_info']
self._label_name = None
# status variable
self._cur = 0
self._data = None
self._label = None
# get first batch to fill in provide_data and provide_label
self.next()
self.reset()
@property
def provide_data(self):
return [(k, v.shape) for k, v in zip(self._data_name, self._data)]
@property
def provide_label(self):
return None
def reset(self):
self._cur = 0
def iter_next(self):
return self._cur + self._batch_size <= self._size
def next(self):
if self.iter_next():
data_batch = mx.io.DataBatch(data=self.getdata(), label=self.getlabel(),
pad=self.getpad(), index=self.getindex(),
provide_data=self.provide_data, provide_label=self.provide_label)
self._cur += self._batch_size
return data_batch
else:
raise StopIteration
def getdata(self):
indices = self.getindex()
im_tensor, im_info = [], []
for index in indices:
roi_rec = self._roidb[index]
b_im_tensor, b_im_info, _ = get_image(roi_rec, self._short, self._max_size, self._mean, self._std)
im_tensor.append(b_im_tensor)
im_info.append(b_im_info)
im_tensor = mx.nd.array(tensor_vstack(im_tensor, pad=0))
im_info = mx.nd.array(tensor_vstack(im_info, pad=0))
self._data = im_tensor, im_info
return self._data
def getlabel(self):
return None
def getindex(self):
cur_from = self._cur
cur_to = min(cur_from + self._batch_size, self._size)
return np.arange(cur_from, cur_to)
def getpad(self):
return max(self._cur + self.batch_size - self._size, 0)
class AnchorLoader(mx.io.DataIter):
def __init__(self, roidb, batch_size, short, max_size, mean, std,
feat_sym, anchor_generator: AnchorGenerator, anchor_sampler: AnchorSampler,
shuffle=False):
super(AnchorLoader, self).__init__()
# save parameters as properties
self._roidb = roidb
self._batch_size = batch_size
self._short = short
self._max_size = max_size
self._mean = mean
self._std = std
self._feat_sym = feat_sym
self._ag = anchor_generator
self._as = anchor_sampler
self._shuffle = shuffle
# infer properties from roidb
self._size = len(roidb)
self._index = np.arange(self._size)
# decide data and label names
self._data_name = ['data', 'im_info', 'gt_boxes']
self._label_name = ['label', 'bbox_target', 'bbox_weight']
# status variable
self._cur = 0
self._data = None
self._label = None
# get first batch to fill in provide_data and provide_label
self.next()
self.reset()
@property
def provide_data(self):
return [(k, v.shape) for k, v in zip(self._data_name, self._data)]
@property
def provide_label(self):
return [(k, v.shape) for k, v in zip(self._label_name, self._label)]
def reset(self):
self._cur = 0
if self._shuffle:
np.random.shuffle(self._index)
def iter_next(self):
return self._cur + self._batch_size <= self._size
def next(self):
if self.iter_next():
data_batch = mx.io.DataBatch(data=self.getdata(), label=self.getlabel(),
pad=self.getpad(), index=self.getindex(),
provide_data=self.provide_data, provide_label=self.provide_label)
self._cur += self._batch_size
return data_batch
else:
raise StopIteration
def getdata(self):
indices = self.getindex()
im_tensor, im_info, gt_boxes = [], [], []
for index in indices:
roi_rec = self._roidb[index]
b_im_tensor, b_im_info, b_gt_boxes = get_image(roi_rec, self._short, self._max_size, self._mean, self._std)
im_tensor.append(b_im_tensor)
im_info.append(b_im_info)
gt_boxes.append(b_gt_boxes)
im_tensor = mx.nd.array(tensor_vstack(im_tensor, pad=0))
im_info = mx.nd.array(tensor_vstack(im_info, pad=0))
gt_boxes = mx.nd.array(tensor_vstack(gt_boxes, pad=-1))
self._data = im_tensor, im_info, gt_boxes
return self._data
def getlabel(self):
im_tensor, im_info, gt_boxes = self._data
# all stacked image share same anchors
_, out_shape, _ = self._feat_sym.infer_shape(data=im_tensor.shape)
feat_height, feat_width = out_shape[0][-2:]
anchors = self._ag.generate(feat_height, feat_width)
# assign anchor according to their real size encoded in im_info
label, bbox_target, bbox_weight = [], [], []
for batch_ind in range(im_info.shape[0]):
b_im_info = im_info[batch_ind].asnumpy()
b_gt_boxes = gt_boxes[batch_ind].asnumpy()
b_im_height, b_im_width = b_im_info[:2]
b_label, b_bbox_target, b_bbox_weight = self._as.assign(anchors, b_gt_boxes, b_im_height, b_im_width)
b_label = b_label.reshape((feat_height, feat_width, -1)).transpose((2, 0, 1)).flatten()
b_bbox_target = b_bbox_target.reshape((feat_height, feat_width, -1)).transpose((2, 0, 1))
b_bbox_weight = b_bbox_weight.reshape((feat_height, feat_width, -1)).transpose((2, 0, 1))
label.append(b_label)
bbox_target.append(b_bbox_target)
bbox_weight.append(b_bbox_weight)
label = mx.nd.array(tensor_vstack(label, pad=-1))
bbox_target = mx.nd.array(tensor_vstack(bbox_target, pad=0))
bbox_weight = mx.nd.array(tensor_vstack(bbox_weight, pad=0))
self._label = label, bbox_target, bbox_weight
return self._label
def getindex(self):
cur_from = self._cur
cur_to = min(cur_from + self._batch_size, self._size)
return np.arange(cur_from, cur_to)
def getpad(self):
return max(self._cur + self.batch_size - self._size, 0)
Functions
def generate_batch(im_tensor, im_info)
-
return batch
Expand source code
def generate_batch(im_tensor, im_info): """return batch""" data = [im_tensor, im_info] data_shapes = [('data', im_tensor.shape), ('im_info', im_info.shape)] data_batch = mx.io.DataBatch(data=data, label=None, provide_data=data_shapes, provide_label=None) return data_batch
def load_test(filename, short, max_size, mean, std)
-
Expand source code
def load_test(filename, short, max_size, mean, std): # read and transform image im_orig = imdecode(filename) im, im_scale = resize(im_orig, short, max_size) height, width = im.shape[:2] im_info = mx.nd.array([height, width, im_scale]) # transform into tensor and normalize im_tensor = transform(im, mean, std) # for 1-batch inference purpose, cannot use batchify (or nd.stack) to expand dims im_tensor = mx.nd.array(im_tensor).expand_dims(0) im_info = mx.nd.array(im_info).expand_dims(0) # transform cv2 BRG image to RGB for matplotlib im_orig = im_orig[:, :, (2, 1, 0)] return im_tensor, im_info, im_orig
Classes
class AnchorLoader (roidb, batch_size, short, max_size, mean, std, feat_sym, anchor_generator:Â symdata.anchor.AnchorGenerator, anchor_sampler:Â symdata.anchor.AnchorSampler, shuffle=False)
-
The base class for an MXNet data iterator.
All I/O in MXNet is handled by specializations of this class. Data iterators in MXNet are similar to standard-iterators in Python. On each call to
next
they return aDataBatch
which represents the next batch of data. When there is no more data to return, it raises aStopIteration
exception.Parameters
batch_size
:int
, optional- The batch size, namely the number of items in the batch.
See Also
NDArrayIter
- Data-iterator for MXNet NDArray or numpy-ndarray objects.
CSVIter
- Data-iterator for csv data.
LibSVMIter
- Data-iterator for libsvm data.
ImageIter
- Data-iterator for images.
Expand source code
class AnchorLoader(mx.io.DataIter): def __init__(self, roidb, batch_size, short, max_size, mean, std, feat_sym, anchor_generator: AnchorGenerator, anchor_sampler: AnchorSampler, shuffle=False): super(AnchorLoader, self).__init__() # save parameters as properties self._roidb = roidb self._batch_size = batch_size self._short = short self._max_size = max_size self._mean = mean self._std = std self._feat_sym = feat_sym self._ag = anchor_generator self._as = anchor_sampler self._shuffle = shuffle # infer properties from roidb self._size = len(roidb) self._index = np.arange(self._size) # decide data and label names self._data_name = ['data', 'im_info', 'gt_boxes'] self._label_name = ['label', 'bbox_target', 'bbox_weight'] # status variable self._cur = 0 self._data = None self._label = None # get first batch to fill in provide_data and provide_label self.next() self.reset() @property def provide_data(self): return [(k, v.shape) for k, v in zip(self._data_name, self._data)] @property def provide_label(self): return [(k, v.shape) for k, v in zip(self._label_name, self._label)] def reset(self): self._cur = 0 if self._shuffle: np.random.shuffle(self._index) def iter_next(self): return self._cur + self._batch_size <= self._size def next(self): if self.iter_next(): data_batch = mx.io.DataBatch(data=self.getdata(), label=self.getlabel(), pad=self.getpad(), index=self.getindex(), provide_data=self.provide_data, provide_label=self.provide_label) self._cur += self._batch_size return data_batch else: raise StopIteration def getdata(self): indices = self.getindex() im_tensor, im_info, gt_boxes = [], [], [] for index in indices: roi_rec = self._roidb[index] b_im_tensor, b_im_info, b_gt_boxes = get_image(roi_rec, self._short, self._max_size, self._mean, self._std) im_tensor.append(b_im_tensor) im_info.append(b_im_info) gt_boxes.append(b_gt_boxes) im_tensor = mx.nd.array(tensor_vstack(im_tensor, pad=0)) im_info = mx.nd.array(tensor_vstack(im_info, pad=0)) gt_boxes = mx.nd.array(tensor_vstack(gt_boxes, pad=-1)) self._data = im_tensor, im_info, gt_boxes return self._data def getlabel(self): im_tensor, im_info, gt_boxes = self._data # all stacked image share same anchors _, out_shape, _ = self._feat_sym.infer_shape(data=im_tensor.shape) feat_height, feat_width = out_shape[0][-2:] anchors = self._ag.generate(feat_height, feat_width) # assign anchor according to their real size encoded in im_info label, bbox_target, bbox_weight = [], [], [] for batch_ind in range(im_info.shape[0]): b_im_info = im_info[batch_ind].asnumpy() b_gt_boxes = gt_boxes[batch_ind].asnumpy() b_im_height, b_im_width = b_im_info[:2] b_label, b_bbox_target, b_bbox_weight = self._as.assign(anchors, b_gt_boxes, b_im_height, b_im_width) b_label = b_label.reshape((feat_height, feat_width, -1)).transpose((2, 0, 1)).flatten() b_bbox_target = b_bbox_target.reshape((feat_height, feat_width, -1)).transpose((2, 0, 1)) b_bbox_weight = b_bbox_weight.reshape((feat_height, feat_width, -1)).transpose((2, 0, 1)) label.append(b_label) bbox_target.append(b_bbox_target) bbox_weight.append(b_bbox_weight) label = mx.nd.array(tensor_vstack(label, pad=-1)) bbox_target = mx.nd.array(tensor_vstack(bbox_target, pad=0)) bbox_weight = mx.nd.array(tensor_vstack(bbox_weight, pad=0)) self._label = label, bbox_target, bbox_weight return self._label def getindex(self): cur_from = self._cur cur_to = min(cur_from + self._batch_size, self._size) return np.arange(cur_from, cur_to) def getpad(self): return max(self._cur + self.batch_size - self._size, 0)
Ancestors
- mxnet.io.io.DataIter
Instance variables
var provide_data
-
Expand source code
@property def provide_data(self): return [(k, v.shape) for k, v in zip(self._data_name, self._data)]
var provide_label
-
Expand source code
@property def provide_label(self): return [(k, v.shape) for k, v in zip(self._label_name, self._label)]
Methods
def getdata(self)
-
Get data of current batch.
Returns
list
ofNDArray
- The data of the current batch.
Expand source code
def getdata(self): indices = self.getindex() im_tensor, im_info, gt_boxes = [], [], [] for index in indices: roi_rec = self._roidb[index] b_im_tensor, b_im_info, b_gt_boxes = get_image(roi_rec, self._short, self._max_size, self._mean, self._std) im_tensor.append(b_im_tensor) im_info.append(b_im_info) gt_boxes.append(b_gt_boxes) im_tensor = mx.nd.array(tensor_vstack(im_tensor, pad=0)) im_info = mx.nd.array(tensor_vstack(im_info, pad=0)) gt_boxes = mx.nd.array(tensor_vstack(gt_boxes, pad=-1)) self._data = im_tensor, im_info, gt_boxes return self._data
def getindex(self)
-
Get index of the current batch.
Returns
index
:numpy.array
- The indices of examples in the current batch.
Expand source code
def getindex(self): cur_from = self._cur cur_to = min(cur_from + self._batch_size, self._size) return np.arange(cur_from, cur_to)
def getlabel(self)
-
Get label of the current batch.
Returns
list
ofNDArray
- The label of the current batch.
Expand source code
def getlabel(self): im_tensor, im_info, gt_boxes = self._data # all stacked image share same anchors _, out_shape, _ = self._feat_sym.infer_shape(data=im_tensor.shape) feat_height, feat_width = out_shape[0][-2:] anchors = self._ag.generate(feat_height, feat_width) # assign anchor according to their real size encoded in im_info label, bbox_target, bbox_weight = [], [], [] for batch_ind in range(im_info.shape[0]): b_im_info = im_info[batch_ind].asnumpy() b_gt_boxes = gt_boxes[batch_ind].asnumpy() b_im_height, b_im_width = b_im_info[:2] b_label, b_bbox_target, b_bbox_weight = self._as.assign(anchors, b_gt_boxes, b_im_height, b_im_width) b_label = b_label.reshape((feat_height, feat_width, -1)).transpose((2, 0, 1)).flatten() b_bbox_target = b_bbox_target.reshape((feat_height, feat_width, -1)).transpose((2, 0, 1)) b_bbox_weight = b_bbox_weight.reshape((feat_height, feat_width, -1)).transpose((2, 0, 1)) label.append(b_label) bbox_target.append(b_bbox_target) bbox_weight.append(b_bbox_weight) label = mx.nd.array(tensor_vstack(label, pad=-1)) bbox_target = mx.nd.array(tensor_vstack(bbox_target, pad=0)) bbox_weight = mx.nd.array(tensor_vstack(bbox_weight, pad=0)) self._label = label, bbox_target, bbox_weight return self._label
def getpad(self)
-
Get the number of padding examples in the current batch.
Returns
int
- Number of padding examples in the current batch.
Expand source code
def getpad(self): return max(self._cur + self.batch_size - self._size, 0)
def iter_next(self)
-
Move to the next batch.
Returns
boolean
- Whether the move is successful.
Expand source code
def iter_next(self): return self._cur + self._batch_size <= self._size
def next(self)
-
Get next data batch from iterator.
Returns
DataBatch
- The data of next batch.
Raises
StopIteration
- If the end of the data is reached.
Expand source code
def next(self): if self.iter_next(): data_batch = mx.io.DataBatch(data=self.getdata(), label=self.getlabel(), pad=self.getpad(), index=self.getindex(), provide_data=self.provide_data, provide_label=self.provide_label) self._cur += self._batch_size return data_batch else: raise StopIteration
def reset(self)
-
Reset the iterator to the begin of the data.
Expand source code
def reset(self): self._cur = 0 if self._shuffle: np.random.shuffle(self._index)
class TestLoader (roidb, batch_size, short, max_size, mean, std)
-
The base class for an MXNet data iterator.
All I/O in MXNet is handled by specializations of this class. Data iterators in MXNet are similar to standard-iterators in Python. On each call to
next
they return aDataBatch
which represents the next batch of data. When there is no more data to return, it raises aStopIteration
exception.Parameters
batch_size
:int
, optional- The batch size, namely the number of items in the batch.
See Also
NDArrayIter
- Data-iterator for MXNet NDArray or numpy-ndarray objects.
CSVIter
- Data-iterator for csv data.
LibSVMIter
- Data-iterator for libsvm data.
ImageIter
- Data-iterator for images.
Expand source code
class TestLoader(mx.io.DataIter): def __init__(self, roidb, batch_size, short, max_size, mean, std): super(TestLoader, self).__init__() # save parameters as properties self._roidb = roidb self._batch_size = batch_size self._short = short self._max_size = max_size self._mean = mean self._std = std # infer properties from roidb self._size = len(self._roidb) self._index = np.arange(self._size) # decide data and label names (only for training) self._data_name = ['data', 'im_info'] self._label_name = None # status variable self._cur = 0 self._data = None self._label = None # get first batch to fill in provide_data and provide_label self.next() self.reset() @property def provide_data(self): return [(k, v.shape) for k, v in zip(self._data_name, self._data)] @property def provide_label(self): return None def reset(self): self._cur = 0 def iter_next(self): return self._cur + self._batch_size <= self._size def next(self): if self.iter_next(): data_batch = mx.io.DataBatch(data=self.getdata(), label=self.getlabel(), pad=self.getpad(), index=self.getindex(), provide_data=self.provide_data, provide_label=self.provide_label) self._cur += self._batch_size return data_batch else: raise StopIteration def getdata(self): indices = self.getindex() im_tensor, im_info = [], [] for index in indices: roi_rec = self._roidb[index] b_im_tensor, b_im_info, _ = get_image(roi_rec, self._short, self._max_size, self._mean, self._std) im_tensor.append(b_im_tensor) im_info.append(b_im_info) im_tensor = mx.nd.array(tensor_vstack(im_tensor, pad=0)) im_info = mx.nd.array(tensor_vstack(im_info, pad=0)) self._data = im_tensor, im_info return self._data def getlabel(self): return None def getindex(self): cur_from = self._cur cur_to = min(cur_from + self._batch_size, self._size) return np.arange(cur_from, cur_to) def getpad(self): return max(self._cur + self.batch_size - self._size, 0)
Ancestors
- mxnet.io.io.DataIter
Instance variables
var provide_data
-
Expand source code
@property def provide_data(self): return [(k, v.shape) for k, v in zip(self._data_name, self._data)]
var provide_label
-
Expand source code
@property def provide_label(self): return None
Methods
def getdata(self)
-
Get data of current batch.
Returns
list
ofNDArray
- The data of the current batch.
Expand source code
def getdata(self): indices = self.getindex() im_tensor, im_info = [], [] for index in indices: roi_rec = self._roidb[index] b_im_tensor, b_im_info, _ = get_image(roi_rec, self._short, self._max_size, self._mean, self._std) im_tensor.append(b_im_tensor) im_info.append(b_im_info) im_tensor = mx.nd.array(tensor_vstack(im_tensor, pad=0)) im_info = mx.nd.array(tensor_vstack(im_info, pad=0)) self._data = im_tensor, im_info return self._data
def getindex(self)
-
Get index of the current batch.
Returns
index
:numpy.array
- The indices of examples in the current batch.
Expand source code
def getindex(self): cur_from = self._cur cur_to = min(cur_from + self._batch_size, self._size) return np.arange(cur_from, cur_to)
def getlabel(self)
-
Get label of the current batch.
Returns
list
ofNDArray
- The label of the current batch.
Expand source code
def getlabel(self): return None
def getpad(self)
-
Get the number of padding examples in the current batch.
Returns
int
- Number of padding examples in the current batch.
Expand source code
def getpad(self): return max(self._cur + self.batch_size - self._size, 0)
def iter_next(self)
-
Move to the next batch.
Returns
boolean
- Whether the move is successful.
Expand source code
def iter_next(self): return self._cur + self._batch_size <= self._size
def next(self)
-
Get next data batch from iterator.
Returns
DataBatch
- The data of next batch.
Raises
StopIteration
- If the end of the data is reached.
Expand source code
def next(self): if self.iter_next(): data_batch = mx.io.DataBatch(data=self.getdata(), label=self.getlabel(), pad=self.getpad(), index=self.getindex(), provide_data=self.provide_data, provide_label=self.provide_label) self._cur += self._batch_size return data_batch else: raise StopIteration
def reset(self)
-
Reset the iterator to the begin of the data.
Expand source code
def reset(self): self._cur = 0