def boundary_2d(pos: torch.Tensor, min_: torch.Tensor, max_: torch.Tensor, sigma=0.01, ac=0.02): """ Function that calculates the indicator function for boundary 2d case but in torch Args: pos(N,d) : positions of the atoms passed in a torch tensor of shape (N,d) min_(d,) : The minimum of the boundary 2d case max_(d,) : The maximum of the boundary 2d case sigma(float) : The width of the Gaussian function ac(float) : The cutoff of the Gaussian function Returns: indicator(N,) : Indicator function in a torch.tensor of shape (N,) """ k = np.sqrt(2 * np.pi * sigma**2) * erf( ac / np.sqrt(2 * sigma**2)) - 2 * ac * np.exp(-ac**2 / (2 * sigma**2)) k1 = 1 / k * np.sqrt(np.pi * sigma**2 / 2) k2 = 1 / k * np.exp(-ac**2 / (2 * sigma**2)) vals = torch.tensor([1.0], dtype=pos.dtype) ft = (k1 * torch.erf((max_ - pos) / math.sqrt(2 * sigma**2)) - k2 * (max_ - pos) - 1 / 2) * torch.heaviside(ac - torch.abs(max_ - pos), vals) st = (k1 * torch.erf((pos - min_) / math.sqrt(2 * sigma**2)) - k2 * (pos - min_) - 1 / 2) * torch.heaviside(ac - torch.abs(pos - min_), vals) tt = torch.heaviside( ac + 1 / 2 * (max_ - min_) - torch.abs(pos - 1 / 2 * (min_ + max_)), vals) return ft + st + tt
def test_manual_backward(self, expected_grad): """ 次に tensor.backward をつかわずに同じ勾配を求める """ # 適当なモデルをインスタンス化する torch.manual_seed(1) # シードは固定する model = MyModel() # 重みだけコピーする w1 = model.fc1.weight.detach().clone() b1 = model.fc1.bias.detach().clone() w2 = model.fc2.weight.detach().clone() b2 = model.fc2.bias.detach().clone() w3 = model.fc3.weight.detach().clone() b3 = model.fc3.bias.detach().clone() # 適当な訓練データを1点用意する x = torch.tensor([0.1, 0.2, 0.3]) y = torch.tensor([1.0]) # 順伝播する z1 = torch.matmul(w1, x) + b1 a1 = F.relu(z1) z2 = torch.matmul(w2, a1) + b2 a2 = F.relu(z2) z3 = torch.matmul(w3, a2) + b3 a3 = F.relu(z3) # 2乗誤差をとる criterion = nn.MSELoss() loss = criterion(a3, y) # 逆伝播する loss_a3 = 2.0 * (a3 - y) a3_z3 = torch.heaviside(z3, torch.tensor([0.0])) # ReLU の微分 loss_z3 = loss_a3 * a3_z3 loss_a2 = loss_z3 * w3.squeeze() # 横ベクトルの w3 を縦ベクトルに転置 a2_z2 = torch.heaviside(z2, torch.tensor([0.0])) # ReLU の微分 loss_z2 = torch.mul(loss_a2, a2_z2) # アダマール積 loss_a1 = torch.matmul(torch.transpose(w2, 0, 1), loss_z2) a1_z1 = torch.heaviside(z1, torch.tensor([0.0])) # ReLU の微分 loss_z1 = torch.mul(loss_a1, a1_z1) # アダマール積 loss_b1 = loss_z1 loss_w1 = torch.matmul(loss_z1.view(5, 1), x.view(1, 3)) # 縦ベクトルの x を横ベクトルに転置 # torch.matmul の左側にベクトルを渡して通常の行列積をしたいとき # 明示的に .view(n, 1) しなければ意図通りにならない # モデルの1層目の勾配が正しいことを確認 assert torch.allclose(loss_w1, expected_grad['w1'], atol=0.0001) assert torch.allclose(loss_b1, expected_grad['b1'], atol=0.0001)
def threshold_output_transform(output): y_pred, y = output print('got in here threshold ') y_pred = torch.heaviside(y_pred, values=torch.zeros(1)) # print(f'y_pred size : {y_pred.size()}') # print(f'y size : {y.size()}') return y_pred, y
def binarize(self,i): std,m=torch.std(x),torch.mean(x) h=(x-m)/std h=h.type(dtype=torch.uint8) h2=torch.matmul(Wbin,h) h3=torch.heaviside(h2,h2) return h3
def tensor_creation_ops(self): i = torch.tensor([[0, 1, 1], [2, 0, 2]]) v = torch.tensor([3, 4, 5], dtype=torch.float32) real = torch.tensor([1, 2], dtype=torch.float32) imag = torch.tensor([3, 4], dtype=torch.float32) inp = torch.tensor([-1.5, 0.0, 2.0]) values = torch.tensor([0.5]) quantized = torch.quantize_per_channel( torch.tensor([[-1.0, 0.0], [1.0, 2.0]]), torch.tensor([0.1, 0.01]), torch.tensor([10, 0]), 0, torch.quint8, ) return ( torch.tensor([[0.1, 1.2], [2.2, 3.1], [4.9, 5.2]]), # torch.sparse_coo_tensor(i, v, [2, 3]), # not work for iOS torch.as_tensor([1, 2, 3]), torch.as_strided(torch.randn(3, 3), (2, 2), (1, 2)), torch.zeros(2, 3), torch.zeros((2, 3)), torch.zeros([2, 3], out=i), torch.zeros(5), torch.zeros_like(torch.empty(2, 3)), torch.ones(2, 3), torch.ones((2, 3)), torch.ones([2, 3]), torch.ones(5), torch.ones_like(torch.empty(2, 3)), torch.arange(5), torch.arange(1, 4), torch.arange(1, 2.5, 0.5), torch.range(1, 4), torch.range(1, 4, 0.5), torch.linspace(3.0, 3.0, steps=1), torch.logspace(start=2, end=2, steps=1, base=2.0), torch.eye(3), torch.empty(2, 3), torch.empty_like(torch.empty(2, 3), dtype=torch.int64), torch.empty_strided((2, 3), (1, 2)), torch.full((2, 3), 3.141592), torch.full_like(torch.full((2, 3), 3.141592), 2.71828), torch.quantize_per_tensor( torch.tensor([-1.0, 0.0, 1.0, 2.0]), 0.1, 10, torch.quint8 ), torch.dequantize(quantized), torch.complex(real, imag), torch.polar(real, imag), torch.heaviside(inp, values), )
def _cut_off(self, _output, tol=0.): """Applies classification cutoff Parameters ---------- _output : torch.tensor *normalized* _output of model._net.forward tol : float, optional tolerance cutoff, by default 0. Returns ------- torch.tensor classes """ return torch.heaviside(-_output + tol, self.heaviside_value)
def forward(self, x: torch.Tensor) -> torch.Tensor: """ Args: x: Tensor or array-like to transform. Must be real and in shape ``[Batch, chns, spatial1, spatial2, ...]``. Returns: torch.Tensor: Analytical signal of ``x``, transformed along axis specified in ``self.axis`` using FFT of size ``self.N``. The absolute value of ``x_ht`` relates to the envelope of ``x`` along axis ``self.axis``. """ # Make input a real tensor x = torch.as_tensor( x, device=x.device if isinstance(x, torch.Tensor) else None) if torch.is_complex(x): raise ValueError("x must be real.") x = x.to(dtype=torch.float) if (self.axis < 0) or (self.axis > len(x.shape) - 1): raise ValueError("Invalid axis for shape of x.") n = x.shape[self.axis] if self.n is None else self.n if n <= 0: raise ValueError("N must be positive.") x = torch.as_tensor(x, dtype=torch.complex64) # Create frequency axis f = torch.cat([ torch.true_divide( torch.arange(0, (n - 1) // 2 + 1, device=x.device), float(n)), torch.true_divide(torch.arange(-(n // 2), 0, device=x.device), float(n)), ]) xf = fft.fft(x, n=n, dim=self.axis) # Create step function u = torch.heaviside(f, torch.tensor([0.5], device=f.device)) u = torch.as_tensor(u, dtype=x.dtype, device=u.device) new_dims_before = self.axis new_dims_after = len(xf.shape) - self.axis - 1 for _ in range(new_dims_before): u.unsqueeze_(0) for _ in range(new_dims_after): u.unsqueeze_(-1) ht = fft.ifft(xf * 2 * u, dim=self.axis) # Apply transform return torch.as_tensor(ht, device=ht.device, dtype=ht.dtype)
def qrelu_naive(q: QTensor) -> QTensor: r""" quaternion relu activation function f(z), where z = a + b*i + c*j + d*k a,b,c,d are real scalars where the last three scalars correspond to the vectorial part of the quaternion number f(z) returns z, iif a + b + c + d > 0. Otherwise it returns 0 Note that f(z) is applied for each dimensionality of q, as in real-valued fashion. :param q: quaternion tensor of shape (b, d) where b is the batch-size and d the dimensionality :return: activated quaternion tensor """ q = q.stack(dim=0) sum = q.sum(dim=0) a = torch.heaviside(sum, values=torch.zeros(sum.size()).to(q.device)) a = a.expand_as(q) q = q * a return QTensor(*q)
def roulette(self): ' Performs roulette-wheel selection from self.generation using self.fitness ' mock_fit = 1 / self.fitness total = torch.sum(mock_fit) mock_fit = mock_fit / total r_wheel = torch.cumsum(mock_fit, 0) spin_values = torch.rand(2 * self.n_pairs, 1, device=self.device, requires_grad=False) r_wheel = r_wheel.unsqueeze(0).expand(2 * self.n_pairs, -1) dist = r_wheel - spin_values dist[torch.heaviside( -dist, torch.tensor(0.0, device=self.device, requires_grad=False)).bool()] = 1 idxs = torch.argmin(dist, dim=1) self.p_child = self.generation[idxs, :].clone() self.p_child = self.p_child.unsqueeze(1).view(self.n_pairs, 2, self.n_params)
def u_cross(self): ' Performs uniform crossover given pairs tensor arranged sequentially in parent-pairs ' rand_vec = torch.rand(self.n_pairs, device=self.device, requires_grad=False) idcs = (rand_vec < self.cross_p).nonzero().squeeze() n_selected = idcs.shape[0] site_mask = torch.heaviside( torch.rand(n_selected, self.n_params, device=self.device, requires_grad=False) - 0.5, torch.tensor(1.0, device=self.device, requires_grad=False)).bool() parentC = self.p_child.clone() for c, i in enumerate(idcs): p0 = self.p_child[i][0] p0c = parentC[i][0] p1 = self.p_child[i][1] p1c = parentC[i][1] p0[site_mask[c]] = p1c[site_mask[c]] p1[site_mask[c]] = p0c[site_mask[c]]
# torch.quantize_per_tensor reveal_type( torch.quantize_per_tensor(torch.tensor([-1.0, 0.0, 1.0, 2.0]), 0.1, 10, torch.quint8)) # E: {Tensor} # torch.quantize_per_channel x = torch.tensor([[-1.0, 0.0], [1.0, 2.0]]) quant = torch.quantize_per_channel(x, torch.tensor([0.1, 0.01]), torch.tensor([10, 0]), 0, torch.quint8) reveal_type(x) # E: {Tensor} # torch.dequantize reveal_type(torch.dequantize(x)) # E: {Tensor} # torch.complex real = torch.tensor([1, 2], dtype=torch.float32) imag = torch.tensor([3, 4], dtype=torch.float32) reveal_type(torch.complex(real, imag)) # E: {Tensor} # torch.polar abs = torch.tensor([1, 2], dtype=torch.float64) pi = torch.acos(torch.zeros(1)).item() * 2 angle = torch.tensor([pi / 2, 5 * pi / 4], dtype=torch.float64) reveal_type(torch.polar(abs, angle)) # E: {Tensor} # torch.heaviside inp = torch.tensor([-1.5, 0, 2.0]) values = torch.tensor([0.5]) reveal_type(torch.heaviside(inp, values)) # E: {Tensor}
# torch.quantize_per_tensor reveal_type( torch.quantize_per_tensor(torch.tensor([-1.0, 0.0, 1.0, 2.0]), 0.1, 10, torch.quint8)) # E: torch.tensor.Tensor # torch.quantize_per_channel x = torch.tensor([[-1.0, 0.0], [1.0, 2.0]]) quant = torch.quantize_per_channel(x, torch.tensor([0.1, 0.01]), torch.tensor([10, 0]), 0, torch.quint8) reveal_type(x) # E: torch.tensor.Tensor # torch.dequantize reveal_type(torch.dequantize(x)) # E: torch.tensor.Tensor # torch.complex real = torch.tensor([1, 2], dtype=torch.float32) imag = torch.tensor([3, 4], dtype=torch.float32) reveal_type(torch.complex(real, imag)) # E: torch.tensor.Tensor # torch.polar abs = torch.tensor([1, 2], dtype=torch.float64) pi = torch.acos(torch.zeros(1)).item() * 2 angle = torch.tensor([pi / 2, 5 * pi / 4], dtype=torch.float64) reveal_type(torch.polar(abs, angle)) # E: torch.tensor.Tensor # torch.heaviside inp = torch.tensor([-1.5, 0, 2.0]) values = torch.tensor([0.5]) reveal_type(torch.heaviside(inp, values)) # E: torch.tensor.Tensor
def train(self, buffer, writer, minimum=None, maximum=None, use_probas=False): # Sample replay buffer state, action, next_state, reward, not_done = buffer.sample( minimum, maximum, use_probas) ################################### ### Policy update ################################### # set networks to train mode self.actor.train() self.actor_target.train() self.Q.train() self.Q_target.train() # calculate advantage with torch.no_grad(): current_Qs = self.Q(state) baseline = [] # sample m times for baseline for _ in range(self.m): actions = self.actor(state) probs = F.softmax(actions, dim=1) dist = Categorical(probs) baseline.append( current_Qs.gather(1, dist.sample().unsqueeze(1))) baseline = torch.stack(baseline, dim=0) # mean style advantage = current_Qs - torch.mean(baseline, dim=0) # max style #advantage = current_Qs - torch.max(baseline, dim=0)[0] # policy loss # exp style #loss = (self.ce(self.actor(state), action.squeeze(1)).unsqueeze(1) * # torch.exp(advantage / self.beta).gather(1, action)).mean() # binary style loss = ( self.ce(self.actor(state), action.squeeze(1)).unsqueeze(1) * torch.heaviside(advantage, values=torch.zeros(1).to( self.device)).gather(1, action)).mean() if self.iterations % 100 == 0: writer.add_scalar("train/policy-loss", torch.mean(loss).detach().cpu().item(), self.iterations) # optimize policy self.p_optim.zero_grad() loss.backward() self.p_optim.step() ################################### ### Critic update ################################### # set networks to train mode self.actor.train() self.actor_target.train() self.Q.train() self.Q_target.train() # Compute the target Q value with torch.no_grad(): actions = self.actor_target(next_state) probs = F.softmax(actions, dim=1) dist = Categorical(probs) target_Q = reward + not_done * self.discount * self.Q_target( next_state).gather(1, dist.sample().unsqueeze(1)) # Get current Q estimate current_Q = self.Q(state).gather(1, action) # Compute Q loss (Huber loss) Q_loss = self.huber(current_Q, target_Q) # log temporal difference error if self.iterations % 100 == 0: writer.add_scalar("train/TD-error", torch.mean(Q_loss).detach().cpu().item(), self.iterations) # Optimize the Q self.optimizer.zero_grad() Q_loss.backward() self.optimizer.step() self.iterations += 1 # Update target network by full copy every X iterations. if self.iterations % self.target_update_freq == 0: self.Q_target.load_state_dict(self.Q.state_dict()) self.actor_target.load_state_dict(self.actor.state_dict())
torch.full((2, 3), 3.141592) torch.full_like(torch.full((2, 3), 3.141592), 2.71828) # torch.quantize_per_tensor torch.quantize_per_tensor(torch.tensor([-1.0, 0.0, 1.0, 2.0]), 0.1, 10, torch.quint8) # torch.quantize_per_channel x = torch.tensor([[-1.0, 0.0], [1.0, 2.0]]) quant = torch.quantize_per_channel(x, torch.tensor([0.1, 0.01]), torch.tensor([10, 0]), 0, torch.quint8) # torch.dequantize torch.dequantize(x) # torch.complex real = torch.tensor([1, 2], dtype=torch.float32) imag = torch.tensor([3, 4], dtype=torch.float32) torch.complex(real, imag) # torch.polar abs = torch.tensor([1, 2], dtype=torch.float64) pi = torch.acos(torch.zeros(1)).item() * 2 angle = torch.tensor([pi / 2, 5 * pi / 4], dtype=torch.float64) torch.polar(abs, angle) # torch.heaviside inp = torch.tensor([-1.5, 0, 2.0]) values = torch.tensor([0.5]) torch.heaviside(inp, values)