mirror of
https://github.com/wassname/denoising-diffusion-pytorch.git
synced 2026-09-10 12:01:08 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0a1bed31a | ||
|
|
82b67fc00a | ||
|
|
7c0cd05c27 | ||
|
|
6dda508ff6 | ||
|
|
9ec8d27217 | ||
|
|
4b4ebab7c3 | ||
|
|
e4a4e4acaa | ||
|
|
cd8329cdd7 | ||
|
|
aec2a26984 | ||
|
|
c78709f887 | ||
|
|
4436128a0b | ||
|
|
e46a89e2bc |
@@ -37,6 +37,9 @@ def default(val, d):
|
|||||||
return val
|
return val
|
||||||
return d() if callable(d) else d
|
return d() if callable(d) else d
|
||||||
|
|
||||||
|
def identity(t, *args, **kwargs):
|
||||||
|
return t
|
||||||
|
|
||||||
def cycle(dl):
|
def cycle(dl):
|
||||||
while True:
|
while True:
|
||||||
for data in dl:
|
for data in dl:
|
||||||
@@ -517,16 +520,19 @@ class GaussianDiffusion(nn.Module):
|
|||||||
posterior_log_variance_clipped = extract(self.posterior_log_variance_clipped, t, x_t.shape)
|
posterior_log_variance_clipped = extract(self.posterior_log_variance_clipped, t, x_t.shape)
|
||||||
return posterior_mean, posterior_variance, posterior_log_variance_clipped
|
return posterior_mean, posterior_variance, posterior_log_variance_clipped
|
||||||
|
|
||||||
def model_predictions(self, x, t, x_self_cond = None):
|
def model_predictions(self, x, t, x_self_cond = None, clip_x_start = False):
|
||||||
model_output = self.model(x, t, x_self_cond)
|
model_output = self.model(x, t, x_self_cond)
|
||||||
|
maybe_clip = partial(torch.clamp, min = -1., max = 1.) if clip_x_start else identity
|
||||||
|
|
||||||
if self.objective == 'pred_noise':
|
if self.objective == 'pred_noise':
|
||||||
pred_noise = model_output
|
pred_noise = model_output
|
||||||
x_start = self.predict_start_from_noise(x, t, model_output)
|
x_start = self.predict_start_from_noise(x, t, pred_noise)
|
||||||
|
x_start = maybe_clip(x_start)
|
||||||
|
|
||||||
elif self.objective == 'pred_x0':
|
elif self.objective == 'pred_x0':
|
||||||
pred_noise = self.predict_noise_from_start(x, t, model_output)
|
|
||||||
x_start = model_output
|
x_start = model_output
|
||||||
|
x_start = maybe_clip(x_start)
|
||||||
|
pred_noise = self.predict_noise_from_start(x, t, x_start)
|
||||||
|
|
||||||
return ModelPrediction(pred_noise, x_start)
|
return ModelPrediction(pred_noise, x_start)
|
||||||
|
|
||||||
@@ -568,31 +574,30 @@ class GaussianDiffusion(nn.Module):
|
|||||||
def ddim_sample(self, shape, clip_denoised = True):
|
def ddim_sample(self, shape, clip_denoised = True):
|
||||||
batch, device, total_timesteps, sampling_timesteps, eta, objective = shape[0], self.betas.device, self.num_timesteps, self.sampling_timesteps, self.ddim_sampling_eta, self.objective
|
batch, device, total_timesteps, sampling_timesteps, eta, objective = shape[0], self.betas.device, self.num_timesteps, self.sampling_timesteps, self.ddim_sampling_eta, self.objective
|
||||||
|
|
||||||
times = torch.linspace(0., total_timesteps, steps = sampling_timesteps + 2)[:-1]
|
times = torch.linspace(-1, total_timesteps - 1, steps=sampling_timesteps + 1) # [-1, 0, 1, 2, ..., T-1] when sampling_timesteps == total_timesteps
|
||||||
times = list(reversed(times.int().tolist()))
|
times = list(reversed(times.int().tolist()))
|
||||||
time_pairs = list(filter(lambda a: a[0] > a[1], zip(times[:-1], times[1:])))
|
time_pairs = list(zip(times[:-1], times[1:])) # [(T-1, T-2), (T-2, T-3), ..., (1, 0), (0, -1)]
|
||||||
|
|
||||||
img = torch.randn(shape, device = device)
|
img = torch.randn(shape, device = device)
|
||||||
|
|
||||||
x_start = None
|
x_start = None
|
||||||
|
|
||||||
for time, time_next in tqdm(time_pairs, desc = 'sampling loop time step'):
|
for time, time_next in tqdm(time_pairs, desc = 'sampling loop time step'):
|
||||||
|
time_cond = torch.full((batch,), time, device=device, dtype=torch.long)
|
||||||
|
self_cond = x_start if self.self_condition else None
|
||||||
|
pred_noise, x_start, *_ = self.model_predictions(img, time_cond, self_cond, clip_x_start = clip_denoised)
|
||||||
|
|
||||||
|
if time_next < 0:
|
||||||
|
img = x_start
|
||||||
|
continue
|
||||||
|
|
||||||
alpha = self.alphas_cumprod[time]
|
alpha = self.alphas_cumprod[time]
|
||||||
alpha_next = self.alphas_cumprod[time_next]
|
alpha_next = self.alphas_cumprod[time_next]
|
||||||
|
|
||||||
time_cond = torch.full((batch,), time, device = device, dtype = torch.long)
|
|
||||||
|
|
||||||
self_cond = x_start if self.self_condition else None
|
|
||||||
|
|
||||||
pred_noise, x_start, *_ = self.model_predictions(img, time_cond, self_cond)
|
|
||||||
|
|
||||||
if clip_denoised:
|
|
||||||
x_start.clamp_(-1., 1.)
|
|
||||||
|
|
||||||
sigma = eta * ((1 - alpha / alpha_next) * (1 - alpha_next) / (1 - alpha)).sqrt()
|
sigma = eta * ((1 - alpha / alpha_next) * (1 - alpha_next) / (1 - alpha)).sqrt()
|
||||||
c = ((1 - alpha_next) - sigma ** 2).sqrt()
|
c = (1 - alpha_next - sigma ** 2).sqrt()
|
||||||
|
|
||||||
noise = torch.randn_like(img) if time_next > 0 else 0.
|
noise = torch.randn_like(img)
|
||||||
|
|
||||||
img = x_start * alpha_next.sqrt() + \
|
img = x_start * alpha_next.sqrt() + \
|
||||||
c * pred_noise + \
|
c * pred_noise + \
|
||||||
@@ -805,7 +810,10 @@ class Trainer(object):
|
|||||||
torch.save(data, str(self.results_folder / f'model-{milestone}.pt'))
|
torch.save(data, str(self.results_folder / f'model-{milestone}.pt'))
|
||||||
|
|
||||||
def load(self, milestone):
|
def load(self, milestone):
|
||||||
data = torch.load(str(self.results_folder / f'model-{milestone}.pt'))
|
accelerator = self.accelerator
|
||||||
|
device = accelerator.device
|
||||||
|
|
||||||
|
data = torch.load(str(self.results_folder / f'model-{milestone}.pt'), map_location=device)
|
||||||
|
|
||||||
model = self.accelerator.unwrap_model(self.model)
|
model = self.accelerator.unwrap_model(self.model)
|
||||||
model.load_state_dict(data['model'])
|
model.load_state_dict(data['model'])
|
||||||
@@ -846,6 +854,7 @@ class Trainer(object):
|
|||||||
|
|
||||||
accelerator.wait_for_everyone()
|
accelerator.wait_for_everyone()
|
||||||
|
|
||||||
|
self.step += 1
|
||||||
if accelerator.is_main_process:
|
if accelerator.is_main_process:
|
||||||
self.ema.to(device)
|
self.ema.to(device)
|
||||||
self.ema.update()
|
self.ema.update()
|
||||||
@@ -862,7 +871,6 @@ class Trainer(object):
|
|||||||
utils.save_image(all_images, str(self.results_folder / f'sample-{milestone}.png'), nrow = int(math.sqrt(self.num_samples)))
|
utils.save_image(all_images, str(self.results_folder / f'sample-{milestone}.png'), nrow = int(math.sqrt(self.num_samples)))
|
||||||
self.save(milestone)
|
self.save(milestone)
|
||||||
|
|
||||||
self.step += 1
|
|
||||||
pbar.update(1)
|
pbar.update(1)
|
||||||
|
|
||||||
accelerator.print('training complete')
|
accelerator.print('training complete')
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
|
|||||||
setup(
|
setup(
|
||||||
name = 'denoising-diffusion-pytorch',
|
name = 'denoising-diffusion-pytorch',
|
||||||
packages = find_packages(),
|
packages = find_packages(),
|
||||||
version = '0.27.5',
|
version = '0.27.9',
|
||||||
license='MIT',
|
license='MIT',
|
||||||
description = 'Denoising Diffusion Probabilistic Models - Pytorch',
|
description = 'Denoising Diffusion Probabilistic Models - Pytorch',
|
||||||
author = 'Phil Wang',
|
author = 'Phil Wang',
|
||||||
@@ -30,4 +30,4 @@ setup(
|
|||||||
'License :: OSI Approved :: MIT License',
|
'License :: OSI Approved :: MIT License',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user