code-search / functions_data.csv
Shamima's picture
Upload 2 files
11b8e37
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