def get_points_from_angles(distance, elevation, azimuth, degrees=True): if isinstance(distance, float) or isinstance(distance, int): if degrees: elevation = math.radians(elevation) azimuth = math.radians(azimuth) return (distance * math.cos(elevation) * math.sin(azimuth), distance * math.sin(elevation), -distance * math.cos(elevation) * math.cos(azimuth)) else: if degrees: elevation = radians(elevation) azimuth = radians(azimuth) return cf.stack([ distance * cf.cos(elevation) * cf.sin(azimuth), distance * cf.sin(elevation), -distance * cf.cos(elevation) * cf.cos(azimuth), ]).transpose()
def euler2rot(angles): """Create rotation matrices from euler angles Args: angles (:class `~chainer.Variable` or :ref:`ndarray`): A 2-D array of shape `(B, 3)` Euler angles along with x, y and z axis respectively. Returns: ~chainer.Variable: Rotation matrices. A 3-D array of shape `(B, 3, 3)` """ xp = backend.get_array_module(angles) xs = angles[:, 0] ys = angles[:, 1] zs = angles[:, 2] zeros = xp.zeros(xs.shape, xs.dtype) ones = xp.ones(xs.shape, xs.dtype) cosxs = F.cos(xs) sinxs = F.sin(xs) Rx = F.stack([ ones, zeros, zeros, zeros, cosxs, -sinxs, zeros, sinxs, cosxs], axis=1).reshape(-1, 3, 3) cosys = F.cos(ys) sinys = F.sin(ys) Ry = F.stack([ cosys, zeros, sinys, zeros, ones, zeros, -sinys, zeros, cosys], axis=1).reshape(-1, 3, 3) coszs = F.cos(zs) sinzs = F.sin(zs) Rz = F.stack([coszs, -sinzs, zeros, sinzs, coszs, zeros, zeros, zeros, ones], axis=1).reshape(-1, 3, 3) return Rz @ Ry @ Rx
def loss(self, logits, labels): xp = chainer.cuda.get_array_module(logits) # add margin z = 1 - 1e-6 theta = F.arccos(F.clip(logits, -z, z)) target_logits = F.cos(theta + self.m) one_hot = xp.eye(self.class_num)[labels] output = logits * (1 - one_hot) + target_logits * one_hot # feature re-scale output *= self.s loss = F.softmax_cross_entropy(output, labels) return loss
def main(): x1 = Variable(np.array([1]).astype(np.float32)) x2 = Variable(np.array([2]).astype(np.float32)) x3 = Variable(np.array([3]).astype(np.float32)) z = (x1 - 2 * x2 - 1)**2 + (x2 * x3 - 1)**2 + 1 print(z.data) z.backward() print(x1.grad) print(x2.grad) print(x3.grad) x = Variable(np.array([-1], dtype=np.float32)) print(F.sin(x).data) print(F.sigmoid(x).data) x = Variable(np.array([-0.5], dtype=np.float32)) z = F.cos(x) print(z.data) z.backward() print(x.grad) print((-1) * F.sin(x).data) x = Variable(np.array([-1, 0, 1], dtype=np.float32)) z = F.sin(x) z.grad = np.ones(3, dtype=np.float32) z.backward() print(x.grad) h = L.Linear(3, 4) print(h.W.data) print(h.b.data) x = Variable(np.array(range(6)).astype(np.float32).reshape(2, 3)) print(x.data) y = h(x) print(y.data) w = h.W.data x0 = x.data print(x0.dot(w.T) + h.b.data) model = MyChain() optimizer = optimizers.SGD() optimizer.setup(model) model.zerograds() loss = model(x, y) loss.backward() optimizer.update()
def batch_rodrigues(theta): """ Theta is N x 3 """ batch_size = theta.shape[0] xp = theta.xp angle = F.expand_dims(F.sqrt(F.batch_l2_norm_squared(theta + 1e-8)), -1) r = F.expand_dims(theta / F.tile(angle, 3), -1) angle = F.expand_dims(angle, -1) cos = F.cos(angle) sin = F.sin(angle) cos = F.tile(cos, (3, 3)) sin = F.tile(sin, (3, 3)) outer = F.matmul(r, r, transb=True) eyes = F.tile(F.expand_dims(Variable(xp.array(xp.eye(3), 'f')), 0), (batch_size, 1, 1)) R = cos * eyes + (1 - cos) * outer + sin * batch_skew(r, batch_size) return R
def batch_rodrigues(theta): """ Theta is N x 3 """ batch_size = theta.shape[0] xp = theta.xp angle = F.expand_dims(F.sqrt(F.batch_l2_norm_squared(theta + 1e-8)), -1) r = F.expand_dims(theta / F.tile(angle, 3), -1) angle = F.expand_dims(angle, -1) cos = F.cos(angle) sin = F.sin(angle) cos = F.tile(cos, (3, 3)) sin = F.tile(sin, (3, 3)) outer = F.matmul(r, r, transb=True) eyes = F.tile(F.expand_dims( Variable(xp.array(xp.eye(3), 'f')), 0), (batch_size, 1, 1)) R = cos * eyes + (1 - cos) * outer + sin * batch_skew(r, batch_size) return R
def forward(self, x, u): # x, u = inputs squeeze = len(x.shape) == 1 if squeeze: # print("squeeze is true") x = F.expand_dims(x, 0) u = F.expand_dims(u, 0) assert len(x.shape) == 2 assert x.shape[0] == u.shape[0] assert x.shape[1] == self.n_state, str(x.shape[1]) assert u.shape[1] == self.n_ctrl # x (n_batch, n_state) # u (n_batch, n_ctrl) assert len(u.shape) == 2, str(u.shape) if not hasattr(self, 'simple') or self.simple: g, m, l = F.separate(self.params) else: g, m, l, d, b = F.separate(self.params) u = F.clip(u, -self.max_torque, self.max_torque)[:, 0] # cos, sin, angular velocity cos_th, sin_th, dth = F.separate(x, axis=1) # theta th = F.arctan2(sin_th, cos_th) # calculate new angular velocity if not hasattr(self, 'simple') or self.simple: newdth = dth newdth += self.dt * (-3. * g / (2. * l) * (-sin_th) + 3. * u / (m * l ** 2)) else: sin_th_bias = F.sin(th + b) newdth = dth newdth += self.dt * (-3. * g / (2. * l) * (-sin_th_bias) + 3. * u / (m * l ** 2) - d * th) newth = th + newdth * self.dt state = F.stack((F.cos(newth), F.sin(newth), newdth), axis=1) if squeeze: state = F.squeeze(state, axis=0) return state
def __call__(self, z_slow, c=None, n_frames=None): if c is not None: raise NotImplementedError # Do not use z_slow instead we radomly sample z_fast xp = self.xp T = n_frames if n_frames is not None else self.n_frames N = len(z_slow) Nz = self.z_fast_dim z_fast = self.make_hidden(N, Nz=Nz) initial = F.broadcast_to(z_fast.reshape(N, Nz, 1), (N, Nz, T)) step = chainer.Variable(xp.arange(0, T, dtype=xp.float32)) step = F.broadcast_to(step.reshape(1, 1, T), (N, Nz, T)) v = F.broadcast_to(self.velocity.reshape(1, Nz, 1), (N, Nz, T)) z_fast = initial + step * v ones = chainer.Variable(xp.ones_like(z_fast.array, dtype=xp.float32)) z_fast = F.fmod(z_fast, ones) # (N, z_fast_dim, n_frames) theta = (2 * numpy.pi) * z_fast z_fast = F.concat([F.cos(theta), F.sin(theta)]) return z_fast.transpose(0, 2, 1) # (N, n_frames, 2 * z_fast_dim)
def euler2mat(r, xp=np): """Converts euler angles to rotation matrix Args: r: rotation angle(x, y, z). Shape is (N, 3). Returns: Rotation matrix corresponding to the euler angles. Shape is (N, 3, 3). """ batchsize = r.shape[0] # start, stop = create_timer() zeros = xp.zeros((batchsize), dtype='f') ones = xp.ones((batchsize), dtype='f') r = F.clip(r, -np.pi, np.pi) cos_r = F.cos(r) sin_r = F.sin(r) zmat = F.stack([ cos_r[:, 2], -sin_r[:, 2], zeros, sin_r[:, 2], cos_r[:, 2], zeros, zeros, zeros, ones ], axis=1).reshape(batchsize, 3, 3) ymat = F.stack([ cos_r[:, 1], zeros, sin_r[:, 1], zeros, ones, zeros, -sin_r[:, 1], zeros, cos_r[:, 1] ], axis=1).reshape(batchsize, 3, 3) xmat = F.stack([ ones, zeros, zeros, zeros, cos_r[:, 0], -sin_r[:, 0], zeros, sin_r[:, 0], cos_r[:, 0] ], axis=1).reshape(batchsize, 3, 3) # #print_timer(start, stop, 'create matrix') # z --> y --> x rotMat = F.batch_matmul(F.batch_matmul(xmat, ymat), zmat) return rotMat
def cos(self, x): return F.cos(x)
print F.sin(x).data print F.sigmoid(x) print F.sigmoid(x).data print "*****************************************" """ ・chainer.functionの中に活性化関数や損失関数などが定義されている ・変数が多次元の場合は、関数の傾きの次元をあらかじめ設定しておく必要がある z.grad = np.ones(z.size,dtype=np.float32) --> z.backward() --> x.grad ・chainer.linksの中にはパラメータありの関数を提供している chainer.functionの中の関数はパラメータなし 自分が考えたモデル(合成関数)をlinks内の関数とfuncions内の関数 を組み合わせて表現する """ x = Variable(np.array([-0.5], dtype=np.float32)) z = F.cos(x) print z.data z.backward() print x.grad print((-1) * F.sin(x).data) # 変数が多次元な場合 x = Variable(np.array([-1, 0, 1], dtype=np.float32)) print x.data z = F.sin(x) print z z.grad = np.ones(z.size, dtype=np.float32) print z.grad z.backward() print z
def forward(self, x): y1 = F.cos(x) return y1
def update_core(self): xp = self.gen.xp use_rotate = True if self.iteration > self.config.start_rotation else False self.gen.cleargrads() self.dis.cleargrads() if self.bigan: self.enc.cleargrads() if self.config.generator_architecture == "stylegan": opt_g_m = self.get_optimizer('map') opt_g_g = self.get_optimizer('gen') opt_d = self.get_optimizer('dis') # z: latent | x: data | y: dis output # *_real/*_fake/*_pertubed: Variable # *_data: just data (xp array) stage = self.stage # Need to retrive the value since next statement may change state (at the stage boundary) batch = self.get_iterator('main').next() batch_size = len(batch) # lr_scale = get_lr_scale_factor(self.total_gpu, stage) x_real_data = self.get_x_real_data(batch, batch_size) z_fake_data = xp.concatenate([self.get_z_fake_data(batch_size // 2)] * 2) # repeat same z if isinstance(chainer.global_config.dtype, chainer._Mixed16): x_real_data = x_real_data.astype("float16") z_fake_data = z_fake_data.astype("float16") # theta->6 DOF thetas = self.prior.sample(batch_size) # thetas = Variable(xp.array(thetas)) # # theta -> camera matrix # random_camera_matrices = xp.array(get_camera_matries(thetas, order=(0, 1, 2)), dtype="float32") # thetas = F.concat([F.cos(thetas[:, :3]), F.sin(thetas[:, :3]), thetas[:, 3:]], axis=1) # theta -> camera matrix thetas_ = xp.array(thetas) random_camera_matrices = xp.array(get_camera_matries(thetas)) thetas = F.concat([F.cos(thetas_[:, :3]), F.sin(thetas_[:, :3]), thetas_[:, 3:]], axis=1) x_real = Variable(x_real_data) # Image.fromarray(convert_batch_images(x_real.data.get(), 4, 4)).save('no_downsized.png') x_real = downsize_real(x_real, stage) x_real = Variable(x_real.data) # Image.fromarray(convert_batch_images(x_real.data.get(), 4, 4)).save('downsized.png') image_size = x_real.shape[2] x_fake = self.gen(z_fake_data, stage, thetas) if self.bigan: # bigan is not supported now assert False, "bigan is not supported" else: y_fake, feat = self.dis(x_fake[:, :3], stage=stage, return_hidden=True) loss_gen = loss_func_dcgan_gen(y_fake) # * lr_scale assert not xp.isnan(loss_gen.data) chainer.report({'loss_adv': loss_gen}, opt_g_g.target) if use_rotate: loss_rotate, warped_zp = self.loss_func_rotate(x_fake[:batch_size // 2], random_camera_matrices[:batch_size // 2], x_fake[batch_size // 2:], random_camera_matrices[batch_size // 2:], self.iteration >= self.config.start_occlusion_aware) if self.config.rotate_feature: downsample_rate = x_real.shape[2] // feat.shape[2] depth = F.average_pooling_2d(x_real[:, -1:], downsample_rate, downsample_rate, 0) feat = F.concat([feat, depth], axis=1) loss_rotate_feature, _ = self.loss_func_rotate_feature(feat[:batch_size // 2], random_camera_matrices[:batch_size // 2], feat[batch_size // 2:], random_camera_matrices[batch_size // 2:], self.iteration >= self.config.start_occlusion_aware) loss_rotate += loss_rotate_feature # loss_rotate *= 10 if self.config.lambda_depth > 0: loss_rotate += F.mean(F.relu(self.config.depth_min - x_fake[:, -1]) ** 2) * \ self.config.lambda_depth # make depth larger assert not xp.isnan(loss_rotate.data) chainer.report({'loss_rotate': loss_rotate}, opt_g_g.target) lambda_rotate = self.config.lambda_rotate if self.config.lambda_rotate else 2 lambda_rotate = lambda_rotate if image_size <= 128 else lambda_rotate * 2 loss_gen += loss_rotate * lambda_rotate if self.config.use_occupancy_net_loss: loss_occupancy = self.loss_func_rotate.occupancy_net_loss(self.gen.occupancy, x_fake[:, -1:], random_camera_matrices, z_fake_data.squeeze()) chainer.report({'loss_occupancy': loss_occupancy}, opt_g_g.target) loss_gen += loss_occupancy * self.config.lambda_occupancy if self.config.optical_flow: assert False, "optical flow loss is not supported" # loss_rotate += - 0.2 * F.log( # F.mean((F.mean(1 / x_fake[:, -1].reshape(batch_size, -1) ** 2, axis=1) - # F.mean(1 / x_fake[:, -1].reshape(batch_size, -1), axis=1) ** 2) + 1e-3)) # loss_depth = self.loss_smooth_depth(x_fake[:, -1:]) * 20 # loss_dsgan = loss_func_dsgan(x_fake, z_fake, theta) # Diversity sensitive gan in ICLR2019 if chainer.global_config.debug: g = c.build_computational_graph(loss_gen) with open('out_loss_gen', 'w') as o: o.write(g.dump()) # assert not xp.isnan(loss_dsgan.data) # with chainer.using_config('debug', True): loss_gen.backward() # loss_depth.backward() # loss_dsgan.backward() if self.config.generator_architecture == "stylegan": opt_g_m.update() opt_g_g.update() del loss_gen self.dis.cleargrads() # keep smoothed generator if instructed to do so. if self.smoothed_gen is not None: # layers_in_use = self.gen.get_layers_in_use(stage=stage) soft_copy_param(self.smoothed_gen, self.gen, 1.0 - self.smoothing) # with chainer.using_config('enable_backprop', False): if self.bigan: assert False, "bigan is not supported" else: v_x_fake = Variable(x_fake.array[:, :3]) y_fake, feat = self.dis(v_x_fake, stage=stage, return_hidden=True) y_real = self.dis(x_real, stage=stage) loss_dis = loss_func_dcgan_dis(y_fake, y_real) # loss_reg_camera_param = calc_distance(est_camera_param_real, xp.array(thetas)) / 10 if not self.dis.sn and self.lambda_gp > 0: # y_perturbed = self.dis(x_perturbed, stage=stage) grad_x_perturbed, = chainer.grad([y_real], [x_real], enable_double_backprop=True) grad_l2 = F.sqrt(F.sum(grad_x_perturbed ** 2, axis=(1, 2, 3))) loss_gp = self.lambda_gp * loss_l2(grad_l2, 0.0) chainer.report({'loss_gp': loss_gp}, self.dis) loss_dis = loss_dis + loss_gp # * lr_scale if use_rotate and self.config.rotate_feature: downsample_rate = x_real.shape[2] // feat.shape[2] depth = F.average_pooling_2d(x_real[:, -1:], downsample_rate, downsample_rate, 0) feat = F.concat([feat, depth], axis=1) loss_rotate_feature, _ = self.loss_func_rotate_feature(feat[:batch_size // 2], random_camera_matrices[:batch_size // 2], feat[batch_size // 2:], random_camera_matrices[batch_size // 2:], self.iteration >= self.config.start_occlusion_aware) loss_dis -= loss_rotate_feature if not self.dis.sn and self.lambda_gp > 0: grad_x_perturbed, = chainer.grad([feat], [v_x_fake], enable_double_backprop=True) grad_l2 = F.sqrt(F.sum(grad_x_perturbed ** 2, axis=(1, 2, 3))) loss_gp = self.lambda_gp * loss_l2(grad_l2, 0.0) loss_dis += loss_gp assert not xp.isnan(loss_dis.data) chainer.report({'loss_adv': loss_dis}, self.dis) loss_dis.backward() opt_d.update() chainer.reporter.report({'stage': stage}) chainer.reporter.report({'batch_size': batch_size}) chainer.reporter.report({'image_size': image_size})
def forward(self, *args, **kwargs): if 'train' in kwargs.keys(): self.train = kwargs['train'] del kwargs['train'] if 'epoch' in kwargs.keys(): if self.target_epoch is not None: self.margin = kwargs[ 'epoch'] / self.target_epoch * self.final_margin self.scale = 1 + kwargs['epoch'] / self.target_epoch * ( self.final_scale - 1) del kwargs['epoch'] if isinstance(self.label_key, int): if not (-len(args) <= self.label_key < len(args)): msg = 'Label key %d is out of bounds' % self.label_key raise ValueError(msg) t = args[self.label_key] if self.label_key == -1: args = args[:-1] else: args = args[:self.label_key] + args[self.label_key + 1:] elif isinstance(self.label_key, str): if self.label_key not in kwargs: msg = 'Label key "%s" is not found' % self.label_key raise ValueError(msg) t = kwargs[self.label_key] del kwargs[self.label_key] self.y = None self.hidden_feature = None self.loss = None self.accuracy = None self.hidden_feature = self.predictor(*args, **kwargs) self.y = self.cosine_similarity(self.hidden_feature) if self.train: xp = chainer.backend.cuda.get_array_module(self.y) if self.method == 'sphereface': penalty = xp.zeros_like(self.y) rows = xp.arange(t.size) penalty[rows, t] = (F.cos(F.arccos(self.y[rows, t]) * self.margin) - self.y[rows, t]).data self.y += penalty elif self.method == 'arcface': penalty = xp.zeros_like(self.y) rows = xp.arange(t.size) penalty[rows, t] = (F.cos(F.arccos(self.y[rows, t]) + self.margin) - self.y[rows, t]).data self.y += penalty elif self.method == 'cosface': self.y[xp.arange(t.size), t] -= self.margin else: raise NotImplementedError self.y *= self.scale self.loss = self.lossfun(self.y, t) reporter.report({'loss': self.loss}, self) if self.compute_accuracy: self.accuracy = self.accfun(self.y, t) reporter.report({'accuracy': self.accuracy}, self) return self.loss