Safetensors
yinuozhang's picture
Add computational release from Zenodo 22960654
aa45001 verified
Raw History Blame Contribute Delete
5.53 kB
# coding=utf-8
# Copyright 2020 The Google Research Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: skip-file
import math
import torch.nn as nn
import torch
import torch.nn.functional as F
import numpy as np
def get_act(FLAGS):
if FLAGS.activation.lower() == 'elu':
return nn.ELU()
elif FLAGS.activation.lower() == 'relu':
return nn.ReLU()
elif FLAGS.activation.lower() == 'lrelu':
return nn.LeakyReLU(negative_slope=0.2)
elif FLAGS.activation.lower() == 'swish':
return nn.SiLU()
elif FLAGS.activation.lower() == 'tanh':
return nn.Tanh()
elif FLAGS.activation.lower() == 'softplus':
return nn.Softplus()
else:
raise NotImplementedError('activation function does not exist!')
def variance_scaling(scale, mode, distribution,
in_axis=1, out_axis=0,
dtype=torch.float32,
device='cpu'):
def _compute_fans(shape, in_axis=1, out_axis=0):
receptive_field_size = np.prod(shape) / shape[in_axis] / shape[out_axis]
fan_in = shape[in_axis] * receptive_field_size
fan_out = shape[out_axis] * receptive_field_size
return fan_in, fan_out
def init(shape, dtype=dtype, device=device):
fan_in, fan_out = _compute_fans(shape, in_axis, out_axis)
if mode == "fan_in":
denominator = fan_in
elif mode == "fan_out":
denominator = fan_out
elif mode == "fan_avg":
denominator = (fan_in + fan_out) / 2
else:
raise ValueError(
"invalid mode for variance scaling initializer: {}".format(mode))
variance = scale / denominator
if distribution == "normal":
return torch.randn(*shape, dtype=dtype, device=device) * np.sqrt(variance)
elif distribution == "uniform":
return (torch.rand(*shape, dtype=dtype, device=device) * 2. - 1.) * np.sqrt(3 * variance)
else:
raise ValueError("invalid distribution for variance scaling initializer")
return init
def default_init(scale=1.):
"""DDPM initialization."""
scale = 1e-10 if scale == 0 else scale
return variance_scaling(scale, 'fan_avg', 'uniform')
def get_timestep_embedding(timesteps, embedding_dim, max_positions=10000):
assert len(timesteps.shape) == 1
half_dim = embedding_dim // 2
emb = math.log(max_positions) / (half_dim - 1)
emb = torch.exp(torch.arange(half_dim, dtype=torch.float32, device=timesteps.device) * -emb)
emb = timesteps.float()[:, None] * emb[None, :]
emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=1)
if embedding_dim % 2 == 1:
emb = F.pad(emb, (0, 1), mode='constant')
assert emb.shape == (timesteps.shape[0], embedding_dim)
return emb
class Encoder(nn.Module):
def __init__(self, encoder_dim, tdim, FLAGS):
super(Encoder, self).__init__()
self.encoding_blocks = nn.ModuleList()
for i in range(len(encoder_dim)):
if (i+1)==len(encoder_dim): break
encoding_block = EncodingBlock(encoder_dim[i], encoder_dim[i+1], tdim, FLAGS)
self.encoding_blocks.append(encoding_block)
def forward(self, x, t):
skip_connections = []
for encoding_block in self.encoding_blocks:
x, skip_connection = encoding_block(x, t)
skip_connections.append(skip_connection)
return skip_connections, x
class EncodingBlock(nn.Module):
def __init__(self, dim_in, dim_out, tdim, FLAGS):
super(EncodingBlock, self).__init__()
self.layer1 = nn.Sequential(
nn.Linear(dim_in, dim_out),
get_act(FLAGS)
)
self.temb_proj = nn.Sequential(
nn.Linear(tdim, dim_out),
get_act(FLAGS)
)
self.layer2 = nn.Sequential(
nn.Linear(dim_out, dim_out),
get_act(FLAGS)
)
def forward(self, x, t):
x = self.layer1(x).clone()
x += self.temb_proj(t)
x = self.layer2(x)
skip_connection = x
return x, skip_connection
class Decoder(nn.Module):
def __init__(self, decoder_dim, tdim, FLAGS):
super(Decoder, self).__init__()
self.decoding_blocks = nn.ModuleList()
for i in range(len(decoder_dim)):
if (i+1)==len(decoder_dim): break
decoding_block = DecodingBlock(decoder_dim[i], decoder_dim[i+1], tdim, FLAGS)
self.decoding_blocks.append(decoding_block)
def forward(self, skip_connections, x, t):
zipped = zip(reversed(skip_connections), self.decoding_blocks)
for skip_connection, decoding_block in zipped:
x = decoding_block(skip_connection, x, t)
return x
class DecodingBlock(nn.Module):
def __init__(self, dim_in, dim_out, tdim, FLAGS):
super(DecodingBlock, self).__init__()
self.layer1 = nn.Sequential(
nn.Linear(dim_in*2, dim_in),
get_act(FLAGS)
)
self.temb_proj = nn.Sequential(
nn.Linear(tdim, dim_in),
get_act(FLAGS)
)
self.layer2 = nn.Sequential(
nn.Linear(dim_in, dim_out),
get_act(FLAGS)
)
def forward(self, skip_connection, x, t):
x = torch.cat((skip_connection, x), dim=1)
x = self.layer1(x).clone()
x += self.temb_proj(t)
x = self.layer2(x)
return x