def grad(self, inputs, outputs): """ Grad implement(i.e. backward-pass). Parameters ---------- inputs : sequence of strs Indicating the operator's inputs + in-grads. The first N strs in sequence is inputs. The N + 1 ... 2N strs in sequence is in-grads. outputs : sequence of strs Indicating the operator's out-grads Returns ------- None """ x1 = ws.FetchTensor(inputs[0]) x2 = ws.FetchTensor(inputs[1]) dy = ws.FetchTensor(inputs[-1]) dx1 = dy * x2 dx2 = dy * x1 ws.FeedTensor(outputs[0], dx1) ws.FeedTensor(outputs[1], dx2)
def forward(self, bottom, top): # fetch matches between default boxes and gt boxes all_match_inds = ws.FetchTensor(bottom[0]) # fetch the labels (after hard mining possibly) all_match_labels = ws.FetchTensor(bottom[1]) # fetch the default boxes(anchors) prior_boxes = ws.FetchTensor(bottom[2]) # fetch the annotations annotations = ws.FetchTensor(bottom[3]) # decode gt boxes from annotations all_gt_boxes = self._fetch_gt_boxes(annotations) num_images = len(all_gt_boxes) num_priors = len(prior_boxes) all_bbox_targets = np.zeros((num_images, num_priors, 12), dtype=np.float32) all_bbox_inside_weights = np.zeros(all_bbox_targets.shape, dtype=np.float32) all_bbox_outside_weights = np.zeros(all_bbox_targets.shape, dtype=np.float32) # number of matched boxes(#positive) # we divide it by ``IMS_PER_BATCH`` as SmoothLLLoss will divide it also bbox_normalization = len( np.where(all_match_labels > 0)[0]) / cfg.TRAIN.IMS_PER_BATCH for im_idx in xrange(num_images): match_inds = all_match_inds[im_idx] match_labels = all_match_labels[im_idx] gt_boxes = np.array(all_gt_boxes[im_idx], dtype=np.float32) # sample fg-rois(default boxes) & gt-rois(gt boxes) ex_inds = np.where(match_labels > 0)[0] ex_rois = prior_boxes[ex_inds] gt_assignment = match_inds[ex_inds].astype(np.int32, copy=False) gt_rois = gt_boxes[gt_assignment] # compute fg targets targets = self._compute_targets(ex_rois, gt_rois) # assign targets & inside weights & outside weights all_bbox_targets[im_idx][ex_inds] = targets[:, 1:] all_bbox_inside_weights[im_idx, :] = cfg.TRAIN.BBOX_INSIDE_WEIGHTS all_bbox_outside_weights[im_idx][ ex_inds] = 1.0 / bbox_normalization # feed bbox targets to compute bbox regression loss ws.FeedTensor(top[0], all_bbox_targets) # feed inside weights for SmoothL1Loss ws.FeedTensor(top[1], all_bbox_inside_weights) # feed outside weights for SmoothL1Loss ws.FeedTensor(top[2], all_bbox_outside_weights)
def forward(self, bottom, top): # assign output ws.FeedTensor(top[0], self.data) ws.FeedTensor(top[1], self.label) # pick next input if self.random: self.idx = random.randint(0, len(self.indices)-1) else: self.idx += 1 if self.idx == len(self.indices): self.idx = 0
def shared(value, name=None, borrow=False): if name is None: name = GetTensorName() if not isinstance(value, np.ndarray): raise TypeError('shared variables be a numpy array') tensor = Tensor(name).Variable() ws.FeedTensor(tensor, value) return tensor
def At(inputs, indices=[], axis=0, acc_gradient=False, **kwargs): args = locals() kwargs = args['kwargs'] del args['kwargs'] kwargs = dict(args, **kwargs) if isinstance(inputs, list): if len(inputs) != 2: raise TypeError('At Operator accpets a list of 2 Tensors') elif isinstance(inputs, Tensor): if not isinstance(indices, list): raise TypeError('At Operator accepts a list of indices') indices = np.array(indices, dtype=np.float32) tensor = GetTensorName() ws.FeedTensor(tensor, indices) kwargs['inputs'] = [kwargs['inputs'], Tensor(tensor)] output = Tensor.CreateOperator(op_type='At', nout=1, **kwargs) if isinstance(inputs, Tensor): if inputs.shape is not None: output.shape = inputs.shape[:] output.shape[axis] = len(indices) return output
def __rdiv__(self, other): """Calculate y / x. Parameters ---------- other : Tensor The y. Returns ------- Tensor The output tensor. """ if not isinstance(other, Tensor): if not isinstance(other, np.ndarray): if not isinstance(other, list): other = [other] other = np.array(other, dtype=np.float32) tensor = Tensor(GetTensorName()) ws.FeedTensor(tensor, other) other = tensor output = self.CreateOperator(inputs=[other, self], nout=1, op_type='RDiv') if self.shape is not None: output.shape = self.shape[:] return output
def GraphDef_Update(graph_def, updater): """ generate all update targets for CC Graph """ if updater is None: return updater._prefix = graph_def.name + '_' extra_kwargs = updater._extra_kwargs extra_kwargs['domain'] = updater._prefix # wrap hyper-parameters as Tensor for CC for k, v in updater._hyper_params.items(): ws.FeedTensor(updater._prefix + k, np.array([v], dtype=np.float32)) # check data parallel if necessary if mpi.is_init(): idx, group = mpi.allow_parallel() if idx != -1: extra_kwargs['comm'], extra_kwargs['group'] \ = mpi.group(root=group[0], incl=group) extra_kwargs['root'] = group[0] extra_kwargs['mode'] = mpi.get_parallel_mode() extra_kwargs['group_size'] = len(group) for tuple in updater._tuples: tensors = tuple[0] kwargs = tuple[1] kwargs = dict(kwargs, **extra_kwargs) u_target = pb.UpdateTarget() u_target.type = updater._type _, u_target.name = GetOperatorName() for tensor in tensors: u_target.tensor.append(tensor) for k, v in kwargs.items(): u_target.arg.add().CopyFrom(MakeArgument(k, v)) graph_def.u_target.extend([u_target])
def forward(self, **kwargs): """Forward pass. [**PyCaffe Style**] Parameters ---------- inputs : dict or None The blobs to feed before. Returns ------- Tensor or list of Tensor The outputs of the net. References ---------- The implementation of `Net_forward(pycaffe.py, L88)`_. """ def GetOutputs(net, net_outputs): ret = {} for output in net_outputs: ret[output] = ws.FetchTensor(net.blobs[output].data) return ret if kwargs: for name, blob in kwargs.items(): ws.FeedTensor(self._inputs_to_tensors[name], blob) self.function()(return_outputs=False, stage='forward') return lambda net = self, net_outputs = self.outputs \ : GetOutputs(net, net_outputs)
def seg(file, save_dir="data/seg_results", mix=True, show=True): if save_dir is not None: if not os.path.exists(save_dir): os.makedirs(save_dir) im = load_image(file) # shape for input (data blob is N x C x H x W), set data im = im.reshape(1, *im.shape) ws.FeedTensor(net.blobs['data'].data, im) # run net and take argmax for prediction net.forward() if save_dir is not None: filename_ext = file.split('/')[-1] filename = filename_ext.split('.')[-2] filepath = os.path.join(save_dir, filename + '.png') mat = ws.FetchTensor(net.blobs['score'].data) im = Image.fromarray(mat[0].argmax(0).astype(np.uint8), mode='P') im.putpalette(color_table) im.save(filepath) if show: if mix: show1 = cv2.imread(file) show2 = cv2.imread(filepath) show3 = cv2.addWeighted(show1, 0.7, show2, 0.5, 1) else: show3 = cv2.imread(filepath) cv2.imshow('Seg-FCN', show3) cv2.waitKey(0)
def feed_parameters(self, group): template = group['slot'] + '/{}' for k, v in group.items(): if k in self._mutable_parameters: _workspace.FeedTensor(template.format( self._mutable_parameters[k]), v, dtype='float32', force_cpu=True)
def WrapScalar(scalar, dtype, device): # We use (DType + Value) to hash different scalars # Setting a Tensor with same DType and shape will not deconstruct it if 'float' in dtype: scalar = float(scalar) if 'int' in dtype: scalar = int(scalar) name = '/share/scalar/{}/{}'.format(dtype, str(scalar)) if not _workspace.HasTensor(name): _workspace.FeedTensor(name, numpy.array(scalar, dtype=dtype)) t = _Tensor(name=name, dtype=dtype, device=device, own_storage=False) t.requires_grad = False return t
def __setattr__(self, key, value): defaults = self.__dict__.get('_defaults') if defaults is not None and key in defaults: if self._registered: # convert all defaults as float32 for convenience ws.FeedTensor(self._slot + '/' + key, np.array([value], dtype=np.float32)) else: self._defaults[key] = value else: object.__setattr__(self, key, value)
def __setattr__(self, key, value): defaults = self.__dict__.get('_defaults') if defaults is not None and key in defaults: if self._registered: ws.FeedTensor(self._slot + '/' + key, value, dtype='float32', force_cpu=True) else: self._defaults[key] = value else: object.__setattr__(self, key, value)
def __div__(self, other): if not isinstance(other, Tensor): if not isinstance(other, np.ndarray): if not isinstance(other, list): other = [other] other = np.array(other, dtype=np.float32) tensor = Tensor(GetTensorName()) ws.FeedTensor(tensor, other) other = tensor output = self.CreateOperator(inputs=[self, other], nout=1, op_type='Div') if self.shape is not None: output.shape = self.shape[:] return output
def grad(self, inputs, outputs): """Gradient method, i.e., backward pass. Parameters ---------- inputs : list of str Indicating the name of input tensors. outputs : list of str Indicating the name of output tensors. Returns ------- None """ x1 = ws.FetchTensor(inputs[0]) x2 = ws.FetchTensor(inputs[1]) dy = ws.FetchTensor(inputs[-1]) dx1 = dy * x2 dx2 = dy * x1 ws.FeedTensor(outputs[0], dx1) ws.FeedTensor(outputs[1], dx2)
def GraphDef_Update(meta_graph, updater): """Inject the update targets into GraphDef. The ``updater`` should generate update targets before. Parameters ---------- meta_graph : dragon_pb2.GraphDef The definition of meta graph. updater : BaseUpdater The updater. Returns ------- None """ if updater is None: return updater._prefix = meta_graph.name + '_' extra_arguments = updater._extra_kwargs extra_arguments['domain'] = updater._prefix parallel_arguments = {} # wrap hyper-parameters as Tensor for CC for k, v in updater._hyper_params.items(): ws.FeedTensor(updater._prefix + k, np.array([v], dtype=np.float32)) # check data parallel if necessary if mpi.Is_Init(): idx, group = mpi.AllowParallel() if idx != -1: parallel_arguments['parallel_mode'] = mpi.GetParallelMode() parallel_arguments['comm'], parallel_arguments['group'] \ = mpi.CreateGroup(root=group[0], incl=group) parallel_arguments['root'] = group[0] for k, v in parallel_arguments.items(): meta_graph.arg.add().CopyFrom(MakeArgument(k, v)) for tuple in updater._tuples: tensors = tuple[0] arguments = tuple[1] kwargs = dict(arguments, **extra_arguments) u_target = pb.UpdateTarget() u_target.type = updater._type _, u_target.name = GetOperatorName() for tensor in tensors: u_target.tensor.append(tensor) for k, v in kwargs.items(): u_target.arg.add().CopyFrom(MakeArgument(k, v)) meta_graph.u_target.extend([u_target])
def forward(self, **kwargs): """ simply follow the pycaffe style """ def GetOutputs(net, net_outputs): ret = {} for output in net_outputs: ret[output] = ws.FetchTensor(net.blobs[output].data) return ret if kwargs: for name, blob in kwargs.items(): ws.FeedTensor(self._inputs_to_tensors[name], blob) self.function(return_outputs=False, stage='forward') return lambda net = self, net_outputs = self.outputs \ : GetOutputs(net, net_outputs)
def constant(value, dtype=None, shape=None, name=None): if dtype == None: dtype = dtypes.float32 if isinstance(value, np.ndarray): feed = value.astype(dtype) elif isinstance(value, list): feed = np.array(value, dtype) else: feed = np.array([value], dtype) if shape is not None: if feed.size == 1: c = feed[0] feed = np.zeros(shape, dtype) feed.fill(c) else: feed = feed.reshape(shape) tensor = Tensor(name) tensor.shape = list(feed.shape) ws.FeedTensor(tensor, feed) return tensor
def interp(net, layers): print 'bilinear-interp for layers:', layers net.forward() # dragon must forward once to create weights for l in layers: net_param = ws.FetchTensor(net.params[l][0].data) m, k, h, w = net_param.shape if m != k and k != 1: print 'input + output channels need to be the same or |output| == 1' raise if h != w: print 'filters need to be square' raise filt = upsample_filt(h) net_param[range(m), range(k), :, :] = filt ws.FeedTensor(net.params[l][0].data._name, net_param)
def forward_v2(self, **kwargs): """Forward pass while silencing all net outputs. Parameters ---------- inputs : dict, optional The blobs to feed before. Returns ------- None """ for name, blob in kwargs.items(): _workspace.FeedTensor(self._inputs_to_tensors[name], blob) self.function()(return_outputs=False, stage='forward')
def run(self, inputs, outputs): """Run method, i.e., forward pass. Parameters ---------- inputs : list of str Indicating the name of input tensors. outputs : list of str Indicating the name of output tensors. Returns ------- None """ ws.FeedTensor(outputs[0], self._queue.get())
def forward(self, bottom, top): # fetch the labels from the primary matches. all_match_labels = ws.FetchTensor(bottom[0]) # fetch the max overlaps between default boxes and gt boxes all_max_overlaps = ws.FetchTensor(bottom[1]) # fetch the confidences computed by SoftmaxLayer all_conf_prob = ws.FetchTensor(bottom[2]) # label ``-1`` will be ignored all_labels = np.empty(all_match_labels.shape, dtype=np.float32) all_labels.fill(-1) for im_idx in xrange(all_match_labels.shape[0]): matche_labels = all_match_labels[im_idx] max_overlaps = all_max_overlaps[im_idx] # compute conf loss conf_prob = all_conf_prob[im_idx] conf_loss = np.zeros(matche_labels.shape, dtype=np.float32) inds = np.where(matche_labels >= 0)[0] flt_min = np.finfo(float).eps conf_loss[inds] = -1.0 * np.log( np.maximum( conf_prob[inds, matche_labels[inds].astype(np.int32)], flt_min)) # filter negatives fg_inds = np.where(matche_labels > 0)[0] neg_inds = np.where(matche_labels == 0)[0] neg_overlaps = max_overlaps[neg_inds] eligible_neg_inds = np.where(neg_overlaps < self._neg_overlap)[0] sel_inds = neg_inds[eligible_neg_inds] # do mining sel_loss = conf_loss[sel_inds] num_pos = len(fg_inds) num_sel = min(int(num_pos * self._neg_pos_ratio), len(sel_inds)) sorted_sel_inds = sel_inds[np.argsort(-sel_loss)] bg_inds = sorted_sel_inds[:num_sel] all_labels[im_idx][fg_inds] = matche_labels[ fg_inds] # keep fg indices all_labels[im_idx][bg_inds] = 0 # use hard negatives as bg indices # feed labels to compute cls loss ws.FeedTensor(top[0], all_labels)
def run(self, inputs, outputs): """ Run implement(i.e. forward-pass). Parameters ---------- inputs : sequence of strs Indicating the operator's inputs outputs : sequence of strs Indicating the operator's outputs Returns ------- None """ ws.FeedTensor(outputs[0], self._queue.get())
def register_in_workspace(self): if not self._registered: for k, v in self._defaults.items(): workspace.FeedTensor(self._slot + "/" + k, v, dtype='float32', force_cpu=True) self._registered = True if self._verbose: print( '---------------------------------------------------------' ) print('Optimizer: {}, Using config:'.format(self.type(True))) pprint.pprint(self._defaults) print( '---------------------------------------------------------' )
def run(self, inputs, outputs): """Run method, i.e., forward pass. Parameters ---------- inputs : list of str Indicating the name of input tensors. outputs : list of str Indicating the name of output tensors. Returns ------- None """ x1 = ws.FetchTensor(inputs[0]) x2 = ws.FetchTensor(inputs[1]) ws.FeedTensor(outputs[0], x1 * x2) # call numpy mult
def run(self, inputs, outputs): """Run method, i.e., forward pass. Parameters ---------- inputs : sequence of str The name of inputs. outputs : sequence of str The name of outputs. Returns ------- None """ blobs = self._data_batch.get() for idx, blob in enumerate(blobs): _workspace.FeedTensor(outputs[idx], blob)
def run(self, inputs, outputs): """Run method, i.e., forward pass. Parameters ---------- inputs : list of str Indicating the name of input tensors. outputs : list of str Indicating the name of output tensors. Returns ------- None """ blobs = self._data_batch.get() for idx, blob in enumerate(blobs): ws.FeedTensor(outputs[idx], blob)
def set_value(self, new_value, **kwargs): """Feed the values to C++ backend. [**Theano Style**] Parameters ---------- new_value : basic type, list or numpy.ndarray The values to set. Returns ------- None See Also -------- `workspace.FeedTensor(*args, **kwargs)`_ - How to feed a Tensor. """ ws.FeedTensor(self, new_value)
def register_in_workspace(self): if not self._registered: for k, v in self._defaults.items(): # convert all defaults as float32 for convenience ws.FeedTensor(self._slot + "/" + k, np.array([v], dtype=np.float32)) self._registered = True if self._verbose: from dragon.config import logger logger.info( '---------------------------------------------------------' ) logger.info('Optimizer: {}, Using config:'.format( self.type(True))) pprint.pprint(self._defaults) logger.info( '---------------------------------------------------------' )
def register_in_workspace(self): if not self._registered: for k, v in self._defaults.items(): ws.FeedTensor(self._slot + "/" + k, v, dtype='float32', force_cpu=True) self._registered = True if self._verbose: from dragon.config import logger logger.info( '---------------------------------------------------------' ) logger.info('Optimizer: {}, Using config:'.format( self.type(True))) pprint.pprint(self._defaults) logger.info( '---------------------------------------------------------' )