def __init__(self, roidb, batch_size=1, shuffle=False): """ This Iter will provide roi data to Fast R-CNN network :param feat_sym: to infer shape of assign_output :param roidb: must be preprocessed :param batch_size: must divide BATCH_SIZE(128) :param shuffle: bool :param ctx: list of contexts :return: AnchorLoader """ # save parameters as properties self.roidb = roidb self.batch_size = batch_size self.shuffle = shuffle # infer properties from roidb self.size = len(roidb) # print('dataloader self.size = ',self.size) self.index = np.arange(self.size) # status variable for synchronization between get_data and get_label self.cur = 0 self.batch = None self.data = None self.label = None # infer shape feat_shape_list = [[batch_size, 4, 20, 20], [batch_size, 4, 40, 40], [batch_size, 4, 80, 80]] # 这是三个stride的feature map大小 self.aa = AA(feat_shape_list) self._debug = False self._debug_id = 0 self._times = [0.0, 0.0, 0.0, 0.0] # get first batch to fill in provide_data and provide_label self.reset()
def __init__(self, feat_sym, roidb, batch_size=1, shuffle=False, ctx=None, work_load_list=None, aspect_grouping=False): """ This Iter will provide roi data to Fast R-CNN network :param feat_sym: to infer shape of assign_output :param roidb: must be preprocessed :param batch_size: must divide BATCH_SIZE(128) :param shuffle: bool :param ctx: list of contexts :param work_load_list: list of work load :param aspect_grouping: group images with similar aspects :return: AnchorLoader """ super(CropLoader, self).__init__() # save parameters as properties self.feat_sym = feat_sym self.roidb = roidb self.batch_size = batch_size self.shuffle = shuffle self.ctx = ctx if self.ctx is None: self.ctx = [mx.cpu()] self.work_load_list = work_load_list #self.feat_stride = feat_stride #self.anchor_scales = anchor_scales #self.anchor_ratios = anchor_ratios #self.allowed_border = allowed_border self.aspect_grouping = aspect_grouping self.feat_stride = config.RPN_FEAT_STRIDE # infer properties from roidb self.size = len(roidb) self.index = np.arange(self.size) # decide data and label names #self.data_name = ['data'] #self.label_name = [] #self.label_name.append('label') #self.label_name.append('bbox_target') #self.label_name.append('bbox_weight') self.data_name = ['data'] #self.label_name = ['label', 'bbox_target', 'bbox_weight'] self.label_name = [] prefixes = ['face'] if config.HEAD_BOX: prefixes.append('head') names = [] for prefix in prefixes: names += [ prefix + '_label', prefix + '_bbox_target', prefix + '_bbox_weight' ] if prefix == 'face' and config.FACE_LANDMARK: names += [ prefix + '_landmark_target', prefix + '_landmark_weight' ] #names = ['label', 'bbox_weight'] for stride in self.feat_stride: for n in names: k = "%s_stride%d" % (n, stride) self.label_name.append(k) if config.CASCADE > 0: self.label_name.append('gt_boxes') # status variable for synchronization between get_data and get_label self.cur = 0 self.batch = None self.data = None self.label = None # infer shape feat_shape_list = [] _data_shape = [('data', (1, 3, max([v[1] for v in config.SCALES]), max([v[1] for v in config.SCALES])))] _data_shape = dict(_data_shape) for i in range(len(self.feat_stride)): _, feat_shape, _ = self.feat_sym[i].infer_shape(**_data_shape) feat_shape = [int(i) for i in feat_shape[0]] feat_shape_list.append(feat_shape) self.aa = AA(feat_shape_list) self._debug = False self._debug_id = 0 self._times = [0.0, 0.0, 0.0, 0.0] # get first batch to fill in provide_data and provide_label self.reset() self.get_batch()
class CropLoader(mx.io.DataIter): def __init__(self, feat_sym, roidb, batch_size=1, shuffle=False, ctx=None, work_load_list=None, aspect_grouping=False): """ This Iter will provide roi data to Fast R-CNN network :param feat_sym: to infer shape of assign_output :param roidb: must be preprocessed :param batch_size: must divide BATCH_SIZE(128) :param shuffle: bool :param ctx: list of contexts :param work_load_list: list of work load :param aspect_grouping: group images with similar aspects :return: AnchorLoader """ super(CropLoader, self).__init__() # save parameters as properties self.feat_sym = feat_sym self.roidb = roidb self.batch_size = batch_size self.shuffle = shuffle self.ctx = ctx if self.ctx is None: self.ctx = [mx.cpu()] self.work_load_list = work_load_list #self.feat_stride = feat_stride #self.anchor_scales = anchor_scales #self.anchor_ratios = anchor_ratios #self.allowed_border = allowed_border self.aspect_grouping = aspect_grouping self.feat_stride = config.RPN_FEAT_STRIDE # infer properties from roidb self.size = len(roidb) self.index = np.arange(self.size) # decide data and label names #self.data_name = ['data'] #self.label_name = [] #self.label_name.append('label') #self.label_name.append('bbox_target') #self.label_name.append('bbox_weight') self.data_name = ['data'] #self.label_name = ['label', 'bbox_target', 'bbox_weight'] self.label_name = [] prefixes = ['face'] if config.HEAD_BOX: prefixes.append('head') names = [] for prefix in prefixes: names += [ prefix + '_label', prefix + '_bbox_target', prefix + '_bbox_weight' ] if prefix == 'face' and config.FACE_LANDMARK: names += [ prefix + '_landmark_target', prefix + '_landmark_weight' ] #names = ['label', 'bbox_weight'] for stride in self.feat_stride: for n in names: k = "%s_stride%d" % (n, stride) self.label_name.append(k) if config.CASCADE > 0: self.label_name.append('gt_boxes') # status variable for synchronization between get_data and get_label self.cur = 0 self.batch = None self.data = None self.label = None # infer shape feat_shape_list = [] _data_shape = [('data', (1, 3, max([v[1] for v in config.SCALES]), max([v[1] for v in config.SCALES])))] _data_shape = dict(_data_shape) for i in range(len(self.feat_stride)): _, feat_shape, _ = self.feat_sym[i].infer_shape(**_data_shape) feat_shape = [int(i) for i in feat_shape[0]] feat_shape_list.append(feat_shape) self.aa = AA(feat_shape_list) self._debug = False self._debug_id = 0 self._times = [0.0, 0.0, 0.0, 0.0] # get first batch to fill in provide_data and provide_label self.reset() self.get_batch() @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(): self.get_batch() self.cur += self.batch_size return mx.io.DataBatch(data=self.data, label=self.label, pad=self.getpad(), index=self.getindex(), provide_data=self.provide_data, provide_label=self.provide_label) else: raise StopIteration def getindex(self): return self.cur / self.batch_size def getpad(self): if self.cur + self.batch_size > self.size: return self.cur + self.batch_size - self.size else: return 0 def infer_shape(self, max_data_shape=None, max_label_shape=None): """ Return maximum data and label shape for single gpu """ if max_data_shape is None: max_data_shape = [] if max_label_shape is None: max_label_shape = [] max_shapes = dict(max_data_shape + max_label_shape) input_batch_size = max_shapes['data'][0] dummy_boxes = np.zeros((0, 5)) dummy_info = [[max_shapes['data'][2], max_shapes['data'][3], 1.0]] dummy_label = {'gt_boxes': dummy_boxes} dummy_blur = np.zeros((0, )) dummy_label['gt_blur'] = dummy_blur label_dict = {} if config.HEAD_BOX: head_label_dict = self.aa.assign_anchor_fpn(dummy_label, dummy_info, False, prefix='head') label_dict.update(head_label_dict) if config.FACE_LANDMARK: dummy_landmarks = np.zeros((0, 5, 3)) dummy_label['gt_landmarks'] = dummy_landmarks face_label_dict = self.aa.assign_anchor_fpn(dummy_label, dummy_info, config.FACE_LANDMARK, prefix='face') label_dict.update(face_label_dict) if config.CASCADE > 0: label_dict['gt_boxes'] = np.zeros( (0, config.TRAIN.MAX_BBOX_PER_IMAGE, 5), dtype=np.float32) label_list = [] for k in self.label_name: label_list.append(label_dict[k]) label_shape = [(k, tuple([input_batch_size] + list(v.shape[1:]))) for k, v in zip(self.label_name, label_list)] return max_data_shape, label_shape def get_batch(self): # slice roidb cur_from = self.cur cur_to = min(cur_from + self.batch_size, self.size) assert cur_to == cur_from + self.batch_size roidb = [self.roidb[self.index[i]] for i in range(cur_from, cur_to)] # decide multi device slice work_load_list = self.work_load_list ctx = self.ctx if work_load_list is None: work_load_list = [1] * len(ctx) assert isinstance(work_load_list, list) and len(work_load_list) == len(ctx), \ "Invalid settings for work load. " slices = _split_input_slice(self.batch_size, work_load_list) # get testing data for multigpu data_list = [] label_list = [] for islice in slices: iroidb = [roidb[i] for i in range(islice.start, islice.stop)] data, label = get_crop_batch(iroidb) data_list += data label_list += label #data_list.append(data) #label_list.append(label) # pad data first and then assign anchor (read label) #data_tensor = tensor_vstack([batch['data'] for batch in data_list]) #for i_card in range(len(data_list)): # data_list[i_card]['data'] = data_tensor[ # i_card * config.TRAIN.BATCH_IMAGES:(1 + i_card) * config.TRAIN.BATCH_IMAGES] #iiddxx = 0 select_stride = 0 if config.RANDOM_FEAT_STRIDE: select_stride = random.choice(config.RPN_FEAT_STRIDE) for data, label in zip(data_list, label_list): data_shape = {k: v.shape for k, v in data.items()} del data_shape['im_info'] feat_shape_list = [] for s in range(len(self.feat_stride)): _, feat_shape, _ = self.feat_sym[s].infer_shape(**data_shape) feat_shape = [int(i) for i in feat_shape[0]] feat_shape_list.append(feat_shape) im_info = data['im_info'] gt_boxes = label['gt_boxes'] gt_label = {'gt_boxes': gt_boxes} if config.USE_BLUR: gt_blur = label['gt_blur'] gt_label['gt_blur'] = gt_blur if self._debug: img = data['data'].copy()[0].transpose( (1, 2, 0))[:, :, ::-1].copy() print('DEBUG SHAPE', data['data'].shape, label['gt_boxes'].shape) box = label['gt_boxes'].copy()[0][0:4].astype(np.int) cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2) filename = './debugout/%d.png' % (self._debug_id) print('debug write', filename) cv2.imwrite(filename, img) self._debug_id += 1 #print('DEBUG', img.shape, bbox.shape) label_dict = {} if config.HEAD_BOX: head_label_dict = self.aa.assign_anchor_fpn( gt_label, im_info, False, prefix='head', select_stride=select_stride) label_dict.update(head_label_dict) if config.FACE_LANDMARK: gt_landmarks = label['gt_landmarks'] gt_label['gt_landmarks'] = gt_landmarks #ta = datetime.datetime.now() #face_label_dict = assign_anchor_fpn(feat_shape_list, gt_label, im_info, config.FACE_LANDMARK, prefix='face', select_stride = select_stride) face_label_dict = self.aa.assign_anchor_fpn( gt_label, im_info, config.FACE_LANDMARK, prefix='face', select_stride=select_stride) #tb = datetime.datetime.now() #self._times[0] += (tb-ta).total_seconds() label_dict.update(face_label_dict) #for k in label_dict: # print(k, label_dict[k].shape) if config.CASCADE > 0: pad_gt_boxes = np.empty( (1, config.TRAIN.MAX_BBOX_PER_IMAGE, 5), dtype=np.float32) pad_gt_boxes.fill(-1) pad_gt_boxes[0, 0:gt_boxes.shape[0], :] = gt_boxes label_dict['gt_boxes'] = pad_gt_boxes #print('im_info', im_info.shape) #print(gt_boxes.shape) for k in self.label_name: label[k] = label_dict[k] all_data = dict() for key in self.data_name: all_data[key] = tensor_vstack([batch[key] for batch in data_list]) all_label = dict() for key in self.label_name: pad = 0 if key.startswith('bbox_') else -1 #print('label vstack', key, pad, len(label_list), file=sys.stderr) all_label[key] = tensor_vstack( [batch[key] for batch in label_list], pad=pad) self.data = [mx.nd.array(all_data[key]) for key in self.data_name] self.label = [mx.nd.array(all_label[key]) for key in self.label_name]
class DataLoader(): def __init__(self, roidb, batch_size=1, shuffle=False): """ This Iter will provide roi data to Fast R-CNN network :param feat_sym: to infer shape of assign_output :param roidb: must be preprocessed :param batch_size: must divide BATCH_SIZE(128) :param shuffle: bool :param ctx: list of contexts :return: AnchorLoader """ # save parameters as properties self.roidb = roidb self.batch_size = batch_size self.shuffle = shuffle # infer properties from roidb self.size = len(roidb) # print('dataloader self.size = ',self.size) self.index = np.arange(self.size) # status variable for synchronization between get_data and get_label self.cur = 0 self.batch = None self.data = None self.label = None # infer shape feat_shape_list = [[batch_size, 4, 20, 20], [batch_size, 4, 40, 40], [batch_size, 4, 80, 80]] # 这是三个stride的feature map大小 self.aa = AA(feat_shape_list) self._debug = False self._debug_id = 0 self._times = [0.0, 0.0, 0.0, 0.0] # get first batch to fill in provide_data and provide_label self.reset() def __iter__(self): return self def reset(self): self.cur = 0 if self.shuffle: print('core/loader: shuffle roidb!\n') random.shuffle(self.roidb) def iter_next(self): return self.cur + self.batch_size <= self.size def get_next(self): if self.iter_next(): batch_roidb = [ self.roidb[i] for i in range(self.cur, self.cur + self.batch_size) ] # print('batch_roidb len=', len(batch_roidb)) data, label = self.get_batch(batch_roidb) label = label_concat(label) self.cur += self.batch_size return data[0], label #TODO :data的第一维度是gpu数目,目前是单GPU else: raise StopIteration def getindex(self): return self.cur / self.batch_size def get_batch(self, roidb): label_name = config.label_name data_name = config.data_name # get testing data for multigpu data_list = [] label_list = [] # TODO:获取单个GPU的rpn_batch,data = {'data': im_array, 'im_info': im_info},label = {'gt_landmarks','gt_boxes'} data, label = get_crop_batch(roidb) # 返回真实label # print('core/loader: label.shape = ', np.array(label).shape,'\n') data_list += data label_list += label # 每个元素为一张图片 # print('core/loader: label_list.shape = ',np.array(label_list).shape) # print('core/loader: before!! label_list[0] = ',label_list[0]) select_stride = 0 for data, label in zip(data_list, label_list): # 这里的label是dict data_shape = {k: v.shape for k, v in data.items()} del data_shape['im_info'] im_info = data['im_info'] gt_boxes = label['gt_boxes'] # print('loader/get_batch: in the gt_label! gt_bboxes.shape=',gt_boxes.shape) gt_label = {'gt_boxes': gt_boxes} label_dict = {} if config.FACE_LANDMARK: gt_landmarks = label['gt_landmarks'] # print('loader/get_batch: in the gt_label! gt_landmarks.shape=', gt_landmarks.shape) gt_label['gt_landmarks'] = gt_landmarks # TODO 上面把label赋值给gt_label的操作好像是没有意义的,gt_label与label没有区别. but, 后面label好像变了,但是否影响这里呢? # ta = datetime.datetime.now() # TODO:产生训练label face_label_dict = self.aa.assign_anchor_fpn( gt_label, im_info, config.FACE_LANDMARK, prefix='face', select_stride=select_stride) # print('face_label_dict.keys = ',face_label_dict.keys()) # tb = datetime.datetime.now() # self._times[0] += (tb-ta).total_seconds() label_dict.update(face_label_dict) # print('im_info', im_info.shape) # print(gt_boxes.shape) for k in label_name: label[k] = label_dict[ k] # TODO 这里实际上是在更新label_list, 由zip函数返回的label应该是引用关系 # print('core/loader: after!! label_list[0] = ', label_list[0]) all_data = dict() for key in data_name: all_data[key] = tensor_vstack([batch[key] for batch in data_list]) all_label = dict() for key in label_name: pad = 0 if key.startswith('bbox_') else -1 # print('label vstack', key, pad, len(label_list), file=sys.stderr) all_label[key] = tensor_vstack( [batch[key] for batch in label_list], pad=pad) # 这里的batch其实就是dict,这个函数的作用是将所有的图片的相同key的list叠起来 # print('batch_key_list len = ',len([batch['gt_boxes'] for batch in label_list])) labels = {} data = [np.array(all_data[key]) for key in data_name] # print('label_list len = ', len([np.array(all_label[key])for key in label_name])) label_d = {} for key in label_name: label_d[key] = all_label[key] # label = [np.array()for key in label_name] #该list是按照顺序存的,要记住label和本list中的array的对应顺序 # for key in label_d.keys(): # print('{}: {}'.format(key,label_d[key].shape)) return data, label_d