{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"accelerator": "GPU",
"colab": {
"name": "GAN for MNIST Tutorial",
"provenance": [],
"collapsed_sections": [],
"authorship_tag": "ABX9TyNZXFZGYfr9stF8/yxgt7BE",
"include_colab_link": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"
"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xrUqXYEepD0o"
},
"source": [
"#### GAN 실습\r\n",
"\r\n",
"* 논문 제목: Generative Adversarial Networks (NIPS 2014)\r\n",
"* 가장 기본적인 GAN 모델을 학습해보는 실습을 진행합니다.\r\n",
"* 학습 데이터셋: MNIST (1 X 28 X 28)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "UEx96DYOpdAK"
},
"source": [
"#### 필요한 라이브러리 불러오기\r\n",
"\r\n",
"* 실습을 위한 PyTorch 라이브러리를 불러옵니다."
]
},
{
"cell_type": "code",
"metadata": {
"id": "CiRb7M3naHyo"
},
"source": [
"import torch\r\n",
"import torch.nn as nn\r\n",
"\r\n",
"from torchvision import datasets\r\n",
"import torchvision.transforms as transforms\r\n",
"from torchvision.utils import save_image"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "tp4hbA95pihv"
},
"source": [
"#### 생성자(Generator) 및 판별자(Discriminator) 모델 정의"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Hj5al6cTZES1"
},
"source": [
"latent_dim = 100\r\n",
"\r\n",
"\r\n",
"# 생성자(Generator) 클래스 정의\r\n",
"class Generator(nn.Module):\r\n",
" def __init__(self):\r\n",
" super(Generator, self).__init__()\r\n",
"\r\n",
" # 하나의 블록(block) 정의\r\n",
" def block(input_dim, output_dim, normalize=True):\r\n",
" layers = [nn.Linear(input_dim, output_dim)]\r\n",
" if normalize:\r\n",
" # 배치 정규화(batch normalization) 수행(차원 동일)\r\n",
" layers.append(nn.BatchNorm1d(output_dim, 0.8))\r\n",
" layers.append(nn.LeakyReLU(0.2, inplace=True))\r\n",
" return layers\r\n",
"\r\n",
" # 생성자 모델은 연속적인 여러 개의 블록을 가짐\r\n",
" self.model = nn.Sequential(\r\n",
" *block(latent_dim, 128, normalize=False),\r\n",
" *block(128, 256),\r\n",
" *block(256, 512),\r\n",
" *block(512, 1024),\r\n",
" nn.Linear(1024, 1 * 28 * 28),\r\n",
" nn.Tanh()\r\n",
" )\r\n",
"\r\n",
" def forward(self, z):\r\n",
" img = self.model(z)\r\n",
" img = img.view(img.size(0), 1, 28, 28)\r\n",
" return img"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "M_kvtvOhaLX6"
},
"source": [
"# 판별자(Discriminator) 클래스 정의\r\n",
"class Discriminator(nn.Module):\r\n",
" def __init__(self):\r\n",
" super(Discriminator, self).__init__()\r\n",
"\r\n",
" self.model = nn.Sequential(\r\n",
" nn.Linear(1 * 28 * 28, 512),\r\n",
" nn.LeakyReLU(0.2, inplace=True),\r\n",
" nn.Linear(512, 256),\r\n",
" nn.LeakyReLU(0.2, inplace=True),\r\n",
" nn.Linear(256, 1),\r\n",
" nn.Sigmoid(),\r\n",
" )\r\n",
"\r\n",
" # 이미지에 대한 판별 결과를 반환\r\n",
" def forward(self, img):\r\n",
" flattened = img.view(img.size(0), -1)\r\n",
" output = self.model(flattened)\r\n",
"\r\n",
" return output"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "NOilX0rBqJXn"
},
"source": [
"#### 학습 데이터셋 불러오기\r\n",
"\r\n",
"* 학습을 위해 MNIST 데이터셋을 불러옵니다."
]
},
{
"cell_type": "code",
"metadata": {
"id": "HrhXIwtAqM7H"
},
"source": [
"transforms_train = transforms.Compose([\r\n",
" transforms.Resize(28),\r\n",
" transforms.ToTensor(),\r\n",
" transforms.Normalize([0.5], [0.5])\r\n",
"])\r\n",
"\r\n",
"train_dataset = datasets.MNIST(root=\"./dataset\", train=True, download=True, transform=transforms_train)\r\n",
"dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True, num_workers=4)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "K54Z7PNIqTkO"
},
"source": [
"#### 모델 학습 및 샘플링\r\n",
"\r\n",
"* 학습을 위해 생성자와 판별자 모델을 초기화합니다.\r\n",
"* 적절한 하이퍼 파라미터를 설정합니다."
]
},
{
"cell_type": "code",
"metadata": {
"id": "tBZf0BmBaN7l"
},
"source": [
"# 생성자(generator)와 판별자(discriminator) 초기화\r\n",
"generator = Generator()\r\n",
"discriminator = Discriminator()\r\n",
"\r\n",
"generator.cuda()\r\n",
"discriminator.cuda()\r\n",
"\r\n",
"# 손실 함수(loss function)\r\n",
"adversarial_loss = nn.BCELoss()\r\n",
"adversarial_loss.cuda()\r\n",
"\r\n",
"# 학습률(learning rate) 설정\r\n",
"lr = 0.0002\r\n",
"\r\n",
"# 생성자와 판별자를 위한 최적화 함수\r\n",
"optimizer_G = torch.optim.Adam(generator.parameters(), lr=lr, betas=(0.5, 0.999))\r\n",
"optimizer_D = torch.optim.Adam(discriminator.parameters(), lr=lr, betas=(0.5, 0.999))"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "F9ThAQIOt-74"
},
"source": [
"* 모델을 학습하면서 주기적으로 샘플링하여 결과를 확인할 수 있습니다."
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "srQI5xI6ar-X",
"outputId": "0bd2c30f-245a-4dea-8660-5a4c927de52e"
},
"source": [
"import time\r\n",
"\r\n",
"n_epochs = 200 # 학습의 횟수(epoch) 설정\r\n",
"sample_interval = 2000 # 몇 번의 배치(batch)마다 결과를 출력할 것인지 설정\r\n",
"start_time = time.time()\r\n",
"\r\n",
"for epoch in range(n_epochs):\r\n",
" for i, (imgs, _) in enumerate(dataloader):\r\n",
"\r\n",
" # 진짜(real) 이미지와 가짜(fake) 이미지에 대한 정답 레이블 생성\r\n",
" real = torch.cuda.FloatTensor(imgs.size(0), 1).fill_(1.0) # 진짜(real): 1\r\n",
" fake = torch.cuda.FloatTensor(imgs.size(0), 1).fill_(0.0) # 가짜(fake): 0\r\n",
"\r\n",
" real_imgs = imgs.cuda()\r\n",
"\r\n",
" \"\"\" 생성자(generator)를 학습합니다. \"\"\"\r\n",
" optimizer_G.zero_grad()\r\n",
"\r\n",
" # 랜덤 노이즈(noise) 샘플링\r\n",
" z = torch.normal(mean=0, std=1, size=(imgs.shape[0], latent_dim)).cuda()\r\n",
"\r\n",
" # 이미지 생성\r\n",
" generated_imgs = generator(z)\r\n",
"\r\n",
" # 생성자(generator)의 손실(loss) 값 계산\r\n",
" g_loss = adversarial_loss(discriminator(generated_imgs), real)\r\n",
"\r\n",
" # 생성자(generator) 업데이트\r\n",
" g_loss.backward()\r\n",
" optimizer_G.step()\r\n",
"\r\n",
" \"\"\" 판별자(discriminator)를 학습합니다. \"\"\"\r\n",
" optimizer_D.zero_grad()\r\n",
"\r\n",
" # 판별자(discriminator)의 손실(loss) 값 계산\r\n",
" real_loss = adversarial_loss(discriminator(real_imgs), real)\r\n",
" fake_loss = adversarial_loss(discriminator(generated_imgs.detach()), fake)\r\n",
" d_loss = (real_loss + fake_loss) / 2\r\n",
"\r\n",
" # 판별자(discriminator) 업데이트\r\n",
" d_loss.backward()\r\n",
" optimizer_D.step()\r\n",
"\r\n",
" done = epoch * len(dataloader) + i\r\n",
" if done % sample_interval == 0:\r\n",
" # 생성된 이미지 중에서 25개만 선택하여 5 X 5 격자 이미지에 출력\r\n",
" save_image(generated_imgs.data[:25], f\"{done}.png\", nrow=5, normalize=True)\r\n",
"\r\n",
" # 하나의 epoch이 끝날 때마다 로그(log) 출력\r\n",
" print(f\"[Epoch {epoch}/{n_epochs}] [D loss: {d_loss.item():.6f}] [G loss: {g_loss.item():.6f}] [Elapsed time: {time.time() - start_time:.2f}s]\")"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"[Epoch 0/200] [D loss: 0.522748] [G loss: 0.829430] [Elapsed time: 14.64s]\n",
"[Epoch 1/200] [D loss: 0.372858] [G loss: 1.517679] [Elapsed time: 29.62s]\n",
"[Epoch 2/200] [D loss: 0.363016] [G loss: 1.329226] [Elapsed time: 44.35s]\n",
"[Epoch 3/200] [D loss: 0.312027] [G loss: 1.289821] [Elapsed time: 58.97s]\n",
"[Epoch 4/200] [D loss: 0.711739] [G loss: 0.354931] [Elapsed time: 73.76s]\n",
"[Epoch 5/200] [D loss: 0.251453] [G loss: 1.115114] [Elapsed time: 88.81s]\n",
"[Epoch 6/200] [D loss: 0.222200] [G loss: 1.638794] [Elapsed time: 103.76s]\n",
"[Epoch 7/200] [D loss: 0.212449] [G loss: 1.299674] [Elapsed time: 118.63s]\n",
"[Epoch 8/200] [D loss: 0.188896] [G loss: 1.600519] [Elapsed time: 133.08s]\n",
"[Epoch 9/200] [D loss: 0.226206] [G loss: 2.084917] [Elapsed time: 148.05s]\n",
"[Epoch 10/200] [D loss: 0.225342] [G loss: 2.228838] [Elapsed time: 163.09s]\n",
"[Epoch 11/200] [D loss: 0.276130] [G loss: 1.518153] [Elapsed time: 178.27s]\n",
"[Epoch 12/200] [D loss: 0.216676] [G loss: 1.424551] [Elapsed time: 193.14s]\n",
"[Epoch 13/200] [D loss: 0.250011] [G loss: 1.505254] [Elapsed time: 207.70s]\n",
"[Epoch 14/200] [D loss: 0.185601] [G loss: 3.071321] [Elapsed time: 222.36s]\n",
"[Epoch 15/200] [D loss: 0.234813] [G loss: 1.806695] [Elapsed time: 237.22s]\n",
"[Epoch 16/200] [D loss: 0.249854] [G loss: 1.138674] [Elapsed time: 251.82s]\n",
"[Epoch 17/200] [D loss: 0.249046] [G loss: 4.156915] [Elapsed time: 266.81s]\n",
"[Epoch 18/200] [D loss: 0.321985] [G loss: 3.767182] [Elapsed time: 281.35s]\n",
"[Epoch 19/200] [D loss: 0.312805] [G loss: 0.984120] [Elapsed time: 296.21s]\n",
"[Epoch 20/200] [D loss: 0.133047] [G loss: 2.177111] [Elapsed time: 311.03s]\n",
"[Epoch 21/200] [D loss: 0.287964] [G loss: 1.124958] [Elapsed time: 325.98s]\n",
"[Epoch 22/200] [D loss: 0.143492] [G loss: 2.103356] [Elapsed time: 340.97s]\n",
"[Epoch 23/200] [D loss: 0.697677] [G loss: 4.264883] [Elapsed time: 355.85s]\n",
"[Epoch 24/200] [D loss: 0.230640] [G loss: 1.688197] [Elapsed time: 370.62s]\n",
"[Epoch 25/200] [D loss: 0.375375] [G loss: 4.324008] [Elapsed time: 385.57s]\n",
"[Epoch 26/200] [D loss: 0.181044] [G loss: 2.331903] [Elapsed time: 400.26s]\n",
"[Epoch 27/200] [D loss: 0.147811] [G loss: 2.690580] [Elapsed time: 415.07s]\n",
"[Epoch 28/200] [D loss: 0.215825] [G loss: 3.242933] [Elapsed time: 430.07s]\n",
"[Epoch 29/200] [D loss: 0.361689] [G loss: 3.526228] [Elapsed time: 445.25s]\n",
"[Epoch 30/200] [D loss: 0.262714] [G loss: 4.088052] [Elapsed time: 460.18s]\n",
"[Epoch 31/200] [D loss: 0.389835] [G loss: 0.873464] [Elapsed time: 475.16s]\n",
"[Epoch 32/200] [D loss: 0.200233] [G loss: 2.727276] [Elapsed time: 490.73s]\n",
"[Epoch 33/200] [D loss: 0.344501] [G loss: 3.287966] [Elapsed time: 505.74s]\n",
"[Epoch 34/200] [D loss: 1.131307] [G loss: 7.970099] [Elapsed time: 520.81s]\n",
"[Epoch 35/200] [D loss: 0.210656] [G loss: 1.844736] [Elapsed time: 536.34s]\n",
"[Epoch 36/200] [D loss: 0.380815] [G loss: 4.722221] [Elapsed time: 551.15s]\n",
"[Epoch 37/200] [D loss: 0.204039] [G loss: 1.780442] [Elapsed time: 566.02s]\n",
"[Epoch 38/200] [D loss: 0.126606] [G loss: 3.045232] [Elapsed time: 581.24s]\n",
"[Epoch 39/200] [D loss: 0.164484] [G loss: 2.620150] [Elapsed time: 596.09s]\n",
"[Epoch 40/200] [D loss: 0.417071] [G loss: 0.942508] [Elapsed time: 610.90s]\n",
"[Epoch 41/200] [D loss: 0.344890] [G loss: 1.239429] [Elapsed time: 625.52s]\n",
"[Epoch 42/200] [D loss: 0.219357] [G loss: 1.801792] [Elapsed time: 640.42s]\n",
"[Epoch 43/200] [D loss: 0.261628] [G loss: 1.403077] [Elapsed time: 655.52s]\n",
"[Epoch 44/200] [D loss: 0.264856] [G loss: 1.670803] [Elapsed time: 669.95s]\n",
"[Epoch 45/200] [D loss: 0.320740] [G loss: 1.294596] [Elapsed time: 684.61s]\n",
"[Epoch 46/200] [D loss: 0.735896] [G loss: 0.457015] [Elapsed time: 699.22s]\n",
"[Epoch 47/200] [D loss: 0.215527] [G loss: 1.622929] [Elapsed time: 714.20s]\n",
"[Epoch 48/200] [D loss: 0.310391] [G loss: 1.838112] [Elapsed time: 728.92s]\n",
"[Epoch 49/200] [D loss: 0.326488] [G loss: 1.143378] [Elapsed time: 744.23s]\n",
"[Epoch 50/200] [D loss: 0.488925] [G loss: 3.819730] [Elapsed time: 759.78s]\n",
"[Epoch 51/200] [D loss: 0.281829] [G loss: 1.752762] [Elapsed time: 774.57s]\n",
"[Epoch 52/200] [D loss: 0.293825] [G loss: 1.591572] [Elapsed time: 789.61s]\n",
"[Epoch 53/200] [D loss: 0.305799] [G loss: 1.273533] [Elapsed time: 804.35s]\n",
"[Epoch 54/200] [D loss: 0.363520] [G loss: 2.063176] [Elapsed time: 819.70s]\n",
"[Epoch 55/200] [D loss: 0.280371] [G loss: 1.596596] [Elapsed time: 834.28s]\n",
"[Epoch 56/200] [D loss: 0.332533] [G loss: 2.254220] [Elapsed time: 849.09s]\n",
"[Epoch 57/200] [D loss: 0.323975] [G loss: 2.045448] [Elapsed time: 863.83s]\n",
"[Epoch 58/200] [D loss: 0.312644] [G loss: 1.940239] [Elapsed time: 878.52s]\n",
"[Epoch 59/200] [D loss: 0.433621] [G loss: 0.831792] [Elapsed time: 892.98s]\n",
"[Epoch 60/200] [D loss: 0.379544] [G loss: 1.479267] [Elapsed time: 907.94s]\n",
"[Epoch 61/200] [D loss: 0.337388] [G loss: 2.652977] [Elapsed time: 923.25s]\n",
"[Epoch 62/200] [D loss: 0.289478] [G loss: 1.463956] [Elapsed time: 938.16s]\n",
"[Epoch 63/200] [D loss: 0.332678] [G loss: 1.354259] [Elapsed time: 953.27s]\n",
"[Epoch 64/200] [D loss: 0.497146] [G loss: 0.947130] [Elapsed time: 968.09s]\n",
"[Epoch 65/200] [D loss: 0.298476] [G loss: 1.794587] [Elapsed time: 982.46s]\n",
"[Epoch 66/200] [D loss: 0.342376] [G loss: 2.761930] [Elapsed time: 997.41s]\n",
"[Epoch 67/200] [D loss: 0.199975] [G loss: 2.286337] [Elapsed time: 1012.32s]\n",
"[Epoch 68/200] [D loss: 0.550259] [G loss: 4.399807] [Elapsed time: 1026.82s]\n",
"[Epoch 69/200] [D loss: 0.348959] [G loss: 1.681570] [Elapsed time: 1041.37s]\n",
"[Epoch 70/200] [D loss: 0.350790] [G loss: 2.678944] [Elapsed time: 1055.61s]\n",
"[Epoch 71/200] [D loss: 0.349744] [G loss: 1.321077] [Elapsed time: 1070.66s]\n",
"[Epoch 72/200] [D loss: 0.454832] [G loss: 0.855591] [Elapsed time: 1085.41s]\n",
"[Epoch 73/200] [D loss: 0.216424] [G loss: 2.202238] [Elapsed time: 1100.12s]\n",
"[Epoch 74/200] [D loss: 0.332032] [G loss: 1.467984] [Elapsed time: 1114.63s]\n",
"[Epoch 75/200] [D loss: 0.334628] [G loss: 1.495943] [Elapsed time: 1129.88s]\n",
"[Epoch 76/200] [D loss: 0.275214] [G loss: 1.497794] [Elapsed time: 1144.08s]\n",
"[Epoch 77/200] [D loss: 0.420321] [G loss: 0.879592] [Elapsed time: 1158.38s]\n",
"[Epoch 78/200] [D loss: 0.406984] [G loss: 1.116465] [Elapsed time: 1172.16s]\n",
"[Epoch 79/200] [D loss: 0.306117] [G loss: 1.586033] [Elapsed time: 1185.82s]\n",
"[Epoch 80/200] [D loss: 0.346746] [G loss: 2.917901] [Elapsed time: 1199.78s]\n",
"[Epoch 81/200] [D loss: 0.414805] [G loss: 4.355955] [Elapsed time: 1213.76s]\n",
"[Epoch 82/200] [D loss: 0.217584] [G loss: 2.185797] [Elapsed time: 1228.37s]\n",
"[Epoch 83/200] [D loss: 0.299525] [G loss: 3.134455] [Elapsed time: 1242.65s]\n",
"[Epoch 84/200] [D loss: 0.453676] [G loss: 3.047255] [Elapsed time: 1257.05s]\n",
"[Epoch 85/200] [D loss: 0.265712] [G loss: 2.504372] [Elapsed time: 1271.58s]\n",
"[Epoch 86/200] [D loss: 0.468562] [G loss: 3.420906] [Elapsed time: 1286.16s]\n",
"[Epoch 87/200] [D loss: 0.313388] [G loss: 3.086492] [Elapsed time: 1300.33s]\n",
"[Epoch 88/200] [D loss: 0.286210] [G loss: 1.856419] [Elapsed time: 1314.43s]\n",
"[Epoch 89/200] [D loss: 0.284829] [G loss: 2.903432] [Elapsed time: 1328.78s]\n",
"[Epoch 90/200] [D loss: 0.334503] [G loss: 1.819413] [Elapsed time: 1342.66s]\n",
"[Epoch 91/200] [D loss: 0.208366] [G loss: 2.947707] [Elapsed time: 1356.72s]\n",
"[Epoch 92/200] [D loss: 0.339319] [G loss: 2.177942] [Elapsed time: 1371.20s]\n",
"[Epoch 93/200] [D loss: 0.308104] [G loss: 2.216433] [Elapsed time: 1385.47s]\n",
"[Epoch 94/200] [D loss: 0.203005] [G loss: 2.104164] [Elapsed time: 1399.74s]\n",
"[Epoch 95/200] [D loss: 0.281514] [G loss: 2.535281] [Elapsed time: 1414.42s]\n",
"[Epoch 96/200] [D loss: 0.323359] [G loss: 1.414945] [Elapsed time: 1428.69s]\n",
"[Epoch 97/200] [D loss: 0.209258] [G loss: 2.121124] [Elapsed time: 1443.10s]\n",
"[Epoch 98/200] [D loss: 0.211430] [G loss: 2.274003] [Elapsed time: 1457.63s]\n",
"[Epoch 99/200] [D loss: 0.248021] [G loss: 2.419493] [Elapsed time: 1472.17s]\n",
"[Epoch 100/200] [D loss: 0.283141] [G loss: 2.182565] [Elapsed time: 1486.11s]\n",
"[Epoch 101/200] [D loss: 0.291069] [G loss: 1.625459] [Elapsed time: 1500.31s]\n",
"[Epoch 102/200] [D loss: 0.266260] [G loss: 1.748940] [Elapsed time: 1514.75s]\n",
"[Epoch 103/200] [D loss: 0.279893] [G loss: 1.801305] [Elapsed time: 1528.98s]\n",
"[Epoch 104/200] [D loss: 0.337647] [G loss: 1.372875] [Elapsed time: 1543.34s]\n",
"[Epoch 105/200] [D loss: 0.372733] [G loss: 2.310965] [Elapsed time: 1557.47s]\n",
"[Epoch 106/200] [D loss: 0.304111] [G loss: 1.503514] [Elapsed time: 1571.95s]\n",
"[Epoch 107/200] [D loss: 0.288937] [G loss: 2.483202] [Elapsed time: 1586.13s]\n",
"[Epoch 108/200] [D loss: 0.294476] [G loss: 1.531241] [Elapsed time: 1600.49s]\n",
"[Epoch 109/200] [D loss: 0.341307] [G loss: 2.055195] [Elapsed time: 1614.86s]\n",
"[Epoch 110/200] [D loss: 0.322244] [G loss: 2.585032] [Elapsed time: 1629.25s]\n",
"[Epoch 111/200] [D loss: 0.331668] [G loss: 1.277997] [Elapsed time: 1643.81s]\n",
"[Epoch 112/200] [D loss: 0.257002] [G loss: 1.585161] [Elapsed time: 1658.57s]\n",
"[Epoch 113/200] [D loss: 0.306509] [G loss: 1.389385] [Elapsed time: 1673.70s]\n",
"[Epoch 114/200] [D loss: 0.288539] [G loss: 2.388597] [Elapsed time: 1689.25s]\n",
"[Epoch 115/200] [D loss: 0.219805] [G loss: 2.253654] [Elapsed time: 1703.90s]\n",
"[Epoch 116/200] [D loss: 0.251945] [G loss: 1.817379] [Elapsed time: 1718.33s]\n",
"[Epoch 117/200] [D loss: 0.266896] [G loss: 2.087219] [Elapsed time: 1733.40s]\n",
"[Epoch 118/200] [D loss: 0.239400] [G loss: 1.614851] [Elapsed time: 1748.42s]\n",
"[Epoch 119/200] [D loss: 0.264902] [G loss: 2.895990] [Elapsed time: 1763.09s]\n",
"[Epoch 120/200] [D loss: 0.297452] [G loss: 2.588012] [Elapsed time: 1777.57s]\n",
"[Epoch 121/200] [D loss: 0.297142] [G loss: 2.225440] [Elapsed time: 1792.15s]\n",
"[Epoch 122/200] [D loss: 0.268688] [G loss: 1.726179] [Elapsed time: 1806.62s]\n",
"[Epoch 123/200] [D loss: 0.310022] [G loss: 1.661120] [Elapsed time: 1821.90s]\n",
"[Epoch 124/200] [D loss: 0.144470] [G loss: 2.571463] [Elapsed time: 1836.72s]\n",
"[Epoch 125/200] [D loss: 0.205969] [G loss: 2.516297] [Elapsed time: 1851.07s]\n",
"[Epoch 126/200] [D loss: 0.327357] [G loss: 2.757601] [Elapsed time: 1866.09s]\n",
"[Epoch 127/200] [D loss: 0.269763] [G loss: 1.721026] [Elapsed time: 1881.54s]\n",
"[Epoch 128/200] [D loss: 0.221831] [G loss: 2.731440] [Elapsed time: 1896.85s]\n",
"[Epoch 129/200] [D loss: 0.321697] [G loss: 2.349569] [Elapsed time: 1911.31s]\n",
"[Epoch 130/200] [D loss: 0.323291] [G loss: 1.700038] [Elapsed time: 1925.97s]\n",
"[Epoch 131/200] [D loss: 0.265377] [G loss: 1.847327] [Elapsed time: 1940.73s]\n",
"[Epoch 132/200] [D loss: 0.308373] [G loss: 1.569885] [Elapsed time: 1955.58s]\n",
"[Epoch 133/200] [D loss: 0.208499] [G loss: 2.428175] [Elapsed time: 1970.32s]\n",
"[Epoch 134/200] [D loss: 0.305512] [G loss: 1.943389] [Elapsed time: 1984.97s]\n",
"[Epoch 135/200] [D loss: 0.272931] [G loss: 2.183786] [Elapsed time: 2000.05s]\n",
"[Epoch 136/200] [D loss: 0.359679] [G loss: 2.021343] [Elapsed time: 2015.21s]\n",
"[Epoch 137/200] [D loss: 0.357651] [G loss: 1.517780] [Elapsed time: 2030.43s]\n",
"[Epoch 138/200] [D loss: 0.184322] [G loss: 2.807851] [Elapsed time: 2045.27s]\n",
"[Epoch 139/200] [D loss: 0.203373] [G loss: 2.053690] [Elapsed time: 2060.09s]\n",
"[Epoch 140/200] [D loss: 0.243935] [G loss: 1.716758] [Elapsed time: 2075.23s]\n",
"[Epoch 141/200] [D loss: 0.322379] [G loss: 2.545387] [Elapsed time: 2090.06s]\n",
"[Epoch 142/200] [D loss: 0.229060] [G loss: 1.970968] [Elapsed time: 2104.85s]\n",
"[Epoch 143/200] [D loss: 0.274554] [G loss: 1.589352] [Elapsed time: 2119.89s]\n",
"[Epoch 144/200] [D loss: 0.288916] [G loss: 2.178538] [Elapsed time: 2134.73s]\n",
"[Epoch 145/200] [D loss: 0.268774] [G loss: 1.766644] [Elapsed time: 2149.62s]\n",
"[Epoch 146/200] [D loss: 0.289206] [G loss: 2.783231] [Elapsed time: 2164.31s]\n",
"[Epoch 147/200] [D loss: 0.225266] [G loss: 1.906159] [Elapsed time: 2179.32s]\n",
"[Epoch 148/200] [D loss: 0.294216] [G loss: 2.146295] [Elapsed time: 2194.25s]\n",
"[Epoch 149/200] [D loss: 0.360563] [G loss: 4.088191] [Elapsed time: 2209.58s]\n",
"[Epoch 150/200] [D loss: 0.265889] [G loss: 2.245625] [Elapsed time: 2224.41s]\n",
"[Epoch 151/200] [D loss: 0.291742] [G loss: 1.483999] [Elapsed time: 2239.37s]\n",
"[Epoch 152/200] [D loss: 0.341779] [G loss: 1.542900] [Elapsed time: 2254.13s]\n",
"[Epoch 153/200] [D loss: 0.200704] [G loss: 2.805265] [Elapsed time: 2268.69s]\n",
"[Epoch 154/200] [D loss: 0.295421] [G loss: 2.333511] [Elapsed time: 2283.07s]\n",
"[Epoch 155/200] [D loss: 0.296589] [G loss: 2.012913] [Elapsed time: 2297.71s]\n",
"[Epoch 156/200] [D loss: 0.275950] [G loss: 2.416452] [Elapsed time: 2312.39s]\n",
"[Epoch 157/200] [D loss: 0.213738] [G loss: 2.616714] [Elapsed time: 2327.23s]\n",
"[Epoch 158/200] [D loss: 0.241508] [G loss: 2.677406] [Elapsed time: 2341.96s]\n",
"[Epoch 159/200] [D loss: 0.194161] [G loss: 2.046714] [Elapsed time: 2356.83s]\n",
"[Epoch 160/200] [D loss: 0.260721] [G loss: 1.942953] [Elapsed time: 2371.48s]\n",
"[Epoch 161/200] [D loss: 0.314604] [G loss: 2.010342] [Elapsed time: 2386.16s]\n",
"[Epoch 162/200] [D loss: 0.210261] [G loss: 1.962100] [Elapsed time: 2401.35s]\n",
"[Epoch 163/200] [D loss: 0.248817] [G loss: 1.703924] [Elapsed time: 2416.14s]\n",
"[Epoch 164/200] [D loss: 0.295533] [G loss: 2.154848] [Elapsed time: 2431.00s]\n",
"[Epoch 165/200] [D loss: 0.360170] [G loss: 1.186311] [Elapsed time: 2445.93s]\n",
"[Epoch 166/200] [D loss: 0.246468] [G loss: 2.128010] [Elapsed time: 2460.56s]\n",
"[Epoch 167/200] [D loss: 0.267691] [G loss: 1.717979] [Elapsed time: 2475.68s]\n",
"[Epoch 168/200] [D loss: 0.238555] [G loss: 2.982985] [Elapsed time: 2490.28s]\n",
"[Epoch 169/200] [D loss: 0.299880] [G loss: 1.650179] [Elapsed time: 2504.60s]\n",
"[Epoch 170/200] [D loss: 0.286263] [G loss: 1.650552] [Elapsed time: 2520.00s]\n",
"[Epoch 171/200] [D loss: 0.351728] [G loss: 1.566897] [Elapsed time: 2535.14s]\n",
"[Epoch 172/200] [D loss: 0.289074] [G loss: 2.197316] [Elapsed time: 2549.66s]\n",
"[Epoch 173/200] [D loss: 0.299471] [G loss: 2.540869] [Elapsed time: 2564.27s]\n",
"[Epoch 174/200] [D loss: 0.262938] [G loss: 2.057458] [Elapsed time: 2578.87s]\n",
"[Epoch 175/200] [D loss: 0.324657] [G loss: 2.369673] [Elapsed time: 2593.65s]\n",
"[Epoch 176/200] [D loss: 0.274170] [G loss: 1.926636] [Elapsed time: 2608.21s]\n",
"[Epoch 177/200] [D loss: 0.242073] [G loss: 2.631045] [Elapsed time: 2623.69s]\n",
"[Epoch 178/200] [D loss: 0.304828] [G loss: 1.962924] [Elapsed time: 2638.48s]\n",
"[Epoch 179/200] [D loss: 0.309665] [G loss: 2.774096] [Elapsed time: 2653.47s]\n",
"[Epoch 180/200] [D loss: 0.436067] [G loss: 1.677492] [Elapsed time: 2668.45s]\n",
"[Epoch 181/200] [D loss: 0.208289] [G loss: 2.460046] [Elapsed time: 2683.23s]\n",
"[Epoch 182/200] [D loss: 0.464152] [G loss: 4.730225] [Elapsed time: 2697.73s]\n",
"[Epoch 183/200] [D loss: 0.236137] [G loss: 2.024809] [Elapsed time: 2712.46s]\n",
"[Epoch 184/200] [D loss: 0.280529] [G loss: 2.612814] [Elapsed time: 2727.13s]\n",
"[Epoch 185/200] [D loss: 0.373649] [G loss: 3.094165] [Elapsed time: 2741.85s]\n",
"[Epoch 186/200] [D loss: 0.244470] [G loss: 2.152431] [Elapsed time: 2756.89s]\n",
"[Epoch 187/200] [D loss: 0.262233] [G loss: 2.924129] [Elapsed time: 2771.52s]\n",
"[Epoch 188/200] [D loss: 0.210062] [G loss: 2.471434] [Elapsed time: 2786.17s]\n",
"[Epoch 189/200] [D loss: 0.279450] [G loss: 1.915476] [Elapsed time: 2800.64s]\n",
"[Epoch 190/200] [D loss: 0.243840] [G loss: 2.639207] [Elapsed time: 2815.62s]\n",
"[Epoch 191/200] [D loss: 0.237666] [G loss: 2.534870] [Elapsed time: 2830.14s]\n",
"[Epoch 192/200] [D loss: 0.293672] [G loss: 2.776765] [Elapsed time: 2845.01s]\n",
"[Epoch 193/200] [D loss: 0.364492] [G loss: 2.845275] [Elapsed time: 2859.84s]\n",
"[Epoch 194/200] [D loss: 0.289933] [G loss: 1.826300] [Elapsed time: 2874.33s]\n",
"[Epoch 195/200] [D loss: 0.334376] [G loss: 2.677049] [Elapsed time: 2888.91s]\n",
"[Epoch 196/200] [D loss: 0.179412] [G loss: 1.981803] [Elapsed time: 2903.51s]\n",
"[Epoch 197/200] [D loss: 0.223154] [G loss: 2.266187] [Elapsed time: 2918.11s]\n",
"[Epoch 198/200] [D loss: 0.219701] [G loss: 2.170232] [Elapsed time: 2932.94s]\n",
"[Epoch 199/200] [D loss: 0.281188] [G loss: 2.861171] [Elapsed time: 2947.38s]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dKhzqw6U8u-H"
},
"source": [
"* 생성된 이미지 예시를 출력합니다."
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 169
},
"id": "FeC3eMGa8vc1",
"outputId": "49201c7d-9673-4555-e4d5-e6e8d2eb214b"
},
"source": [
"from IPython.display import Image\r\n",
"\r\n",
"Image('92000.png')"
],
"execution_count": null,
"outputs": [
{
"output_type": "execute_result",
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAJgAAACYCAIAAACXoLd2AAAnzElEQVR4nO1dd0BUV9af+96bPrShV6kCFoIFg26i2JJYoquiorhojKssGqNGo+YjJtE0O4omQU2Ca2yoG01cY1xjN7Ghoogo2CAygAgyfV79/ribl8kAw5v3Hlmzy+8vmHn3vDO3nHvuuadIJO1oRzueOphMJvt/AQD2/x48eJA35W7dujn5ViaT8absHA4/gQc0Go09KeEEJRLJ+fPnnXyLIIjz5qLwIJSWmEy0gyOioqLYv1tdNFKplP0bRVHnD9tTa3UC2uM/Ow9a+l0OXLnKpEqlYv/29PR0/rA9cfs+b8cfDy7PZhGnf6tr1AEuLVOOwDBMIIX/3X2hVUFhD/tuErfLEAS5cuWK1Wr9+uuv206xagsAAJqV25yEOYqi/fv359iVTd/kHDExMc1+rlKpUBR1TiogIEAqlfIYY5lMduzYMYZhzGaz/cbPHexLAQAIgpw8efL06dM4jtfW1iYkJLgqbyCCg4O7du3q8KFcLscwDL4OQRAURREEQRBEJpN5eHhERETYb6itwLlYgyPXqVOnnJycOXPmxMfHKxQKCbc11OwzsGswDFMoFOx0Y5+Uy+UpKSkIgmi1WgzD3NzcOL7LHiEhIfX19QzD0DQ9a9Ysjq3s30JRlE6nk8vlDMMUFBQwDAOp0TRNkiT8myAIpVLpEmNNgSAIsENgYOCIESOeffbZxMTEvXv3pqamRkdHS4RLLI1GM2DAgEePHpEkabVa4c8wGAyRkZFCDiSZmZlhYWFubm79+/cfMGDAsmXL8vLy6urq4ItIkjxy5IjFYsnLy+NHPzEx0Wq1MgxDEERcXJyrFBoaGsLCwvLy8k6cOAGHrSXU19f36tXLhUXTAjAMk8lkarV68+bNixcvLisrq6urM5vNixYtEr7TSzAM++qrr3Acp2kax/G9e/e+9dZbFEXRND1v3jx+NDUajclk+uabb2JiYgYNGnTu3Lnq6uqSkpIXXnihpqYGEsdxXK1W7969e9KkScXFxa6+AgAQGxtrMBgYhmlsbHRVjQIAmEym/v37Z2RkREVF+fr6xsTEEARBEERVVdWNGzcqKytfeeWVL7/88sKFC3DaGQwGgcoaAEClUr366qvp6ekajSY1NdVqtZIk+f777wsh+2+EhIRYrVaz2WwwGLZt2xYYGDhlyhSSJC0WC3cNwmE7OXXq1MmTJ8ePHz9lypR58+Z9++236enpKIqiKBoTE5Oamrpnz54dO3ZIJBK1Wl1WVsajgxAEiYiIIAiCpumamhpXZzQAICkpSdJkx4HbAfwQbmOTJk2iaZphGIPBsG7dOlf5tIdCoQgNDR07dqyfnx+GYRs3bqQoqqGhQahEBQAolcra2lqKomw2W2RkZOfOnT09PeGK0el0TZs0e1Z14OPixYtQaEyfPn306NGQadgQwzBvb++wsDAURVkjGQSPJfX+++/DgSwoKPDw8BBCzYGy/b+pqakURTEMg+N4RUWFq81ZoCjasWPHRYsWubu7q9XqwMBAuBnv3buXN6u/IjMzE0637du3d+jQIT4+Pj8/nyRJiqK8vb350VSr1RKJRK/XV1VVrV69Gmqt/v7+06ZNi46Ojo2NhatHuAbRr18/yPyIESN4WENa0tEcPvH29rbZbHAsx4wZw49VAICvr++WLVvi4+OlUqmbm9vcuXMJgjCbzQ4TmhOayh8EQaxWK1yRBEFQFAU5vnTpEg/lG9KH+ipcK3V1dRaLhSRJqP5VV1cnJyfL5XK4YgSKlI4dO8KB9PPzc6mhzWbj+HYEQYKCgiD/JEkKMZ4hCKJWq7Vabffu3b/99luj0UjT9AcffMBl/3IULyRJNn2oZ8+eR44cefTo0aefflpbW2s2mxmGYQ893OHm5gbpQ60dymdPT0+5XG42mymKslqtnp6eX3/99apVq4YNGwafdOkVDmAnn6t05HI5x7czDHPz5k0oVAAAQ4YM4cmrRELTtMlkMhgM9fX1/v7+dXV11dXVp06dIgiCN81mIJVKURTt3LmzwWCgKKpHjx5cWjkZbHhyQhBEoVAoFAqtVpuamlpXV3fs2LFevXoFBwc7b84FAwcOhGvF399fCB0ncHNzg4ueYZjy8nLhBBEEiY2NraysfPDgwdy5c+EB2gXQNM3lMY1GU19fX1ZWxl2uNjQ0cNEsAAB+fn5btmwJDg5WKBQajUa4uS4mJgZK7ISEBJeoLVmyhOOTkZGRcCApiqqqqmr1La1ueACA0NDQ3Nzc9PR01lTCFRyfRlF01apV165d69u3rwvUOdPHMOz48eNDhw718fFxiX5LSE9PpyiKJMnY2FjnPDT9lstxRSaTnTt3DopugiC6du3qMGV5zMXevXvn5+cvWrRIqVS2lbFeKpX+85//vHr1qnATRrPQarU2m62goACqtc3Cpd+m1WobGxtNJlNqampb3OH5+Piwxp3169ejKCpQ05ZKpdOmTZs+fXr37t35GXJbBwAgLi6usrLSZrMJXzFQm3Cgf+/ePZIkHaxFDgPg0kAqlUqLxaLX67ds2TJixAiX2nJ5uKysjB1IVxXjZhEUFHTy5MnMzEylUunSSfffj3I0fH/wwQcajWbXrl11dXU8OZVIAAB6vZ4dSFa3hvqO2Wxev369/fMOOptL+ieO49CinZSU5OHhwbFrrl+/zuVFAAB4kqYoqrq6+tGjR9wZaxYYho0aNerGjRtGoxEatAUSbB7PPvvsnTt3bt261fQKxiVgGLZr167Y2FiVSoUgCFSG3dzcsrOznzx5Ehoa6vC8kH0CQZDGxkaapvV6/YULF8TdcpRKJUEQDMM8fvxYFIK+vr4ff/xxTk5OS/LZCf8umB83bdpEEMTdu3dv3rzpMo92oChq2rRp48aNwzDs5s2bBoNh8+bNRUVFY8eONZvNDx8+dHheyFESQZAlS5asXbtWoVBcvnxZCNsOAAA8//zz8O/79++LQrNnz56nT5+2Wq1Wq7XZB5x0xW8GEkVRiqKafc7d3f38+fNyuXz//v3NGg1+pYhhzh9gGMZoNG7btm3ZsmUpKSlubm4PHjwICAgoLS0dMWKEuPKEJMlHjx5Bi+WyZcsEmhccMGzYMKjZdujQAUGQZjlv9nMAgAMnAAAvL6+UlJRjx46dOXPGCZ9s26ZEOKGgoMBisdy9e3fdunUcD4XNfs6a6KA5vnv37vn5+SqVysPDQy6XT58+3WXOWkNOTo7ZbK6qqgoKCuLR3Ik027x5MzxB/vjjj0FBQfwcVhAEkcvlSUlJNTU1DQ0Np0+fdn7QbJ2ykycGDBiQlpZ248aNAwcODBw4sCVTsv3nDlcNDmBPL/AeFTbneM20YcMGLo+JDgc1GwCQm5tL0/S1a9daPSc4eQDatpRKZXx8/KxZs9RqdbO+OezDggYyPDw8LCzs4cOHFEXhOM7J/4czpFJpaGjo4cOH4d1eU2ptdSgWjC+//JJhmCFDhrRk1A4ICOBOrX///uxURhBk4sSJfHhySRF1qWedH8MdSHEx8/8O49qlS5emH7IbipB5zO8S9Kmdyu1oRzucY/Xq1fb/OqzlZl062gjtYuR3gghOee343dCnTx8J553ZXkNpX0/taEcb4GlYWImJie7u7uy/8OAsnGy3bt1WrVrVFjFfol8fshdkfBqLNYQwLEQI3n333YULFz7zzDOi8AMBANixYwfDMKtWrRKR7IABAw4cOHD58uUvv/xSRLL2IQkuN1ar1c2qMxiGwRnHe6Rv3brF8Ulo4tm5c+eePXu4THPuLH3xxRdVVVU2m01EbwGZTFZTU8MwTE1NTWRkpCg0m8aWQJ9CrmhW4ECZJpVKPTw8MAzr3Lnza6+9lpWVJbpHiVqthneTGRkZBEHA25zw8HCx6KempkIbd1VVlYiiddu2bZAsTdOihGA6rEJBAtYB7u7u69evLygouHfvXn19vU6noyiKIIitW7cK7BGFQoEgSGBgYOfOnUeOHCmVSqVS6fjx43fu3Gk2m2maFmuuIAiC4zjsEd7O4E0RGxvb2NgIyVIUxW+bdBgkSG3ChAn2/4rAq1QqHTt2bG1trV6vb2hoOHv27KRJk5KTkwmCsNlsLntd/gIYccgwTG1t7aeffpqdnf3uu+9CB3MEQfbt2wcvEUU5tiIIEhISAgniOC6Kcw3EgQMH2IG0Wq3C9R1fX1/7kcMwjOdANnv5MG/ePKPROGvWrD59+sDg4aCgIIvFotPpeK8YVmJUVFRs3bq1urraYDAEBQV16tRp8eLFMKgR+u0Lx7hx4w4dOsQwTGVlJfR7FgVqtVqv17PeySNGjBCFrPhyFcaPDRs2zGKxGAyGpUuXwltDBEGMRiNJkleuXGnaiosecf/+fbiprFmzBn6ye/furKwsFEX//ve/T548mV/ARrMICAgwGo2wOxYsWCDivj5gwAA2+hXHceGKOkTTgRSFrKS0tBRuAP7+/nK5XCaTTZkyxWAwEATR1KWRI2iadnd3d7hSh+ETGo1mzpw5FEXB4EjhgDG5DMPo9frAwEBRaELMnj3bXq6IRZbNQgbnumgDGRMTQ5KkzWYzGAw4jsO/GYb54YcfeG8Jy5Yta2kSwMgmhmHECQqUSMrLyxmG2bFjx969ezndsHPGlStXmF/yCWRlZbm6IlsdITH1VYlEolarFy5cWFhYqNPpdu/eXVJScufOHZqmy8rKeGvb27Ztu3TpUtPPAQBsiJ0oao5UKq2pqcFx3MvLS1xrDjzpMgxjNpuvX7/OW+lrCXAIXXZFa3WeAgCgSunh4XHr1i2aplNSUnhzGRISQlHUn//8Z+iCBRdKRETEoEGDtm7dCiW5KEvnu+++gycl0e1n3bp1g3KvoqKiZ8+ePGaJk6UmaC0yDMMxrrOkpMRgMAjc261Wq9FoNJlMrNZH/wK4nwkhDuHu7m6xWGia3rRpk7gDCQC4efMmZNtkMj333HMiSmzGDi435j6htFptYWHhsWPHhLCOYdj06dN1Oh3MZsQC7r4Mwwg3oQUHBz958gTSbDUUy1UkJCSw86+oqEjE4Evmt+De8N/jx10Wq9Xq0NBQo9Ho/DHnHUeSZGFhYadOnSZOnFhSUkKSZFFR0dGjR2GGk44dOwqP0a2trVUqlQzDzJgx4/bt26KpDBKJRCLx9fWFP9BsNj969KihoUE4zXPnzonGJJdpO378eJqmW3WSd8lDVyaTTZgwwcPDY8+ePcuWLRNl9SgUCpj6QKxzuj3y8/Phijlx4kRWVhbvY5gDIM3k5GT+opWj/gkAOH/+PEmSERERLr+jBYLu7u5arXbv3r0vvvjiwYMHQ0JChJPVaDTZ2dkEQdTV1Yl1I2EPk8kEO3rixIli7b4OgyfmwaMp5HK5Tqczm82iXANJpdL4+PiEhIRHjx6dPn06JSVl8uTJoixHuVxuNBrbSF+F+UigdjZgwACxdl+mCUQh2zzc3NyMRqOQ4Eh7aDSa3Nzca9euwWgesQSURCJBEARenpw8eVIsmixgqBPUV/lkwGkBOI7DdCkijGKr6yw4ONhoNO7fv9/JMy6dqFAULSoqCgwMVKlUIiqWGIYVFxdbLJYVK1aIRZMFAAAOZElJibg+heKvxZb6dO7cudBK1+pocR/Oy5cvNzY2sqE8LvHZEry9vT/55JOsrKy2SLaLouh33313+/ZtsazkbQs2rtr+k5UrV1qt1srKymZnov3gccypCQCIj4//6quv2tTdS3TiYnmC/Wfg7+8PT8G5ublizfRevXqJQscB9lNQXEO5PWQy2dPgbvgbvPfee9wfbqu0Ie1oRzva0Q6R4GSbcXAhcCl5RnuwkfhwVSNgXXXaN+OnDlyOiQzDpKamtkrqqV1qDr/uv20WOvk9ly9fhsnjoY+rWPmj/lvhJNsHH2g0GiEWDQBAaGioyWTCMCw8PNzePWDz5s3isPgfQnZ2dlpa2qhRo9i+FuVqAUXRyspK12I/WgWCIPfv3zebzaNGjeJNxNvbOy0tbc2aNQ0NDRMmTKBp+uuvv/bw8FCpVL169WoLK0xxcbHJZHrttdfEpcwiLi7OarXW1tYyDKNUKjt06ICiqChdDwB49tln9Xo9SZJi7ikAgIqKCrPZ7FJ1CzbN/DPPPJOYmBgWFgYA6NChg7u7OywIJZFIfHx8unTpkp6eLvoWyNq4aZp2NbNWqx7SKIpu375906ZNNpvNZrM5JCFKSEjgw7EdFAoFzHL+008/CST1G6AoWlJSQtP0mTNneDSXy+UjR45UqVRxcXEBAQGs8Qxm8Z49e/bVq1dhzZSWwCNPrLe3NyvAxRVQQUFBtbW1BEHo9fopU6a8/fbbbHEEiUQCABgyZIiQeQkAOHr0KOS8d+/eInH9C+kffviBJMkFCxa41BDmLKuqqho6dKjDzuHn5zdp0iSYwXzy5Mmt3vAtXbrUpVcPHjyYHUge6ehaSiXWpUuXPn36FBQUrFy5MiQkxMH47OnpuXz58pqaGrlcztubQqlUsgF7IvvNAgCKiooMBgOP0i0XL15cu3atr68vm+YaJqLr0qULjKIFACxfvnz69OnibpOvvvoqq08NHz5cIDXof5ufn5+bmxsZGblkyRIHtRyuSJVKlZiYKOQGHkXRgIAAyDmO462ubNfuYtRqdceOHWUyWdPbj1Z7Pykp6Y033qirq2NjG4YNGxYREQFHkWEYFEVNJlNOTs727ds51jTmAjY7GwDApSTHzV5UMQzTr1+/MWPGAADCwsLOnTvHihAEQcLDwz/88MOjR4+eOXPmwoULRqORt+KanJx84MABiURCkmRcXJzzzKkuY+LEiTDE0KHKgKenJ7/7OYcSoElJSbW1tRs3bvT29rYfS/gMj/0GQRAYhAThJOc9d8TExFRUVOTm5gYHB3fp0oUdKh8fH5itmWEYkiRhARN+EddyuRwGrDEMc/XqVS5961rve3l5SSSSgoKCCxcu2H/+5MmTVj1jYe6e37wbQRxq5BQWFg4ePLixsTElJcX+tAqfIUmSezZQtiHrPQzD2bm3bQl3794lCGLUqFE+Pj5wIvr4+Mjl8tGjR7u5uV27dm3p0qUymSwwMHDgwIH8kisHBwdDb0Kapn/66Sfxk5vPnj2bpmkRPY6aAgCwaNGisLCwbt26iUJNr9fDqV1aWspRMjt/TC6Xl5WVffTRRxkZGcHBwZ6engEBAXPnzv3+++/ZvAqsQs5vv8/Pz6dp2mKxWCyWoKAgLm5prq3IgIAAGInPgznu2LVrV1RUVHFxsShaz+zZsyUSCUVRq1ev5si588eio6Ohq5hOp/Pw8AgODp40aVL37t0nTZpksVhgW9aHikdfAQDu3bsHADhy5EhaWlpNTY1Ykdv/Boqijx8/pijKpYrmTuDp6cnKSRiWBROH5ObmRkVFOehTvDOdnjp1imEYgiCef/554TMDABAdHV1WVnbx4sUxY8Zs2bIFsu3n5yeWsq3RaGAV2ldeeYVHJbnWgWGYyWR6/PgxD5WhWXdvpVIJS9fAGPeSkpL58+er1epZs2YNHToUAODp6QlrvEokEn5FbqCmCrUPV8++zVILDw9vaGiAtRdNJpPVaoXJq2EOC4H0IRYuXMgwDEVRe/fuFdHX91fAm4qzZ8+K6EAG07OgKDpjxoxVq1ZdvXp1wIABSqUyMDBQoVCsWbMG6oSw8Dk/+nCPJAjixRdf5M0nPGy8/PLLVVVVI0eOzMvLu3nzJqycyDvUq9m8G8OHD4d6r81mS0tLaxOPy6ioKIvFMnPmzLawa3t5eWVmZl64cEGtVsvlcujNTVHUwoUL7QfAVROdWq1my9dnZ2fzZk8qlWZkZFit1oqKirfeeksmk/n7+5vNZpvNBjV5sfD222/D8no5OTliBdg44uTJkzRNd+7cWUSaUVFRGo2mR48eBoOBpumGhoZu3brNmTOHDXfasWMHiqK8vS9lMhlrMX/y5AlvPgcNGqTT6exTd4wcOdJqtX722WfsOVKU+Q0DRqEi0hbe1RIAwM8//0xRlLhnj+zs7AULFrDnaJ1OB+t8w1F88uSJt7d30/wf3OlLpVK2uOOsWbN4cAjL5cJ6VXV1dQqFAsMwtVo9d+7cGzduDB8+XERPAFgFGZb4dZUs141HpVL5+fnBYro8+Gup1Ycffuju7v748eN169ZdvXrVy8urqqoKfjV27NgTJ05AwSixKzzjkkLPbueM6+mXINuwXO79+/fj4+MRBDl69GhOTk5AQEBVVdWQIUPUarVCoYDBN4BfaRw7dO/eHTo9Q7OOEFItYsaMGRRFXbt2rS30KLbUmVKpDAsL+8c//sF+JXC+R0ZGwrOd2WwWIqnc3d1LS0tLS0ufPHlSXFw8evRotVqNomjfvn3Dw8ODgoJa0kpcUgxnzJgBRVF6erqrHHJ9TWBgILSStEUJULi90zQNtYnRo0ezX7VUq4sjTCYTXCgmkwnHcd50jEbj8OHDT5w4UVdX5+Xl1blzZ5VK5e7u/uabbx48eBBmKWz2dOSSALtw4QLcBU6dOsWb1VYQFBS0cePG5ORkfls6W9jNJQhXH1jxCG0lQujAwkfw33379uXn5x89evT+/fvQ/2jo0KHCs+7K5fLMzMyoqCiBdP47AY0joqiU9kTUavXYsWPtw7L+wPFZXMBuHqI44/AYD3tD4B8FUqn0qYvzahbOa9k9zfjDzYl2tKMd7fgfx3+5utSOdrSjOfwxFOJ2cISHh0dqauorr7zSduP6xRdfMAzz6NEjUe5x1Gq1KF6QzhEeHv7kyZO1a9eK4k0yffr0Bw8eiJuB3RGDBw+2WCyPHz9uo3RBAIDs7Gyj0Wg0GgV2Ciz3odfrcRyPjY0Vi8OmAAB069btwoULBEEILBMNAIiKioKW55KSkjZ0WPTy8iorK6utrW2jgZRKpfX19ZWVlf/3f/8nkBQAQCaT1dXV0TTNJRaaN1QqVXFx8QcffJCZmSmcmlqthq6KOI6npaUJJ9g8/P39KYoym81tFFq9evVqaOYWxfrj6ekJb631en0b7QUIgly8eNFms9XX14vi9uHr6wuzTzIMc+TIEeEEm0d8fDxFUfX19W1x6AEAsBk0RZkoKIreu3ePoqjS0lLh1JqFj48PjuM4jh8+fFiUPpHL5WwZry1btnBs5fKLJ06cSJLkxYsXxfdjl0hQFIUXT9DjQThBiqJgXYo2GkipVDp//nwURc+cOZOdnc39Wt+JeLCvsLBt2zYRuGz29eXl5TRNN735FC64MAzbtGkTdNUR0aoO98g9e/aIRdAeUC9jGCYiIsKl5eiku1g/I4Zh1q9fLwabTeDv7w9FX1FRkT0rffr0CQsLc86fcwAA5s+fD7nfs2cPb28rB8hksoaGBoZhli9fLvpekJSUBMsiGI1Ge2VVqVTaFxV2Ff369WMHsri42P4r0bb5uLg46JaRkZEhru6AYVh1dTV0CZ88ebKIlKHPjog5qyFQFP3iiy8oiiJJct68eSISf+aZZ9g4wNu3b4tF9jcYOHAgTdMzZ84U/YidmJhIkqTJZGpoaPD09BTRxauiooJhmI4dO4pFEAJBkNu3b9M07evrq9VqRaTMVp6laXrIkCFc+eH+AgDACy+8AKMpzGYzLyZbxNSpU1EUvXz58sCBA41Go4jxR9988w3DMKJfCCclJUVERFRXV9fX19fX17vU1vnyvXLlChvHGR8fz5GmCwOJYdjrr78u+UVYcW/YKlQqFTxKf/XVV0VFRQI95xwAfXbEPVmjKHrs2DEURTUaDQ/t2nnvNTQ0sNOOIAiOW7sLA6nVaqFCZTAYuLfigpUrV0qlUsaupBL3tq3+TljGJTw8XKxtDEGQkSNHQo+6d955R3RPYqvVCgcSALBq1SpxiUskv9hcGhsbRTQAIgjy+uuvw8EzGAw+Pj7i6pYAgOPHj5MkOX/+fLEG8uWXX4aqu8lkagt37R49erCWHTZtf6vg2msw/Q9FUTt37hQlEh+CYRhoUzUYDKmpqUajUVw7A8Mwhw8fJggiISFBrCliNBphsFh4eLjIscQSiUQi0el0Dx8+hH+7ubk5r6Dm8o+SSqWwPie/NBUtAcMwaI6Cxtu2MIeeP38ex/GtW7eGhoYKp4YgSO/evc1mc2Njo7gBdSwwDHv8+DF7lDQYDFy6het4pqSkAABomq6srBTG56+Ijo4uLCyEuT3u3r3rkOFDLMAqJREREc7vxbh0FgCgsLDw+PHjEolkw4YNjY2NYjL6CyiKKisrY/lRqVRckvVwGkgURffv3w8AKCsrE0v0yWQyFEXDw8OhfbXt7msUCgUAQKvVxsTEOJkoXOZQp06dUBSFmkhlZWVbWJshJ3fv3mX/NZlMomVL6tq1K7RiDxw4UByKEolEItFqtTiOQwWq7fwN4uLiCIK4f/8+j4SEDvDx8Tl06BBJksXFxW0RzMQCnmqgaM3KyhJtO1uzZg2O4wRBCDEhNoVarX7w4AGM+xWRrAP8/f1xHG9oaBCeBtfLy2vBggUVFRXjxo1rU5dzFEUfPnwIbdpiJvaAwd9/UOerQYMG3b17NycnR/hAwmQCv08/AADgpiBpd3trRzuaAe/Ehu34X0F7pEA72tEOVzF06FAhzdskaZAwNE2Mzl026nQ6Ia8WOUU9D3C/JXiqVG1+LpnwJ7z00kstVUdpNllWS1nweTDACSKSFiW17tMMl/qqvLy87TgRExyt0r8DJ+34FXK5PC8vjyCI8PBwuVzODkBTWeTq2DTr1iVcQXdzc4uOjv7vqCAnznEFAODm5ga9cqEXhX3tGVHoO3yiVqudX662iri4uPPnz1ssluTkZO6tXDr7/26yBMOwl156SYTXeXt722w2GPd1586dFStW2H/rpF6Hq34FyC9QqVQmk2nlypWAb9H4wYMH4zhus9m4exdyAfxRrA8qjuNZWVlcGqIo6uoVGBw5mUzWs2dPs9l88uRJiZClqdVqdTodzEO5cuXKQYMGOUwNgTOFTVGFomhqaqrJZFq8ePHjx4937tx569Yt3mQzMzNpmrbZbKI4CUCkp6cfOXKEsQNN07W1tcIvy1jA3NIw//ahQ4dwHJ8xYwZBEHfu3LGPD2kRLT0BAHB3d9+1a1dVVdWBAweio6ObPglXJPfDH4IgcPA6d+785ptv3rt3r6GhwWKxlJeXw6vKiooKiqKsVquQKXLkyBGKosrLy0URgDDMCA4em1rWZrOVlZVlZGQkJiYKf8XUqVNv375NEARJkiRJ2mw2mE/61q1b0NNfkEs0AECtVpeXl3/22Wew0EDTfnHpujUvLw8OJIZhpaWlMBmsxWIhCMJsNtfW1l6/fh3DsCtXriQkJAjx+KqtrYUihDcFCJho0h4kSer1+qqqqh9//DE0NDQmJmbOnDkC3+Lr60uSJFziJpPJbDbD0jPff/+9TCa7d+/eqFGjCIJohVEnX0ml0vT09J9//lmn0wUFBTkcZj08PLp168Z9IGGJATiKn332GazUlJubu2vXrjFjxkCPCliiTaVSmc1m3oupT58+cIq89dZbDl+5usfAKg4QJpPp+vXro0aNWrx48aVLl6DYwHFcYGyCXC6HuYZhoZL9+/dPnTpVo9FotVqoz2MYJvSSPCws7OOPP37w4MGNGzdgBRMAgK+vb3JyMkVRBoNBKpWGhoY22+MOwlYmk2k0GsjN4MGDy8vLr1+/vnTpUqVSKZVKWS6blsdyFQAAeNVO07SD+/2pU6c6dOjAnVRKSgocQqPROGLECK1Wy86DEydOwIoDRqORCyknkTO7d+8mSdJsNs+cORPDMIVCERwcDAv82E87/vkuMQzbuHHjvn37KioqJkyYkJCQAGn169dPKpWypYRcQmBg4P79+2022/379/v27XvixIlx48bZZzAXfuzr1KkTdPb96KOPeJQNYSGTydi16OCfDcsVsxKF9ysAAKxkWrt2bWFhYVpaWlBQEPSiAwBw6o1WhyE2NvYvf/nLhx9+uGLFioCAAHd3dw8PD1hFkm3rql/CgQMHoNCDIcoURen1+r/97W9SqZTNcitQPUlJSYH7jUA6sC47lHjshIDeGP/6179Ylefhw4e8fc8TEhLsS4fD80xeXl5CQoKfn19AQIDz5r/mbnfyECxzER0dXV9fr9FoPDw8tFptUFAQLMDAtmVcTB7fo0eP+vp6s9lsNpunTZtWUlLy4MGD995779tvv71x40ZOTg5cBxypNYsJEyYAAO7cuSOQTkZGBqSAIIjJZIJued7e3l26dBkwYAAr9D7//HPevudHjx5lUwewS/zVV189d+7c5cuXRfD4RVHUy8srPz//1q1bR48etVqtcXFx7u7usJiuEMpNz6A+Pj4//vhjXV3d9evXYdS/kFcgCAKjgmBmcyGsoijKVoZl9VVWt2Q/FPIWDMNgiVs3NzcMwxITE1etWoXjOEVRBw8eFOF4GhAQcPr0aSj6oCTs06cPdKrjuIdxD/pRqVRz585NSEhISUnp3r27QKOiTCaDvSzWxcL333/P1juCvWE2m9mB7NevHxcizqsaQyMAZH7x4sW1tbV//etfXVLKmgcAIDs7e/ny5WfPntXr9ZDpvn378tYhJU5VGK1WW1pa+txzz4kSVvHGG29Ahnfu3CmcGgT8CdHR0QqFQqPRHD58GK5L3qKv2Z5EUdTPz+/QoUNms1mERGZQ1qWmpo4ZMyY5OXnJkiU4jpMkKfCopFQqmzX9AAD27duH4/jEiRNFMcFERETAgYTVUdsCU6dOhdJ13bp1/ChAzY79F8o5AMCYMWMIgtDpdEJVd7jGhw8f7uXlBQCQy+Vnz56laVqn03l7e/PoaHi6z8/P37Fjx8svvwxTUbG/QaFQ5OXlwY3H4ZzAe1C7du0qfOtyAhjVBF+xYcMGl9rC7aZ3794bNmzo0qWLwWBAEITdsI4fPw4tlEVFRYL4g3Bzc/v88887duwYEhLSr1+/yspKkiQLCwuhNYAHZWj3gco6SZLBwcFyuTwtLS0yMnLFihU//fRTdXW1iDG6UNlro1AbiUTSqVMnVs2B09QlwKUGJTNFUX/605+6du366aef7t69G8fxurq6JUuWiHD1CADIyMi4ePHiqlWrZs6ceffu3Xv37l27dm3nzp2wJDm/SyWZTAZZt9lsdXV1SUlJOp3OYDCYzWadTgdzFLTEj0svksvlcMbgOM5j2nFpYq+vukqffQs8cpAkaTAYXnjhBZg5jyTJTz75RHiMw78hk8k8PT2TkpIuXbq0adOmd955Jzo6OjMzMyQkRKvVtnT8aLULlEolrJLe2NhYU1MD42eNRuP48eNFdNUNDw+HHb19+/a2EK32dyAjRozgTUcmk0ETrslkqqiogHe9u3btcpVnZx1HEIRer7958+bevXtLS0tPnDih1+slEklWVpbVarVarc2eK1qdnhaLxcvLKzQ09NatWziOP3jwYNOmTXFxcQUFBSKKQTg/JBJJdXW1WDTtsXHjRravDx482NJjrY4HvJPat28frHE+b9684ODgtLQ0ESwALTEEY7I6dOjg5+cHP3F+JGqJTqufiAWtVtsmNYolEskvdc0heAsStjJzZGQkR88ScdyOngYvNziN/rPQaDRwCD09PQVGvNrfY/Do3qfQgbtFPA2zp63B/Tf+MXrjD8Fle2RdO9rRjtbw/6T2UG2O41iIAAAAAElFTkSuQmCC\n",
"text/plain": [
""
]
},
"metadata": {
"tags": []
},
"execution_count": 22
}
]
}
]
}