我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用torch.clamp()。
def intersect(box_a, box_b): """ We resize both tensors to [A,B,2] without new malloc: [A,2] -> [A,1,2] -> [A,B,2] [B,2] -> [1,B,2] -> [A,B,2] Then we compute the area of intersect between box_a and box_b. Args: box_a: (tensor) bounding boxes, Shape: [A,4]. box_b: (tensor) bounding boxes, Shape: [B,4]. Return: (tensor) intersection area, Shape: [A,B]. """ A = box_a.size(0) B = box_b.size(0) max_xy = torch.min(box_a[:, 2:].unsqueeze(1).expand(A, B, 2), box_b[:, 2:].unsqueeze(0).expand(A, B, 2)) min_xy = torch.max(box_a[:, :2].unsqueeze(1).expand(A, B, 2), box_b[:, :2].unsqueeze(0).expand(A, B, 2)) inter = torch.clamp((max_xy - min_xy), min=0) return inter[:, :, 0] * inter[:, :, 1]
def _loss(self, output, target, dist, scale_const): # compute the probability of the label class versus the maximum other real = (target * output).sum(1) other = ((1. - target) * output - target * 10000.).max(1)[0] if self.targeted: # if targeted, optimize for making the other class most likely loss1 = torch.clamp(other - real + self.confidence, min=0.) # equiv to max(..., 0.) else: # if non-targeted, optimize for making this class least likely. loss1 = torch.clamp(real - other + self.confidence, min=0.) # equiv to max(..., 0.) loss1 = torch.sum(scale_const * loss1) loss2 = dist.sum() loss = loss1 + loss2 return loss
def intersect(box_a, box_b): """ We resize both tensors to [A,B,2] without new malloc: [A,2] -> [A,1,2] -> [A,B,2] [B,2] -> [1,B,2] -> [A,B,2] Then we compute the area of intersect between box_a and box_b. Args: box_a: (tensor) bounding boxes, Shape: [A,4]. box_b: (tensor) bounding boxes, Shape: [B,4]. Return: (tensor) intersection area, Shape: [A,B]. """ A = box_a.size(0) B = box_b.size(0) #pdb.set_trace() max_xy = torch.min(box_a[:, 2:].unsqueeze(1).expand(A, B, 2), box_b[:, 2:].unsqueeze(0).expand(A, B, 2)) min_xy = torch.max(box_a[:, :2].unsqueeze(1).expand(A, B, 2), box_b[:, :2].unsqueeze(0).expand(A, B, 2)) inter = torch.clamp((max_xy - min_xy), min=0) return inter[:, :, 0] * inter[:, :, 1]
def cosine_similarity(x1, x2, dim=1, eps=1e-8): r"""Returns cosine similarity between x1 and x2, computed along dim. Args: x1 (Variable): First input. x2 (Variable): Second input (of size matching x1). dim (int, optional): Dimension of vectors. Default: 1 eps (float, optional): Small value to avoid division by zero. Default: 1e-8 Shape: - Input: :math:`(\ast_1, D, \ast_2)` where D is at position `dim`. - Output: :math:`(\ast_1, \ast_2)` where 1 is at position `dim`. """ w12 = torch.sum(x1 * x2, dim) w1 = torch.norm(x1, 2, dim) w2 = torch.norm(x2, 2, dim) return (w12 / (w1 * w2).clamp(min=eps)).squeeze()
def normalize(input, p=2, dim=1, eps=1e-12): r"""Performs :math:`L_p` normalization of inputs over specified dimension. Does: .. math:: v = \frac{v}{\max(\lVert v \rVert_p, \epsilon)} for each subtensor v over dimension dim of input. Each subtensor is flattened into a vector, i.e. :math:`\lVert v \rVert_p` is not a matrix norm. With default arguments normalizes over the second dimension with Euclidean norm. Args: input: input tensor of any shape p (float): the exponent value in the norm formulation dim (int): the dimension to reduce eps (float): small value to avoid division by zero """ return input / input.norm(p, dim, True).clamp(min=eps).expand_as(input)
def normalize(input, p=2, dim=1, eps=1e-12): r"""Performs :math:`L_p` normalization of inputs over specified dimension. Does: .. math:: v = \frac{v}{\max(\lVert v \rVert_p, \epsilon)} for each subtensor v over dimension dim of input. Each subtensor is flattened into a vector, i.e. :math:`\lVert v \rVert_p` is not a matrix norm. With default arguments normalizes over the second dimension with Euclidean norm. Args: input: input tensor of any shape p (float): the exponent value in the norm formulation. Default: 2 dim (int): the dimension to reduce. Default: 1 eps (float): small value to avoid division by zero. Default: 1e-12 """ return input / input.norm(p, dim, True).clamp(min=eps).expand_as(input)
def th_nearest_interp2d(input, coords): """ 2d nearest neighbor interpolation th.Tensor """ # take clamp of coords so they're in the image bounds x = th.clamp(coords[:,:,0], 0, input.size(1)-1).round() y = th.clamp(coords[:,:,1], 0, input.size(2)-1).round() stride = th.LongTensor(input.stride()) x_ix = x.mul(stride[1]).long() y_ix = y.mul(stride[2]).long() input_flat = input.view(input.size(0),-1) mapped_vals = input_flat.gather(1, x_ix.add(y_ix)) return mapped_vals.view_as(input)
def th_nearest_interp3d(input, coords): """ 2d nearest neighbor interpolation th.Tensor """ # take clamp of coords so they're in the image bounds coords[:,0] = th.clamp(coords[:,0], 0, input.size(1)-1).round() coords[:,1] = th.clamp(coords[:,1], 0, input.size(2)-1).round() coords[:,2] = th.clamp(coords[:,2], 0, input.size(3)-1).round() stride = th.LongTensor(input.stride())[1:].float() idx = coords.mv(stride).long() input_flat = th_flatten(input) mapped_vals = input_flat[idx] return mapped_vals.view_as(input)
def forward(self, anchor, positive, negative): #eucl distance #dist = torch.sum( (anchor - positive) ** 2 - (anchor - negative) ** 2, dim=1)\ # + self.margin if self.dist_type == 0: dist_p = F.pairwise_distance(anchor ,positive) dist_n = F.pairwise_distance(anchor ,negative) if self.dist_type == 1: dist_p = cosine_similarity(anchor, positive) disp_n = cosine_similarity(anchor, negative) dist_hinge = torch.clamp(dist_p - dist_n + self.margin, min=0.0) if self.use_ohem: v, idx = torch.sort(dist_hinge,descending=True) loss = torch.mean(v[0:self.ohem_bs]) else: loss = torch.mean(dist_hinge) return loss
def clip(tensor: T.FloatTensor, a_min: T.Scalar = -numpy.inf, a_max: T.Scalar = numpy.inf) -> T.FloatTensor: """ Return a tensor with its values clipped between a_min and a_max. Args: tensor: A tensor. a_min (optional): The desired lower bound on the elements of the tensor. a_max (optional): The desired upper bound on the elements of the tensor. Returns: tensor: A new tensor with its values clipped between a_min and a_max. """ return tensor.clamp(a_min, a_max)
def clip_inplace(tensor: T.FloatTensor, a_min: T.Scalar = -numpy.inf, a_max: T.Scalar = numpy.inf) -> None: """ Clip the values of a tensor between a_min and a_max. Note: Modifies tensor in place. Args: tensor: A tensor. a_min (optional): The desired lower bound on the elements of the tensor. a_max (optional): The desired upper bound on the elements of the tensor. Returns: None """ return torch.clamp(tensor, a_min, a_max, out=tensor)
def hard_negative_mining(self, conf_loss, pos): '''Return negative indices that is 3x the number as postive indices. Args: conf_loss: (tensor) cross entroy loss between conf_preds and conf_targets, sized [N*8732,]. pos: (tensor) positive(matched) box indices, sized [N,8732]. Return: (tensor) negative indices, sized [N,8732]. ''' batch_size, num_boxes = pos.size() # print(pos) # print(conf_loss.size()) conf_loss[pos] = 0 # set pos boxes = 0, the rest are neg conf_loss conf_loss = conf_loss.view(batch_size, -1) # [N,8732] _,idx = conf_loss.sort(1, descending=True) # sort by neg conf_loss _,rank = idx.sort(1) # [N,8732] num_pos = pos.long().sum(1) # [N,1] num_neg = torch.clamp(3*num_pos, max=num_boxes-1) # [N,1] neg = rank < num_neg.view(-1, 1).expand_as(rank) # [N,8732] return neg
def select_action(self, state_batch): # state_batch: n_agents x state_dim actions = Variable(th.zeros( self.n_agents, self.n_actions)) FloatTensor = th.cuda.FloatTensor if self.use_cuda else th.FloatTensor for i in range(self.n_agents): sb = state_batch[i, :].detach() act = self.actors[i](sb.unsqueeze(0)).squeeze() act += Variable( th.from_numpy( np.random.randn(2) * self.var[i]).type(FloatTensor)) if self.episode_done > self.episodes_before_train and\ self.var[i] > 0.05: self.var[i] *= 0.999998 act = th.clamp(act, -1.0, 1.0) actions[i, :] = act self.steps_done += 1 return actions
def get_update(self): actions, log_actions, rewards, critics, entropies, states, advantages = self._sample() # Compute auxiliary losses critics = self.critic(states) critic_loss = (rewards - critics).pow(2).mean() critic_loss = self.critic_weight * critic_loss entropy_loss = entropies.mean() entropy_loss = - self.entropy_weight * entropy_loss # Compute policy loss advantages = advantages.detach().view(-1, 1) new_actions = self.policy(states) log_probs = new_actions.compute_log_prob(actions) ratios = (log_probs - log_actions.detach()).exp() surr = ratios.view(-1, 1) * advantages clipped = th.clamp(ratios, 1.0 - self.clip, 1.0 + self.clip).view(-1, 1) * advantages policy_loss = - th.min(surr, clipped).mean() # Proceed to optimization loss = policy_loss + critic_loss + entropy_loss if self.epoch_optimized == self.num_epochs: loss.backward(retain_graph=False) else: loss.backward(retain_graph=True) if self.grad_clip > 0.0: th.nn.utils.clip_grad_norm(self.parameters(), self.grad_clip) # Store statistics self.stats['Num. Updates'] += 1.0 self.stats['Critic Loss'] += critic_loss.data[0] self.stats['Entropy Loss'] += entropy_loss.data[0] self.stats['Policy Loss'] += policy_loss.data[0] self.stats['Total Loss'] += loss.data[0] return [p.grad.clone() for p in self.parameters()]
def forward(self, input): if self.gpu_ids and isinstance(input.data, torch.cuda.FloatTensor) and self.use_parallel: output = nn.parallel.data_parallel(self.model, input, self.gpu_ids) else: output = self.model(input) if self.learn_residual: output = input + output output = torch.clamp(output,min = -1,max = 1) return output # Define a resnet block
def forward(self, input): if self.gpu_ids and isinstance(input.data, torch.cuda.FloatTensor) and self.use_parallel: output = nn.parallel.data_parallel(self.model, input, self.gpu_ids) else: output = self.model(input) if self.learn_residual: output = input + output output = torch.clamp(output,min = -1,max = 1) return output # Defines the submodule with skip connection. # X -------------------identity---------------------- X # |-- downsampling -- |submodule| -- upsampling --|
def forward(self, anchor1, anchor2, img_sentc, sent_imgc): cost_sent = torch.clamp(self.margin - anchor1 + img_sentc, min=0.0).sum() cost_img = torch.clamp(self.margin - anchor2 + sent_imgc, min=0.0).sum() loss = cost_sent + cost_img return loss
def postprocess_caffe(output): output = output.data.cpu().clamp(0, 255).numpy() output = output[0].transpose(1, 2, 0).astype('uint8') output = output[..., ::-1] output = Image.fromarray(output) return output
def postprocess_torch(output): # Should we? def denormalize(image): for t in range(3): image[t, :, :] = (image[t, :, :] * STD[t]) + MEAN[t] return image transformer = transforms.Compose([ transforms.ToPILImage()]) image = output.cpu().data[0] image = torch.clamp(denormalize(image), min=0, max=1) return transformer(image)
def forward(self, x0, x1, y): # euclidian distance diff = x0 - x1 dist_sq = torch.sum(torch.pow(diff, 2), 1) dist = torch.sqrt(dist_sq) mdist = self.margin - dist dist = torch.clamp(mdist, min=0.0) loss = y * dist_sq + (1 - y) * torch.pow(dist, 2) loss = torch.sum(loss) / 2.0 / x0.size()[0] return loss
def __init__(self, targeted=True, search_steps=None, max_steps=None, cuda=True, debug=False): self.debug = debug self.targeted = targeted self.num_classes = 1000 self.confidence = 20 # FIXME need to find a good value for this, 0 value used in paper not doing much... self.initial_const = 0.1 # bumped up from default of .01 in reference code self.binary_search_steps = search_steps or 5 self.repeat = self.binary_search_steps >= 10 self.max_steps = max_steps or 1000 self.abort_early = True self.clip_min = -1. self.clip_max = 1. self.cuda = cuda self.clamp_fn = 'tanh' # set to something else perform a simple clamp instead of tanh self.init_rand = False # an experiment, does a random starting point help?
def _optimize(self, optimizer, model, input_var, modifier_var, target_var, scale_const_var, input_orig=None): # apply modifier and clamp resulting image to keep bounded from clip_min to clip_max if self.clamp_fn == 'tanh': input_adv = tanh_rescale(modifier_var + input_var, self.clip_min, self.clip_max) else: input_adv = torch.clamp(modifier_var + input_var, self.clip_min, self.clip_max) output = model(input_adv) # distance to the original input data if input_orig is None: dist = l2_dist(input_adv, input_var, keepdim=False) else: dist = l2_dist(input_adv, input_orig, keepdim=False) loss = self._loss(output, target_var, dist, scale_const_var) optimizer.zero_grad() loss.backward() optimizer.step() loss_np = loss.data[0] dist_np = dist.data.cpu().numpy() output_np = output.data.cpu().numpy() input_adv_np = input_adv.data.permute(0, 2, 3, 1).cpu().numpy() # back to BHWC for numpy consumption return loss_np, dist_np, output_np, input_adv_np
def task_loss(Y_sched, Y_actual, params): return (params["gamma_under"] * torch.clamp(Y_actual - Y_sched, min=0) + params["gamma_over"] * torch.clamp(Y_sched - Y_actual, min=0) + 0.5 * (Y_sched - Y_actual)**2).mean(0)
def test_clamp(self): m1 = torch.rand(100).mul(5).add(-2.5) # uniform in [-2.5, 2.5] # just in case we're extremely lucky. min_val = -1 max_val = 1 m1[1] = min_val m1[2] = max_val res1 = m1.clone() res1.clamp_(min_val, max_val) res2 = m1.clone() for i in iter_indices(res2): res2[i] = max(min_val, min(max_val, res2[i])) self.assertEqual(res1, res2) res1 = torch.clamp(m1, min=min_val) res2 = m1.clone() for i in iter_indices(res2): res2[i] = max(min_val, res2[i]) self.assertEqual(res1, res2) res1 = torch.clamp(m1, max=max_val) res2 = m1.clone() for i in iter_indices(res2): res2[i] = min(max_val, res2[i]) self.assertEqual(res1, res2)
def test_masked_select(self): num_src = 10 src = torch.randn(num_src) mask = torch.rand(num_src).clamp(0, 1).mul(2).floor().byte() dst = src.masked_select(mask) dst2 = [] for i in range(num_src): if mask[i]: dst2 += [src[i]] self.assertEqual(dst, torch.Tensor(dst2), 0)
def th_map_coordinates(input, coords, order=1): """Tensorflow verion of scipy.ndimage.map_coordinates Note that coords is transposed and only 2D is supported Parameters ---------- input : tf.Tensor. shape = (s, s) coords : tf.Tensor. shape = (n_points, 2) """ assert order == 1 input_size = input.size(0) coords = torch.clamp(coords, 0, input_size - 1) coords_lt = coords.floor().long() coords_rb = coords.ceil().long() coords_lb = torch.stack([coords_lt[:, 0], coords_rb[:, 1]], 1) coords_rt = torch.stack([coords_rb[:, 0], coords_lt[:, 1]], 1) vals_lt = th_gather_2d(input, coords_lt.detach()) vals_rb = th_gather_2d(input, coords_rb.detach()) vals_lb = th_gather_2d(input, coords_lb.detach()) vals_rt = th_gather_2d(input, coords_rt.detach()) coords_offset_lt = coords - coords_lt.type(coords.data.type()) vals_t = vals_lt + (vals_rt - vals_lt) * coords_offset_lt[:, 0] vals_b = vals_lb + (vals_rb - vals_lb) * coords_offset_lt[:, 0] mapped_vals = vals_t + (vals_b - vals_t) * coords_offset_lt[:, 1] return mapped_vals
def hinge_loss(positive_predictions, negative_predictions, mask=None): """ Hinge pairwise loss function. Parameters ---------- positive_predictions: tensor Tensor containing predictions for known positive items. negative_predictions: tensor Tensor containing predictions for sampled negative items. mask: tensor, optional A binary tensor used to zero the loss from some entries of the loss tensor. Returns ------- loss, float The mean value of the loss function. """ loss = torch.clamp(negative_predictions - positive_predictions + 1.0, 0.0) if mask is not None: mask = mask.float() loss = loss * mask return loss.sum() / mask.sum() return loss.mean()
def logistic_loss(observed_ratings, predicted_ratings): """ Logistic loss for explicit data. Parameters ---------- observed_ratings: tensor Tensor containing observed ratings which should be +1 or -1 for this loss function. predicted_ratings: tensor Tensor containing rating predictions. Returns ------- loss, float The mean value of the loss function. """ assert_no_grad(observed_ratings) # Convert target classes from (-1, 1) to (0, 1) observed_ratings = torch.clamp(observed_ratings, 0, 1) return F.binary_cross_entropy_with_logits(predicted_ratings, observed_ratings, size_average=True)
def _set_hook_func(self): def func_b(module, grad_in, grad_out): self.all_grads[id(module)] = grad_in[0].cpu() # Cut off negative gradients if isinstance(module, nn.ReLU): return (torch.clamp(grad_in[0], min=0.0),) for module in self.model.named_modules(): module[1].register_backward_hook(func_b)
def log_Bernoulli(x, mean, average=False, dim=None): probs = torch.clamp( mean, min=1e-7, max=1.-1e-7 ) log_bernoulli = x * torch.log( probs ) + (1. - x ) * torch.log( 1. - probs ) if average: return torch.mean( log_bernoulli, dim ) else: return torch.sum( log_bernoulli, dim )
def binary_cross_entropy_with_logits(input, target, weight=None, size_average=True): r"""Function that measures Binary Cross Entropy between target and output logits. See :class:`~torch.nn.BCEWithLogitsLoss` for details. Args: input: Variable of arbitrary shape target: Variable of the same shape as input weight (Variable, optional): a manual rescaling weight if provided it's repeated to match input tensor shape size_average (bool, optional): By default, the losses are averaged over observations for each minibatch. However, if the field sizeAverage is set to False, the losses are instead summed for each minibatch. Default: True Examples:: >>> input = autograd.Variable(torch.randn(3), requires_grad=True) >>> target = autograd.Variable(torch.FloatTensor(3).random_(2)) >>> loss = F.binary_cross_entropy_with_logits(input, target) >>> loss.backward() """ if not (target.size() == input.size()): raise ValueError("Target size ({}) must be the same as input size ({})".format(target.size(), input.size())) max_val = (-input).clamp(min=0) loss = input - input * target + max_val + ((-max_val).exp() + (-input - max_val).exp()).log() if weight is not None: loss = loss * weight if size_average: return loss.mean() else: return loss.sum()
def cosine_similarity(x1, x2, dim=1, eps=1e-8): r"""Returns cosine similarity between x1 and x2, computed along dim. .. math :: \text{similarity} = \dfrac{x_1 \cdot x_2}{\max(\Vert x_1 \Vert _2 \cdot \Vert x_2 \Vert _2, \epsilon)} Args: x1 (Variable): First input. x2 (Variable): Second input (of size matching x1). dim (int, optional): Dimension of vectors. Default: 1 eps (float, optional): Small value to avoid division by zero. Default: 1e-8 Shape: - Input: :math:`(\ast_1, D, \ast_2)` where D is at position `dim`. - Output: :math:`(\ast_1, \ast_2)` where 1 is at position `dim`. Example:: >>> input1 = autograd.Variable(torch.randn(100, 128)) >>> input2 = autograd.Variable(torch.randn(100, 128)) >>> output = F.cosine_similarity(input1, input2) >>> print(output) """ w12 = torch.sum(x1 * x2, dim) w1 = torch.norm(x1, 2, dim) w2 = torch.norm(x2, 2, dim) return (w12 / (w1 * w2).clamp(min=eps)).squeeze()
def test_erfinv(self): def checkType(tensor): inputValues = torch.randn(4, 4, out=tensor()).clamp(-2., 2.) self.assertEqual(tensor(inputValues).erf().erfinv(), tensor(inputValues)) # test inf self.assertTrue(torch.equal(tensor([-1, 1]).erfinv(), tensor([float('-inf'), float('inf')]))) # test nan self.assertEqual(tensor([-2, 2]).erfinv(), tensor([float('nan'), float('nan')])) checkType(torch.FloatTensor) checkType(torch.DoubleTensor)
def forward(self, anchor, positive, negative): d_p = self.pdist.forward(anchor, positive) d_n = self.pdist.forward(anchor, negative) dist_hinge = torch.clamp(self.margin + d_p - d_n, min=0.0) loss = torch.mean(dist_hinge) return loss
def clip(tensor, a_min=None, a_max=None, inplace=False): if a_max is None: a_max = torch.max(tensor) if a_min is None: a_min = torch.min(tensor) if inplace: return torch.clamp(tensor, a_min, a_max, out=tensor) else: return torch.clamp(tensor, a_min, a_max)
def __call__(self, *inputs): outputs = [] for idx, _input in enumerate(inputs): _input = th.clamp(_input.float().add(self.value).type(_input.type()), 0, 1) outputs.append(_input) return outputs if idx > 1 else outputs[0]
def __call__(self, *inputs): outputs = [] for idx, _input in enumerate(inputs): _in_gs = Grayscale(keep_channels=True)(_input) alpha = 1.0 + self.value _in = th.clamp(_blend(_input, _in_gs, alpha), 0, 1) outputs.append(_in) return outputs if idx > 1 else outputs[0]
def __call__(self, *inputs): outputs = [] for idx, _input in enumerate(inputs): channel_means = _input.mean(1).mean(2) channel_means = channel_means.expand_as(_input) _input = th.clamp((_input - channel_means) * self.value + channel_means,0,1) outputs.append(_input) return outputs if idx > 1 else outputs[0]
def F_bilinear_interp2d(input, coords): """ bilinear interpolation of 2d torch.autograd.Variable """ x = torch.clamp(coords[:,:,0], 0, input.size(1)-2) x0 = x.floor() x1 = x0 + 1 y = torch.clamp(coords[:,:,1], 0, input.size(2)-2) y0 = y.floor() y1 = y0 + 1 stride = torch.LongTensor(input.stride()) x0_ix = x0.mul(stride[1]).long() x1_ix = x1.mul(stride[1]).long() y0_ix = y0.mul(stride[2]).long() y1_ix = y1.mul(stride[2]).long() input_flat = input.view(input.size(0),-1).contiguous() vals_00 = input_flat.gather(1, x0_ix.add(y0_ix).detach()) vals_10 = input_flat.gather(1, x1_ix.add(y0_ix).detach()) vals_01 = input_flat.gather(1, x0_ix.add(y1_ix).detach()) vals_11 = input_flat.gather(1, x1_ix.add(y1_ix).detach()) xd = x - x0 yd = y - y0 xm = 1 - xd ym = 1 - yd x_mapped = (vals_00.mul(xm).mul(ym) + vals_10.mul(xd).mul(ym) + vals_01.mul(xm).mul(yd) + vals_11.mul(xd).mul(yd)) return x_mapped.view_as(input)
def F_batch_bilinear_interp2d(input, coords): """ input : torch.Tensor size = (N,H,W,C) coords : torch.Tensor size = (N,H*W*C,2) """ x = torch.clamp(coords[:,:,0], 0, input.size(2)-2) x0 = x.floor() x1 = x0 + 1 y = torch.clamp(coords[:,:,1], 0, input.size(3)-2) y0 = y.floor() y1 = y0 + 1 stride = torch.LongTensor(input.stride()) x0_ix = x0.mul(stride[2]).long() x1_ix = x1.mul(stride[2]).long() y0_ix = y0.mul(stride[3]).long() y1_ix = y1.mul(stride[3]).long() input_flat = input.view(input.size(0),-1).contiguous() vals_00 = input_flat.gather(1, x0_ix.add(y0_ix).detach()) vals_10 = input_flat.gather(1, x1_ix.add(y0_ix).detach()) vals_01 = input_flat.gather(1, x0_ix.add(y1_ix).detach()) vals_11 = input_flat.gather(1, x1_ix.add(y1_ix).detach()) xd = x - x0 yd = y - y0 xm = 1 - xd ym = 1 - yd x_mapped = (vals_00.mul(xm).mul(ym) + vals_10.mul(xd).mul(ym) + vals_01.mul(xm).mul(yd) + vals_11.mul(xd).mul(yd)) return x_mapped.view_as(input)
def th_bilinear_interp2d(input, coords): """ bilinear interpolation in 2d """ x = th.clamp(coords[:,:,0], 0, input.size(1)-2) x0 = x.floor() x1 = x0 + 1 y = th.clamp(coords[:,:,1], 0, input.size(2)-2) y0 = y.floor() y1 = y0 + 1 stride = th.LongTensor(input.stride()) x0_ix = x0.mul(stride[1]).long() x1_ix = x1.mul(stride[1]).long() y0_ix = y0.mul(stride[2]).long() y1_ix = y1.mul(stride[2]).long() input_flat = input.view(input.size(0),-1) vals_00 = input_flat.gather(1, x0_ix.add(y0_ix)) vals_10 = input_flat.gather(1, x1_ix.add(y0_ix)) vals_01 = input_flat.gather(1, x0_ix.add(y1_ix)) vals_11 = input_flat.gather(1, x1_ix.add(y1_ix)) xd = x - x0 yd = y - y0 xm = 1 - xd ym = 1 - yd x_mapped = (vals_00.mul(xm).mul(ym) + vals_10.mul(xd).mul(ym) + vals_01.mul(xm).mul(yd) + vals_11.mul(xd).mul(yd)) return x_mapped.view_as(input)
def forward(self, input_vb): # NOTE: the operation order must be the following: control, access{write, read}, output # 1. first feed {input, read_vec_{t-1}} to controller hidden_vb = self.controller.forward(input_vb, self.read_vec_vb) # 2. then we write to memory_{t-1} to get memory_{t}; then read from memory_{t} to get read_vec_{t} self.read_vec_vb = self.accessor.forward(hidden_vb) # 3. finally we concat the output from the controller and the current read_vec_{t} to get the final output output_vb = self.hid_to_out(torch.cat((hidden_vb.view(-1, self.hidden_dim), self.read_vec_vb.view(-1, self.read_vec_dim)), 1)) # we clip the output values here return F.sigmoid(torch.clamp(output_vb, min=-self.clip_value, max=self.clip_value)).view(1, self.batch_size, self.output_dim)