Generative Adversarial Networks (GANs)는 예술 창작부터 딥페이크 비디오 생성에 이르기까지 수많은 분야에서 전례 없는 발전을 이루어냈습니다. 하지만 GANs의 잠재력은 2D 공간에만 국한되지 않습니다. 3D GANs의 개발과 응용은 특히 디자인 분야에서 새로운 가능성을 열었습니다.
이 프로젝트는 다음과 같은 목표를 가지고 디자인 분야에서의 3D GANs의 가능성을 탐구합니다:
먼저, point cloud 데이터로 단일 구체를 생성하는 GAN 학습의 실제 구현을 진행해보겠습니다. 신경망을 구현하기 전에, Rhino로 모델링한 하나의 구체 형태의 point cloud를 파일에서 불러오는 것부터 시작합니다.
일반적으로, 정규화는 훈련 데이터가 다양한 크기의 유사한 객체로 구성되어 있거나 절대적인 크기가 중요하지 않은 경우에 특히 유용합니다. 우리의 단일 구체 데이터셋에서는 절대적인 크기가 중요하지 않습니다. 따라서 정규화를 진행하겠습니다. 구체는 numpy를 사용하여 다음과 같이 쉽게 정규화할 수 있습니다:
서로 다른 3D 모델들이 각각 다른 수의 정점을 가지고 있을 때, 각 모델에서 일정한 수의 포인트를 샘플링하는 것은 입력 크기를 균일하게 유지할 수 있게 합니다. 이는 일관된 입력 크기를 필요로 하는 신경망에 데이터를 공급할 때 매우 중요합니다. PointSampler와 관련된 코드는 다음 링크를 참조해 주시기 바랍니다. 포인트 클라우드로 표현된 구체 왼쪽부터, 원본 구체 · 무작위 샘플링된 구체 · 정규화 및 무작위 샘플링된 구체
이제 데이터 전처리가 완료되었고 모델 학습을 위한 준비가 되었습니다. 다음과 같이 간단한 생성자와 판별자로 구성된 모델을 구축하고 학습해보겠습니다:
class Generator(nn.Module):
def __init__(self, input_dim=3, output_dim=3, hidden_dim=128):
super(Generator, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, hidden_dim)
self.fc3 = nn.Linear(hidden_dim, hidden_dim)
self.fc4 = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = torch.relu(self.fc3(x))
x = torch.tanh(self.fc4(x))
return x
class Discriminator(nn.Module):
def __init__(self, input_dim=3, hidden_dim=128):
super(Discriminator, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, hidden_dim)
self.fc3 = nn.Linear(hidden_dim, hidden_dim)
self.fc4 = nn.Linear(hidden_dim, 1)
def forward(self, x):
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = torch.relu(self.fc3(x))
x = torch.sigmoid(self.fc4(x))
return x
생성자, 판별자, 데이터, 학습 과정 등에 대한 자세한 내용이 포함된 전체 코드는 다음 링크에서 확인할 수 있습니다. 또한, matplotlib을 사용하여 시각화한 학습 과정은 아래에서 확인할 수 있습니다. loss 상태 그래프를 살펴보면, 약 2700 epoch 부근에서 구체가 생성되기 시작하는 것을 확인할 수 있습니다. 이 시점 이후로는 loss 값의 진동이 멈추고 수렴하는 그래프를 보여줍니다. 단일 구체 GAN의 학습 과정 왼쪽부터, loss 상태 · 생성된 포인트 클라우드 구체
Implementing MassGAN 🧱
위에서 우리는 기본 구현과 단일 구체 GAN을 통해 GANs에 대한 이해를 얻었습니다. 이제 이 이해를 바탕으로, 건축가들이 설계한 건물(Masses)로 모델을 학습시키고 가짜 Masses를 생성하는 생성자를 만들어보겠습니다.
The procedure for the implementation of MassGAN follows the below processes:
데이터셋 준비 및 전처리
모델 구현 및 학습
생성자 평가 및 latent space 탐색
Preparation and preprocessing of the dataset
모델 학습을 위해 여러 유명 건축가들이 설계한 건물 모델들을 수집했습니다. 아래 그림은 제가 수집한 모델링 데이터의 실제 건물들을 보여줍니다. 복셀 형태의 건물들 왼쪽부터, RED7(MVRDV architects) · 79 and Park(BIG architects) · Mountain dwelling(BIG architects)
위에서 언급한 건물들은 복셀 형태의 구성이라는 공통적인 특징을 가지고 있습니다. 앞서 설명했듯이, 우리는 GANs와 관련된 세 가지 3D 형상 표현 방식에 대해 배웠습니다. 복셀 형태 표현의 주요 한계점은 고해상도 표현의 어려움에 있습니다. 하지만 건축 디자인 분야에서는 이러한 제약이 오히려 기회가 될 수 있습니다. 복셀 형태는 건축 분야에서 널리 사용되며, 이러한 형태의 고해상도 표현이 반드시 필요한 것은 아닙니다.
따라서, 우리는 적절한 해상도의 복셀 데이터를 사용하여 위와 같은 매스를 생성하는 생성 모델을 만들 것입니다. 먼저, 모델링 데이터를 사용하여 모델을 학습시키기 위해서는 데이터 구조를 .obj 형식에서 더 적합한 .binvox 형식으로 변환해야 합니다. .binvox 형식은 데이터를 이진 복셀 그리드 구조로 표현하며, 실제 있는 영역은 True (1), 비어있는 영역은 False (0)로 표시합니다. 아래에서 .binvox 형식으로 전처리된 예시를 살펴보겠습니다.
이진 복셀 그리드 표현 왼쪽부터, 주어진 구체 · 복셀화된 구체 · 이진 복셀 그리드(9번째 복셀 그리드) 이는 제 포스팅의 Voxelate 부분에서 이전에 언급되었습니다 위의 이진 복셀 그리드에서 볼 수 있듯이, 비어있는 영역은 0으로, 실제 있는 영역은 1로 표시됩니다. .binvox 형식으로의 전처리에 대한 모든 상세 코드는 다음 링크에서 확인할 수 있으며, 이를 활용하여 아래 6개의 모델을 32 x 32 x 32 해상도로 전처리했습니다. binvox를 활용하여 이진 복셀 그리드로 전처리된 데이터 위쪽부터 왼쪽으로, 79 and Park · Lego tower, RED7 아래쪽부터 왼쪽으로, Vancouver house · CCTV Headquarter, Mountain dwelling
Implementation of models and training them
이제 데이터 수집과 전처리 과정을 완료했습니다. 이어서 생성자와 판별자의 구현을 시작할 준비가 되었습니다.
따라서 여러 3D 생성 모델이 구현된 GitHub 저장소들을 참고하여 gradient penalty가 적용된 DCGAN(WGAN)을 구현했습니다. 모델 정의에 대한 전체 코드는 다음 링크에서 확인할 수 있습니다: massGAN/model.py
또한 모델 학습, 평가, 저장을 포함한 모델 관리를 위해 MassganTrainer를 정의했습니다. 이 과정에서 학습 단계에서 발생하는 모든 문제를 모니터링했습니다. 기록된 결과는 아래와 같습니다: 0에서 20000 epoch까지 200 epoch마다 시각화된 학습 과정 위에서부터, loss 상태 · 모델 학습 중 생성된 매스들 이전에 학습했던 단일 구체 GAN과는 달리, MassGAN은 데이터의 복잡성으로 인해 loss 값이 하나의 지점으로 수렴하지 않습니다. 그럼에도 불구하고, 학습의 초기와 최종 단계를 비교해보면 loss 값이 낮은 범위 내에서 진동하는 것을 관찰할 수 있습니다. 더욱이, 모니터링된 가짜 매스들을 관찰해보면 점진적으로 실제 매스의 형태에 근접해가는 것을 확인할 수 있습니다.
Evaluating generator, and exploration for the latent spaces
학습률, 배치 크기, 노이즈 차원 등과 같은 모델 학습을 위한 매개변수는 다음과 같이 사용되었습니다:
class ModelConfig:
"""Configuration related to the GAN models
"""
DEVICE = "cpu"
if torch.cuda.is_available():
DEVICE = "cuda"
SEED = 777
GENERATOR_INIT_OUT_CHANNELS = 256
DISCRIMINATOR_INIT_OUT_CHANNELS = 64
EPOCHS = 20000
LEARNING_RATE = 0.0001
BATCH_SIZE = 6
BATCH_SIZE_TO_EVALUATE = 6
Z_DIM = 128
BETAS = (0.5, 0.999)
LAMBDA_1 = 10
LOG_INTERVAL = 200
이제 해당 ModelConfig로 학습된 모델을 불러와서 평가해보겠습니다. GAN에서는 loss 상태와 같은 정량적인 모델 평가도 중요하지만, 생성자가 생성한 데이터를 정성적으로 평가하는 것도 모델 평가에 효과적입니다. 다음 그림들은 evaluate 함수를 통해 MassGAN 모델이 생성한 매스들입니다. MassGAN 모델이 생성한 매스들 전반적으로 괜찮은 데이터를 생성하는 것으로 보입니다. 이어서, 생성자가 만든 매스들 중 일부를 선택하여 그들 사이의 잠재 공간에서의 보간을 관찰해보겠습니다. 잠재 공간에서의 보간 왼쪽부터, RED7 · 보간 · CCTV 본사 잠재 공간에서의 보간 왼쪽부터, 레고 타워 · 보간 · Mountain dwelling 잠재 공간에서의 보간 왼쪽부터, Vancouver house · 보간 · 레고 타워