๐ ๋ชฉ์ฐจ
1. Normalizing Flow
2. RealNVP
3. GLOW & FFJORD
4. ์์ฝ
๐ง preview:
์์ ์ค๋ช ํ VAE, GAN, AR๋ชจ๋ธ์ ๋ถํฌ p(x)๋ชจ๋ธ๋ง๋ฌธ์ ํด๊ฒฐ์ ์ํด
Sampling๊ฐ๋ฅํ latent variable์ด๋ (=VAE Decoder, GAN Generator)
์ด์ pixel๊ฐ์ ๋ํ ํจ์๋ก ๋ถํฌ๋ฅผ ๋ชจ๋ธ๋ง(=AR)ํ๋ค.
Normalizing Flow์์ ๊ณตํต์ :
โ AR์ฒ๋ผ ๋ค๋ฃจ๊ธฐ ์ฝ๊ณ ๋ช ์์ ์ธ data์์ฑ๋ถํฌ p(x)๋ฅผ ๋ชจ๋ธ๋ง
โ VAE์ฒ๋ผ data๋ฅผ Gaussian๋ถํฌ์ฒ๋ผ ๊ฐ๋จํ ๋ถํฌ์ mapping
Normalizing Flow์ ๋ค๋ฅธ์ :
โ mappingํจ์์ ํํ์ ์ ์ฝ์ ๋๋ค.
(= ์ด ํจ์๋ ๋ฐ์ ๊ฐ๋ฅํด์ผํ๊ณ , ์ด๋ฅผ ์ด์ฉํด ์ data point์์ฑ์ด ๊ฐ๋ฅํด์ผํจ.)
1. Normalizing Flow
Normalizing Flow๋ VAE์ ์๋นํ ์ ์ฌํ๋ค.
VAE
Encoderํ์ต โ ๋ณต์กํ ๋ถํฌ์ sampling๊ฐ๋ฅํ ๊ฐ๋จํ ๋ถํฌ๋ฅผ mapping
โ Decoderํ์ต โ ๋จ์ํ๋ถํฌ์์ ๋ณต์กํ ๋ถํฌ๋ก mapping
โด ๋จ์ํ ๋ถํฌ์์ point z๋ฅผ sampling, ํ์ต๋ ๋ณํ์ ์ ์ฉ ์, ์ data point๋ฅผ ์ป์.
์ฆ, Decoder๋ p(x|z)๋ฅผ ๋ชจ๋ธ๋ง.
Encoder๋ p(z|x)์ ๊ทผ์ฌ์น์ธ q(z|x)๋ก ๋์ ์์ ํ ๋ค๋ฅธ ์ ๊ฒฝ๋ง์.
Normalizing Flows
Decodingํจ์ = Encodingํจ์์ ์ญํจ์ (= ๊ณ์ฐ์ด ์ฉ์ดํจ.)
Butโ๏ธ์ ๊ฒฝ๋ง์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ์ ๊ฐ๋ฅํ ํจ์๊ฐ ์๋๋ค!
์ด๋ฅผ ์ํด ๋ณ์๋ณํ์ด๋ผ๋ ๊ธฐ๋ฒ์ด ํ์ํ ๊ฒ.
Change of Variables
๋ณ์๋ณํ:
px(x)๊ฐ 2์ฐจ์ x = (x1, x2) ์ง์ฌ๊ฐํ X์์ ์ ์๋์ด์๋ค ๊ฐ์ ํ์.์ด ํจ์๋ฅผ ์ฃผ์ด์ง ๋ถํฌ์์ญ์์ ์ ๋ถํ๋ฉด 1์ด ๋๋ค. (x1์ ๋ฒ์: [1,4] , x2:[0.2])
๋ฐ๋ผ์ ์๋์ ๊ฐ์ด ์ ์ ์๋ ํ๋ฅ ๋ถํฌ๋ฅผ ์ ์ํ ์ ์๋ค:์ด ๋ถํฌ๋ฅผ ์ด๋ํ๊ณ scalingํ์ฌ ๋จ์ ์ ์ฌ๊ฐํ Z์ ๋ํด ์ ์ํ๋ค ๊ฐ์ ํ์.
์ด๋ฅผ ์ํด ์๋ก์ด z=(z1, z2)๋ณ์์ X์ ๊ฐ point๋ฅผ ์ ํํ Z์ ํ Point์ mappingํ๋ ํจ์ f๋ฅผ ์ ์ํ ์ ์๋ค:์ด๋ฐ ํจ์๋ฅผ ๊ฐ์ญํจ์(invertible function)๋ผ ํ๋ค.
์ฆ, ๋ชจ๋ z๋ฅผ ์ด์ ํด๋นํ๋ x๋ก ๋ค์ mapping๊ฐ๋ฅํ gํจ์๊ฐ ์กด์ฌํ๋ค. (๋ณ์๋ณํ์ ํ์์ .)
์ด gํจ์๊ฐ ์์ผ๋ฉด ๋ ๊ณต๊ฐ์ฌ์ด๋ฅผ mappingํ ์ ์๋ค.
์ด๋, pz(z) = ((3z1+1)-1)(2z2)/9 = 2z1z2/3๋ก ๋ณํ๊ฐ๋ฅํ๋ค.
๋ค๋ง, pz(z)๋ฅผ ๋จ์๋ฉด์ ์ ๋ํด ์ ๋ถํ๋ฉด ์๋์ ๊ฐ์ ๋ฌธ์ ์ ๋ด์ฐฉํ๋ค:1/6๊ฐ์ด ๋์๊ธฐ์, ๋์ด์ ์ ํจํ ํ๋ฅ ๋ถํฌ๊ฐ ์๋๋ค. (์ ๋ถ๊ฒฐ๊ณผ๊ฐ 1์ด ๋์ด์ผํจ.)
์์ธ: ๋ณํ๋ ํ๋ฅ ๋ถํฌ ์์ญ์ด ์๋ณธ์ 1/6๋ก ์์์ก๊ธฐ ๋๋ฌธ.
ํด๊ฒฐ: ์๋ก์ด ํ๋ฅ ๋ถํฌ์ ์๋์ ๋ฉด์ ๋ณํ์ ํด๋นํ๋ ์ ๊ทํ๊ณ์๋ฅผ ๊ณฑํด์ผํจ
โ ๋ณํ์ ์ํ ๋ถํผ๋ณํ = Jacobian Matrix์ ์ ๋๊ฐ.
Jacobian Matrix:
z = f(x)์ Jacobain Matrix๋ 1๊ณ ํธ๋ฏธ๋ถ๋ํจ์์ ํ๋ ฌ์ด๋ค.
x1์ ๋ํ z1์ ํธ๋ฏธ๋ถ์ 1/3์ด๊ณ , x1์ ๋ํ z2์ ํธ๋ฏธ๋ถ์ 0์ด๋ฉฐ,
x2์ ๋ํ z2์ ํธ๋ฏธ๋ถ์ 0์ด๊ณ , x2์ ๋ํ z2์ ํธ๋ฏธ๋ถ์ 1/2์ด๋ค.
๋ฐ๋ผ์ ํจ์ f(x)์ Jacobian Matrix๋ ์๋์ ๊ฐ๋ค.
ํ๋ ฌ์(determinant)์ ์ ๋ฐฉํ๋ ฌ(square matrix)์์๋ง ์ ์๋๋ค.
ํด๋นํ๋ ฌ๋ก ํํ๋๋ ๋ณํ์ ๋จ์ ์ด์ ๋ฐฉ์ฒด์ ์ ์ฉํด ๋ง๋ค์ด์ง ํํ์ก๋ฉด์ฒด ๋ถํผ์ ๊ฐ๋ค.
์ฆ, 2์ฐจ์ ํ๋ ฌ๋ก ํํ๋๋ ๋ณํ์ ๋จ์ ์ ์ฌ๊ฐํ์ ์ ์ฉํด ๋ง๋ค์ด์ง ํํ์ฌ๋ณํ์ ๋ฉด์ ์ ํด๋นํ๋ค.
์์ ์์๋ฅผ ๋ณด์. det(a b c d) = ad - bc์ด๋ฏ๋ก
์ ์์์์ Jacobian ํ๋ ฌ์์ 1/3 ร 1/2 = 1/6์ด๋ค.
์ด๊ฐ์ด ๋ฐ๋ก scaling๊ณ์์ด๋ค.
๋ณ์ ๋ณํ ๋ฐฉ์ ์
ํ๋์ ๋ฐฉ์ ์์ผ๋ก X์ Z์ฌ์ด ๋ณ์๋ณํ๊ณผ์ ์ ์ค๋ช ํ ์ ์๋ค.
์ด๋ฅผ "๋ณ์๋ณํ๋ฐฉ์ ์(change of variables equation)"์ด๋ผ ํ๋ค.๊ฐ๋จํ ๋ถํฌ๋ผ๋ฉด, XโZ๋ก mappingํ ์ ์ ํ ๊ฐ์ญํจ์ f(x)์
sampling๋ z๋ฅผ ๊ธฐ์กด domain point x๋ก ๋ค์ mapping ์ ์ฌ์ฉํ ์ญํจ์ g(z)๋ฅผ ์ฐพ์ผ๋ฉด ๋๋ค.
์ด๋ฅผ ์ํด, ํ์ํ 2๊ฐ์ง ๋ฌธ์ ๊ฐ ์กด์ฌํ๋ค.
โ ๊ณ ์ฐจ์ ํ๋ ฌ์์ Too Hight Cost. O(n3)์๊ฐ์ด ๋ ๋ค.
โก f(x)์ ์ญํจ์ ๊ณ์ฐ์ด ๋ช ํํ์ง ์๋ค.
์์ ๋ฌธ์ ๋ค ํด๊ฒฐ์ ์ํด RealNVP๋ผ๋ ๋ณํ๊ธฐ๋ฒ์ผ๋ก ์ํ๊ฐ๋ฅํ๋ค.
2. RealNVP
prev.
RealNVP๋ ๋ณต์กํ data๋ถํฌ๋ฅผ ๊ฐ๋จํ Gaussian๋ถํฌ๋ก ๋ณํํ๋ ์ ๊ฒฝ๋ง์ ๋ง๋ค ์ ์๋ค.
๋ํ, ์ญ๋ณํ์ด ๊ฐ๋ฅํ๊ณ Jacobian Matrix๋ฅผ ์ฝ๊ฒ ๊ณ์ฐํ ์ ์๋ค.
Coupling Layer
Coupling์ธต์ input์์์ ๋ํด scale๊ณ์์ translation๊ณ์๋ฅผ ๋ง๋ ๋ค.
์๋ ์์์ฒ๋ผ Linear์ธต์ผ๋ก Scale์ถ๋ ฅ์ ๋ง๋ค๊ณ ,
๋๋ค๋ฅธ Linearfh translation๊ณ์๋ฅผ ๋ง๋ ๋ค.
class CouplingLayer(nn.Module): def __init__(self, input_dim, output_dim, hid_dim, mask): super().__init__() self.s_fc1 = nn.Linear(input_dim, hid_dim) self.s_fc2 = nn.Linear(hid_dim, hid_dim) self.s_fc3 = nn.Linear(hid_dim, output_dim) self.t_fc1 = nn.Linear(input_dim, hid_dim) self.t_fc2 = nn.Linear(hid_dim, hid_dim) self.t_fc3 = nn.Linear(hid_dim, output_dim) self.mask = mask def forward(self, x): x_m = x * self.mask s_out = torch.tanh(self.s_fc3(F.relu(self.s_fc2(F.relu(self.s_fc1(x_m)))))) t_out = self.t_fc3(F.relu(self.t_fc2(F.relu(self.t_fc1(x_m))))) y = x_m + (1-self.mask)*(x*torch.exp(s_out)+t_out) log_det_jacobian = s_out.sum(dim=1) return y, log_det_jacobian def backward(self, y): y_m = y * self.mask s_out = torch.tanh(self.s_fc3(F.relu(self.s_fc2(F.relu(self.s_fc1(y_m)))))) t_out = self.t_fc3(F.relu(self.t_fc2(F.relu(self.t_fc1(y_m))))) x = y_m + (1-self.mask)*(y-t_out)*torch.exp(-s_out) return xโ
๋ ๋ณต์กํ ํํ์ ํ์ตํ๊ธฐ ์ํด ์ฐจ์์ ๋๋ ธ๋ค ๋ค์ ์๋ณธ์ฐจ์์ผ๋ก ์ถ์ํ๋ค.
Coupling Layer๋ input data๊ฐ ๋ค์ด๊ฐ ๋, Masking ํ ๋ณํ๋๋ ๋ฐฉ์์ด ๋ ํนํ๋ค.
Step 1. ์ฒ์ d์ฐจ์๋ง Coupling Layer์ ์ฃผ์ .
Step 2. ๋จ์ D-d์ฐจ์์ ์์ ํ Masking(= 0์ผ๋ก ์ค์ .)์ด๋, ๋ง์ ์ ๋ณด๋ฅผ Maskingํ๋ ์ด์ ๊ฐ ๋ญ๊น?
์ด๋ฅผ ์๊ธฐ์ํด, ์ด ํจ์์ Jacobian Matrix๋ฅผ ์ดํด๋ณด๋ฉด ์ ์ ์๋ค.
์ฅ์ 1
ํ์ผ๊ฐํ๋ ฌํํ๋ก ํ์ผ๊ฐํ๋ ฌ์ ํ๋ ฌ์์ ๋จ์ํ ๋๊ฐ์์์ ๊ณฑ๊ณผ ๊ฐ๋ค.
์ฆ, ์ข์ธกํ๋จ์ ๋ณต์กํ ๋ํจ์์ ์๊ด์ด ์์ด์ง๋ค!
์ฅ์ 2
์๋ ๊ทธ๋ฆผ ๋ฐ ์์ ๋ณด๋ฉด, ์ฝ๊ฒ ์ญ์ ํ ์ ์๋ ํจ์๋ผ๋ ๋ชฉํ๋ฌ์ฑ์ด ๊ฐ๋ฅํ๋ค.
์ ๋ฐฉํฅ๊ณ์ฐ์ ์ฌ์ ๋ ฌํ๋ฉด, ์๋์ ๊ฐ์ ์ญํจ์์์ ๋ง๋ค ์ ์๋ค.
Step 3. ๊ทธ๋ฌ๋ฉด ์ด์ ์ฒ์ ์ ๋ ฅ์ d๊ฐ ์์๋ฅผ ์ด๋ป๊ฒ updateํด์ผํ ๊น?
Coupling Layer ์๊ธฐ
์ ํ๋์ํ์ ํ๋ ฌ์ ์กฐ๊ฑด
๋ฐ๋ผ์ ์์ ์ ํ๋์ํ ํ๋ ฌ์์กฐ๊ฑด์ ๋ฐ๋ผ Coupling Layer๋ฅผ ์๊ณ ,
๋งค๋ฒ Masking์ ๋ค์ง์ผ๋ฉด, ๊ฐ๋จํ Jacobian Matrix์ ๊ฐ์ญ์ฑ์ด๋ผ๋ ํ์์์ฑ์ ์ ์งํ๋ฉฐ
์ ์ฒด input tensor๋ฅผ ๋ณํํ๋ ์ ๊ฒฝ๋ง์ ๋ง๋ค ์ ์๋ค.
RealNVP ๋ชจ๋ธํ๋ จ
class RealNVP(nn.Module): def __init__(self, input_dim, output_dim, hid_dim, mask, n_layers = 6): super().__init__() assert n_layers >= 2, 'num of coupling layers should be greater or equal to 2' self.modules = [] self.modules.append(CouplingLayer(input_dim, output_dim, hid_dim, mask)) for _ in range(n_layers-2): mask = 1 - mask self.modules.append(CouplingLayer(input_dim, output_dim, hid_dim, mask)) self.modules.append(CouplingLayer(input_dim, output_dim, hid_dim, 1 - mask)) self.module_list = nn.ModuleList(self.modules) def forward(self, x): ldj_sum = 0 # sum of log determinant of jacobian for module in self.module_list: x, ldj= module(x) ldj_sum += ldj return x, ldj_sum def backward(self, z): for module in reversed(self.module_list): z = module.backward(z) return z mask = torch.from_numpy(np.array([0, 1]).astype(np.float32)) model = RealNVP(INPUT_DIM, OUTPUT_DIM, HIDDEN_DIM, mask, N_COUPLE_LAYERS) optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) prior_z = distributions.MultivariateNormal(torch.zeros(2), torch.eye(2))
Loss functions: NLL Loss
def train(epoch): model.train() train_loss = 0 for batch_idx, data in enumerate(train_loader): optimizer.zero_grad() z, log_det_j_sum = model(data) loss = -(prior_z.log_prob(z)+log_det_j_sum).mean() loss.backward() cur_loss = loss.item() train_loss += cur_loss optimizer.step() if batch_idx % LOG_INTERVAL == 0: print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( epoch, batch_idx * len(data), len(train_loader.dataset), 100.*batch_idx / len(train_loader), cur_loss/len(data))) print('====> Epoch: {} Average loss: {:.4f}'.format( epoch, train_loss / len(train_loader.dataset) ))
[train ๊ฒฐ๊ณผ]:๋ณต์กํ input์ด ๋จ์ํ Gaussian๋ถํฌํํ๋ก mapping๋จ.
3. GLOW &. FFJORD
GLOW
๊ณ ํ์ง sample์์ฑ ๋ฐ ์ ์๋ฏธํ latent space ์์ฑ๊ฐ์ผ.
ํต์ฌ: ์ญ๋ง์คํน ์ค์ ์ ๋ฐ์ ๊ฐ๋ฅํ 1ร1 conv๋ก ๋์ฒด
์ค์ฃฝํ๋ฉด ๋ ผ๋ฌธ์ ๋ชฉ๋ Glow: Generative Flow with Invertible 1x1 Convolutions
์ด๋ฅผ ์ด์ฉํด ๋ชจ๋ธ์ด ์ํ๋ ์ฑ๋์์ผ๋ก ์กฐํฉ์์ฑ ๊ฐ๋ฅ.
FFJORD
Discrete time Normalizing Flows: RealNVP, GLOW
Continuous time Normalizing Flows: FFJORD
์ฆ, Normalizing Flow์ ๋จ๊ณ์๊ฐ ๋ฌดํ๋์ด๊ณ , ๋จ๊ณํฌ๊ธฐ๊ฐ 0์ ๊ฐ๊น๊ธฐ์
์ ๊ฒฝ๋ง์ ์ํด parameter๊ฐ ์ ์๋๋ ์๋ฏธ๋ถ๋ฐฉ์ ์(ODE)์ ์ฌ์ฉํด
data๋ถํฌ์ ํ์ค์ ๊ท๋ถํฌ์ฌ์ด ๋ณํ์ ๋ชจ๋ธ๋ง:
4. ์์ฝ
Normalizing Flow๋, ๋ค๋ฃจ๊ธฐ ์ฌ์ด data๋ฐ๋ํจ์๋ฅผ ๋ง๋ค๋ฉด์ ๊ณ ํ์ง sample์ ์์ฑํ๋ ๊ฐ๋ ฅํ ์์ฑ๋ชจ๋ธ๋ง๋ฐฉ๋ฒ์ด๋ค.
์ด๋ฅผ ์ํด ์ ๊ฒฝ๋ง์ ํํ๋ฅผ ์ ํํด ๊ฐ์ญ์ฑ๊ณผ ๊ณ์ฐํ๊ธฐ ์ฌ์ด Jacobian determinant๋ฅผ ๊ณ์ฐํ๋ค.
'Gain Study > Generation' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[G]Part 2-6. Diffusion Models (0) | 2024.01.30 |
---|---|
[G]Part 2-5. Energy-based Model (0) | 2024.01.29 |
[G]Part 2-3. Auto Regressive Models (0) | 2024.01.26 |
[G]Part 2-2. GAN (0) | 2024.01.26 |
[G]Part 2-1. VAE (2) | 2024.01.25 |