Spaces:
Runtime error
Runtime error
function_name,docstring,function_body,file_path | |
diffusion_from_config,,"def diffusion_from_config(config: Dict[str, Any]) ->GaussianDiffusion: | |
schedule = config['schedule'] | |
steps = config['timesteps'] | |
respace = config.get('respacing', None) | |
mean_type = config.get('mean_type', 'epsilon') | |
betas = get_named_beta_schedule(schedule, steps) | |
channel_scales = config.get('channel_scales', None) | |
channel_biases = config.get('channel_biases', None) | |
if channel_scales is not None: | |
channel_scales = np.array(channel_scales) | |
if channel_biases is not None: | |
channel_biases = np.array(channel_biases) | |
kwargs = dict(betas=betas, model_mean_type=mean_type, model_var_type= | |
'learned_range', loss_type='mse', channel_scales=channel_scales, | |
channel_biases=channel_biases) | |
if respace is None: | |
return GaussianDiffusion(**kwargs) | |
else: | |
return SpacedDiffusion(use_timesteps=space_timesteps(steps, respace | |
), **kwargs) | |
",point_e\diffusion\configs.py | |
get_beta_schedule,"This is the deprecated API for creating beta schedules. | |
See get_named_beta_schedule() for the new library of schedules.","def get_beta_schedule(beta_schedule, *, beta_start, beta_end, | |
num_diffusion_timesteps): | |
"""""""""""" | |
if beta_schedule == 'linear': | |
betas = np.linspace(beta_start, beta_end, num_diffusion_timesteps, | |
dtype=np.float64) | |
else: | |
raise NotImplementedError(beta_schedule) | |
assert betas.shape == (num_diffusion_timesteps,) | |
return betas | |
",point_e\diffusion\gaussian_diffusion.py | |
get_named_beta_schedule,"Get a pre-defined beta schedule for the given name. | |
The beta schedule library consists of beta schedules which remain similar | |
in the limit of num_diffusion_timesteps. | |
Beta schedules may be added, but should not be removed or changed once | |
they are committed to maintain backwards compatibility.","def get_named_beta_schedule(schedule_name, num_diffusion_timesteps): | |
"""""""""""" | |
if schedule_name == 'linear': | |
scale = 1000 / num_diffusion_timesteps | |
return get_beta_schedule('linear', beta_start=scale * 0.0001, | |
beta_end=scale * 0.02, num_diffusion_timesteps= | |
num_diffusion_timesteps) | |
elif schedule_name == 'cosine': | |
return betas_for_alpha_bar(num_diffusion_timesteps, lambda t: math. | |
cos((t + 0.008) / 1.008 * math.pi / 2) ** 2) | |
else: | |
raise NotImplementedError(f'unknown beta schedule: {schedule_name}') | |
",point_e\diffusion\gaussian_diffusion.py | |
betas_for_alpha_bar,"Create a beta schedule that discretizes the given alpha_t_bar function, | |
which defines the cumulative product of (1-beta) over time from t = [0,1]. | |
:param num_diffusion_timesteps: the number of betas to produce. | |
:param alpha_bar: a lambda that takes an argument t from 0 to 1 and | |
produces the cumulative product of (1-beta) up to that | |
part of the diffusion process. | |
:param max_beta: the maximum beta to use; use values lower than 1 to | |
prevent singularities.","def betas_for_alpha_bar(num_diffusion_timesteps, alpha_bar, max_beta=0.999): | |
"""""""""""" | |
betas = [] | |
for i in range(num_diffusion_timesteps): | |
t1 = i / num_diffusion_timesteps | |
t2 = (i + 1) / num_diffusion_timesteps | |
betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta)) | |
return np.array(betas) | |
",point_e\diffusion\gaussian_diffusion.py | |
space_timesteps,"Create a list of timesteps to use from an original diffusion process, | |
given the number of timesteps we want to take from equally-sized portions | |
of the original process. | |
For example, if there's 300 timesteps and the section counts are [10,15,20] | |
then the first 100 timesteps are strided to be 10 timesteps, the second 100 | |
are strided to be 15 timesteps, and the final 100 are strided to be 20. | |
:param num_timesteps: the number of diffusion steps in the original | |
process to divide up. | |
:param section_counts: either a list of numbers, or a string containing | |
comma-separated numbers, indicating the step count | |
per section. As a special case, use ""ddimN"" where N | |
is a number of steps to use the striding from the | |
DDIM paper. | |
:return: a set of diffusion steps from the original process to use.","def space_timesteps(num_timesteps, section_counts): | |
"""""""""""" | |
if isinstance(section_counts, str): | |
if section_counts.startswith('ddim'): | |
desired_count = int(section_counts[len('ddim'):]) | |
for i in range(1, num_timesteps): | |
if len(range(0, num_timesteps, i)) == desired_count: | |
return set(range(0, num_timesteps, i)) | |
raise ValueError( | |
f'cannot create exactly {num_timesteps} steps with an integer stride' | |
) | |
elif section_counts.startswith('exact'): | |
res = set(int(x) for x in section_counts[len('exact'):].split(',')) | |
for x in res: | |
if x < 0 or x >= num_timesteps: | |
raise ValueError(f'timestep out of bounds: {x}') | |
return res | |
section_counts = [int(x) for x in section_counts.split(',')] | |
size_per = num_timesteps // len(section_counts) | |
extra = num_timesteps % len(section_counts) | |
start_idx = 0 | |
all_steps = [] | |
for i, section_count in enumerate(section_counts): | |
size = size_per + (1 if i < extra else 0) | |
if size < section_count: | |
raise ValueError( | |
f'cannot divide section of {size} steps into {section_count}') | |
if section_count <= 1: | |
frac_stride = 1 | |
else: | |
frac_stride = (size - 1) / (section_count - 1) | |
cur_idx = 0.0 | |
taken_steps = [] | |
for _ in range(section_count): | |
taken_steps.append(start_idx + round(cur_idx)) | |
cur_idx += frac_stride | |
all_steps += taken_steps | |
start_idx += size | |
return set(all_steps) | |
",point_e\diffusion\gaussian_diffusion.py | |
_extract_into_tensor,"Extract values from a 1-D numpy array for a batch of indices. | |
:param arr: the 1-D numpy array. | |
:param timesteps: a tensor of indices into the array to extract. | |
:param broadcast_shape: a larger shape of K dimensions with the batch | |
dimension equal to the length of timesteps. | |
:return: a tensor of shape [batch_size, 1, ...] where the shape has K dims.","def _extract_into_tensor(arr, timesteps, broadcast_shape): | |
"""""""""""" | |
res = th.from_numpy(arr).to(device=timesteps.device)[timesteps].float() | |
while len(res.shape) < len(broadcast_shape): | |
res = res[..., None] | |
return res + th.zeros(broadcast_shape, device=timesteps.device) | |
",point_e\diffusion\gaussian_diffusion.py | |
normal_kl,"Compute the KL divergence between two gaussians. | |
Shapes are automatically broadcasted, so batches can be compared to | |
scalars, among other use cases.","def normal_kl(mean1, logvar1, mean2, logvar2): | |
"""""""""""" | |
tensor = None | |
for obj in (mean1, logvar1, mean2, logvar2): | |
if isinstance(obj, th.Tensor): | |
tensor = obj | |
break | |
assert tensor is not None, 'at least one argument must be a Tensor' | |
logvar1, logvar2 = [(x if isinstance(x, th.Tensor) else th.tensor(x).to | |
(tensor)) for x in (logvar1, logvar2)] | |
return 0.5 * (-1.0 + logvar2 - logvar1 + th.exp(logvar1 - logvar2) + ( | |
mean1 - mean2) ** 2 * th.exp(-logvar2)) | |
",point_e\diffusion\gaussian_diffusion.py | |
approx_standard_normal_cdf,"A fast approximation of the cumulative distribution function of the | |
standard normal.","def approx_standard_normal_cdf(x): | |
"""""""""""" | |
return 0.5 * (1.0 + th.tanh(np.sqrt(2.0 / np.pi) * (x + 0.044715 * th. | |
pow(x, 3)))) | |
",point_e\diffusion\gaussian_diffusion.py | |
discretized_gaussian_log_likelihood,"Compute the log-likelihood of a Gaussian distribution discretizing to a | |
given image. | |
:param x: the target images. It is assumed that this was uint8 values, | |
rescaled to the range [-1, 1]. | |
:param means: the Gaussian mean Tensor. | |
:param log_scales: the Gaussian log stddev Tensor. | |
:return: a tensor like x of log probabilities (in nats).","def discretized_gaussian_log_likelihood(x, *, means, log_scales): | |
"""""""""""" | |
assert x.shape == means.shape == log_scales.shape | |
centered_x = x - means | |
inv_stdv = th.exp(-log_scales) | |
plus_in = inv_stdv * (centered_x + 1.0 / 255.0) | |
cdf_plus = approx_standard_normal_cdf(plus_in) | |
min_in = inv_stdv * (centered_x - 1.0 / 255.0) | |
cdf_min = approx_standard_normal_cdf(min_in) | |
log_cdf_plus = th.log(cdf_plus.clamp(min=1e-12)) | |
log_one_minus_cdf_min = th.log((1.0 - cdf_min).clamp(min=1e-12)) | |
cdf_delta = cdf_plus - cdf_min | |
log_probs = th.where(x < -0.999, log_cdf_plus, th.where(x > 0.999, | |
log_one_minus_cdf_min, th.log(cdf_delta.clamp(min=1e-12)))) | |
assert log_probs.shape == x.shape | |
return log_probs | |
",point_e\diffusion\gaussian_diffusion.py | |
mean_flat,Take the mean over all non-batch dimensions.,"def mean_flat(tensor): | |
"""""""""""" | |
return tensor.flatten(1).mean(1) | |
",point_e\diffusion\gaussian_diffusion.py | |
__init__,,"def __init__(self, *, betas: Sequence[float], model_mean_type: str, | |
model_var_type: str, loss_type: str, discretized_t0: bool=False, | |
channel_scales: Optional[np.ndarray]=None, channel_biases: Optional[np. | |
ndarray]=None): | |
self.model_mean_type = model_mean_type | |
self.model_var_type = model_var_type | |
self.loss_type = loss_type | |
self.discretized_t0 = discretized_t0 | |
self.channel_scales = channel_scales | |
self.channel_biases = channel_biases | |
betas = np.array(betas, dtype=np.float64) | |
self.betas = betas | |
assert len(betas.shape) == 1, 'betas must be 1-D' | |
assert (betas > 0).all() and (betas <= 1).all() | |
self.num_timesteps = int(betas.shape[0]) | |
alphas = 1.0 - betas | |
self.alphas_cumprod = np.cumprod(alphas, axis=0) | |
self.alphas_cumprod_prev = np.append(1.0, self.alphas_cumprod[:-1]) | |
self.alphas_cumprod_next = np.append(self.alphas_cumprod[1:], 0.0) | |
assert self.alphas_cumprod_prev.shape == (self.num_timesteps,) | |
self.sqrt_alphas_cumprod = np.sqrt(self.alphas_cumprod) | |
self.sqrt_one_minus_alphas_cumprod = np.sqrt(1.0 - self.alphas_cumprod) | |
self.log_one_minus_alphas_cumprod = np.log(1.0 - self.alphas_cumprod) | |
self.sqrt_recip_alphas_cumprod = np.sqrt(1.0 / self.alphas_cumprod) | |
self.sqrt_recipm1_alphas_cumprod = np.sqrt(1.0 / self.alphas_cumprod - 1) | |
self.posterior_variance = betas * (1.0 - self.alphas_cumprod_prev) / ( | |
1.0 - self.alphas_cumprod) | |
self.posterior_log_variance_clipped = np.log(np.append(self. | |
posterior_variance[1], self.posterior_variance[1:])) | |
self.posterior_mean_coef1 = betas * np.sqrt(self.alphas_cumprod_prev) / ( | |
1.0 - self.alphas_cumprod) | |
self.posterior_mean_coef2 = (1.0 - self.alphas_cumprod_prev) * np.sqrt( | |
alphas) / (1.0 - self.alphas_cumprod) | |
",point_e\diffusion\gaussian_diffusion.py | |
get_sigmas,,"def get_sigmas(self, t): | |
return _extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, t.shape) | |
",point_e\diffusion\gaussian_diffusion.py | |
q_mean_variance,"Get the distribution q(x_t | x_0). | |
:param x_start: the [N x C x ...] tensor of noiseless inputs. | |
:param t: the number of diffusion steps (minus 1). Here, 0 means one step. | |
:return: A tuple (mean, variance, log_variance), all of x_start's shape.","def q_mean_variance(self, x_start, t): | |
"""""""""""" | |
mean = _extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape | |
) * x_start | |
variance = _extract_into_tensor(1.0 - self.alphas_cumprod, t, x_start.shape | |
) | |
log_variance = _extract_into_tensor(self.log_one_minus_alphas_cumprod, | |
t, x_start.shape) | |
return mean, variance, log_variance | |
",point_e\diffusion\gaussian_diffusion.py | |
q_sample,"Diffuse the data for a given number of diffusion steps. | |
In other words, sample from q(x_t | x_0). | |
:param x_start: the initial data batch. | |
:param t: the number of diffusion steps (minus 1). Here, 0 means one step. | |
:param noise: if specified, the split-out normal noise. | |
:return: A noisy version of x_start.","def q_sample(self, x_start, t, noise=None): | |
"""""""""""" | |
if noise is None: | |
noise = th.randn_like(x_start) | |
assert noise.shape == x_start.shape | |
return _extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape | |
) * x_start + _extract_into_tensor(self. | |
sqrt_one_minus_alphas_cumprod, t, x_start.shape) * noise | |
",point_e\diffusion\gaussian_diffusion.py | |
q_posterior_mean_variance,"Compute the mean and variance of the diffusion posterior: | |
q(x_{t-1} | x_t, x_0)","def q_posterior_mean_variance(self, x_start, x_t, t): | |
"""""""""""" | |
assert x_start.shape == x_t.shape | |
posterior_mean = _extract_into_tensor(self.posterior_mean_coef1, t, x_t | |
.shape) * x_start + _extract_into_tensor(self.posterior_mean_coef2, | |
t, x_t.shape) * x_t | |
posterior_variance = _extract_into_tensor(self.posterior_variance, t, | |
x_t.shape) | |
posterior_log_variance_clipped = _extract_into_tensor(self. | |
posterior_log_variance_clipped, t, x_t.shape) | |
assert posterior_mean.shape[0] == posterior_variance.shape[0 | |
] == posterior_log_variance_clipped.shape[0] == x_start.shape[0] | |
return posterior_mean, posterior_variance, posterior_log_variance_clipped | |
",point_e\diffusion\gaussian_diffusion.py | |
p_mean_variance,"Apply the model to get p(x_{t-1} | x_t), as well as a prediction of | |
the initial x, x_0. | |
:param model: the model, which takes a signal and a batch of timesteps | |
as input. | |
:param x: the [N x C x ...] tensor at time t. | |
:param t: a 1-D Tensor of timesteps. | |
:param clip_denoised: if True, clip the denoised signal into [-1, 1]. | |
:param denoised_fn: if not None, a function which applies to the | |
x_start prediction before it is used to sample. Applies before | |
clip_denoised. | |
:param model_kwargs: if not None, a dict of extra keyword arguments to | |
pass to the model. This can be used for conditioning. | |
:return: a dict with the following keys: | |
- 'mean': the model mean output. | |
- 'variance': the model variance output. | |
- 'log_variance': the log of 'variance'. | |
- 'pred_xstart': the prediction for x_0.","def p_mean_variance(self, model, x, t, clip_denoised=False, denoised_fn= | |
None, model_kwargs=None): | |
"""""""""""" | |
if model_kwargs is None: | |
model_kwargs = {} | |
B, C = x.shape[:2] | |
assert t.shape == (B,) | |
model_output = model(x, t, **model_kwargs) | |
if isinstance(model_output, tuple): | |
model_output, extra = model_output | |
else: | |
extra = None | |
if self.model_var_type in ['learned', 'learned_range']: | |
assert model_output.shape == (B, C * 2, *x.shape[2:]) | |
model_output, model_var_values = th.split(model_output, C, dim=1) | |
if self.model_var_type == 'learned': | |
model_log_variance = model_var_values | |
model_variance = th.exp(model_log_variance) | |
else: | |
min_log = _extract_into_tensor(self. | |
posterior_log_variance_clipped, t, x.shape) | |
max_log = _extract_into_tensor(np.log(self.betas), t, x.shape) | |
frac = (model_var_values + 1) / 2 | |
model_log_variance = frac * max_log + (1 - frac) * min_log | |
model_variance = th.exp(model_log_variance) | |
else: | |
model_variance, model_log_variance = {'fixed_large': (np.append( | |
self.posterior_variance[1], self.betas[1:]), np.log(np.append( | |
self.posterior_variance[1], self.betas[1:]))), 'fixed_small': ( | |
self.posterior_variance, self.posterior_log_variance_clipped)}[self | |
.model_var_type] | |
model_variance = _extract_into_tensor(model_variance, t, x.shape) | |
model_log_variance = _extract_into_tensor(model_log_variance, t, x. | |
shape) | |
def process_xstart(x): | |
if denoised_fn is not None: | |
x = denoised_fn(x) | |
if clip_denoised: | |
return x.clamp(-1, 1) | |
return x | |
if self.model_mean_type == 'x_prev': | |
pred_xstart = process_xstart(self._predict_xstart_from_xprev(x_t=x, | |
t=t, xprev=model_output)) | |
model_mean = model_output | |
elif self.model_mean_type in ['x_start', 'epsilon']: | |
if self.model_mean_type == 'x_start': | |
pred_xstart = process_xstart(model_output) | |
else: | |
pred_xstart = process_xstart(self._predict_xstart_from_eps(x_t= | |
x, t=t, eps=model_output)) | |
model_mean, _, _ = self.q_posterior_mean_variance(x_start= | |
pred_xstart, x_t=x, t=t) | |
else: | |
raise NotImplementedError(self.model_mean_type) | |
assert model_mean.shape == model_log_variance.shape == pred_xstart.shape == x.shape | |
return {'mean': model_mean, 'variance': model_variance, 'log_variance': | |
model_log_variance, 'pred_xstart': pred_xstart, 'extra': extra} | |
",point_e\diffusion\gaussian_diffusion.py | |
_predict_xstart_from_eps,,"def _predict_xstart_from_eps(self, x_t, t, eps): | |
assert x_t.shape == eps.shape | |
return _extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t.shape | |
) * x_t - _extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, | |
x_t.shape) * eps | |
",point_e\diffusion\gaussian_diffusion.py | |
_predict_xstart_from_xprev,,"def _predict_xstart_from_xprev(self, x_t, t, xprev): | |
assert x_t.shape == xprev.shape | |
return _extract_into_tensor(1.0 / self.posterior_mean_coef1, t, x_t.shape | |
) * xprev - _extract_into_tensor(self.posterior_mean_coef2 / self. | |
posterior_mean_coef1, t, x_t.shape) * x_t | |
",point_e\diffusion\gaussian_diffusion.py | |
_predict_eps_from_xstart,,"def _predict_eps_from_xstart(self, x_t, t, pred_xstart): | |
return (_extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t. | |
shape) * x_t - pred_xstart) / _extract_into_tensor(self. | |
sqrt_recipm1_alphas_cumprod, t, x_t.shape) | |
",point_e\diffusion\gaussian_diffusion.py | |
condition_mean,"Compute the mean for the previous step, given a function cond_fn that | |
computes the gradient of a conditional log probability with respect to | |
x. In particular, cond_fn computes grad(log(p(y|x))), and we want to | |
condition on y. | |
This uses the conditioning strategy from Sohl-Dickstein et al. (2015).","def condition_mean(self, cond_fn, p_mean_var, x, t, model_kwargs=None): | |
"""""""""""" | |
gradient = cond_fn(x, t, **model_kwargs) | |
new_mean = p_mean_var['mean'].float() + p_mean_var['variance' | |
] * gradient.float() | |
return new_mean | |
",point_e\diffusion\gaussian_diffusion.py | |
condition_score,"Compute what the p_mean_variance output would have been, should the | |
model's score function be conditioned by cond_fn. | |
See condition_mean() for details on cond_fn. | |
Unlike condition_mean(), this instead uses the conditioning strategy | |
from Song et al (2020).","def condition_score(self, cond_fn, p_mean_var, x, t, model_kwargs=None): | |
"""""""""""" | |
alpha_bar = _extract_into_tensor(self.alphas_cumprod, t, x.shape) | |
eps = self._predict_eps_from_xstart(x, t, p_mean_var['pred_xstart']) | |
eps = eps - (1 - alpha_bar).sqrt() * cond_fn(x, t, **model_kwargs) | |
out = p_mean_var.copy() | |
out['pred_xstart'] = self._predict_xstart_from_eps(x, t, eps) | |
out['mean'], _, _ = self.q_posterior_mean_variance(x_start=out[ | |
'pred_xstart'], x_t=x, t=t) | |
return out | |
",point_e\diffusion\gaussian_diffusion.py | |
p_sample,"Sample x_{t-1} from the model at the given timestep. | |
:param model: the model to sample from. | |
:param x: the current tensor at x_{t-1}. | |
:param t: the value of t, starting at 0 for the first diffusion step. | |
:param clip_denoised: if True, clip the x_start prediction to [-1, 1]. | |
:param denoised_fn: if not None, a function which applies to the | |
x_start prediction before it is used to sample. | |
:param cond_fn: if not None, this is a gradient function that acts | |
similarly to the model. | |
:param model_kwargs: if not None, a dict of extra keyword arguments to | |
pass to the model. This can be used for conditioning. | |
:return: a dict containing the following keys: | |
- 'sample': a random sample from the model. | |
- 'pred_xstart': a prediction of x_0.","def p_sample(self, model, x, t, clip_denoised=False, denoised_fn=None, | |
cond_fn=None, model_kwargs=None): | |
"""""""""""" | |
out = self.p_mean_variance(model, x, t, clip_denoised=clip_denoised, | |
denoised_fn=denoised_fn, model_kwargs=model_kwargs) | |
noise = th.randn_like(x) | |
nonzero_mask = (t != 0).float().view(-1, *([1] * (len(x.shape) - 1))) | |
if cond_fn is not None: | |
out['mean'] = self.condition_mean(cond_fn, out, x, t, model_kwargs= | |
model_kwargs) | |
sample = out['mean'] + nonzero_mask * th.exp(0.5 * out['log_variance'] | |
) * noise | |
return {'sample': sample, 'pred_xstart': out['pred_xstart']} | |
",point_e\diffusion\gaussian_diffusion.py | |
p_sample_loop,"Generate samples from the model. | |
:param model: the model module. | |
:param shape: the shape of the samples, (N, C, H, W). | |
:param noise: if specified, the noise from the encoder to sample. | |
Should be of the same shape as `shape`. | |
:param clip_denoised: if True, clip x_start predictions to [-1, 1]. | |
:param denoised_fn: if not None, a function which applies to the | |
x_start prediction before it is used to sample. | |
:param cond_fn: if not None, this is a gradient function that acts | |
similarly to the model. | |
:param model_kwargs: if not None, a dict of extra keyword arguments to | |
pass to the model. This can be used for conditioning. | |
:param device: if specified, the device to create the samples on. | |
If not specified, use a model parameter's device. | |
:param progress: if True, show a tqdm progress bar. | |
:return: a non-differentiable batch of samples.","def p_sample_loop(self, model, shape, noise=None, clip_denoised=False, | |
denoised_fn=None, cond_fn=None, model_kwargs=None, device=None, | |
progress=False, temp=1.0): | |
"""""""""""" | |
final = None | |
for sample in self.p_sample_loop_progressive(model, shape, noise=noise, | |
clip_denoised=clip_denoised, denoised_fn=denoised_fn, cond_fn= | |
cond_fn, model_kwargs=model_kwargs, device=device, progress= | |
progress, temp=temp): | |
final = sample | |
return final['sample'] | |
",point_e\diffusion\gaussian_diffusion.py | |
p_sample_loop_progressive,"Generate samples from the model and yield intermediate samples from | |
each timestep of diffusion. | |
Arguments are the same as p_sample_loop(). | |
Returns a generator over dicts, where each dict is the return value of | |
p_sample().","def p_sample_loop_progressive(self, model, shape, noise=None, clip_denoised | |
=False, denoised_fn=None, cond_fn=None, model_kwargs=None, device=None, | |
progress=False, temp=1.0): | |
"""""""""""" | |
if device is None: | |
device = next(model.parameters()).device | |
assert isinstance(shape, (tuple, list)) | |
if noise is not None: | |
img = noise | |
else: | |
img = th.randn(*shape, device=device) * temp | |
indices = list(range(self.num_timesteps))[::-1] | |
if progress: | |
from tqdm.auto import tqdm | |
indices = tqdm(indices) | |
for i in indices: | |
t = th.tensor([i] * shape[0], device=device) | |
with th.no_grad(): | |
out = self.p_sample(model, img, t, clip_denoised=clip_denoised, | |
denoised_fn=denoised_fn, cond_fn=cond_fn, model_kwargs= | |
model_kwargs) | |
yield self.unscale_out_dict(out) | |
img = out['sample'] | |
",point_e\diffusion\gaussian_diffusion.py | |
ddim_sample,"Sample x_{t-1} from the model using DDIM. | |
Same usage as p_sample().","def ddim_sample(self, model, x, t, clip_denoised=False, denoised_fn=None, | |
cond_fn=None, model_kwargs=None, eta=0.0): | |
"""""""""""" | |
out = self.p_mean_variance(model, x, t, clip_denoised=clip_denoised, | |
denoised_fn=denoised_fn, model_kwargs=model_kwargs) | |
if cond_fn is not None: | |
out = self.condition_score(cond_fn, out, x, t, model_kwargs= | |
model_kwargs) | |
eps = self._predict_eps_from_xstart(x, t, out['pred_xstart']) | |
alpha_bar = _extract_into_tensor(self.alphas_cumprod, t, x.shape) | |
alpha_bar_prev = _extract_into_tensor(self.alphas_cumprod_prev, t, x.shape) | |
sigma = eta * th.sqrt((1 - alpha_bar_prev) / (1 - alpha_bar)) * th.sqrt( | |
1 - alpha_bar / alpha_bar_prev) | |
noise = th.randn_like(x) | |
mean_pred = out['pred_xstart'] * th.sqrt(alpha_bar_prev) + th.sqrt(1 - | |
alpha_bar_prev - sigma ** 2) * eps | |
nonzero_mask = (t != 0).float().view(-1, *([1] * (len(x.shape) - 1))) | |
sample = mean_pred + nonzero_mask * sigma * noise | |
return {'sample': sample, 'pred_xstart': out['pred_xstart']} | |
",point_e\diffusion\gaussian_diffusion.py | |
ddim_reverse_sample,Sample x_{t+1} from the model using DDIM reverse ODE.,"def ddim_reverse_sample(self, model, x, t, clip_denoised=False, denoised_fn | |
=None, cond_fn=None, model_kwargs=None, eta=0.0): | |
"""""""""""" | |
assert eta == 0.0, 'Reverse ODE only for deterministic path' | |
out = self.p_mean_variance(model, x, t, clip_denoised=clip_denoised, | |
denoised_fn=denoised_fn, model_kwargs=model_kwargs) | |
if cond_fn is not None: | |
out = self.condition_score(cond_fn, out, x, t, model_kwargs= | |
model_kwargs) | |
eps = (_extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x.shape) * | |
x - out['pred_xstart']) / _extract_into_tensor(self. | |
sqrt_recipm1_alphas_cumprod, t, x.shape) | |
alpha_bar_next = _extract_into_tensor(self.alphas_cumprod_next, t, x.shape) | |
mean_pred = out['pred_xstart'] * th.sqrt(alpha_bar_next) + th.sqrt(1 - | |
alpha_bar_next) * eps | |
return {'sample': mean_pred, 'pred_xstart': out['pred_xstart']} | |
",point_e\diffusion\gaussian_diffusion.py | |
ddim_sample_loop,"Generate samples from the model using DDIM. | |
Same usage as p_sample_loop().","def ddim_sample_loop(self, model, shape, noise=None, clip_denoised=False, | |
denoised_fn=None, cond_fn=None, model_kwargs=None, device=None, | |
progress=False, eta=0.0, temp=1.0): | |
"""""""""""" | |
final = None | |
for sample in self.ddim_sample_loop_progressive(model, shape, noise= | |
noise, clip_denoised=clip_denoised, denoised_fn=denoised_fn, | |
cond_fn=cond_fn, model_kwargs=model_kwargs, device=device, progress | |
=progress, eta=eta, temp=temp): | |
final = sample | |
return final['sample'] | |
",point_e\diffusion\gaussian_diffusion.py | |
ddim_sample_loop_progressive,"Use DDIM to sample from the model and yield intermediate samples from | |
each timestep of DDIM. | |
Same usage as p_sample_loop_progressive().","def ddim_sample_loop_progressive(self, model, shape, noise=None, | |
clip_denoised=False, denoised_fn=None, cond_fn=None, model_kwargs=None, | |
device=None, progress=False, eta=0.0, temp=1.0): | |
"""""""""""" | |
if device is None: | |
device = next(model.parameters()).device | |
assert isinstance(shape, (tuple, list)) | |
if noise is not None: | |
img = noise | |
else: | |
img = th.randn(*shape, device=device) * temp | |
indices = list(range(self.num_timesteps))[::-1] | |
if progress: | |
from tqdm.auto import tqdm | |
indices = tqdm(indices) | |
for i in indices: | |
t = th.tensor([i] * shape[0], device=device) | |
with th.no_grad(): | |
out = self.ddim_sample(model, img, t, clip_denoised= | |
clip_denoised, denoised_fn=denoised_fn, cond_fn=cond_fn, | |
model_kwargs=model_kwargs, eta=eta) | |
yield self.unscale_out_dict(out) | |
img = out['sample'] | |
",point_e\diffusion\gaussian_diffusion.py | |
_vb_terms_bpd,"Get a term for the variational lower-bound. | |
The resulting units are bits (rather than nats, as one might expect). | |
This allows for comparison to other papers. | |
:return: a dict with the following keys: | |
- 'output': a shape [N] tensor of NLLs or KLs. | |
- 'pred_xstart': the x_0 predictions.","def _vb_terms_bpd(self, model, x_start, x_t, t, clip_denoised=False, | |
model_kwargs=None): | |
"""""""""""" | |
true_mean, _, true_log_variance_clipped = self.q_posterior_mean_variance( | |
x_start=x_start, x_t=x_t, t=t) | |
out = self.p_mean_variance(model, x_t, t, clip_denoised=clip_denoised, | |
model_kwargs=model_kwargs) | |
kl = normal_kl(true_mean, true_log_variance_clipped, out['mean'], out[ | |
'log_variance']) | |
kl = mean_flat(kl) / np.log(2.0) | |
decoder_nll = -discretized_gaussian_log_likelihood(x_start, means=out[ | |
'mean'], log_scales=0.5 * out['log_variance']) | |
if not self.discretized_t0: | |
decoder_nll = th.zeros_like(decoder_nll) | |
assert decoder_nll.shape == x_start.shape | |
decoder_nll = mean_flat(decoder_nll) / np.log(2.0) | |
output = th.where(t == 0, decoder_nll, kl) | |
return {'output': output, 'pred_xstart': out['pred_xstart'], 'extra': | |
out['extra']} | |
",point_e\diffusion\gaussian_diffusion.py | |
training_losses,"Compute training losses for a single timestep. | |
:param model: the model to evaluate loss on. | |
:param x_start: the [N x C x ...] tensor of inputs. | |
:param t: a batch of timestep indices. | |
:param model_kwargs: if not None, a dict of extra keyword arguments to | |
pass to the model. This can be used for conditioning. | |
:param noise: if specified, the specific Gaussian noise to try to remove. | |
:return: a dict with the key ""loss"" containing a tensor of shape [N]. | |
Some mean or variance settings may also have other keys.","def training_losses(self, model, x_start, t, model_kwargs=None, noise=None | |
) ->Dict[str, th.Tensor]: | |
"""""""""""" | |
x_start = self.scale_channels(x_start) | |
if model_kwargs is None: | |
model_kwargs = {} | |
if noise is None: | |
noise = th.randn_like(x_start) | |
x_t = self.q_sample(x_start, t, noise=noise) | |
terms = {} | |
if self.loss_type == 'kl' or self.loss_type == 'rescaled_kl': | |
vb_terms = self._vb_terms_bpd(model=model, x_start=x_start, x_t=x_t, | |
t=t, clip_denoised=False, model_kwargs=model_kwargs) | |
terms['loss'] = vb_terms['output'] | |
if self.loss_type == 'rescaled_kl': | |
terms['loss'] *= self.num_timesteps | |
extra = vb_terms['extra'] | |
elif self.loss_type == 'mse' or self.loss_type == 'rescaled_mse': | |
model_output = model(x_t, t, **model_kwargs) | |
if isinstance(model_output, tuple): | |
model_output, extra = model_output | |
else: | |
extra = {} | |
if self.model_var_type in ['learned', 'learned_range']: | |
B, C = x_t.shape[:2] | |
assert model_output.shape == (B, C * 2, *x_t.shape[2:]) | |
model_output, model_var_values = th.split(model_output, C, dim=1) | |
frozen_out = th.cat([model_output.detach(), model_var_values], | |
dim=1) | |
terms['vb'] = self._vb_terms_bpd(model=lambda *args, r= | |
frozen_out: r, x_start=x_start, x_t=x_t, t=t, clip_denoised | |
=False)['output'] | |
if self.loss_type == 'rescaled_mse': | |
terms['vb'] *= self.num_timesteps / 1000.0 | |
target = {'x_prev': self.q_posterior_mean_variance(x_start=x_start, | |
x_t=x_t, t=t)[0], 'x_start': x_start, 'epsilon': noise}[self. | |
model_mean_type] | |
assert model_output.shape == target.shape == x_start.shape | |
terms['mse'] = mean_flat((target - model_output) ** 2) | |
if 'vb' in terms: | |
terms['loss'] = terms['mse'] + terms['vb'] | |
else: | |
terms['loss'] = terms['mse'] | |
else: | |
raise NotImplementedError(self.loss_type) | |
if 'losses' in extra: | |
terms.update({k: loss for k, (loss, _scale) in extra['losses'].items()} | |
) | |
for loss, scale in extra['losses'].values(): | |
terms['loss'] = terms['loss'] + loss * scale | |
return terms | |
",point_e\diffusion\gaussian_diffusion.py | |
_prior_bpd,"Get the prior KL term for the variational lower-bound, measured in | |
bits-per-dim. | |
This term can't be optimized, as it only depends on the encoder. | |
:param x_start: the [N x C x ...] tensor of inputs. | |
:return: a batch of [N] KL values (in bits), one per batch element.","def _prior_bpd(self, x_start): | |
"""""""""""" | |
batch_size = x_start.shape[0] | |
t = th.tensor([self.num_timesteps - 1] * batch_size, device=x_start.device) | |
qt_mean, _, qt_log_variance = self.q_mean_variance(x_start, t) | |
kl_prior = normal_kl(mean1=qt_mean, logvar1=qt_log_variance, mean2=0.0, | |
logvar2=0.0) | |
return mean_flat(kl_prior) / np.log(2.0) | |
",point_e\diffusion\gaussian_diffusion.py | |
calc_bpd_loop,"Compute the entire variational lower-bound, measured in bits-per-dim, | |
as well as other related quantities. | |
:param model: the model to evaluate loss on. | |
:param x_start: the [N x C x ...] tensor of inputs. | |
:param clip_denoised: if True, clip denoised samples. | |
:param model_kwargs: if not None, a dict of extra keyword arguments to | |
pass to the model. This can be used for conditioning. | |
:return: a dict containing the following keys: | |
- total_bpd: the total variational lower-bound, per batch element. | |
- prior_bpd: the prior term in the lower-bound. | |
- vb: an [N x T] tensor of terms in the lower-bound. | |
- xstart_mse: an [N x T] tensor of x_0 MSEs for each timestep. | |
- mse: an [N x T] tensor of epsilon MSEs for each timestep.","def calc_bpd_loop(self, model, x_start, clip_denoised=False, model_kwargs=None | |
): | |
"""""""""""" | |
device = x_start.device | |
batch_size = x_start.shape[0] | |
vb = [] | |
xstart_mse = [] | |
mse = [] | |
for t in list(range(self.num_timesteps))[::-1]: | |
t_batch = th.tensor([t] * batch_size, device=device) | |
noise = th.randn_like(x_start) | |
x_t = self.q_sample(x_start=x_start, t=t_batch, noise=noise) | |
with th.no_grad(): | |
out = self._vb_terms_bpd(model, x_start=x_start, x_t=x_t, t= | |
t_batch, clip_denoised=clip_denoised, model_kwargs=model_kwargs | |
) | |
vb.append(out['output']) | |
xstart_mse.append(mean_flat((out['pred_xstart'] - x_start) ** 2)) | |
eps = self._predict_eps_from_xstart(x_t, t_batch, out['pred_xstart']) | |
mse.append(mean_flat((eps - noise) ** 2)) | |
vb = th.stack(vb, dim=1) | |
xstart_mse = th.stack(xstart_mse, dim=1) | |
mse = th.stack(mse, dim=1) | |
prior_bpd = self._prior_bpd(x_start) | |
total_bpd = vb.sum(dim=1) + prior_bpd | |
return {'total_bpd': total_bpd, 'prior_bpd': prior_bpd, 'vb': vb, | |
'xstart_mse': xstart_mse, 'mse': mse} | |
",point_e\diffusion\gaussian_diffusion.py | |
scale_channels,,"def scale_channels(self, x: th.Tensor) ->th.Tensor: | |
if self.channel_scales is not None: | |
x = x * th.from_numpy(self.channel_scales).to(x).reshape([1, -1, *( | |
[1] * (len(x.shape) - 2))]) | |
if self.channel_biases is not None: | |
x = x + th.from_numpy(self.channel_biases).to(x).reshape([1, -1, *( | |
[1] * (len(x.shape) - 2))]) | |
return x | |
",point_e\diffusion\gaussian_diffusion.py | |
unscale_channels,,"def unscale_channels(self, x: th.Tensor) ->th.Tensor: | |
if self.channel_biases is not None: | |
x = x - th.from_numpy(self.channel_biases).to(x).reshape([1, -1, *( | |
[1] * (len(x.shape) - 2))]) | |
if self.channel_scales is not None: | |
x = x / th.from_numpy(self.channel_scales).to(x).reshape([1, -1, *( | |
[1] * (len(x.shape) - 2))]) | |
return x | |
",point_e\diffusion\gaussian_diffusion.py | |
unscale_out_dict,,"def unscale_out_dict(self, out: Dict[str, Union[th.Tensor, Any]]) ->Dict[ | |
str, Union[th.Tensor, Any]]: | |
return {k: (self.unscale_channels(v) if isinstance(v, th.Tensor) else v | |
) for k, v in out.items()} | |
",point_e\diffusion\gaussian_diffusion.py | |
__init__,,"def __init__(self, use_timesteps: Iterable[int], **kwargs): | |
self.use_timesteps = set(use_timesteps) | |
self.timestep_map = [] | |
self.original_num_steps = len(kwargs['betas']) | |
base_diffusion = GaussianDiffusion(**kwargs) | |
last_alpha_cumprod = 1.0 | |
new_betas = [] | |
for i, alpha_cumprod in enumerate(base_diffusion.alphas_cumprod): | |
if i in self.use_timesteps: | |
new_betas.append(1 - alpha_cumprod / last_alpha_cumprod) | |
last_alpha_cumprod = alpha_cumprod | |
self.timestep_map.append(i) | |
kwargs['betas'] = np.array(new_betas) | |
super().__init__(**kwargs) | |
",point_e\diffusion\gaussian_diffusion.py | |
p_mean_variance,,"def p_mean_variance(self, model, *args, **kwargs): | |
return super().p_mean_variance(self._wrap_model(model), *args, **kwargs) | |
",point_e\diffusion\gaussian_diffusion.py | |
training_losses,,"def training_losses(self, model, *args, **kwargs): | |
return super().training_losses(self._wrap_model(model), *args, **kwargs) | |
",point_e\diffusion\gaussian_diffusion.py | |
condition_mean,,"def condition_mean(self, cond_fn, *args, **kwargs): | |
return super().condition_mean(self._wrap_model(cond_fn), *args, **kwargs) | |
",point_e\diffusion\gaussian_diffusion.py | |
condition_score,,"def condition_score(self, cond_fn, *args, **kwargs): | |
return super().condition_score(self._wrap_model(cond_fn), *args, **kwargs) | |
",point_e\diffusion\gaussian_diffusion.py | |
_wrap_model,,"def _wrap_model(self, model): | |
if isinstance(model, _WrappedModel): | |
return model | |
return _WrappedModel(model, self.timestep_map, self.original_num_steps) | |
",point_e\diffusion\gaussian_diffusion.py | |
__init__,,"def __init__(self, model, timestep_map, original_num_steps): | |
self.model = model | |
self.timestep_map = timestep_map | |
self.original_num_steps = original_num_steps | |
",point_e\diffusion\gaussian_diffusion.py | |
__call__,,"def __call__(self, x, ts, **kwargs): | |
map_tensor = th.tensor(self.timestep_map, device=ts.device, dtype=ts.dtype) | |
new_ts = map_tensor[ts] | |
return self.model(x, new_ts, **kwargs) | |
",point_e\diffusion\gaussian_diffusion.py | |
karras_sample,,"def karras_sample(*args, **kwargs): | |
last = None | |
for x in karras_sample_progressive(*args, **kwargs): | |
last = x['x'] | |
return last | |
",point_e\diffusion\k_diffusion.py | |
karras_sample_progressive,,"def karras_sample_progressive(diffusion, model, shape, steps, clip_denoised | |
=True, progress=False, model_kwargs=None, device=None, sigma_min=0.002, | |
sigma_max=80, rho=7.0, sampler='heun', s_churn=0.0, s_tmin=0.0, s_tmax= | |
float('inf'), s_noise=1.0, guidance_scale=0.0): | |
sigmas = get_sigmas_karras(steps, sigma_min, sigma_max, rho, device=device) | |
x_T = th.randn(*shape, device=device) * sigma_max | |
sample_fn = {'heun': sample_heun, 'dpm': sample_dpm, 'ancestral': | |
sample_euler_ancestral}[sampler] | |
if sampler != 'ancestral': | |
sampler_args = dict(s_churn=s_churn, s_tmin=s_tmin, s_tmax=s_tmax, | |
s_noise=s_noise) | |
else: | |
sampler_args = {} | |
if isinstance(diffusion, KarrasDenoiser): | |
def denoiser(x_t, sigma): | |
_, denoised = diffusion.denoise(model, x_t, sigma, **model_kwargs) | |
if clip_denoised: | |
denoised = denoised.clamp(-1, 1) | |
return denoised | |
elif isinstance(diffusion, GaussianDiffusion): | |
model = GaussianToKarrasDenoiser(model, diffusion) | |
def denoiser(x_t, sigma): | |
_, denoised = model.denoise(x_t, sigma, clip_denoised= | |
clip_denoised, model_kwargs=model_kwargs) | |
return denoised | |
else: | |
raise NotImplementedError | |
if guidance_scale != 0 and guidance_scale != 1: | |
def guided_denoiser(x_t, sigma): | |
x_t = th.cat([x_t, x_t], dim=0) | |
sigma = th.cat([sigma, sigma], dim=0) | |
x_0 = denoiser(x_t, sigma) | |
cond_x_0, uncond_x_0 = th.split(x_0, len(x_0) // 2, dim=0) | |
x_0 = uncond_x_0 + guidance_scale * (cond_x_0 - uncond_x_0) | |
return x_0 | |
else: | |
guided_denoiser = denoiser | |
for obj in sample_fn(guided_denoiser, x_T, sigmas, progress=progress, | |
**sampler_args): | |
if isinstance(diffusion, GaussianDiffusion): | |
yield diffusion.unscale_out_dict(obj) | |
else: | |
yield obj | |
",point_e\diffusion\k_diffusion.py | |
get_sigmas_karras,Constructs the noise schedule of Karras et al. (2022).,"def get_sigmas_karras(n, sigma_min, sigma_max, rho=7.0, device='cpu'): | |
"""""""""""" | |
ramp = th.linspace(0, 1, n) | |
min_inv_rho = sigma_min ** (1 / rho) | |
max_inv_rho = sigma_max ** (1 / rho) | |
sigmas = (max_inv_rho + ramp * (min_inv_rho - max_inv_rho)) ** rho | |
return append_zero(sigmas).to(device) | |
",point_e\diffusion\k_diffusion.py | |
to_d,Converts a denoiser output to a Karras ODE derivative.,"def to_d(x, sigma, denoised): | |
"""""""""""" | |
return (x - denoised) / append_dims(sigma, x.ndim) | |
",point_e\diffusion\k_diffusion.py | |
get_ancestral_step,"Calculates the noise level (sigma_down) to step down to and the amount | |
of noise to add (sigma_up) when doing an ancestral sampling step.","def get_ancestral_step(sigma_from, sigma_to): | |
"""""""""""" | |
sigma_up = (sigma_to ** 2 * (sigma_from ** 2 - sigma_to ** 2) / | |
sigma_from ** 2) ** 0.5 | |
sigma_down = (sigma_to ** 2 - sigma_up ** 2) ** 0.5 | |
return sigma_down, sigma_up | |
",point_e\diffusion\k_diffusion.py | |
sample_euler_ancestral,Ancestral sampling with Euler method steps.,"@th.no_grad() | |
def sample_euler_ancestral(model, x, sigmas, progress=False): | |
"""""""""""" | |
s_in = x.new_ones([x.shape[0]]) | |
indices = range(len(sigmas) - 1) | |
if progress: | |
from tqdm.auto import tqdm | |
indices = tqdm(indices) | |
for i in indices: | |
denoised = model(x, sigmas[i] * s_in) | |
sigma_down, sigma_up = get_ancestral_step(sigmas[i], sigmas[i + 1]) | |
yield {'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigmas[i], | |
'pred_xstart': denoised} | |
d = to_d(x, sigmas[i], denoised) | |
dt = sigma_down - sigmas[i] | |
x = x + d * dt | |
x = x + th.randn_like(x) * sigma_up | |
yield {'x': x, 'pred_xstart': x} | |
",point_e\diffusion\k_diffusion.py | |
sample_heun,Implements Algorithm 2 (Heun steps) from Karras et al. (2022).,"@th.no_grad() | |
def sample_heun(denoiser, x, sigmas, progress=False, s_churn=0.0, s_tmin= | |
0.0, s_tmax=float('inf'), s_noise=1.0): | |
"""""""""""" | |
s_in = x.new_ones([x.shape[0]]) | |
indices = range(len(sigmas) - 1) | |
if progress: | |
from tqdm.auto import tqdm | |
indices = tqdm(indices) | |
for i in indices: | |
gamma = min(s_churn / (len(sigmas) - 1), 2 ** 0.5 - 1 | |
) if s_tmin <= sigmas[i] <= s_tmax else 0.0 | |
eps = th.randn_like(x) * s_noise | |
sigma_hat = sigmas[i] * (gamma + 1) | |
if gamma > 0: | |
x = x + eps * (sigma_hat ** 2 - sigmas[i] ** 2) ** 0.5 | |
denoised = denoiser(x, sigma_hat * s_in) | |
d = to_d(x, sigma_hat, denoised) | |
yield {'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigma_hat, | |
'pred_xstart': denoised} | |
dt = sigmas[i + 1] - sigma_hat | |
if sigmas[i + 1] == 0: | |
x = x + d * dt | |
else: | |
x_2 = x + d * dt | |
denoised_2 = denoiser(x_2, sigmas[i + 1] * s_in) | |
d_2 = to_d(x_2, sigmas[i + 1], denoised_2) | |
d_prime = (d + d_2) / 2 | |
x = x + d_prime * dt | |
yield {'x': x, 'pred_xstart': denoised} | |
",point_e\diffusion\k_diffusion.py | |
sample_dpm,A sampler inspired by DPM-Solver-2 and Algorithm 2 from Karras et al. (2022).,"@th.no_grad() | |
def sample_dpm(denoiser, x, sigmas, progress=False, s_churn=0.0, s_tmin=0.0, | |
s_tmax=float('inf'), s_noise=1.0): | |
"""""""""""" | |
s_in = x.new_ones([x.shape[0]]) | |
indices = range(len(sigmas) - 1) | |
if progress: | |
from tqdm.auto import tqdm | |
indices = tqdm(indices) | |
for i in indices: | |
gamma = min(s_churn / (len(sigmas) - 1), 2 ** 0.5 - 1 | |
) if s_tmin <= sigmas[i] <= s_tmax else 0.0 | |
eps = th.randn_like(x) * s_noise | |
sigma_hat = sigmas[i] * (gamma + 1) | |
if gamma > 0: | |
x = x + eps * (sigma_hat ** 2 - sigmas[i] ** 2) ** 0.5 | |
denoised = denoiser(x, sigma_hat * s_in) | |
d = to_d(x, sigma_hat, denoised) | |
yield {'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigma_hat, | |
'denoised': denoised} | |
sigma_mid = ((sigma_hat ** (1 / 3) + sigmas[i + 1] ** (1 / 3)) / 2 | |
) ** 3 | |
dt_1 = sigma_mid - sigma_hat | |
dt_2 = sigmas[i + 1] - sigma_hat | |
x_2 = x + d * dt_1 | |
denoised_2 = denoiser(x_2, sigma_mid * s_in) | |
d_2 = to_d(x_2, sigma_mid, denoised_2) | |
x = x + d_2 * dt_2 | |
yield {'x': x, 'pred_xstart': denoised} | |
",point_e\diffusion\k_diffusion.py | |
append_dims,Appends dimensions to the end of a tensor until it has target_dims dimensions.,"def append_dims(x, target_dims): | |
"""""""""""" | |
dims_to_append = target_dims - x.ndim | |
if dims_to_append < 0: | |
raise ValueError( | |
f'input has {x.ndim} dims but target_dims is {target_dims}, which is less' | |
) | |
return x[(...,) + (None,) * dims_to_append] | |
",point_e\diffusion\k_diffusion.py | |
append_zero,,"def append_zero(x): | |
return th.cat([x, x.new_zeros([1])]) | |
",point_e\diffusion\k_diffusion.py | |
__init__,,"def __init__(self, sigma_data: float=0.5): | |
self.sigma_data = sigma_data | |
",point_e\diffusion\k_diffusion.py | |
get_snr,,"def get_snr(self, sigmas): | |
return sigmas ** -2 | |
",point_e\diffusion\k_diffusion.py | |
get_sigmas,,"def get_sigmas(self, sigmas): | |
return sigmas | |
",point_e\diffusion\k_diffusion.py | |
get_scalings,,"def get_scalings(self, sigma): | |
c_skip = self.sigma_data ** 2 / (sigma ** 2 + self.sigma_data ** 2) | |
c_out = sigma * self.sigma_data / (sigma ** 2 + self.sigma_data ** 2 | |
) ** 0.5 | |
c_in = 1 / (sigma ** 2 + self.sigma_data ** 2) ** 0.5 | |
return c_skip, c_out, c_in | |
",point_e\diffusion\k_diffusion.py | |
training_losses,,"def training_losses(self, model, x_start, sigmas, model_kwargs=None, noise=None | |
): | |
if model_kwargs is None: | |
model_kwargs = {} | |
if noise is None: | |
noise = th.randn_like(x_start) | |
terms = {} | |
dims = x_start.ndim | |
x_t = x_start + noise * append_dims(sigmas, dims) | |
c_skip, c_out, _ = [append_dims(x, dims) for x in self.get_scalings(sigmas) | |
] | |
model_output, denoised = self.denoise(model, x_t, sigmas, **model_kwargs) | |
target = (x_start - c_skip * x_t) / c_out | |
terms['mse'] = mean_flat((model_output - target) ** 2) | |
terms['xs_mse'] = mean_flat((denoised - x_start) ** 2) | |
if 'vb' in terms: | |
terms['loss'] = terms['mse'] + terms['vb'] | |
else: | |
terms['loss'] = terms['mse'] | |
return terms | |
",point_e\diffusion\k_diffusion.py | |
denoise,,"def denoise(self, model, x_t, sigmas, **model_kwargs): | |
c_skip, c_out, c_in = [append_dims(x, x_t.ndim) for x in self. | |
get_scalings(sigmas)] | |
rescaled_t = 1000 * 0.25 * th.log(sigmas + 1e-44) | |
model_output = model(c_in * x_t, rescaled_t, **model_kwargs) | |
denoised = c_out * model_output + c_skip * x_t | |
return model_output, denoised | |
",point_e\diffusion\k_diffusion.py | |
__init__,,"def __init__(self, model, diffusion): | |
from scipy import interpolate | |
self.model = model | |
self.diffusion = diffusion | |
self.alpha_cumprod_to_t = interpolate.interp1d(diffusion.alphas_cumprod, | |
np.arange(0, diffusion.num_timesteps)) | |
",point_e\diffusion\k_diffusion.py | |
sigma_to_t,,"def sigma_to_t(self, sigma): | |
alpha_cumprod = 1.0 / (sigma ** 2 + 1) | |
if alpha_cumprod > self.diffusion.alphas_cumprod[0]: | |
return 0 | |
elif alpha_cumprod <= self.diffusion.alphas_cumprod[-1]: | |
return self.diffusion.num_timesteps - 1 | |
else: | |
return float(self.alpha_cumprod_to_t(alpha_cumprod)) | |
",point_e\diffusion\k_diffusion.py | |
denoise,,"def denoise(self, x_t, sigmas, clip_denoised=True, model_kwargs=None): | |
t = th.tensor([self.sigma_to_t(sigma) for sigma in sigmas.cpu().numpy() | |
], dtype=th.long, device=sigmas.device) | |
c_in = append_dims(1.0 / (sigmas ** 2 + 1) ** 0.5, x_t.ndim) | |
out = self.diffusion.p_mean_variance(self.model, x_t * c_in, t, | |
clip_denoised=clip_denoised, model_kwargs=model_kwargs) | |
return None, out['pred_xstart'] | |
",point_e\diffusion\k_diffusion.py | |
__init__,,"def __init__(self, device: torch.device, models: Sequence[nn.Module], | |
diffusions: Sequence[GaussianDiffusion], num_points: Sequence[int], | |
aux_channels: Sequence[str], model_kwargs_key_filter: Sequence[str]=( | |
'*',), guidance_scale: Sequence[float]=(3.0, 3.0), clip_denoised: bool= | |
True, use_karras: Sequence[bool]=(True, True), karras_steps: Sequence[ | |
int]=(64, 64), sigma_min: Sequence[float]=(0.001, 0.001), sigma_max: | |
Sequence[float]=(120, 160), s_churn: Sequence[float]=(3, 0)): | |
n = len(models) | |
assert n > 0 | |
if n > 1: | |
if len(guidance_scale) == 1: | |
guidance_scale = list(guidance_scale) + [1.0] * (n - 1) | |
if len(use_karras) == 1: | |
use_karras = use_karras * n | |
if len(karras_steps) == 1: | |
karras_steps = karras_steps * n | |
if len(sigma_min) == 1: | |
sigma_min = sigma_min * n | |
if len(sigma_max) == 1: | |
sigma_max = sigma_max * n | |
if len(s_churn) == 1: | |
s_churn = s_churn * n | |
if len(model_kwargs_key_filter) == 1: | |
model_kwargs_key_filter = model_kwargs_key_filter * n | |
if len(model_kwargs_key_filter) == 0: | |
model_kwargs_key_filter = ['*'] * n | |
assert len(guidance_scale) == n | |
assert len(use_karras) == n | |
assert len(karras_steps) == n | |
assert len(sigma_min) == n | |
assert len(sigma_max) == n | |
assert len(s_churn) == n | |
assert len(model_kwargs_key_filter) == n | |
self.device = device | |
self.num_points = num_points | |
self.aux_channels = aux_channels | |
self.model_kwargs_key_filter = model_kwargs_key_filter | |
self.guidance_scale = guidance_scale | |
self.clip_denoised = clip_denoised | |
self.use_karras = use_karras | |
self.karras_steps = karras_steps | |
self.sigma_min = sigma_min | |
self.sigma_max = sigma_max | |
self.s_churn = s_churn | |
self.models = models | |
self.diffusions = diffusions | |
",point_e\diffusion\sampler.py | |
num_stages,,"@property | |
def num_stages(self) ->int: | |
return len(self.models) | |
",point_e\diffusion\sampler.py | |
sample_batch,,"def sample_batch(self, batch_size: int, model_kwargs: Dict[str, Any] | |
) ->torch.Tensor: | |
samples = None | |
for x in self.sample_batch_progressive(batch_size, model_kwargs): | |
samples = x | |
return samples | |
",point_e\diffusion\sampler.py | |
sample_batch_progressive,,"def sample_batch_progressive(self, batch_size: int, model_kwargs: Dict[str, | |
Any]) ->Iterator[torch.Tensor]: | |
samples = None | |
for model, diffusion, stage_num_points, stage_guidance_scale, stage_use_karras, stage_karras_steps, stage_sigma_min, stage_sigma_max, stage_s_churn, stage_key_filter in zip( | |
self.models, self.diffusions, self.num_points, self.guidance_scale, | |
self.use_karras, self.karras_steps, self.sigma_min, self.sigma_max, | |
self.s_churn, self.model_kwargs_key_filter): | |
stage_model_kwargs = model_kwargs.copy() | |
if stage_key_filter != '*': | |
use_keys = set(stage_key_filter.split(',')) | |
stage_model_kwargs = {k: v for k, v in stage_model_kwargs.items | |
() if k in use_keys} | |
if samples is not None: | |
stage_model_kwargs['low_res'] = samples | |
if hasattr(model, 'cached_model_kwargs'): | |
stage_model_kwargs = model.cached_model_kwargs(batch_size, | |
stage_model_kwargs) | |
sample_shape = batch_size, 3 + len(self.aux_channels), stage_num_points | |
if stage_guidance_scale != 1 and stage_guidance_scale != 0: | |
for k, v in stage_model_kwargs.copy().items(): | |
stage_model_kwargs[k] = torch.cat([v, torch.zeros_like(v)], | |
dim=0) | |
if stage_use_karras: | |
samples_it = karras_sample_progressive(diffusion=diffusion, | |
model=model, shape=sample_shape, steps=stage_karras_steps, | |
clip_denoised=self.clip_denoised, model_kwargs= | |
stage_model_kwargs, device=self.device, sigma_min= | |
stage_sigma_min, sigma_max=stage_sigma_max, s_churn= | |
stage_s_churn, guidance_scale=stage_guidance_scale) | |
else: | |
internal_batch_size = batch_size | |
if stage_guidance_scale: | |
model = self._uncond_guide_model(model, stage_guidance_scale) | |
internal_batch_size *= 2 | |
samples_it = diffusion.p_sample_loop_progressive(model, shape=( | |
internal_batch_size, *sample_shape[1:]), model_kwargs= | |
stage_model_kwargs, device=self.device, clip_denoised=self. | |
clip_denoised) | |
for x in samples_it: | |
samples = x['pred_xstart'][:batch_size] | |
if 'low_res' in stage_model_kwargs: | |
samples = torch.cat([stage_model_kwargs['low_res'][:len( | |
samples)], samples], dim=-1) | |
yield samples | |
",point_e\diffusion\sampler.py | |
combine,,"@classmethod | |
def combine(cls, *samplers: 'PointCloudSampler') ->'PointCloudSampler': | |
assert all(x.device == samplers[0].device for x in samplers[1:]) | |
assert all(x.aux_channels == samplers[0].aux_channels for x in samplers[1:] | |
) | |
assert all(x.clip_denoised == samplers[0].clip_denoised for x in | |
samplers[1:]) | |
return cls(device=samplers[0].device, models=[x for y in samplers for x in | |
y.models], diffusions=[x for y in samplers for x in y.diffusions], | |
num_points=[x for y in samplers for x in y.num_points], | |
aux_channels=samplers[0].aux_channels, model_kwargs_key_filter=[x for | |
y in samplers for x in y.model_kwargs_key_filter], guidance_scale=[ | |
x for y in samplers for x in y.guidance_scale], clip_denoised= | |
samplers[0].clip_denoised, use_karras=[x for y in samplers for x in | |
y.use_karras], karras_steps=[x for y in samplers for x in y. | |
karras_steps], sigma_min=[x for y in samplers for x in y.sigma_min], | |
sigma_max=[x for y in samplers for x in y.sigma_max], s_churn=[x for | |
y in samplers for x in y.s_churn]) | |
",point_e\diffusion\sampler.py | |
_uncond_guide_model,,"def _uncond_guide_model(self, model: Callable[..., torch.Tensor], scale: float | |
) ->Callable[..., torch.Tensor]: | |
def model_fn(x_t, ts, **kwargs): | |
half = x_t[:len(x_t) // 2] | |
combined = torch.cat([half, half], dim=0) | |
model_out = model(combined, ts, **kwargs) | |
eps, rest = model_out[:, :3], model_out[:, 3:] | |
cond_eps, uncond_eps = torch.chunk(eps, 2, dim=0) | |
half_eps = uncond_eps + scale * (cond_eps - uncond_eps) | |
eps = torch.cat([half_eps, half_eps], dim=0) | |
return torch.cat([eps, rest], dim=1) | |
return model_fn | |
",point_e\diffusion\sampler.py | |
split_model_output,,"def split_model_output(self, output: torch.Tensor, rescale_colors: bool=False | |
) ->Tuple[torch.Tensor, Dict[str, torch.Tensor]]: | |
assert len(self.aux_channels) + 3 == output.shape[1 | |
], 'there must be three spatial channels before aux' | |
pos, joined_aux = output[:, :3], output[:, 3:] | |
aux = {} | |
for i, name in enumerate(self.aux_channels): | |
v = joined_aux[:, i] | |
if name in {'R', 'G', 'B', 'A'}: | |
v = v.clamp(0, 255).round() | |
if rescale_colors: | |
v = v / 255.0 | |
aux[name] = v | |
return pos, aux | |
",point_e\diffusion\sampler.py | |
output_to_point_clouds,,"def output_to_point_clouds(self, output: torch.Tensor) ->List[PointCloud]: | |
res = [] | |
for sample in output: | |
xyz, aux = self.split_model_output(sample[None], rescale_colors=True) | |
res.append(PointCloud(coords=xyz[0].t().cpu().numpy(), channels={k: | |
v[0].cpu().numpy() for k, v in aux.items()})) | |
return res | |
",point_e\diffusion\sampler.py | |
with_options,,"def with_options(self, guidance_scale: float, clip_denoised: bool, | |
use_karras: Sequence[bool]=(True, True), karras_steps: Sequence[int]=( | |
64, 64), sigma_min: Sequence[float]=(0.001, 0.001), sigma_max: Sequence | |
[float]=(120, 160), s_churn: Sequence[float]=(3, 0)) ->'PointCloudSampler': | |
return PointCloudSampler(device=self.device, models=self.models, | |
diffusions=self.diffusions, num_points=self.num_points, | |
aux_channels=self.aux_channels, model_kwargs_key_filter=self. | |
model_kwargs_key_filter, guidance_scale=guidance_scale, | |
clip_denoised=clip_denoised, use_karras=use_karras, karras_steps= | |
karras_steps, sigma_min=sigma_min, sigma_max=sigma_max, s_churn=s_churn | |
) | |
",point_e\diffusion\sampler.py | |
get_torch_devices,,"def get_torch_devices() ->List[Union[str, torch.device]]: | |
if torch.cuda.is_available(): | |
return [torch.device(f'cuda:{i}') for i in range(torch.cuda. | |
device_count())] | |
else: | |
return ['cpu'] | |
",point_e\evals\feature_extractor.py | |
normalize_point_clouds,,"def normalize_point_clouds(pc: np.ndarray) ->np.ndarray: | |
centroids = np.mean(pc, axis=1, keepdims=True) | |
pc = pc - centroids | |
m = np.max(np.sqrt(np.sum(pc ** 2, axis=-1, keepdims=True)), axis=1, | |
keepdims=True) | |
pc = pc / m | |
return pc | |
",point_e\evals\feature_extractor.py | |
supports_predictions,,"@property | |
@abstractmethod | |
def supports_predictions(self) ->bool: | |
pass | |
",point_e\evals\feature_extractor.py | |
feature_dim,,"@property | |
@abstractmethod | |
def feature_dim(self) ->int: | |
pass | |
",point_e\evals\feature_extractor.py | |
num_classes,,"@property | |
@abstractmethod | |
def num_classes(self) ->int: | |
pass | |
",point_e\evals\feature_extractor.py | |
features_and_preds,"For a stream of point cloud batches, compute feature vectors and class | |
predictions. | |
:param point_clouds: a streamer for a sample batch. Typically, arr_0 | |
will contain the XYZ coordinates. | |
:return: a tuple (features, predictions) | |
- features: a [B x feature_dim] array of feature vectors. | |
- predictions: a [B x num_classes] array of probabilities.","@abstractmethod | |
def features_and_preds(self, streamer: NpzStreamer) ->Tuple[np.ndarray, np. | |
ndarray]: | |
"""""""""""" | |
",point_e\evals\feature_extractor.py | |
__init__,,"def __init__(self, devices: List[Union[str, torch.device]], | |
device_batch_size: int=64, cache_dir: Optional[str]=None): | |
state_dict = load_checkpoint('pointnet', device=torch.device('cpu'), | |
cache_dir=cache_dir)['model_state_dict'] | |
self.device_batch_size = device_batch_size | |
self.devices = devices | |
self.models = [] | |
for device in devices: | |
model = get_model(num_class=40, normal_channel=False, width_mult=2) | |
model.load_state_dict(state_dict) | |
model.to(device) | |
model.eval() | |
self.models.append(model) | |
",point_e\evals\feature_extractor.py | |
supports_predictions,,"@property | |
def supports_predictions(self) ->bool: | |
return True | |
",point_e\evals\feature_extractor.py | |
feature_dim,,"@property | |
def feature_dim(self) ->int: | |
return 256 | |
",point_e\evals\feature_extractor.py | |
num_classes,,"@property | |
def num_classes(self) ->int: | |
return 40 | |
",point_e\evals\feature_extractor.py | |
features_and_preds,,"def features_and_preds(self, streamer: NpzStreamer) ->Tuple[np.ndarray, np. | |
ndarray]: | |
batch_size = self.device_batch_size * len(self.devices) | |
point_clouds = (x['arr_0'] for x in streamer.stream(batch_size, ['arr_0'])) | |
output_features = [] | |
output_predictions = [] | |
with ThreadPool(len(self.devices)) as pool: | |
for batch in point_clouds: | |
batch = normalize_point_clouds(batch) | |
batches = [] | |
for i, device in zip(range(0, len(batch), self. | |
device_batch_size), self.devices): | |
batches.append(torch.from_numpy(batch[i:i + self. | |
device_batch_size]).permute(0, 2, 1).to(dtype=torch. | |
float32, device=device)) | |
def compute_features(i_batch): | |
i, batch = i_batch | |
with torch.no_grad(): | |
return self.models[i](batch, features=True) | |
for logits, _, features in pool.imap(compute_features, | |
enumerate(batches)): | |
output_features.append(features.cpu().numpy()) | |
output_predictions.append(logits.exp().cpu().numpy()) | |
return np.concatenate(output_features, axis=0), np.concatenate( | |
output_predictions, axis=0) | |
",point_e\evals\feature_extractor.py | |
compute_statistics,,"def compute_statistics(feats: np.ndarray) ->FIDStatistics: | |
mu = np.mean(feats, axis=0) | |
sigma = np.cov(feats, rowvar=False) | |
return FIDStatistics(mu, sigma) | |
",point_e\evals\fid_is.py | |
compute_inception_score,,"def compute_inception_score(preds: np.ndarray, split_size: int=5000) ->float: | |
scores = [] | |
for i in range(0, len(preds), split_size): | |
part = preds[i:i + split_size] | |
kl = part * (np.log(part) - np.log(np.expand_dims(np.mean(part, 0), 0)) | |
) | |
kl = np.mean(np.sum(kl, 1)) | |
scores.append(np.exp(kl)) | |
return float(np.mean(scores)) | |
",point_e\evals\fid_is.py | |
__init__,,"def __init__(self, mu: np.ndarray, sigma: np.ndarray): | |
self.mu = mu | |
self.sigma = sigma | |
",point_e\evals\fid_is.py | |
frechet_distance,Compute the Frechet distance between two sets of statistics.,"def frechet_distance(self, other, eps=1e-06): | |
"""""""""""" | |
mu1, sigma1 = self.mu, self.sigma | |
mu2, sigma2 = other.mu, other.sigma | |
mu1 = np.atleast_1d(mu1) | |
mu2 = np.atleast_1d(mu2) | |
sigma1 = np.atleast_2d(sigma1) | |
sigma2 = np.atleast_2d(sigma2) | |
assert mu1.shape == mu2.shape, f'Training and test mean vectors have different lengths: {mu1.shape}, {mu2.shape}' | |
assert sigma1.shape == sigma2.shape, f'Training and test covariances have different dimensions: {sigma1.shape}, {sigma2.shape}' | |
diff = mu1 - mu2 | |
covmean, _ = linalg.sqrtm(sigma1.dot(sigma2), disp=False) | |
if not np.isfinite(covmean).all(): | |
msg = ( | |
'fid calculation produces singular product; adding %s to diagonal of cov estimates' | |
% eps) | |
warnings.warn(msg) | |
offset = np.eye(sigma1.shape[0]) * eps | |
covmean = linalg.sqrtm((sigma1 + offset).dot(sigma2 + offset)) | |
if np.iscomplexobj(covmean): | |
if not np.allclose(np.diagonal(covmean).imag, 0, atol=0.001): | |
m = np.max(np.abs(covmean.imag)) | |
raise ValueError('Imaginary component {}'.format(m)) | |
covmean = covmean.real | |
tr_covmean = np.trace(covmean) | |
return diff.dot(diff) + np.trace(sigma1) + np.trace(sigma2 | |
) - 2 * tr_covmean | |
",point_e\evals\fid_is.py | |
_npz_paths_and_length,,"def _npz_paths_and_length(glob_path: str) ->Tuple[List[str], Optional[int]]: | |
count_match = re.match('^(.*)\\[:([0-9]*)\\]$', glob_path) | |
if count_match: | |
raw_path = count_match[1] | |
max_count = int(count_match[2]) | |
else: | |
raw_path = glob_path | |
max_count = None | |
paths = sorted(glob.glob(raw_path)) | |
if not len(paths): | |
raise ValueError(f'no paths found matching: {glob_path}') | |
return paths, max_count | |
",point_e\evals\npz_stream.py | |
open_npz_arrays,,"@contextmanager | |
def open_npz_arrays(path: str, arr_names: Sequence[str]) ->List[NpzArrayReader | |
]: | |
if not len(arr_names): | |
yield [] | |
return | |
arr_name = arr_names[0] | |
with open_array(path, arr_name) as arr_f: | |
version = np.lib.format.read_magic(arr_f) | |
header = None | |
if version == (1, 0): | |
header = np.lib.format.read_array_header_1_0(arr_f) | |
elif version == (2, 0): | |
header = np.lib.format.read_array_header_2_0(arr_f) | |
if header is None: | |
reader = MemoryNpzArrayReader.load(path, arr_name) | |
else: | |
shape, fortran, dtype = header | |
if fortran or dtype.hasobject: | |
reader = MemoryNpzArrayReader.load(path, arr_name) | |
else: | |
reader = StreamingNpzArrayReader(arr_f, shape, dtype) | |
with open_npz_arrays(path, arr_names[1:]) as next_readers: | |
yield [reader] + next_readers | |
",point_e\evals\npz_stream.py | |
_read_bytes,"Copied from: https://github.com/numpy/numpy/blob/fb215c76967739268de71aa4bda55dd1b062bc2e/numpy/lib/format.py#L788-L886 | |
Read from file-like object until size bytes are read. | |
Raises ValueError if not EOF is encountered before size bytes are read. | |
Non-blocking objects only supported if they derive from io objects. | |
Required as e.g. ZipExtFile in python 2.6 can return less data than | |
requested.","def _read_bytes(fp, size, error_template='ran out of data'): | |
"""""""""""" | |
data = bytes() | |
while True: | |
try: | |
r = fp.read(size - len(data)) | |
data += r | |
if len(r) == 0 or len(data) == size: | |
break | |
except io.BlockingIOError: | |
pass | |
if len(data) != size: | |
msg = 'EOF: reading %s, expected %d bytes got %d' | |
raise ValueError(msg % (error_template, size, len(data))) | |
else: | |
return data | |
",point_e\evals\npz_stream.py | |
open_array,,"@contextmanager | |
def open_array(path: str, arr_name: str): | |
with open(path, 'rb') as f: | |
with zipfile.ZipFile(f, 'r') as zip_f: | |
if f'{arr_name}.npy' not in zip_f.namelist(): | |
raise ValueError(f'missing {arr_name} in npz file') | |
with zip_f.open(f'{arr_name}.npy', 'r') as arr_f: | |
yield arr_f | |
",point_e\evals\npz_stream.py | |
_dict_batch_size,,"def _dict_batch_size(objs: Dict[str, np.ndarray]) ->int: | |
return len(next(iter(objs.values()))) | |
",point_e\evals\npz_stream.py | |
infos_from_first_file,,"@classmethod | |
def infos_from_first_file(cls, glob_path: str) ->Dict[str, 'NumpyArrayInfo']: | |
paths, _ = _npz_paths_and_length(glob_path) | |
return cls.infos_from_file(paths[0]) | |
",point_e\evals\npz_stream.py | |
infos_from_file,Extract the info of every array in an npz file.,"@classmethod | |
def infos_from_file(cls, npz_path: str) ->Dict[str, 'NumpyArrayInfo']: | |
"""""""""""" | |
if not os.path.exists(npz_path): | |
raise FileNotFoundError(f'batch of samples was not found: {npz_path}') | |
results = {} | |
with open(npz_path, 'rb') as f: | |
with zipfile.ZipFile(f, 'r') as zip_f: | |
for name in zip_f.namelist(): | |
if not name.endswith('.npy'): | |
continue | |
key_name = name[:-len('.npy')] | |
with zip_f.open(name, 'r') as arr_f: | |
version = np.lib.format.read_magic(arr_f) | |
if version == (1, 0): | |
header = np.lib.format.read_array_header_1_0(arr_f) | |
elif version == (2, 0): | |
header = np.lib.format.read_array_header_2_0(arr_f) | |
else: | |
raise ValueError( | |
f'unknown numpy array version: {version}') | |
shape, _, dtype = header | |
results[key_name] = cls(name=key_name, dtype=dtype, | |
shape=shape) | |
return results | |
",point_e\evals\npz_stream.py | |
elem_shape,,"@property | |
def elem_shape(self) ->Tuple[int]: | |
return self.shape[1:] | |
",point_e\evals\npz_stream.py | |
validate,,"def validate(self): | |
if self.name in {'R', 'G', 'B'}: | |
if len(self.shape) != 2: | |
raise ValueError( | |
f""expecting exactly 2-D shape for '{self.name}' but got: {self.shape}"" | |
) | |
elif self.name == 'arr_0': | |
if len(self.shape) < 2: | |
raise ValueError( | |
f'expecting at least 2-D shape but got: {self.shape}') | |
elif len(self.shape) == 3: | |
if not np.issubdtype(self.dtype, np.floating): | |
raise ValueError( | |
f'invalid dtype for audio batch: {self.dtype} (expected float)' | |
) | |
elif self.dtype != np.uint8: | |
raise ValueError( | |
f'invalid dtype for image batch: {self.dtype} (expected uint8)' | |
) | |
",point_e\evals\npz_stream.py | |
__init__,,"def __init__(self, glob_path: str): | |
self.paths, self.trunc_length = _npz_paths_and_length(glob_path) | |
self.infos = NumpyArrayInfo.infos_from_file(self.paths[0]) | |
",point_e\evals\npz_stream.py | |
keys,,"def keys(self) ->List[str]: | |
return list(self.infos.keys()) | |
",point_e\evals\npz_stream.py | |
stream,,"def stream(self, batch_size: int, keys: Sequence[str]) ->Iterator[Dict[str, | |
np.ndarray]]: | |
cur_batch = None | |
num_remaining = self.trunc_length | |
for path in self.paths: | |
if num_remaining is not None and num_remaining <= 0: | |
break | |
with open_npz_arrays(path, keys) as readers: | |
combined_reader = CombinedReader(keys, readers) | |
while num_remaining is None or num_remaining > 0: | |
read_bs = batch_size | |
if cur_batch is not None: | |
read_bs -= _dict_batch_size(cur_batch) | |
if num_remaining is not None: | |
read_bs = min(read_bs, num_remaining) | |
batch = combined_reader.read_batch(read_bs) | |
if batch is None: | |
break | |
if num_remaining is not None: | |
num_remaining -= _dict_batch_size(batch) | |
if cur_batch is None: | |
cur_batch = batch | |
else: | |
cur_batch = {k: np.concatenate([cur_batch[k], v], axis= | |
0) for k, v in batch.items()} | |
if _dict_batch_size(cur_batch) == batch_size: | |
yield cur_batch | |
cur_batch = None | |
if cur_batch is not None: | |
yield cur_batch | |
",point_e\evals\npz_stream.py | |
read_batch,,"@abstractmethod | |
def read_batch(self, batch_size: int) ->Optional[np.ndarray]: | |
pass | |
",point_e\evals\npz_stream.py | |
__init__,,"def __init__(self, arr_f, shape, dtype): | |
self.arr_f = arr_f | |
self.shape = shape | |
self.dtype = dtype | |
self.idx = 0 | |
",point_e\evals\npz_stream.py | |
read_batch,,"def read_batch(self, batch_size: int) ->Optional[np.ndarray]: | |
if self.idx >= self.shape[0]: | |
return None | |
bs = min(batch_size, self.shape[0] - self.idx) | |
self.idx += bs | |
if self.dtype.itemsize == 0: | |
return np.ndarray([bs, *self.shape[1:]], dtype=self.dtype) | |
read_count = bs * np.prod(self.shape[1:]) | |
read_size = int(read_count * self.dtype.itemsize) | |
data = _read_bytes(self.arr_f, read_size, 'array data') | |
return np.frombuffer(data, dtype=self.dtype).reshape([bs, *self.shape[1:]]) | |
",point_e\evals\npz_stream.py | |
__init__,,"def __init__(self, arr): | |
self.arr = arr | |
self.idx = 0 | |
",point_e\evals\npz_stream.py | |
load,,"@classmethod | |
def load(cls, path: str, arr_name: str): | |
with open(path, 'rb') as f: | |
arr = np.load(f)[arr_name] | |
return cls(arr) | |
",point_e\evals\npz_stream.py | |
read_batch,,"def read_batch(self, batch_size: int) ->Optional[np.ndarray]: | |
if self.idx >= self.arr.shape[0]: | |
return None | |
res = self.arr[self.idx:self.idx + batch_size] | |
self.idx += batch_size | |
return res | |
",point_e\evals\npz_stream.py | |
__init__,,"def __init__(self, keys: List[str], readers: List[NpzArrayReader]): | |
self.keys = keys | |
self.readers = readers | |
",point_e\evals\npz_stream.py | |
read_batch,,"def read_batch(self, batch_size: int) ->Optional[Dict[str, np.ndarray]]: | |
batches = [r.read_batch(batch_size) for r in self.readers] | |
any_none = any(x is None for x in batches) | |
all_none = all(x is None for x in batches) | |
if any_none != all_none: | |
raise RuntimeError('different keys had different numbers of elements') | |
if any_none: | |
return None | |
if any(len(x) != len(batches[0]) for x in batches): | |
raise RuntimeError('different keys had different numbers of elements') | |
return dict(zip(self.keys, batches)) | |
",point_e\evals\npz_stream.py | |
__init__,,"def __init__(self, num_class, normal_channel=True, width_mult=1): | |
super(get_model, self).__init__() | |
self.width_mult = width_mult | |
in_channel = 6 if normal_channel else 3 | |
self.normal_channel = normal_channel | |
self.sa1 = PointNetSetAbstraction(npoint=512, radius=0.2, nsample=32, | |
in_channel=in_channel, mlp=[64 * width_mult, 64 * width_mult, 128 * | |
width_mult], group_all=False) | |
self.sa2 = PointNetSetAbstraction(npoint=128, radius=0.4, nsample=64, | |
in_channel=128 * width_mult + 3, mlp=[128 * width_mult, 128 * | |
width_mult, 256 * width_mult], group_all=False) | |
self.sa3 = PointNetSetAbstraction(npoint=None, radius=None, nsample= | |
None, in_channel=256 * width_mult + 3, mlp=[256 * width_mult, 512 * | |
width_mult, 1024 * width_mult], group_all=True) | |
self.fc1 = nn.Linear(1024 * width_mult, 512 * width_mult) | |
self.bn1 = nn.BatchNorm1d(512 * width_mult) | |
self.drop1 = nn.Dropout(0.4) | |
self.fc2 = nn.Linear(512 * width_mult, 256 * width_mult) | |
self.bn2 = nn.BatchNorm1d(256 * width_mult) | |
self.drop2 = nn.Dropout(0.4) | |
self.fc3 = nn.Linear(256 * width_mult, num_class) | |
",point_e\evals\pointnet2_cls_ssg.py | |
forward,,"def forward(self, xyz, features=False): | |
B, _, _ = xyz.shape | |
if self.normal_channel: | |
norm = xyz[:, 3:, :] | |
xyz = xyz[:, :3, :] | |
else: | |
norm = None | |
l1_xyz, l1_points = self.sa1(xyz, norm) | |
l2_xyz, l2_points = self.sa2(l1_xyz, l1_points) | |
l3_xyz, l3_points = self.sa3(l2_xyz, l2_points) | |
x = l3_points.view(B, 1024 * self.width_mult) | |
x = self.drop1(F.relu(self.bn1(self.fc1(x)))) | |
result_features = self.bn2(self.fc2(x)) | |
x = self.drop2(F.relu(result_features)) | |
x = self.fc3(x) | |
x = F.log_softmax(x, -1) | |
if features: | |
return x, l3_points, result_features | |
else: | |
return x, l3_points | |
",point_e\evals\pointnet2_cls_ssg.py | |
__init__,,"def __init__(self): | |
super(get_loss, self).__init__() | |
",point_e\evals\pointnet2_cls_ssg.py | |
forward,,"def forward(self, pred, target, trans_feat): | |
total_loss = F.nll_loss(pred, target) | |
return total_loss | |
",point_e\evals\pointnet2_cls_ssg.py | |
timeit,,"def timeit(tag, t): | |
print('{}: {}s'.format(tag, time() - t)) | |
return time() | |
",point_e\evals\pointnet2_utils.py | |
pc_normalize,,"def pc_normalize(pc): | |
l = pc.shape[0] | |
centroid = np.mean(pc, axis=0) | |
pc = pc - centroid | |
m = np.max(np.sqrt(np.sum(pc ** 2, axis=1))) | |
pc = pc / m | |
return pc | |
",point_e\evals\pointnet2_utils.py | |
square_distance,"Calculate Euclid distance between each two points. | |
src^T * dst = xn * xm + yn * ym + zn * zm; | |
sum(src^2, dim=-1) = xn*xn + yn*yn + zn*zn; | |
sum(dst^2, dim=-1) = xm*xm + ym*ym + zm*zm; | |
dist = (xn - xm)^2 + (yn - ym)^2 + (zn - zm)^2 | |
= sum(src**2,dim=-1)+sum(dst**2,dim=-1)-2*src^T*dst | |
Input: | |
src: source points, [B, N, C] | |
dst: target points, [B, M, C] | |
Output: | |
dist: per-point square distance, [B, N, M]","def square_distance(src, dst): | |
"""""""""""" | |
B, N, _ = src.shape | |
_, M, _ = dst.shape | |
dist = -2 * torch.matmul(src, dst.permute(0, 2, 1)) | |
dist += torch.sum(src ** 2, -1).view(B, N, 1) | |
dist += torch.sum(dst ** 2, -1).view(B, 1, M) | |
return dist | |
",point_e\evals\pointnet2_utils.py | |
index_points,"Input: | |
points: input points data, [B, N, C] | |
idx: sample index data, [B, S] | |
Return: | |
new_points:, indexed points data, [B, S, C]","def index_points(points, idx): | |
"""""""""""" | |
device = points.device | |
B = points.shape[0] | |
view_shape = list(idx.shape) | |
view_shape[1:] = [1] * (len(view_shape) - 1) | |
repeat_shape = list(idx.shape) | |
repeat_shape[0] = 1 | |
batch_indices = torch.arange(B, dtype=torch.long).to(device).view( | |
view_shape).repeat(repeat_shape) | |
new_points = points[batch_indices, idx, :] | |
return new_points | |
",point_e\evals\pointnet2_utils.py | |
farthest_point_sample,"Input: | |
xyz: pointcloud data, [B, N, 3] | |
npoint: number of samples | |
Return: | |
centroids: sampled pointcloud index, [B, npoint]","def farthest_point_sample(xyz, npoint, deterministic=False): | |
"""""""""""" | |
device = xyz.device | |
B, N, C = xyz.shape | |
centroids = torch.zeros(B, npoint, dtype=torch.long).to(device) | |
distance = torch.ones(B, N).to(device) * 10000000000.0 | |
if deterministic: | |
farthest = torch.arange(0, B, dtype=torch.long).to(device) | |
else: | |
farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device) | |
batch_indices = torch.arange(B, dtype=torch.long).to(device) | |
for i in range(npoint): | |
centroids[:, i] = farthest | |
centroid = xyz[batch_indices, farthest, :].view(B, 1, 3) | |
dist = torch.sum((xyz - centroid) ** 2, -1) | |
mask = dist < distance | |
distance[mask] = dist[mask] | |
farthest = torch.max(distance, -1)[1] | |
return centroids | |
",point_e\evals\pointnet2_utils.py | |
query_ball_point,"Input: | |
radius: local region radius | |
nsample: max sample number in local region | |
xyz: all points, [B, N, 3] | |
new_xyz: query points, [B, S, 3] | |
Return: | |
group_idx: grouped points index, [B, S, nsample]","def query_ball_point(radius, nsample, xyz, new_xyz): | |
"""""""""""" | |
device = xyz.device | |
B, N, C = xyz.shape | |
_, S, _ = new_xyz.shape | |
group_idx = torch.arange(N, dtype=torch.long).to(device).view(1, 1, N | |
).repeat([B, S, 1]) | |
sqrdists = square_distance(new_xyz, xyz) | |
group_idx[sqrdists > radius ** 2] = N | |
group_idx = group_idx.sort(dim=-1)[0][:, :, :nsample] | |
group_first = group_idx[:, :, 0].view(B, S, 1).repeat([1, 1, nsample]) | |
mask = group_idx == N | |
group_idx[mask] = group_first[mask] | |
return group_idx | |
",point_e\evals\pointnet2_utils.py | |
sample_and_group,"Input: | |
npoint: | |
radius: | |
nsample: | |
xyz: input points position data, [B, N, 3] | |
points: input points data, [B, N, D] | |
Return: | |
new_xyz: sampled points position data, [B, npoint, nsample, 3] | |
new_points: sampled points data, [B, npoint, nsample, 3+D]","def sample_and_group(npoint, radius, nsample, xyz, points, returnfps=False, | |
deterministic=False): | |
"""""""""""" | |
B, N, C = xyz.shape | |
S = npoint | |
fps_idx = farthest_point_sample(xyz, npoint, deterministic=deterministic) | |
new_xyz = index_points(xyz, fps_idx) | |
idx = query_ball_point(radius, nsample, xyz, new_xyz) | |
grouped_xyz = index_points(xyz, idx) | |
grouped_xyz_norm = grouped_xyz - new_xyz.view(B, S, 1, C) | |
if points is not None: | |
grouped_points = index_points(points, idx) | |
new_points = torch.cat([grouped_xyz_norm, grouped_points], dim=-1) | |
else: | |
new_points = grouped_xyz_norm | |
if returnfps: | |
return new_xyz, new_points, grouped_xyz, fps_idx | |
else: | |
return new_xyz, new_points | |
",point_e\evals\pointnet2_utils.py | |
sample_and_group_all,"Input: | |
xyz: input points position data, [B, N, 3] | |
points: input points data, [B, N, D] | |
Return: | |
new_xyz: sampled points position data, [B, 1, 3] | |
new_points: sampled points data, [B, 1, N, 3+D]","def sample_and_group_all(xyz, points): | |
"""""""""""" | |
device = xyz.device | |
B, N, C = xyz.shape | |
new_xyz = torch.zeros(B, 1, C).to(device) | |
grouped_xyz = xyz.view(B, 1, N, C) | |
if points is not None: | |
new_points = torch.cat([grouped_xyz, points.view(B, 1, N, -1)], dim=-1) | |
else: | |
new_points = grouped_xyz | |
return new_xyz, new_points | |
",point_e\evals\pointnet2_utils.py | |
__init__,,"def __init__(self, npoint, radius, nsample, in_channel, mlp, group_all): | |
super(PointNetSetAbstraction, self).__init__() | |
self.npoint = npoint | |
self.radius = radius | |
self.nsample = nsample | |
self.mlp_convs = nn.ModuleList() | |
self.mlp_bns = nn.ModuleList() | |
last_channel = in_channel | |
for out_channel in mlp: | |
self.mlp_convs.append(nn.Conv2d(last_channel, out_channel, 1)) | |
self.mlp_bns.append(nn.BatchNorm2d(out_channel)) | |
last_channel = out_channel | |
self.group_all = group_all | |
",point_e\evals\pointnet2_utils.py | |
forward,"Input: | |
xyz: input points position data, [B, C, N] | |
points: input points data, [B, D, N] | |
Return: | |
new_xyz: sampled points position data, [B, C, S] | |
new_points_concat: sample points feature data, [B, D', S]","def forward(self, xyz, points): | |
"""""""""""" | |
xyz = xyz.permute(0, 2, 1) | |
if points is not None: | |
points = points.permute(0, 2, 1) | |
if self.group_all: | |
new_xyz, new_points = sample_and_group_all(xyz, points) | |
else: | |
new_xyz, new_points = sample_and_group(self.npoint, self.radius, | |
self.nsample, xyz, points, deterministic=not self.training) | |
new_points = new_points.permute(0, 3, 2, 1) | |
for i, conv in enumerate(self.mlp_convs): | |
bn = self.mlp_bns[i] | |
new_points = F.relu(bn(conv(new_points))) | |
new_points = torch.max(new_points, 2)[0] | |
new_xyz = new_xyz.permute(0, 2, 1) | |
return new_xyz, new_points | |
",point_e\evals\pointnet2_utils.py | |
__init__,,"def __init__(self, npoint, radius_list, nsample_list, in_channel, mlp_list): | |
super(PointNetSetAbstractionMsg, self).__init__() | |
self.npoint = npoint | |
self.radius_list = radius_list | |
self.nsample_list = nsample_list | |
self.conv_blocks = nn.ModuleList() | |
self.bn_blocks = nn.ModuleList() | |
for i in range(len(mlp_list)): | |
convs = nn.ModuleList() | |
bns = nn.ModuleList() | |
last_channel = in_channel + 3 | |
for out_channel in mlp_list[i]: | |
convs.append(nn.Conv2d(last_channel, out_channel, 1)) | |
bns.append(nn.BatchNorm2d(out_channel)) | |
last_channel = out_channel | |
self.conv_blocks.append(convs) | |
self.bn_blocks.append(bns) | |
",point_e\evals\pointnet2_utils.py | |
forward,"Input: | |
xyz: input points position data, [B, C, N] | |
points: input points data, [B, D, N] | |
Return: | |
new_xyz: sampled points position data, [B, C, S] | |
new_points_concat: sample points feature data, [B, D', S]","def forward(self, xyz, points): | |
"""""""""""" | |
xyz = xyz.permute(0, 2, 1) | |
if points is not None: | |
points = points.permute(0, 2, 1) | |
B, N, C = xyz.shape | |
S = self.npoint | |
new_xyz = index_points(xyz, farthest_point_sample(xyz, S, deterministic | |
=not self.training)) | |
new_points_list = [] | |
for i, radius in enumerate(self.radius_list): | |
K = self.nsample_list[i] | |
group_idx = query_ball_point(radius, K, xyz, new_xyz) | |
grouped_xyz = index_points(xyz, group_idx) | |
grouped_xyz -= new_xyz.view(B, S, 1, C) | |
if points is not None: | |
grouped_points = index_points(points, group_idx) | |
grouped_points = torch.cat([grouped_points, grouped_xyz], dim=-1) | |
else: | |
grouped_points = grouped_xyz | |
grouped_points = grouped_points.permute(0, 3, 2, 1) | |
for j in range(len(self.conv_blocks[i])): | |
conv = self.conv_blocks[i][j] | |
bn = self.bn_blocks[i][j] | |
grouped_points = F.relu(bn(conv(grouped_points))) | |
new_points = torch.max(grouped_points, 2)[0] | |
new_points_list.append(new_points) | |
new_xyz = new_xyz.permute(0, 2, 1) | |
new_points_concat = torch.cat(new_points_list, dim=1) | |
return new_xyz, new_points_concat | |
",point_e\evals\pointnet2_utils.py | |
__init__,,"def __init__(self, in_channel, mlp): | |
super(PointNetFeaturePropagation, self).__init__() | |
self.mlp_convs = nn.ModuleList() | |
self.mlp_bns = nn.ModuleList() | |
last_channel = in_channel | |
for out_channel in mlp: | |
self.mlp_convs.append(nn.Conv1d(last_channel, out_channel, 1)) | |
self.mlp_bns.append(nn.BatchNorm1d(out_channel)) | |
last_channel = out_channel | |
",point_e\evals\pointnet2_utils.py | |
forward,"Input: | |
xyz1: input points position data, [B, C, N] | |
xyz2: sampled input points position data, [B, C, S] | |
points1: input points data, [B, D, N] | |
points2: input points data, [B, D, S] | |
Return: | |
new_points: upsampled points data, [B, D', N]","def forward(self, xyz1, xyz2, points1, points2): | |
"""""""""""" | |
xyz1 = xyz1.permute(0, 2, 1) | |
xyz2 = xyz2.permute(0, 2, 1) | |
points2 = points2.permute(0, 2, 1) | |
B, N, C = xyz1.shape | |
_, S, _ = xyz2.shape | |
if S == 1: | |
interpolated_points = points2.repeat(1, N, 1) | |
else: | |
dists = square_distance(xyz1, xyz2) | |
dists, idx = dists.sort(dim=-1) | |
dists, idx = dists[:, :, :3], idx[:, :, :3] | |
dist_recip = 1.0 / (dists + 1e-08) | |
norm = torch.sum(dist_recip, dim=2, keepdim=True) | |
weight = dist_recip / norm | |
interpolated_points = torch.sum(index_points(points2, idx) * weight | |
.view(B, N, 3, 1), dim=2) | |
if points1 is not None: | |
points1 = points1.permute(0, 2, 1) | |
new_points = torch.cat([points1, interpolated_points], dim=-1) | |
else: | |
new_points = interpolated_points | |
new_points = new_points.permute(0, 2, 1) | |
for i, conv in enumerate(self.mlp_convs): | |
bn = self.mlp_bns[i] | |
new_points = F.relu(bn(conv(new_points))) | |
return new_points | |
",point_e\evals\pointnet2_utils.py | |
clear_scene,,"def clear_scene(): | |
bpy.ops.object.select_all(action='SELECT') | |
bpy.ops.object.delete() | |
",point_e\evals\scripts\blender_script.py | |
clear_lights,,"def clear_lights(): | |
bpy.ops.object.select_all(action='DESELECT') | |
for obj in bpy.context.scene.objects.values(): | |
if isinstance(obj.data, bpy.types.Light): | |
obj.select_set(True) | |
bpy.ops.object.delete() | |
",point_e\evals\scripts\blender_script.py | |
import_model,,"def import_model(path): | |
clear_scene() | |
_, ext = os.path.splitext(path) | |
ext = ext.lower() | |
if ext == '.obj': | |
bpy.ops.import_scene.obj(filepath=path) | |
elif ext in ['.glb', '.gltf']: | |
bpy.ops.import_scene.gltf(filepath=path) | |
elif ext == '.stl': | |
bpy.ops.import_mesh.stl(filepath=path) | |
elif ext == '.fbx': | |
bpy.ops.import_scene.fbx(filepath=path) | |
elif ext == '.dae': | |
bpy.ops.wm.collada_import(filepath=path) | |
elif ext == '.ply': | |
bpy.ops.import_mesh.ply(filepath=path) | |
else: | |
raise RuntimeError(f'unexpected extension: {ext}') | |
",point_e\evals\scripts\blender_script.py | |
scene_root_objects,,"def scene_root_objects(): | |
for obj in bpy.context.scene.objects.values(): | |
if not obj.parent: | |
yield obj | |
",point_e\evals\scripts\blender_script.py | |
scene_bbox,,"def scene_bbox(single_obj=None, ignore_matrix=False): | |
bbox_min = (math.inf,) * 3 | |
bbox_max = (-math.inf,) * 3 | |
found = False | |
for obj in (scene_meshes() if single_obj is None else [single_obj]): | |
found = True | |
for coord in obj.bound_box: | |
coord = Vector(coord) | |
if not ignore_matrix: | |
coord = obj.matrix_world @ coord | |
bbox_min = tuple(min(x, y) for x, y in zip(bbox_min, coord)) | |
bbox_max = tuple(max(x, y) for x, y in zip(bbox_max, coord)) | |
if not found: | |
raise RuntimeError('no objects in scene to compute bounding box for') | |
return Vector(bbox_min), Vector(bbox_max) | |
",point_e\evals\scripts\blender_script.py | |
scene_meshes,,"def scene_meshes(): | |
for obj in bpy.context.scene.objects.values(): | |
if isinstance(obj.data, bpy.types.Mesh): | |
yield obj | |
",point_e\evals\scripts\blender_script.py | |
normalize_scene,,"def normalize_scene(): | |
bbox_min, bbox_max = scene_bbox() | |
scale = 1 / max(bbox_max - bbox_min) | |
for obj in scene_root_objects(): | |
obj.scale = obj.scale * scale | |
bpy.context.view_layer.update() | |
bbox_min, bbox_max = scene_bbox() | |
offset = -(bbox_min + bbox_max) / 2 | |
for obj in scene_root_objects(): | |
obj.matrix_world.translation += offset | |
bpy.ops.object.select_all(action='DESELECT') | |
",point_e\evals\scripts\blender_script.py | |
create_camera,,"def create_camera(): | |
camera_data = bpy.data.cameras.new(name='Camera') | |
camera_object = bpy.data.objects.new('Camera', camera_data) | |
bpy.context.scene.collection.objects.link(camera_object) | |
bpy.context.scene.camera = camera_object | |
",point_e\evals\scripts\blender_script.py | |
set_camera,,"def set_camera(direction, camera_dist=2.0): | |
camera_pos = -camera_dist * direction | |
bpy.context.scene.camera.location = camera_pos | |
rot_quat = direction.to_track_quat('-Z', 'Y') | |
bpy.context.scene.camera.rotation_euler = rot_quat.to_euler() | |
bpy.context.view_layer.update() | |
",point_e\evals\scripts\blender_script.py | |
randomize_camera,,"def randomize_camera(camera_dist=2.0): | |
direction = random_unit_vector() | |
set_camera(direction, camera_dist=camera_dist) | |
",point_e\evals\scripts\blender_script.py | |
pan_camera,,"def pan_camera(time, axis='Z', camera_dist=2.0, elevation=-0.1): | |
angle = time * math.pi * 2 | |
direction = [-math.cos(angle), -math.sin(angle), -elevation] | |
assert axis in ['X', 'Y', 'Z'] | |
if axis == 'X': | |
direction = [direction[2], *direction[:2]] | |
elif axis == 'Y': | |
direction = [direction[0], -elevation, direction[1]] | |
direction = Vector(direction).normalized() | |
set_camera(direction, camera_dist=camera_dist) | |
",point_e\evals\scripts\blender_script.py | |
place_camera,,"def place_camera(time, camera_pose_mode='random', camera_dist_min=2.0, | |
camera_dist_max=2.0): | |
camera_dist = random.uniform(camera_dist_min, camera_dist_max) | |
if camera_pose_mode == 'random': | |
randomize_camera(camera_dist=camera_dist) | |
elif camera_pose_mode == 'z-circular': | |
pan_camera(time, axis='Z', camera_dist=camera_dist) | |
elif camera_pose_mode == 'z-circular-elevated': | |
pan_camera(time, axis='Z', camera_dist=camera_dist, elevation= | |
0.2617993878) | |
else: | |
raise ValueError(f'Unknown camera pose mode: {camera_pose_mode}') | |
",point_e\evals\scripts\blender_script.py | |
create_light,,"def create_light(location, energy=1.0, angle=0.5 * math.pi / 180): | |
light_data = bpy.data.lights.new(name='Light', type='SUN') | |
light_data.energy = energy | |
light_data.angle = angle | |
light_object = bpy.data.objects.new(name='Light', object_data=light_data) | |
direction = -location | |
rot_quat = direction.to_track_quat('-Z', 'Y') | |
light_object.rotation_euler = rot_quat.to_euler() | |
bpy.context.view_layer.update() | |
bpy.context.collection.objects.link(light_object) | |
light_object.location = location | |
",point_e\evals\scripts\blender_script.py | |
create_random_lights,,"def create_random_lights(count=4, distance=2.0, energy=1.5): | |
clear_lights() | |
for _ in range(count): | |
create_light(random_unit_vector() * distance, energy=energy) | |
",point_e\evals\scripts\blender_script.py | |
create_camera_light,,"def create_camera_light(): | |
clear_lights() | |
create_light(bpy.context.scene.camera.location, energy=5.0) | |
",point_e\evals\scripts\blender_script.py | |
create_uniform_light,,"def create_uniform_light(backend): | |
clear_lights() | |
pos = Vector(UNIFORM_LIGHT_DIRECTION) | |
angle = 0.0092 if backend == 'CYCLES' else math.pi | |
create_light(pos, energy=5.0, angle=angle) | |
create_light(-pos, energy=5.0, angle=angle) | |
",point_e\evals\scripts\blender_script.py | |
create_vertex_color_shaders,,"def create_vertex_color_shaders(): | |
for obj in bpy.context.scene.objects.values(): | |
if not isinstance(obj.data, bpy.types.Mesh): | |
continue | |
if len(obj.data.materials): | |
continue | |
color_keys = (obj.data.vertex_colors or {}).keys() | |
if not len(color_keys): | |
continue | |
mat = bpy.data.materials.new(name='VertexColored') | |
mat.use_nodes = True | |
bsdf_node = None | |
for node in mat.node_tree.nodes: | |
if node.type == 'BSDF_PRINCIPLED': | |
bsdf_node = node | |
assert bsdf_node is not None, 'material has no Principled BSDF node to modify' | |
socket_map = {} | |
for input in bsdf_node.inputs: | |
socket_map[input.name] = input | |
socket_map['Specular'].default_value = 0.0 | |
socket_map['Roughness'].default_value = 1.0 | |
v_color = mat.node_tree.nodes.new('ShaderNodeVertexColor') | |
v_color.layer_name = color_keys[0] | |
mat.node_tree.links.new(v_color.outputs[0], socket_map['Base Color']) | |
obj.data.materials.append(mat) | |
",point_e\evals\scripts\blender_script.py | |
create_default_materials,,"def create_default_materials(): | |
for obj in bpy.context.scene.objects.values(): | |
if isinstance(obj.data, bpy.types.Mesh): | |
if not len(obj.data.materials): | |
mat = bpy.data.materials.new(name='DefaultMaterial') | |
mat.use_nodes = True | |
obj.data.materials.append(mat) | |
",point_e\evals\scripts\blender_script.py | |
find_materials,,"def find_materials(): | |
all_materials = set() | |
for obj in bpy.context.scene.objects.values(): | |
if not isinstance(obj.data, bpy.types.Mesh): | |
continue | |
for mat in obj.data.materials: | |
all_materials.add(mat) | |
return all_materials | |
",point_e\evals\scripts\blender_script.py | |
get_socket_value,,"def get_socket_value(tree, socket): | |
default = socket.default_value | |
if not isinstance(default, float): | |
default = list(default) | |
for link in tree.links: | |
if link.to_socket == socket: | |
return link.from_socket, default | |
return None, default | |
",point_e\evals\scripts\blender_script.py | |
clear_socket_input,,"def clear_socket_input(tree, socket): | |
for link in list(tree.links): | |
if link.to_socket == socket: | |
tree.links.remove(link) | |
",point_e\evals\scripts\blender_script.py | |
set_socket_value,,"def set_socket_value(tree, socket, socket_and_default): | |
clear_socket_input(tree, socket) | |
old_source_socket, default = socket_and_default | |
if isinstance(default, float) and not isinstance(socket.default_value, | |
float): | |
socket.default_value = [default] * 3 + [1.0] | |
else: | |
socket.default_value = default | |
if old_source_socket is not None: | |
tree.links.new(old_source_socket, socket) | |
",point_e\evals\scripts\blender_script.py | |
setup_nodes,,"def setup_nodes(output_path, capturing_material_alpha: bool=False): | |
tree = bpy.context.scene.node_tree | |
links = tree.links | |
for node in tree.nodes: | |
tree.nodes.remove(node) | |
def node_op(op: str, *args, clamp=False): | |
node = tree.nodes.new(type='CompositorNodeMath') | |
node.operation = op | |
if clamp: | |
node.use_clamp = True | |
for i, arg in enumerate(args): | |
if isinstance(arg, (int, float)): | |
node.inputs[i].default_value = arg | |
else: | |
links.new(arg, node.inputs[i]) | |
return node.outputs[0] | |
def node_clamp(x, maximum=1.0): | |
return node_op('MINIMUM', x, maximum) | |
def node_mul(x, y, **kwargs): | |
return node_op('MULTIPLY', x, y, **kwargs) | |
input_node = tree.nodes.new(type='CompositorNodeRLayers') | |
input_node.scene = bpy.context.scene | |
input_sockets = {} | |
for output in input_node.outputs: | |
input_sockets[output.name] = output | |
if capturing_material_alpha: | |
color_socket = input_sockets['Image'] | |
else: | |
raw_color_socket = input_sockets['Image'] | |
color_node = tree.nodes.new(type='CompositorNodeConvertColorSpace') | |
color_node.from_color_space = 'Linear' | |
color_node.to_color_space = 'sRGB' | |
tree.links.new(raw_color_socket, color_node.inputs[0]) | |
color_socket = color_node.outputs[0] | |
split_node = tree.nodes.new(type='CompositorNodeSepRGBA') | |
tree.links.new(color_socket, split_node.inputs[0]) | |
for i, channel in (enumerate('rgba') if not capturing_material_alpha else | |
[(0, 'MatAlpha')]): | |
output_node = tree.nodes.new(type='CompositorNodeOutputFile') | |
output_node.base_path = f'{output_path}_{channel}' | |
links.new(split_node.outputs[i], output_node.inputs[0]) | |
if capturing_material_alpha: | |
return | |
depth_out = node_clamp(node_mul(input_sockets['Depth'], 1 / MAX_DEPTH)) | |
output_node = tree.nodes.new(type='CompositorNodeOutputFile') | |
output_node.base_path = f'{output_path}_depth' | |
links.new(depth_out, output_node.inputs[0]) | |
",point_e\evals\scripts\blender_script.py | |
render_scene,,"def render_scene(output_path, fast_mode: bool): | |
use_workbench = bpy.context.scene.render.engine == 'BLENDER_WORKBENCH' | |
if use_workbench: | |
bpy.context.scene.render.engine = 'BLENDER_EEVEE' | |
bpy.context.scene.eevee.taa_render_samples = 1 | |
if fast_mode: | |
if bpy.context.scene.render.engine == 'BLENDER_EEVEE': | |
bpy.context.scene.eevee.taa_render_samples = 1 | |
elif bpy.context.scene.render.engine == 'CYCLES': | |
bpy.context.scene.cycles.samples = 256 | |
elif bpy.context.scene.render.engine == 'CYCLES': | |
bpy.context.scene.cycles.time_limit = 40 | |
bpy.context.view_layer.update() | |
bpy.context.scene.use_nodes = True | |
bpy.context.scene.view_layers['ViewLayer'].use_pass_z = True | |
bpy.context.scene.view_settings.view_transform = 'Raw' | |
bpy.context.scene.render.film_transparent = True | |
bpy.context.scene.render.resolution_x = 512 | |
bpy.context.scene.render.resolution_y = 512 | |
bpy.context.scene.render.image_settings.file_format = 'PNG' | |
bpy.context.scene.render.image_settings.color_mode = 'BW' | |
bpy.context.scene.render.image_settings.color_depth = '16' | |
bpy.context.scene.render.filepath = output_path | |
setup_nodes(output_path) | |
bpy.ops.render.render(write_still=True) | |
for channel_name in ['r', 'g', 'b', 'a', 'depth']: | |
sub_dir = f'{output_path}_{channel_name}' | |
image_path = os.path.join(sub_dir, os.listdir(sub_dir)[0]) | |
name, ext = os.path.splitext(output_path) | |
if channel_name == 'depth' or not use_workbench: | |
os.rename(image_path, f'{name}_{channel_name}{ext}') | |
else: | |
os.remove(image_path) | |
os.removedirs(sub_dir) | |
if use_workbench: | |
bpy.context.scene.use_nodes = False | |
bpy.context.scene.render.engine = 'BLENDER_WORKBENCH' | |
bpy.context.scene.render.image_settings.color_mode = 'RGBA' | |
bpy.context.scene.render.image_settings.color_depth = '8' | |
bpy.context.scene.display.shading.color_type = 'TEXTURE' | |
bpy.context.scene.display.shading.light = 'FLAT' | |
if fast_mode: | |
bpy.context.scene.display.render_aa = 'FXAA' | |
os.remove(output_path) | |
bpy.ops.render.render(write_still=True) | |
bpy.context.scene.render.image_settings.color_mode = 'BW' | |
bpy.context.scene.render.image_settings.color_depth = '16' | |
",point_e\evals\scripts\blender_script.py | |
scene_fov,,"def scene_fov(): | |
x_fov = bpy.context.scene.camera.data.angle_x | |
y_fov = bpy.context.scene.camera.data.angle_y | |
width = bpy.context.scene.render.resolution_x | |
height = bpy.context.scene.render.resolution_y | |
if bpy.context.scene.camera.data.angle == x_fov: | |
y_fov = 2 * math.atan(math.tan(x_fov / 2) * height / width) | |
else: | |
x_fov = 2 * math.atan(math.tan(y_fov / 2) * width / height) | |
return x_fov, y_fov | |
",point_e\evals\scripts\blender_script.py | |
write_camera_metadata,,"def write_camera_metadata(path): | |
x_fov, y_fov = scene_fov() | |
bbox_min, bbox_max = scene_bbox() | |
matrix = bpy.context.scene.camera.matrix_world | |
with open(path, 'w') as f: | |
json.dump(dict(format_version=FORMAT_VERSION, max_depth=MAX_DEPTH, | |
bbox=[list(bbox_min), list(bbox_max)], origin=list(matrix.col[3 | |
])[:3], x_fov=x_fov, y_fov=y_fov, x=list(matrix.col[0])[:3], y= | |
list(-matrix.col[1])[:3], z=list(-matrix.col[2])[:3]), f) | |
",point_e\evals\scripts\blender_script.py | |
save_rendering_dataset,,"def save_rendering_dataset(input_path: str, output_path: str, num_images: | |
int, backend: str, light_mode: str, camera_pose: str, camera_dist_min: | |
float, camera_dist_max: float, fast_mode: bool): | |
assert light_mode in ['random', 'uniform', 'camera'] | |
assert camera_pose in ['random', 'z-circular', 'z-circular-elevated'] | |
import_model(input_path) | |
bpy.context.scene.render.engine = backend | |
normalize_scene() | |
if light_mode == 'random': | |
create_random_lights() | |
elif light_mode == 'uniform': | |
create_uniform_light(backend) | |
create_camera() | |
create_vertex_color_shaders() | |
for i in range(num_images): | |
t = i / max(num_images - 1, 1) | |
place_camera(t, camera_pose_mode=camera_pose, camera_dist_min= | |
camera_dist_min, camera_dist_max=camera_dist_max) | |
if light_mode == 'camera': | |
create_camera_light() | |
render_scene(os.path.join(output_path, f'{i:05}.png'), fast_mode= | |
fast_mode) | |
write_camera_metadata(os.path.join(output_path, f'{i:05}.json')) | |
with open(os.path.join(output_path, 'info.json'), 'w') as f: | |
info = dict(backend=backend, light_mode=light_mode, fast_mode= | |
fast_mode, format_version=FORMAT_VERSION, channels=['R', 'G', | |
'B', 'A', 'D'], scale=0.5) | |
json.dump(info, f) | |
",point_e\evals\scripts\blender_script.py | |
main,,"def main(): | |
try: | |
dash_index = sys.argv.index('--') | |
except ValueError as exc: | |
raise ValueError(""arguments must be preceded by '--'"") from exc | |
raw_args = sys.argv[dash_index + 1:] | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--input_path', required=True, type=str) | |
parser.add_argument('--output_path', required=True, type=str) | |
parser.add_argument('--num_images', type=int, default=20) | |
parser.add_argument('--backend', type=str, default='BLENDER_EEVEE') | |
parser.add_argument('--light_mode', type=str, default='uniform') | |
parser.add_argument('--camera_pose', type=str, default='random') | |
parser.add_argument('--camera_dist_min', type=float, default=2.0) | |
parser.add_argument('--camera_dist_max', type=float, default=2.0) | |
parser.add_argument('--fast_mode', action='store_true') | |
args = parser.parse_args(raw_args) | |
save_rendering_dataset(input_path=args.input_path, output_path=args. | |
output_path, num_images=args.num_images, backend=args.backend, | |
light_mode=args.light_mode, camera_pose=args.camera_pose, | |
camera_dist_min=args.camera_dist_min, camera_dist_max=args. | |
camera_dist_max, fast_mode=args.fast_mode) | |
",point_e\evals\scripts\blender_script.py | |
main,,"def main(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--cache_dir', type=str, default=None) | |
parser.add_argument('batch_1', type=str) | |
parser.add_argument('batch_2', type=str) | |
args = parser.parse_args() | |
print('creating classifier...') | |
clf = PointNetClassifier(devices=get_torch_devices(), cache_dir=args. | |
cache_dir) | |
print('computing first batch activations') | |
features_1, _ = clf.features_and_preds(NpzStreamer(args.batch_1)) | |
stats_1 = compute_statistics(features_1) | |
del features_1 | |
features_2, _ = clf.features_and_preds(NpzStreamer(args.batch_2)) | |
stats_2 = compute_statistics(features_2) | |
del features_2 | |
print(f'P-FID: {stats_1.frechet_distance(stats_2)}') | |
",point_e\evals\scripts\evaluate_pfid.py | |
main,,"def main(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--cache_dir', type=str, default=None) | |
parser.add_argument('batch', type=str) | |
args = parser.parse_args() | |
print('creating classifier...') | |
clf = PointNetClassifier(devices=get_torch_devices(), cache_dir=args. | |
cache_dir) | |
print('computing batch predictions') | |
_, preds = clf.features_and_preds(NpzStreamer(args.batch)) | |
print(f'P-IS: {compute_inception_score(preds)}') | |
",point_e\evals\scripts\evaluate_pis.py | |
checkpoint,"Evaluate a function without caching intermediate activations, allowing for | |
reduced memory at the expense of extra compute in the backward pass. | |
:param func: the function to evaluate. | |
:param inputs: the argument sequence to pass to `func`. | |
:param params: a sequence of parameters `func` depends on but does not | |
explicitly take as arguments. | |
:param flag: if False, disable gradient checkpointing.","def checkpoint(func: Callable[..., Union[torch.Tensor, Sequence[torch. | |
Tensor]]], inputs: Sequence[torch.Tensor], params: Iterable[torch. | |
Tensor], flag: bool): | |
"""""""""""" | |
if flag: | |
args = tuple(inputs) + tuple(params) | |
return CheckpointFunction.apply(func, len(inputs), *args) | |
else: | |
return func(*inputs) | |
",point_e\models\checkpoint.py | |
forward,,"@staticmethod | |
def forward(ctx, run_function, length, *args): | |
ctx.run_function = run_function | |
ctx.input_tensors = list(args[:length]) | |
ctx.input_params = list(args[length:]) | |
with torch.no_grad(): | |
output_tensors = ctx.run_function(*ctx.input_tensors) | |
return output_tensors | |
",point_e\models\checkpoint.py | |
backward,,"@staticmethod | |
def backward(ctx, *output_grads): | |
ctx.input_tensors = [x.detach().requires_grad_(True) for x in ctx. | |
input_tensors] | |
with torch.enable_grad(): | |
shallow_copies = [x.view_as(x) for x in ctx.input_tensors] | |
output_tensors = ctx.run_function(*shallow_copies) | |
input_grads = torch.autograd.grad(output_tensors, ctx.input_tensors + | |
ctx.input_params, output_grads, allow_unused=True) | |
del ctx.input_tensors | |
del ctx.input_params | |
del output_tensors | |
return (None, None) + input_grads | |
",point_e\models\checkpoint.py | |
model_from_config,,"def model_from_config(config: Dict[str, Any], device: torch.device | |
) ->nn.Module: | |
config = config.copy() | |
name = config.pop('name') | |
if name == 'PointDiffusionTransformer': | |
return PointDiffusionTransformer(device=device, dtype=torch.float32, | |
**config) | |
elif name == 'CLIPImagePointDiffusionTransformer': | |
return CLIPImagePointDiffusionTransformer(device=device, dtype= | |
torch.float32, **config) | |
elif name == 'CLIPImageGridPointDiffusionTransformer': | |
return CLIPImageGridPointDiffusionTransformer(device=device, dtype= | |
torch.float32, **config) | |
elif name == 'UpsamplePointDiffusionTransformer': | |
return UpsamplePointDiffusionTransformer(device=device, dtype=torch | |
.float32, **config) | |
elif name == 'CLIPImageGridUpsamplePointDiffusionTransformer': | |
return CLIPImageGridUpsamplePointDiffusionTransformer(device=device, | |
dtype=torch.float32, **config) | |
elif name == 'CrossAttentionPointCloudSDFModel': | |
return CrossAttentionPointCloudSDFModel(device=device, dtype=torch. | |
float32, **config) | |
raise ValueError(f'unknown model name: {name}') | |
",point_e\models\configs.py | |
default_cache_dir,,"@lru_cache() | |
def default_cache_dir() ->str: | |
return os.path.join(os.path.abspath(os.getcwd()), 'point_e_model_cache') | |
",point_e\models\download.py | |
fetch_file_cached,"Download the file at the given URL into a local file and return the path. | |
If cache_dir is specified, it will be used to download the files. | |
Otherwise, default_cache_dir() is used.","def fetch_file_cached(url: str, progress: bool=True, cache_dir: Optional[ | |
str]=None, chunk_size: int=4096) ->str: | |
"""""""""""" | |
if cache_dir is None: | |
cache_dir = default_cache_dir() | |
os.makedirs(cache_dir, exist_ok=True) | |
local_path = os.path.join(cache_dir, url.split('/')[-1]) | |
if os.path.exists(local_path): | |
return local_path | |
response = requests.get(url, stream=True) | |
size = int(response.headers.get('content-length', '0')) | |
with FileLock(local_path + '.lock'): | |
if progress: | |
pbar = tqdm(total=size, unit='iB', unit_scale=True) | |
tmp_path = local_path + '.tmp' | |
with open(tmp_path, 'wb') as f: | |
for chunk in response.iter_content(chunk_size): | |
if progress: | |
pbar.update(len(chunk)) | |
f.write(chunk) | |
os.rename(tmp_path, local_path) | |
if progress: | |
pbar.close() | |
return local_path | |
",point_e\models\download.py | |
load_checkpoint,,"def load_checkpoint(checkpoint_name: str, device: torch.device, progress: | |
bool=True, cache_dir: Optional[str]=None, chunk_size: int=4096) ->Dict[ | |
str, torch.Tensor]: | |
if checkpoint_name not in MODEL_PATHS: | |
raise ValueError( | |
f'Unknown checkpoint name {checkpoint_name}. Known names are: {MODEL_PATHS.keys()}.' | |
) | |
path = fetch_file_cached(MODEL_PATHS[checkpoint_name], progress= | |
progress, cache_dir=cache_dir, chunk_size=chunk_size) | |
return torch.load(path, map_location=device) | |
",point_e\models\download.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_data: int, | |
width: int, heads: int, init_scale: float, data_width: Optional[int]=None): | |
super().__init__() | |
self.n_data = n_data | |
self.width = width | |
self.heads = heads | |
self.data_width = width if data_width is None else data_width | |
self.c_q = nn.Linear(width, width, device=device, dtype=dtype) | |
self.c_kv = nn.Linear(self.data_width, width * 2, device=device, dtype= | |
dtype) | |
self.c_proj = nn.Linear(width, width, device=device, dtype=dtype) | |
self.attention = QKVMultiheadCrossAttention(device=device, dtype=dtype, | |
heads=heads, n_data=n_data) | |
init_linear(self.c_q, init_scale) | |
init_linear(self.c_kv, init_scale) | |
init_linear(self.c_proj, init_scale) | |
",point_e\models\perceiver.py | |
forward,,"def forward(self, x, data): | |
x = self.c_q(x) | |
data = self.c_kv(data) | |
x = checkpoint(self.attention, (x, data), (), True) | |
x = self.c_proj(x) | |
return x | |
",point_e\models\perceiver.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, heads: int, | |
n_data: int): | |
super().__init__() | |
self.device = device | |
self.dtype = dtype | |
self.heads = heads | |
self.n_data = n_data | |
",point_e\models\perceiver.py | |
forward,,"def forward(self, q, kv): | |
_, n_ctx, _ = q.shape | |
bs, n_data, width = kv.shape | |
attn_ch = width // self.heads // 2 | |
scale = 1 / math.sqrt(math.sqrt(attn_ch)) | |
q = q.view(bs, n_ctx, self.heads, -1) | |
kv = kv.view(bs, n_data, self.heads, -1) | |
k, v = torch.split(kv, attn_ch, dim=-1) | |
weight = torch.einsum('bthc,bshc->bhts', q * scale, k * scale) | |
wdtype = weight.dtype | |
weight = torch.softmax(weight.float(), dim=-1).type(wdtype) | |
return torch.einsum('bhts,bshc->bthc', weight, v).reshape(bs, n_ctx, -1) | |
",point_e\models\perceiver.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_data: int, | |
width: int, heads: int, data_width: Optional[int]=None, init_scale: | |
float=1.0): | |
super().__init__() | |
if data_width is None: | |
data_width = width | |
self.attn = MultiheadCrossAttention(device=device, dtype=dtype, n_data= | |
n_data, width=width, heads=heads, data_width=data_width, init_scale | |
=init_scale) | |
self.ln_1 = nn.LayerNorm(width, device=device, dtype=dtype) | |
self.ln_2 = nn.LayerNorm(data_width, device=device, dtype=dtype) | |
self.mlp = MLP(device=device, dtype=dtype, width=width, init_scale= | |
init_scale) | |
self.ln_3 = nn.LayerNorm(width, device=device, dtype=dtype) | |
",point_e\models\perceiver.py | |
forward,,"def forward(self, x: torch.Tensor, data: torch.Tensor): | |
x = x + self.attn(self.ln_1(x), self.ln_2(data)) | |
x = x + self.mlp(self.ln_3(x)) | |
return x | |
",point_e\models\perceiver.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_data: int, | |
width: int, layers: int, heads: int, init_scale: float=0.25, data_width: | |
Optional[int]=None): | |
super().__init__() | |
self.width = width | |
self.layers = layers | |
init_scale = init_scale * math.sqrt(1.0 / width) | |
self.resblocks = nn.ModuleList([ResidualCrossAttentionBlock(device= | |
device, dtype=dtype, n_data=n_data, width=width, heads=heads, | |
init_scale=init_scale, data_width=data_width) for _ in range(layers)]) | |
",point_e\models\perceiver.py | |
forward,,"def forward(self, x: torch.Tensor, data: torch.Tensor): | |
for block in self.resblocks: | |
x = block(x, data) | |
return x | |
",point_e\models\perceiver.py | |
_image_to_pil,,"def _image_to_pil(obj: Optional[ImageType]) ->Image.Image: | |
if obj is None: | |
return Image.fromarray(np.zeros([64, 64, 3], dtype=np.uint8)) | |
if isinstance(obj, np.ndarray): | |
return Image.fromarray(obj.astype(np.uint8)) | |
elif isinstance(obj, torch.Tensor): | |
return Image.fromarray(obj.detach().cpu().numpy().astype(np.uint8)) | |
else: | |
return obj | |
",point_e\models\pretrained_clip.py | |
__init__,,"def __init__(self, device: torch.device, dtype: Optional[torch.dtype]=torch | |
.float32, ensure_used_params: bool=True, clip_name: str='ViT-L/14', | |
cache_dir: Optional[str]=None): | |
super().__init__() | |
assert clip_name in ['ViT-L/14', 'ViT-B/32'] | |
self.device = device | |
self.ensure_used_params = ensure_used_params | |
import clip | |
self.clip_model, self.preprocess = clip.load(clip_name, device=device, | |
download_root=cache_dir or default_cache_dir()) | |
self.clip_name = clip_name | |
if dtype is not None: | |
self.clip_model.to(dtype) | |
self._tokenize = clip.tokenize | |
",point_e\models\pretrained_clip.py | |
feature_dim,,"@property | |
def feature_dim(self) ->int: | |
if self.clip_name == 'ViT-L/14': | |
return 768 | |
else: | |
return 512 | |
",point_e\models\pretrained_clip.py | |
grid_size,,"@property | |
def grid_size(self) ->int: | |
if self.clip_name == 'ViT-L/14': | |
return 16 | |
else: | |
return 7 | |
",point_e\models\pretrained_clip.py | |
grid_feature_dim,,"@property | |
def grid_feature_dim(self) ->int: | |
if self.clip_name == 'ViT-L/14': | |
return 1024 | |
else: | |
return 768 | |
",point_e\models\pretrained_clip.py | |
forward,"Generate a batch of embeddings from a mixture of images, texts, | |
precomputed embeddings, and possibly empty values. | |
For each batch element, at most one of images, texts, and embeddings | |
should have a non-None value. Embeddings from multiple modalities | |
cannot be mixed for a single batch element. If no modality is provided, | |
a zero embedding will be used for the batch element.","def forward(self, batch_size: int, images: Optional[Iterable[Optional[ | |
ImageType]]]=None, texts: Optional[Iterable[Optional[str]]]=None, | |
embeddings: Optional[Iterable[Optional[torch.Tensor]]]=None | |
) ->torch.Tensor: | |
"""""""""""" | |
image_seq = [None] * batch_size if images is None else list(images) | |
text_seq = [None] * batch_size if texts is None else list(texts) | |
embedding_seq = [None] * batch_size if embeddings is None else list( | |
embeddings) | |
assert len(image_seq | |
) == batch_size, 'number of images should match batch size' | |
assert len(text_seq | |
) == batch_size, 'number of texts should match batch size' | |
assert len(embedding_seq | |
) == batch_size, 'number of embeddings should match batch size' | |
if self.ensure_used_params: | |
return self._static_multimodal_embed(images=image_seq, texts= | |
text_seq, embeddings=embedding_seq) | |
result = torch.zeros((batch_size, self.feature_dim), device=self.device) | |
index_images = [] | |
index_texts = [] | |
for i, (image, text, emb) in enumerate(zip(image_seq, text_seq, | |
embedding_seq)): | |
assert sum([int(image is not None), int(text is not None), int(emb | |
is not None)] | |
) < 2, 'only one modality may be non-None per batch element' | |
if image is not None: | |
index_images.append((i, image)) | |
elif text is not None: | |
index_texts.append((i, text)) | |
elif emb is not None: | |
result[i] = emb.to(result) | |
if len(index_images): | |
embs = self.embed_images(img for _, img in index_images) | |
for (i, _), emb in zip(index_images, embs): | |
result[i] = emb.to(result) | |
if len(index_texts): | |
embs = self.embed_text(text for _, text in index_texts) | |
for (i, _), emb in zip(index_texts, embs): | |
result[i] = emb.to(result) | |
return result | |
",point_e\models\pretrained_clip.py | |
_static_multimodal_embed,"Like forward(), but always runs all encoders to ensure that | |
the forward graph looks the same on every rank.","def _static_multimodal_embed(self, images: List[Optional[ImageType]]=None, | |
texts: List[Optional[str]]=None, embeddings: List[Optional[torch.Tensor | |
]]=None) ->torch.Tensor: | |
"""""""""""" | |
image_emb = self.embed_images(images) | |
text_emb = self.embed_text(t if t else '' for t in texts) | |
joined_embs = torch.stack([(emb.to(device=self.device, dtype=torch. | |
float32) if emb is not None else torch.zeros(self.feature_dim, | |
device=self.device)) for emb in embeddings], dim=0) | |
image_flag = torch.tensor([(x is not None) for x in images], device= | |
self.device)[:, None].expand_as(image_emb) | |
text_flag = torch.tensor([(x is not None) for x in texts], device=self. | |
device)[:, None].expand_as(image_emb) | |
emb_flag = torch.tensor([(x is not None) for x in embeddings], device= | |
self.device)[:, None].expand_as(image_emb) | |
return image_flag.float() * image_emb + text_flag.float( | |
) * text_emb + emb_flag.float( | |
) * joined_embs + self.clip_model.logit_scale * 0 | |
",point_e\models\pretrained_clip.py | |
embed_images,":param xs: N images, stored as numpy arrays, tensors, or PIL images. | |
:return: an [N x D] tensor of features.","def embed_images(self, xs: Iterable[Optional[ImageType]]) ->torch.Tensor: | |
"""""""""""" | |
clip_inputs = self.images_to_tensor(xs) | |
results = self.clip_model.encode_image(clip_inputs).float() | |
return results / torch.linalg.norm(results, dim=-1, keepdim=True) | |
",point_e\models\pretrained_clip.py | |
embed_text,Embed text prompts as an [N x D] tensor.,"def embed_text(self, prompts: Iterable[str]) ->torch.Tensor: | |
"""""""""""" | |
enc = self.clip_model.encode_text(self._tokenize(list(prompts), | |
truncate=True).to(self.device)).float() | |
return enc / torch.linalg.norm(enc, dim=-1, keepdim=True) | |
",point_e\models\pretrained_clip.py | |
embed_images_grid,"Embed images into latent grids. | |
:param xs: an iterable of images to embed. | |
:return: a tensor of shape [N x C x L], where L = self.grid_size**2.","def embed_images_grid(self, xs: Iterable[Optional[ImageType]]) ->torch.Tensor: | |
"""""""""""" | |
if self.ensure_used_params: | |
extra_value = 0.0 | |
for p in self.parameters(): | |
extra_value = extra_value + p.mean() * 0.0 | |
else: | |
extra_value = 0.0 | |
x = self.images_to_tensor(xs).to(self.clip_model.dtype) | |
vt = self.clip_model.visual | |
x = vt.conv1(x) | |
x = x.reshape(x.shape[0], x.shape[1], -1) | |
x = x.permute(0, 2, 1) | |
x = torch.cat([vt.class_embedding.to(x.dtype) + torch.zeros(x.shape[0], | |
1, x.shape[-1], dtype=x.dtype, device=x.device), x], dim=1) | |
x = x + vt.positional_embedding.to(x.dtype) | |
x = vt.ln_pre(x) | |
x = x.permute(1, 0, 2) | |
x = vt.transformer(x) | |
x = x.permute(1, 2, 0) | |
return x[..., 1:].contiguous().float() + extra_value | |
",point_e\models\pretrained_clip.py | |
images_to_tensor,,"def images_to_tensor(self, xs: Iterable[Optional[ImageType]]) ->torch.Tensor: | |
return torch.stack([self.preprocess(_image_to_pil(x)) for x in xs], dim=0 | |
).to(self.device) | |
",point_e\models\pretrained_clip.py | |
__init__,,"def __init__(self, device: torch.device, **kwargs): | |
self.model = ImageCLIP(device, dtype=None, ensure_used_params=False, ** | |
kwargs) | |
for parameter in self.model.parameters(): | |
parameter.requires_grad_(False) | |
",point_e\models\pretrained_clip.py | |
feature_dim,,"@property | |
def feature_dim(self) ->int: | |
return self.model.feature_dim | |
",point_e\models\pretrained_clip.py | |
grid_size,,"@property | |
def grid_size(self) ->int: | |
return self.model.grid_size | |
",point_e\models\pretrained_clip.py | |
grid_feature_dim,,"@property | |
def grid_feature_dim(self) ->int: | |
return self.model.grid_feature_dim | |
",point_e\models\pretrained_clip.py | |
__call__,,"def __call__(self, batch_size: int, images: Optional[Iterable[Optional[ | |
ImageType]]]=None, texts: Optional[Iterable[Optional[str]]]=None, | |
embeddings: Optional[Iterable[Optional[torch.Tensor]]]=None | |
) ->torch.Tensor: | |
return self.model(batch_size=batch_size, images=images, texts=texts, | |
embeddings=embeddings) | |
",point_e\models\pretrained_clip.py | |
embed_images,,"def embed_images(self, xs: Iterable[Optional[ImageType]]) ->torch.Tensor: | |
with torch.no_grad(): | |
return self.model.embed_images(xs) | |
",point_e\models\pretrained_clip.py | |
embed_text,,"def embed_text(self, prompts: Iterable[str]) ->torch.Tensor: | |
with torch.no_grad(): | |
return self.model.embed_text(prompts) | |
",point_e\models\pretrained_clip.py | |
embed_images_grid,,"def embed_images_grid(self, xs: Iterable[Optional[ImageType]]) ->torch.Tensor: | |
with torch.no_grad(): | |
return self.model.embed_images_grid(xs) | |
",point_e\models\pretrained_clip.py | |
device,Get the device that should be used for input tensors.,"@property | |
@abstractmethod | |
def device(self) ->torch.device: | |
"""""""""""" | |
",point_e\models\sdf.py | |
default_batch_size,"Get a reasonable default number of query points for the model. | |
In some cases, this might be the only supported size.","@property | |
@abstractmethod | |
def default_batch_size(self) ->int: | |
"""""""""""" | |
",point_e\models\sdf.py | |
encode_point_clouds,"Encode a batch of point clouds to cache part of the SDF calculation | |
done by forward(). | |
:param point_clouds: a batch of [batch x 3 x N] points. | |
:return: a state representing the encoded point cloud batch.","@abstractmethod | |
def encode_point_clouds(self, point_clouds: torch.Tensor) ->Dict[str, torch | |
.Tensor]: | |
"""""""""""" | |
",point_e\models\sdf.py | |
forward,"Predict the SDF at the coordinates x, given a batch of point clouds. | |
Either point_clouds or encoded should be passed. Only exactly one of | |
these arguments should be None. | |
:param x: a [batch x 3 x N'] tensor of query points. | |
:param point_clouds: a [batch x 3 x N] batch of point clouds. | |
:param encoded: the result of calling encode_point_clouds(). | |
:return: a [batch x N'] tensor of SDF predictions.","def forward(self, x: torch.Tensor, point_clouds: Optional[torch.Tensor]= | |
None, encoded: Optional[Dict[str, torch.Tensor]]=None) ->torch.Tensor: | |
"""""""""""" | |
assert point_clouds is not None or encoded is not None | |
assert point_clouds is None or encoded is None | |
if point_clouds is not None: | |
encoded = self.encode_point_clouds(point_clouds) | |
return self.predict_sdf(x, encoded) | |
",point_e\models\sdf.py | |
predict_sdf,"Predict the SDF at the query points given the encoded point clouds. | |
Each query point should be treated independently, only conditioning on | |
the point clouds themselves.","@abstractmethod | |
def predict_sdf(self, x: torch.Tensor, encoded: Optional[Dict[str, torch. | |
Tensor]]) ->torch.Tensor: | |
"""""""""""" | |
",point_e\models\sdf.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_ctx: int= | |
4096, width: int=512, encoder_layers: int=12, encoder_heads: int=8, | |
decoder_layers: int=4, decoder_heads: int=8, init_scale: float=0.25): | |
super().__init__() | |
self._device = device | |
self.n_ctx = n_ctx | |
self.encoder_input_proj = nn.Linear(3, width, device=device, dtype=dtype) | |
self.encoder = Transformer(device=device, dtype=dtype, n_ctx=n_ctx, | |
width=width, layers=encoder_layers, heads=encoder_heads, init_scale | |
=init_scale) | |
self.decoder_input_proj = nn.Linear(3, width, device=device, dtype=dtype) | |
self.decoder = SimplePerceiver(device=device, dtype=dtype, n_data=n_ctx, | |
width=width, layers=decoder_layers, heads=decoder_heads, init_scale | |
=init_scale) | |
self.ln_post = nn.LayerNorm(width, device=device, dtype=dtype) | |
self.output_proj = nn.Linear(width, 1, device=device, dtype=dtype) | |
",point_e\models\sdf.py | |
device,,"@property | |
def device(self) ->torch.device: | |
return self._device | |
",point_e\models\sdf.py | |
default_batch_size,,"@property | |
def default_batch_size(self) ->int: | |
return self.n_query | |
",point_e\models\sdf.py | |
encode_point_clouds,,"def encode_point_clouds(self, point_clouds: torch.Tensor) ->Dict[str, torch | |
.Tensor]: | |
h = self.encoder_input_proj(point_clouds.permute(0, 2, 1)) | |
h = self.encoder(h) | |
return dict(latents=h) | |
",point_e\models\sdf.py | |
predict_sdf,,"def predict_sdf(self, x: torch.Tensor, encoded: Optional[Dict[str, torch. | |
Tensor]]) ->torch.Tensor: | |
data = encoded['latents'] | |
x = self.decoder_input_proj(x.permute(0, 2, 1)) | |
x = self.decoder(x, data) | |
x = self.ln_post(x) | |
x = self.output_proj(x) | |
return x[..., 0] | |
",point_e\models\sdf.py | |
init_linear,,"def init_linear(l, stddev): | |
nn.init.normal_(l.weight, std=stddev) | |
if l.bias is not None: | |
nn.init.constant_(l.bias, 0.0) | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_ctx: int, | |
width: int, heads: int, init_scale: float): | |
super().__init__() | |
self.n_ctx = n_ctx | |
self.width = width | |
self.heads = heads | |
self.c_qkv = nn.Linear(width, width * 3, device=device, dtype=dtype) | |
self.c_proj = nn.Linear(width, width, device=device, dtype=dtype) | |
self.attention = QKVMultiheadAttention(device=device, dtype=dtype, | |
heads=heads, n_ctx=n_ctx) | |
init_linear(self.c_qkv, init_scale) | |
init_linear(self.c_proj, init_scale) | |
",point_e\models\transformer.py | |
forward,,"def forward(self, x): | |
x = self.c_qkv(x) | |
x = checkpoint(self.attention, (x,), (), True) | |
x = self.c_proj(x) | |
return x | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, width: int, | |
init_scale: float): | |
super().__init__() | |
self.width = width | |
self.c_fc = nn.Linear(width, width * 4, device=device, dtype=dtype) | |
self.c_proj = nn.Linear(width * 4, width, device=device, dtype=dtype) | |
self.gelu = nn.GELU() | |
init_linear(self.c_fc, init_scale) | |
init_linear(self.c_proj, init_scale) | |
",point_e\models\transformer.py | |
forward,,"def forward(self, x): | |
return self.c_proj(self.gelu(self.c_fc(x))) | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, heads: int, | |
n_ctx: int): | |
super().__init__() | |
self.device = device | |
self.dtype = dtype | |
self.heads = heads | |
self.n_ctx = n_ctx | |
",point_e\models\transformer.py | |
forward,,"def forward(self, qkv): | |
bs, n_ctx, width = qkv.shape | |
attn_ch = width // self.heads // 3 | |
scale = 1 / math.sqrt(math.sqrt(attn_ch)) | |
qkv = qkv.view(bs, n_ctx, self.heads, -1) | |
q, k, v = torch.split(qkv, attn_ch, dim=-1) | |
weight = torch.einsum('bthc,bshc->bhts', q * scale, k * scale) | |
wdtype = weight.dtype | |
weight = torch.softmax(weight.float(), dim=-1).type(wdtype) | |
return torch.einsum('bhts,bshc->bthc', weight, v).reshape(bs, n_ctx, -1) | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_ctx: int, | |
width: int, heads: int, init_scale: float=1.0): | |
super().__init__() | |
self.attn = MultiheadAttention(device=device, dtype=dtype, n_ctx=n_ctx, | |
width=width, heads=heads, init_scale=init_scale) | |
self.ln_1 = nn.LayerNorm(width, device=device, dtype=dtype) | |
self.mlp = MLP(device=device, dtype=dtype, width=width, init_scale= | |
init_scale) | |
self.ln_2 = nn.LayerNorm(width, device=device, dtype=dtype) | |
",point_e\models\transformer.py | |
forward,,"def forward(self, x: torch.Tensor): | |
x = x + self.attn(self.ln_1(x)) | |
x = x + self.mlp(self.ln_2(x)) | |
return x | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_ctx: int, | |
width: int, layers: int, heads: int, init_scale: float=0.25): | |
super().__init__() | |
self.n_ctx = n_ctx | |
self.width = width | |
self.layers = layers | |
init_scale = init_scale * math.sqrt(1.0 / width) | |
self.resblocks = nn.ModuleList([ResidualAttentionBlock(device=device, | |
dtype=dtype, n_ctx=n_ctx, width=width, heads=heads, init_scale= | |
init_scale) for _ in range(layers)]) | |
",point_e\models\transformer.py | |
forward,,"def forward(self, x: torch.Tensor): | |
for block in self.resblocks: | |
x = block(x) | |
return x | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, | |
input_channels: int=3, output_channels: int=3, n_ctx: int=1024, width: | |
int=512, layers: int=12, heads: int=8, init_scale: float=0.25, | |
time_token_cond: bool=False): | |
super().__init__() | |
self.input_channels = input_channels | |
self.output_channels = output_channels | |
self.n_ctx = n_ctx | |
self.time_token_cond = time_token_cond | |
self.time_embed = MLP(device=device, dtype=dtype, width=width, | |
init_scale=init_scale * math.sqrt(1.0 / width)) | |
self.ln_pre = nn.LayerNorm(width, device=device, dtype=dtype) | |
self.backbone = Transformer(device=device, dtype=dtype, n_ctx=n_ctx + | |
int(time_token_cond), width=width, layers=layers, heads=heads, | |
init_scale=init_scale) | |
self.ln_post = nn.LayerNorm(width, device=device, dtype=dtype) | |
self.input_proj = nn.Linear(input_channels, width, device=device, dtype | |
=dtype) | |
self.output_proj = nn.Linear(width, output_channels, device=device, | |
dtype=dtype) | |
with torch.no_grad(): | |
self.output_proj.weight.zero_() | |
self.output_proj.bias.zero_() | |
",point_e\models\transformer.py | |
forward,":param x: an [N x C x T] tensor. | |
:param t: an [N] tensor. | |
:return: an [N x C' x T] tensor.","def forward(self, x: torch.Tensor, t: torch.Tensor): | |
"""""""""""" | |
assert x.shape[-1] == self.n_ctx | |
t_embed = self.time_embed(timestep_embedding(t, self.backbone.width)) | |
return self._forward_with_cond(x, [(t_embed, self.time_token_cond)]) | |
",point_e\models\transformer.py | |
_forward_with_cond,,"def _forward_with_cond(self, x: torch.Tensor, cond_as_token: List[Tuple[ | |
torch.Tensor, bool]]) ->torch.Tensor: | |
h = self.input_proj(x.permute(0, 2, 1)) | |
for emb, as_token in cond_as_token: | |
if not as_token: | |
h = h + emb[:, None] | |
extra_tokens = [(emb[:, None] if len(emb.shape) == 2 else emb) for emb, | |
as_token in cond_as_token if as_token] | |
if len(extra_tokens): | |
h = torch.cat(extra_tokens + [h], dim=1) | |
h = self.ln_pre(h) | |
h = self.backbone(h) | |
h = self.ln_post(h) | |
if len(extra_tokens): | |
h = h[:, sum(h.shape[1] for h in extra_tokens):] | |
h = self.output_proj(h) | |
return h.permute(0, 2, 1) | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_ctx: int= | |
1024, token_cond: bool=False, cond_drop_prob: float=0.0, frozen_clip: | |
bool=True, cache_dir: Optional[str]=None, **kwargs): | |
super().__init__(device=device, dtype=dtype, n_ctx=n_ctx + int( | |
token_cond), **kwargs) | |
self.n_ctx = n_ctx | |
self.token_cond = token_cond | |
self.clip = (FrozenImageCLIP if frozen_clip else ImageCLIP)(device, | |
cache_dir=cache_dir) | |
self.clip_embed = nn.Linear(self.clip.feature_dim, self.backbone.width, | |
device=device, dtype=dtype) | |
self.cond_drop_prob = cond_drop_prob | |
",point_e\models\transformer.py | |
cached_model_kwargs,,"def cached_model_kwargs(self, batch_size: int, model_kwargs: Dict[str, Any] | |
) ->Dict[str, Any]: | |
with torch.no_grad(): | |
return dict(embeddings=self.clip(batch_size, **model_kwargs)) | |
",point_e\models\transformer.py | |
forward,":param x: an [N x C x T] tensor. | |
:param t: an [N] tensor. | |
:param images: a batch of images to condition on. | |
:param texts: a batch of texts to condition on. | |
:param embeddings: a batch of CLIP embeddings to condition on. | |
:return: an [N x C' x T] tensor.","def forward(self, x: torch.Tensor, t: torch.Tensor, images: Optional[ | |
Iterable[Optional[ImageType]]]=None, texts: Optional[Iterable[Optional[ | |
str]]]=None, embeddings: Optional[Iterable[Optional[torch.Tensor]]]=None): | |
"""""""""""" | |
assert x.shape[-1] == self.n_ctx | |
t_embed = self.time_embed(timestep_embedding(t, self.backbone.width)) | |
clip_out = self.clip(batch_size=len(x), images=images, texts=texts, | |
embeddings=embeddings) | |
assert len(clip_out.shape) == 2 and clip_out.shape[0] == x.shape[0] | |
if self.training: | |
mask = torch.rand(size=[len(x)]) >= self.cond_drop_prob | |
clip_out = clip_out * mask[:, None].to(clip_out) | |
clip_out = math.sqrt(clip_out.shape[1]) * clip_out | |
clip_embed = self.clip_embed(clip_out) | |
cond = [(clip_embed, self.token_cond), (t_embed, self.time_token_cond)] | |
return self._forward_with_cond(x, cond) | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_ctx: int= | |
1024, cond_drop_prob: float=0.0, frozen_clip: bool=True, cache_dir: | |
Optional[str]=None, **kwargs): | |
clip = (FrozenImageCLIP if frozen_clip else ImageCLIP)(device, | |
cache_dir=cache_dir) | |
super().__init__(device=device, dtype=dtype, n_ctx=n_ctx + clip. | |
grid_size ** 2, **kwargs) | |
self.n_ctx = n_ctx | |
self.clip = clip | |
self.clip_embed = nn.Sequential(nn.LayerNorm(normalized_shape=(self. | |
clip.grid_feature_dim,), device=device, dtype=dtype), nn.Linear( | |
self.clip.grid_feature_dim, self.backbone.width, device=device, | |
dtype=dtype)) | |
self.cond_drop_prob = cond_drop_prob | |
",point_e\models\transformer.py | |
cached_model_kwargs,,"def cached_model_kwargs(self, batch_size: int, model_kwargs: Dict[str, Any] | |
) ->Dict[str, Any]: | |
_ = batch_size | |
with torch.no_grad(): | |
return dict(embeddings=self.clip.embed_images_grid(model_kwargs[ | |
'images'])) | |
",point_e\models\transformer.py | |
forward,":param x: an [N x C x T] tensor. | |
:param t: an [N] tensor. | |
:param images: a batch of images to condition on. | |
:param embeddings: a batch of CLIP latent grids to condition on. | |
:return: an [N x C' x T] tensor.","def forward(self, x: torch.Tensor, t: torch.Tensor, images: Optional[ | |
Iterable[ImageType]]=None, embeddings: Optional[Iterable[torch.Tensor]] | |
=None): | |
"""""""""""" | |
assert images is not None or embeddings is not None, 'must specify images or embeddings' | |
assert images is None or embeddings is None, 'cannot specify both images and embeddings' | |
assert x.shape[-1] == self.n_ctx | |
t_embed = self.time_embed(timestep_embedding(t, self.backbone.width)) | |
if images is not None: | |
clip_out = self.clip.embed_images_grid(images) | |
else: | |
clip_out = embeddings | |
if self.training: | |
mask = torch.rand(size=[len(x)]) >= self.cond_drop_prob | |
clip_out = clip_out * mask[:, None, None].to(clip_out) | |
clip_out = clip_out.permute(0, 2, 1) | |
clip_embed = self.clip_embed(clip_out) | |
cond = [(t_embed, self.time_token_cond), (clip_embed, True)] | |
return self._forward_with_cond(x, cond) | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, | |
cond_input_channels: Optional[int]=None, cond_ctx: int=1024, n_ctx: int | |
=4096 - 1024, channel_scales: Optional[Sequence[float]]=None, | |
channel_biases: Optional[Sequence[float]]=None, **kwargs): | |
super().__init__(device=device, dtype=dtype, n_ctx=n_ctx + cond_ctx, ** | |
kwargs) | |
self.n_ctx = n_ctx | |
self.cond_input_channels = cond_input_channels or self.input_channels | |
self.cond_point_proj = nn.Linear(self.cond_input_channels, self. | |
backbone.width, device=device, dtype=dtype) | |
self.register_buffer('channel_scales', torch.tensor(channel_scales, | |
dtype=dtype, device=device) if channel_scales is not None else None) | |
self.register_buffer('channel_biases', torch.tensor(channel_biases, | |
dtype=dtype, device=device) if channel_biases is not None else None) | |
",point_e\models\transformer.py | |
forward,":param x: an [N x C1 x T] tensor. | |
:param t: an [N] tensor. | |
:param low_res: an [N x C2 x T'] tensor of conditioning points. | |
:return: an [N x C3 x T] tensor.","def forward(self, x: torch.Tensor, t: torch.Tensor, *, low_res: torch.Tensor): | |
"""""""""""" | |
assert x.shape[-1] == self.n_ctx | |
t_embed = self.time_embed(timestep_embedding(t, self.backbone.width)) | |
low_res_embed = self._embed_low_res(low_res) | |
cond = [(t_embed, self.time_token_cond), (low_res_embed, True)] | |
return self._forward_with_cond(x, cond) | |
",point_e\models\transformer.py | |
_embed_low_res,,"def _embed_low_res(self, x: torch.Tensor) ->torch.Tensor: | |
if self.channel_scales is not None: | |
x = x * self.channel_scales[None, :, None] | |
if self.channel_biases is not None: | |
x = x + self.channel_biases[None, :, None] | |
return self.cond_point_proj(x.permute(0, 2, 1)) | |
",point_e\models\transformer.py | |
__init__,,"def __init__(self, *, device: torch.device, dtype: torch.dtype, n_ctx: int= | |
4096 - 1024, cond_drop_prob: float=0.0, frozen_clip: bool=True, | |
cache_dir: Optional[str]=None, **kwargs): | |
clip = (FrozenImageCLIP if frozen_clip else ImageCLIP)(device, | |
cache_dir=cache_dir) | |
super().__init__(device=device, dtype=dtype, n_ctx=n_ctx + clip. | |
grid_size ** 2, **kwargs) | |
self.n_ctx = n_ctx | |
self.clip = clip | |
self.clip_embed = nn.Sequential(nn.LayerNorm(normalized_shape=(self. | |
clip.grid_feature_dim,), device=device, dtype=dtype), nn.Linear( | |
self.clip.grid_feature_dim, self.backbone.width, device=device, | |
dtype=dtype)) | |
self.cond_drop_prob = cond_drop_prob | |
",point_e\models\transformer.py | |
cached_model_kwargs,,"def cached_model_kwargs(self, batch_size: int, model_kwargs: Dict[str, Any] | |
) ->Dict[str, Any]: | |
if 'images' not in model_kwargs: | |
zero_emb = torch.zeros([batch_size, self.clip.grid_feature_dim, | |
self.clip.grid_size ** 2], device=next(self.parameters()).device) | |
return dict(embeddings=zero_emb, low_res=model_kwargs['low_res']) | |
with torch.no_grad(): | |
return dict(embeddings=self.clip.embed_images_grid(model_kwargs[ | |
'images']), low_res=model_kwargs['low_res']) | |
",point_e\models\transformer.py | |
forward,":param x: an [N x C1 x T] tensor. | |
:param t: an [N] tensor. | |
:param low_res: an [N x C2 x T'] tensor of conditioning points. | |
:param images: a batch of images to condition on. | |
:param embeddings: a batch of CLIP latent grids to condition on. | |
:return: an [N x C3 x T] tensor.","def forward(self, x: torch.Tensor, t: torch.Tensor, *, low_res: torch. | |
Tensor, images: Optional[Iterable[ImageType]]=None, embeddings: | |
Optional[Iterable[torch.Tensor]]=None): | |
"""""""""""" | |
assert x.shape[-1] == self.n_ctx | |
t_embed = self.time_embed(timestep_embedding(t, self.backbone.width)) | |
low_res_embed = self._embed_low_res(low_res) | |
if images is not None: | |
clip_out = self.clip.embed_images_grid(images) | |
elif embeddings is not None: | |
clip_out = embeddings | |
else: | |
clip_out = torch.zeros([len(x), self.clip.grid_feature_dim, self. | |
clip.grid_size ** 2], dtype=x.dtype, device=x.device) | |
if self.training: | |
mask = torch.rand(size=[len(x)]) >= self.cond_drop_prob | |
clip_out = clip_out * mask[:, None, None].to(clip_out) | |
clip_out = clip_out.permute(0, 2, 1) | |
clip_embed = self.clip_embed(clip_out) | |
cond = [(t_embed, self.time_token_cond), (clip_embed, True), ( | |
low_res_embed, True)] | |
return self._forward_with_cond(x, cond) | |
",point_e\models\transformer.py | |
timestep_embedding,"Create sinusoidal timestep embeddings. | |
:param timesteps: a 1-D Tensor of N indices, one per batch element. | |
These may be fractional. | |
:param dim: the dimension of the output. | |
:param max_period: controls the minimum frequency of the embeddings. | |
:return: an [N x dim] Tensor of positional embeddings.","def timestep_embedding(timesteps, dim, max_period=10000): | |
"""""""""""" | |
half = dim // 2 | |
freqs = torch.exp(-math.log(max_period) * torch.arange(start=0, end= | |
half, dtype=torch.float32) / half).to(device=timesteps.device) | |
args = timesteps[:, None].to(timesteps.dtype) * freqs[None] | |
embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) | |
if dim % 2: | |
embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1] | |
)], dim=-1) | |
return embedding | |
",point_e\models\util.py | |
load,Load the mesh from a .npz file.,"@classmethod | |
def load(cls, f: Union[str, BinaryIO]) ->'TriMesh': | |
"""""""""""" | |
if isinstance(f, str): | |
with open(f, 'rb') as reader: | |
return cls.load(reader) | |
else: | |
obj = np.load(f) | |
keys = list(obj.keys()) | |
verts = obj['verts'] | |
faces = obj['faces'] | |
normals = obj['normals'] if 'normals' in keys else None | |
vertex_channels = {} | |
face_channels = {} | |
for key in keys: | |
if key.startswith('v_'): | |
vertex_channels[key[2:]] = obj[key] | |
elif key.startswith('f_'): | |
face_channels[key[2:]] = obj[key] | |
return cls(verts=verts, faces=faces, normals=normals, | |
vertex_channels=vertex_channels, face_channels=face_channels) | |
",point_e\util\mesh.py | |
save,Save the mesh to a .npz file.,"def save(self, f: Union[str, BinaryIO]): | |
"""""""""""" | |
if isinstance(f, str): | |
with open(f, 'wb') as writer: | |
self.save(writer) | |
else: | |
obj_dict = dict(verts=self.verts, faces=self.faces) | |
if self.normals is not None: | |
obj_dict['normals'] = self.normals | |
for k, v in self.vertex_channels.items(): | |
obj_dict[f'v_{k}'] = v | |
for k, v in self.face_channels.items(): | |
obj_dict[f'f_{k}'] = v | |
np.savez(f, **obj_dict) | |
",point_e\util\mesh.py | |
has_vertex_colors,,"def has_vertex_colors(self) ->bool: | |
return self.vertex_channels is not None and all(x in self. | |
vertex_channels for x in 'RGB') | |
",point_e\util\mesh.py | |
write_ply,,"def write_ply(self, raw_f: BinaryIO): | |
write_ply(raw_f, coords=self.verts, rgb=np.stack([self.vertex_channels[ | |
x] for x in 'RGB'], axis=1) if self.has_vertex_colors() else None, | |
faces=self.faces) | |
",point_e\util\mesh.py | |
marching_cubes_mesh,"Run marching cubes on the SDF predicted from a point cloud to produce a | |
mesh representing the 3D surface. | |
:param pc: the point cloud to apply marching cubes to. | |
:param model: the model to use to predict SDF values. | |
:param grid_size: the number of samples along each axis. A total of | |
grid_size**3 function evaluations are performed. | |
:param side_length: the size of the cube containing the model, which is | |
assumed to be centered at the origin. | |
:param fill_vertex_channels: if True, use the nearest neighbor of each mesh | |
vertex in the point cloud to compute vertex | |
data (e.g. colors).","def marching_cubes_mesh(pc: PointCloud, model: PointCloudSDFModel, | |
batch_size: int=4096, grid_size: int=128, side_length: float=1.02, | |
fill_vertex_channels: bool=True, progress: bool=False) ->TriMesh: | |
"""""""""""" | |
voxel_size = side_length / (grid_size - 1) | |
min_coord = -side_length / 2 | |
def int_coord_to_float(int_coords: torch.Tensor) ->torch.Tensor: | |
return int_coords.float() * voxel_size + min_coord | |
with torch.no_grad(): | |
cond = model.encode_point_clouds(torch.from_numpy(pc.coords). | |
permute(1, 0).to(model.device)[None]) | |
indices = range(0, grid_size ** 3, batch_size) | |
if progress: | |
indices = tqdm(indices) | |
volume = [] | |
for i in indices: | |
indices = torch.arange(i, min(i + batch_size, grid_size ** 3), step | |
=1, dtype=torch.int64, device=model.device) | |
zs = int_coord_to_float(indices % grid_size) | |
ys = int_coord_to_float(torch.div(indices, grid_size, rounding_mode | |
='trunc') % grid_size) | |
xs = int_coord_to_float(torch.div(indices, grid_size ** 2, | |
rounding_mode='trunc')) | |
coords = torch.stack([xs, ys, zs], dim=0) | |
with torch.no_grad(): | |
volume.append(model(coords[None], encoded=cond)[0]) | |
volume_np = torch.cat(volume).view(grid_size, grid_size, grid_size).cpu( | |
).numpy() | |
if np.all(volume_np < 0) or np.all(volume_np > 0): | |
volume_np -= np.mean(volume_np) | |
verts, faces, normals, _ = skimage.measure.marching_cubes(volume= | |
volume_np, level=0, allow_degenerate=False, spacing=(voxel_size,) * 3) | |
old_f1 = faces[:, 0].copy() | |
faces[:, 0] = faces[:, 1] | |
faces[:, 1] = old_f1 | |
verts += min_coord | |
return TriMesh(verts=verts, faces=faces, normals=normals, | |
vertex_channels=None if not fill_vertex_channels else | |
_nearest_vertex_channels(pc, verts)) | |
",point_e\util\pc_to_mesh.py | |
_nearest_vertex_channels,,"def _nearest_vertex_channels(pc: PointCloud, verts: np.ndarray) ->Dict[str, | |
np.ndarray]: | |
nearest = pc.nearest_points(verts) | |
return {ch: arr[nearest] for ch, arr in pc.channels.items()} | |
",point_e\util\pc_to_mesh.py | |
plot_point_cloud,"Render a point cloud as a plot to the given image path. | |
:param pc: the PointCloud to plot. | |
:param image_path: the path to save the image, with a file extension. | |
:param color: if True, show the RGB colors from the point cloud. | |
:param grid_size: the number of random rotations to render.","def plot_point_cloud(pc: PointCloud, color: bool=True, grid_size: int=1, | |
fixed_bounds: Optional[Tuple[Tuple[float, float, float], Tuple[float, | |
float, float]]]=((-0.75, -0.75, -0.75), (0.75, 0.75, 0.75))): | |
"""""""""""" | |
fig = plt.figure(figsize=(8, 8)) | |
for i in range(grid_size): | |
for j in range(grid_size): | |
ax = fig.add_subplot(grid_size, grid_size, 1 + j + i * | |
grid_size, projection='3d') | |
color_args = {} | |
if color: | |
color_args['c'] = np.stack([pc.channels['R'], pc.channels[ | |
'G'], pc.channels['B']], axis=-1) | |
c = pc.coords | |
if grid_size > 1: | |
theta = np.pi * 2 * (i * grid_size + j) / grid_size ** 2 | |
rotation = np.array([[np.cos(theta), -np.sin(theta), 0.0], | |
[np.sin(theta), np.cos(theta), 0.0], [0.0, 0.0, 1.0]]) | |
c = c @ rotation | |
ax.scatter(c[:, 0], c[:, 1], c[:, 2], **color_args) | |
if fixed_bounds is None: | |
min_point = c.min(0) | |
max_point = c.max(0) | |
size = (max_point - min_point).max() / 2 | |
center = (min_point + max_point) / 2 | |
ax.set_xlim3d(center[0] - size, center[0] + size) | |
ax.set_ylim3d(center[1] - size, center[1] + size) | |
ax.set_zlim3d(center[2] - size, center[2] + size) | |
else: | |
ax.set_xlim3d(fixed_bounds[0][0], fixed_bounds[1][0]) | |
ax.set_ylim3d(fixed_bounds[0][1], fixed_bounds[1][1]) | |
ax.set_zlim3d(fixed_bounds[0][2], fixed_bounds[1][2]) | |
return fig | |
",point_e\util\plotting.py | |
write_ply,"Write a PLY file for a mesh or a point cloud. | |
:param coords: an [N x 3] array of floating point coordinates. | |
:param rgb: an [N x 3] array of vertex colors, in the range [0.0, 1.0]. | |
:param faces: an [N x 3] array of triangles encoded as integer indices.","def write_ply(raw_f: BinaryIO, coords: np.ndarray, rgb: Optional[np.ndarray | |
]=None, faces: Optional[np.ndarray]=None): | |
"""""""""""" | |
with buffered_writer(raw_f) as f: | |
f.write(b'ply\n') | |
f.write(b'format binary_little_endian 1.0\n') | |
f.write(bytes(f'element vertex {len(coords)}\n', 'ascii')) | |
f.write(b'property float x\n') | |
f.write(b'property float y\n') | |
f.write(b'property float z\n') | |
if rgb is not None: | |
f.write(b'property uchar red\n') | |
f.write(b'property uchar green\n') | |
f.write(b'property uchar blue\n') | |
if faces is not None: | |
f.write(bytes(f'element face {len(faces)}\n', 'ascii')) | |
f.write(b'property list uchar int vertex_index\n') | |
f.write(b'end_header\n') | |
if rgb is not None: | |
rgb = (rgb * 255.499).round().astype(int) | |
vertices = [(*coord, *rgb) for coord, rgb in zip(coords.tolist( | |
), rgb.tolist())] | |
format = struct.Struct('<3f3B') | |
for item in vertices: | |
f.write(format.pack(*item)) | |
else: | |
format = struct.Struct('<3f') | |
for vertex in coords.tolist(): | |
f.write(format.pack(*vertex)) | |
if faces is not None: | |
format = struct.Struct('<B3I') | |
for tri in faces.tolist(): | |
f.write(format.pack(len(tri), *tri)) | |
",point_e\util\ply_util.py | |
buffered_writer,,"@contextmanager | |
def buffered_writer(raw_f: BinaryIO) ->Iterator[io.BufferedIOBase]: | |
if isinstance(raw_f, io.BufferedIOBase): | |
yield raw_f | |
else: | |
f = io.BufferedWriter(raw_f) | |
yield f | |
f.flush() | |
",point_e\util\ply_util.py | |
preprocess,,"def preprocess(data, channel): | |
if channel in COLORS: | |
return np.round(data * 255.0) | |
return data | |
",point_e\util\point_cloud.py | |
load,Load the point cloud from a .npz file.,"@classmethod | |
def load(cls, f: Union[str, BinaryIO]) ->'PointCloud': | |
"""""""""""" | |
if isinstance(f, str): | |
with open(f, 'rb') as reader: | |
return cls.load(reader) | |
else: | |
obj = np.load(f) | |
keys = list(obj.keys()) | |
return PointCloud(coords=obj['coords'], channels={k: obj[k] for k in | |
keys if k != 'coords'}) | |
",point_e\util\point_cloud.py | |
save,Save the point cloud to a .npz file.,"def save(self, f: Union[str, BinaryIO]): | |
"""""""""""" | |
if isinstance(f, str): | |
with open(f, 'wb') as writer: | |
self.save(writer) | |
else: | |
np.savez(f, coords=self.coords, **self.channels) | |
",point_e\util\point_cloud.py | |
write_ply,,"def write_ply(self, raw_f: BinaryIO): | |
write_ply(raw_f, coords=self.coords, rgb=np.stack([self.channels[x] for | |
x in 'RGB'], axis=1) if all(x in self.channels for x in 'RGB') else | |
None) | |
",point_e\util\point_cloud.py | |
random_sample,"Sample a random subset of this PointCloud. | |
:param num_points: maximum number of points to sample. | |
:param subsample_kwargs: arguments to self.subsample(). | |
:return: a reduced PointCloud, or self if num_points is not less than | |
the current number of points.","def random_sample(self, num_points: int, **subsample_kwargs) ->'PointCloud': | |
"""""""""""" | |
if len(self.coords) <= num_points: | |
return self | |
indices = np.random.choice(len(self.coords), size=(num_points,), | |
replace=False) | |
return self.subsample(indices, **subsample_kwargs) | |
",point_e\util\point_cloud.py | |
farthest_point_sample,"Sample a subset of the point cloud that is evenly distributed in space. | |
First, a random point is selected. Then each successive point is chosen | |
such that it is furthest from the currently selected points. | |
The time complexity of this operation is O(NM), where N is the original | |
number of points and M is the reduced number. Therefore, performance | |
can be improved by randomly subsampling points with random_sample() | |
before running farthest_point_sample(). | |
:param num_points: maximum number of points to sample. | |
:param init_idx: if specified, the first point to sample. | |
:param subsample_kwargs: arguments to self.subsample(). | |
:return: a reduced PointCloud, or self if num_points is not less than | |
the current number of points.","def farthest_point_sample(self, num_points: int, init_idx: Optional[int]= | |
None, **subsample_kwargs) ->'PointCloud': | |
"""""""""""" | |
if len(self.coords) <= num_points: | |
return self | |
init_idx = random.randrange(len(self.coords) | |
) if init_idx is None else init_idx | |
indices = np.zeros([num_points], dtype=np.int64) | |
indices[0] = init_idx | |
sq_norms = np.sum(self.coords ** 2, axis=-1) | |
def compute_dists(idx: int): | |
return sq_norms + sq_norms[idx] - 2 * (self.coords @ self.coords[idx]) | |
cur_dists = compute_dists(init_idx) | |
for i in range(1, num_points): | |
idx = np.argmax(cur_dists) | |
indices[i] = idx | |
cur_dists = np.minimum(cur_dists, compute_dists(idx)) | |
return self.subsample(indices, **subsample_kwargs) | |
",point_e\util\point_cloud.py | |
subsample,,"def subsample(self, indices: np.ndarray, average_neighbors: bool=False | |
) ->'PointCloud': | |
if not average_neighbors: | |
return PointCloud(coords=self.coords[indices], channels={k: v[ | |
indices] for k, v in self.channels.items()}) | |
new_coords = self.coords[indices] | |
neighbor_indices = PointCloud(coords=new_coords, channels={} | |
).nearest_points(self.coords) | |
neighbor_indices[indices] = np.arange(len(indices)) | |
new_channels = {} | |
for k, v in self.channels.items(): | |
v_sum = np.zeros_like(v[:len(indices)]) | |
v_count = np.zeros_like(v[:len(indices)]) | |
np.add.at(v_sum, neighbor_indices, v) | |
np.add.at(v_count, neighbor_indices, 1) | |
new_channels[k] = v_sum / v_count | |
return PointCloud(coords=new_coords, channels=new_channels) | |
",point_e\util\point_cloud.py | |
select_channels,,"def select_channels(self, channel_names: List[str]) ->np.ndarray: | |
data = np.stack([preprocess(self.channels[name], name) for name in | |
channel_names], axis=-1) | |
return data | |
",point_e\util\point_cloud.py | |
nearest_points,"For each point in another set of points, compute the point in this | |
pointcloud which is closest. | |
:param points: an [N x 3] array of points. | |
:param batch_size: the number of neighbor distances to compute at once. | |
Smaller values save memory, while larger values may | |
make the computation faster. | |
:return: an [N] array of indices into self.coords.","def nearest_points(self, points: np.ndarray, batch_size: int=16384 | |
) ->np.ndarray: | |
"""""""""""" | |
norms = np.sum(self.coords ** 2, axis=-1) | |
all_indices = [] | |
for i in range(0, len(points), batch_size): | |
batch = points[i:i + batch_size] | |
dists = norms + np.sum(batch ** 2, axis=-1)[:, None] - 2 * (batch @ | |
self.coords.T) | |
all_indices.append(np.argmin(dists, axis=-1)) | |
return np.concatenate(all_indices, axis=0) | |
",point_e\util\point_cloud.py | |
combine,,"def combine(self, other: 'PointCloud') ->'PointCloud': | |
assert self.channels.keys() == other.channels.keys() | |
return PointCloud(coords=np.concatenate([self.coords, other.coords], | |
axis=0), channels={k: np.concatenate([v, other.channels[k]], axis=0 | |
) for k, v in self.channels.items()}) | |
",point_e\util\point_cloud.py | |