Пример #1
0
def generate(dataset):
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    sample_dir = os.path.join('samples', dataset)
    weights_dir = os.path.join('weights', dataset)
    os.makedirs(sample_dir, exist_ok=True)

    G = models.Generator(params['nz'], params['ngf'], params['image_size'],
                         params['labels'])
    G.load_state_dict(torch.load(os.path.join(weights_dir, 'G.ckpt')))
    G.eval()
    G = G.to(device)

    with torch.no_grad():
        random_labels = torch.LongTensor(
            np.random.randint(0, 10, params['batch_size'])).to(device)
        z = torch.randn(params['batch_size'], params['nz']).to(device)
        fake_images = G(z, random_labels)

    dt_now = datetime.datetime.now()
    now_str = dt_now.strftime('%y%m%d%H%M%S')
    fake_images = fake_images.reshape(-1, 1, 28, 28)
    save_image(utils.denorm(fake_images),
               os.path.join(sample_dir, 'fake_images_{}.png'.format(now_str)))
    print('Saved Image ' +
          os.path.join(sample_dir, 'fake_images_{}.png'.format(now_str)))
Пример #2
0
def generate():
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    sample_dir = 'samples'
    os.makedirs(sample_dir, exist_ok=True)

    G = models.Generator(params['image_size'], params['latent_size'],
                         params['hidden_size'])
    G.load_state_dict(torch.load('weights/G.ckpt'))
    G.eval()
    G = G.to(device)

    with torch.no_grad():
        z = torch.randn(params['batch_size'], params['latent_size']).to(device)
        fake_images = G(z)

    fake_images = fake_images.reshape(params['batch_size'], 1, 28, 28)
    dt_now = datetime.datetime.now()
    now_str = dt_now.strftime('%y%m%d%H%M%S')
    save_image(utils.denorm(fake_images),
               os.path.join(sample_dir, 'fake_images_{}.png'.format(now_str)))
    print('Saved Image ' +
          os.path.join(sample_dir, 'fake_images_{}.png'.format(now_str)))
Пример #3
0
def train():
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    sample_dir = 'samples'
    os.makedirs(sample_dir, exist_ok=True)

    transform = transforms.Compose(
        [transforms.ToTensor(),
         transforms.Normalize(mean=[0.5], std=[0.5])])

    mnist = torchvision.datasets.MNIST(root='data',
                                       train=True,
                                       transform=transform,
                                       download=True)

    data_loader = torch.utils.data.DataLoader(dataset=mnist,
                                              batch_size=params['batch_size'],
                                              shuffle=True)

    D = models.Discriminator(params['image_size'], params['hidden_size'])
    G = models.Generator(params['image_size'], params['latent_size'],
                         params['hidden_size'])

    D = D.to(device)
    G = G.to(device)

    criterion = nn.BCELoss()
    d_optimizer = utils.get_optim(params, D)
    g_optimizer = utils.get_optim(params, G)

    d_losses = []
    g_losses = []
    total_step = len(data_loader)
    for epoch in range(params['epochs']):
        for i, (images, _) in enumerate(data_loader):  # labelは使わない
            # (batch_size, 1, 28, 28) -> (batch_size, 1*28*28)
            b_size = images.size(0)
            images = images.reshape(b_size, -1).to(device)

            real_labels = torch.ones(b_size, 1).to(device)
            fake_labels = torch.zeros(b_size, 1).to(device)

            # Train discriminator
            outputs = D(images)
            d_loss_real = criterion(outputs, real_labels)
            real_score = outputs

            z = torch.randn(b_size, params['latent_size']).to(device)
            fake_images = G(z.detach())
            outputs = D(fake_images)
            d_loss_fake = criterion(outputs, fake_labels)
            fake_score = outputs

            d_loss = d_loss_real + d_loss_fake
            d_optimizer.zero_grad()
            d_loss.backward()
            d_optimizer.step()

            # Train generator
            fake_images = G(z)
            outputs = D(fake_images)

            g_loss = criterion(outputs, real_labels)

            g_optimizer.zero_grad()
            g_loss.backward()
            g_optimizer.step()

            print(
                'Epoch [{}/{}], step [{}/{}], d_loss: {:.4f}, g_loss: {:.4f}, D(x): {:.2f}, D(G(z)): {:.2f}'
                .format(
                    epoch, params['epochs'], i + 1, total_step, d_loss.item(),
                    g_loss.item(),
                    real_score.mean().item(),
                    fake_score.mean().item()))  # .item():ゼロ次元Tensorから値を取り出す

            d_losses.append(d_loss.item())
            g_losses.append(g_loss.item())

        if (epoch + 1) == 1:
            images = images.reshape(b_size, 1, 28, 28)
            save_image(utils.denorm(images),
                       os.path.join(sample_dir, 'real_images.png'))
        fake_images = fake_images.reshape(b_size, 1, 28, 28)
        save_image(
            utils.denorm(fake_images),
            os.path.join(sample_dir, 'fake_images-{}.png'.format(epoch + 1)))

    torch.save(G.state_dict(), 'weights/G.ckpt')
    torch.save(D.state_dict(), 'weights/D.ckpt')

    plt.figure(figsize=(10, 5))
    plt.title("Generator and Discriminator Loss During Training")
    plt.plot(g_losses, label="Generator")
    plt.plot(d_losses, label="Discriminator")
    plt.xlabel("iterations")
    plt.ylabel("Loss")
    plt.legend()
    plt.savefig(os.path.join(sample_dir, 'loss.png'))
Пример #4
0
def train(dataset):
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

  sample_dir = os.path.join('samples', dataset)
  weights_dir = os.path.join('weights', dataset)
  os.makedirs(sample_dir, exist_ok=True)
  os.makedirs(weights_dir, exist_ok=True)

  transforms_ = [
      transforms.Resize(int(params['img_height'] * 1.12), Image.BICUBIC),  # 短い方の辺をsizeにする, 比率はそのまま
      transforms.RandomCrop((params['img_height'],['img_width'])),
      transforms.RandomHorizontalFlip(),
      transforms.ToTensor(),
      transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
  ]

  # DataLoader
  data_loader = torch.utils.data.DataLoader(
      ImageDataset(os.path.join('data', dataset), transforms_=transforms_, unaligned=True),
      batch_size=params['batch_size'],
      shuffle=True
  )

  val_data_loader = torch.utils.data.DataLoader(
      ImageDataset(os.path.join('data', dataset), transforms_=transforms_, unaligned=True, mode='test'),
      batch_size=5,
      shuffle=True
  )

  # Models
  D_A = models.Discriminator(params['channels'])
  D_B = models.Discriminator(params['channels'])
  G_AB = models.Generator(params['channels'], params['n_residual_blocks'])
  G_BA = models.Generator(params['channels'], params['n_residual_blocks'])

  D_A = D_A.to(device)
  D_B = D_B.to(device)
  G_AB = G_AB.to(device)
  G_BA = G_BA.to(device)

  # initialize models parameters
  D_A.apply(utils.weights_init)
  D_B.apply(utils.weights_init)
  G_AB.apply(utils.weights_init)
  G_BA.apply(utils.weights_init)

  # Losses
  criterion_GAN = nn.MSELoss()
  criterion_cycle = nn.L1Loss()
  criterion_identity = nn.L1Loss()

  # Optimizer
  # Generatorは同時に最適化を行う
  optimizer_G = utils.get_optim(
      params,
      itertools.chain(G_AB.parameters(),G_BA.parameters()), 
  )
  optimizer_D_A = utils.get_optim(params, D_A)
  optimizer_D_B = utils.get_optim(params, D_B)

  # learning rate schedulers
  lr_scheduler_G = torch.optim.lr_scheduler.LambdaLR(
      optimizer_G, lr_lambda=utils.LambdaLR(params['epochs'], decay_start_epoch=params['decay_epoch']).step
  )
  lr_scheduler_D_A = torch.optim.lr_scheduler.LambdaLR(
      optimizer_D_A, lr_lambda=utils.LambdaLR(params['epochs'], decay_start_epoch=params['decay_epoch']).step
  )
  lr_scheduler_D_B = torch.optim.lr_scheduler.LambdaLR(
      optimizer_D_B
      , lr_lambda=utils.LambdaLR(params['epochs'], decay_start_epoch=params['decay_epoch']).step
  )
  # Buffers of previously generated samples
  fake_A_buffer = utils.ReplayBuffer()
  fake_B_buffer = utils.ReplayBuffer()

  def sample_images(epochs):
      """Saves a generated sample from the test set"""
      imgs = next(iter(val_data_loader))
      G_AB.eval()
      G_BA.eval()
      with torch.no_grad():
        real_A = imgs["A"].to(device)
        fake_B = G_AB(real_A)
        real_B = imgs["B"].to(device)
        fake_A = G_BA(real_B)
      # Arange images along x-axis
      real_A = make_grid(real_A, nrow=5, normalize=True)
      real_B = make_grid(real_B, nrow=5, normalize=True)
      fake_A = make_grid(fake_A, nrow=5, normalize=True)
      fake_B = make_grid(fake_B, nrow=5, normalize=True)
      # Arange images along y-axis
      image_grid = torch.cat((real_A, fake_B, real_B, fake_A), 1)
      save_image(image_grid, os.path.join(samples_dir,"fake_images-%s.png" % (epochs)), normalize=False)

  losses_D = []
  losses_G = []
  total_step = len(data_loader)
  for epoch in range(params['epochs']):
    for i, images in enumerate(data_loader):
      real_A = images['A'].to(device)
      real_B = images['B'].to(device)

      b_size = real_A.size(0)

      # TODO: require_grad, G.train(), 自動化できないか
      real_labels = torch.ones((b_size, 1, 16, 16)).to(device)
      fake_labels = torch.zeros((b_size, 1, 16, 16)).to(device)

      # Train Generator
      optimizer_G.zero_grad()

      # GAN loss
      fake_B = G_AB(real_A)
      loss_GAN_AB = criterion_GAN(D_B(fake_B), real_labels)
      fake_A = G_BA(real_B)
      loss_GAN_BA = criterion_GAN(D_A(fake_A), real_labels)
      loss_GAN = (loss_GAN_AB + loss_GAN_BA) / 2

      # Cycle loss
      recov_A = G_BA(fake_B)
      loss_cycle_A = criterion_cycle(recov_A, real_A)
      recov_B = G_AB(fake_A)
      loss_cycle_B = criterion_cycle(recov_B, real_B)

      loss_cycle = (loss_cycle_A + loss_cycle_B) / 2

      # Total loss
      loss_G = loss_GAN + params['lambda_cyc'] * loss_cycle

      loss_G.backward()
      optimizer_G.step()

      # Train discriminator A
      optimizer_D_A.zero_grad()

      loss_real_A = criterion_GAN(D_A(real_A), real_labels)
      fake_A_ = fake_A_buffer.push_and_pop(fake_A)
      loss_fake_A = criterion_GAN(D_A(fake_A_.detach()), fake_labels)
      loss_D_A = (loss_real_A + loss_fake_A) / 2
      loss_D_A.backward()
      optimizer_D_A.step()

      # Train discriminator B
      optimizer_D_B.zero_grad()

      loss_real_B = criterion_GAN(D_B(real_B), real_labels)
      fake_B_ = fake_A_buffer.push_and_pop(fake_B)
      loss_fake_B = criterion_GAN(D_B(fake_B_.detach()), fake_labels)
      loss_D_B = (loss_real_B + loss_fake_B) / 2
      loss_D_B.backward()
      optimizer_D_B.step()

      loss_D = (loss_D_A + loss_D_B) / 2


      print('Epoch [{}/{}], step [{}/{}], loss_D: {:.4f}, loss_G: {:.4f}, D_A(x): {:.2f}, D_A(G_BA(z)): {:.2f}, D_B(x): {:.2f}, D_B(G_AB(z)): {:.2f}'
            .format(epoch, params['epochs'], i + 1, total_step, loss_D.item(), loss_G.item(),
                    loss_real_A.mean().item(), loss_real_B.mean().item(),
                    loss_real_B.mean().item(), loss_real_B.mean().item()))  

      losses_G.append(loss_G.item())
      losses_D.append(loss_D.item())

    if epoch % params['checkpoint_interval'] == 0:
      torch.save(G_AB.state_dict(), os.path.join(weights_dir, 'G_AB.ckpt'))
      torch.save(G_BA.state_dict(), os.path.join(weights_dir, 'G_BA.ckpt'))
      torch.save(D_A.state_dict(), os.path.join(weights_dir, 'D_A.ckpt'))
      torch.save(D_B.state_dict(), os.path.join(weights_dir, 'D_B.ckpt'))

    # if (epoch + 1) == 1:
    #   save_image(utils.denorm(images), os.path.join(
    #       sample_dir, 'real_images.png'))
    sample_images(epoch + 1)


  plt.figure(figsize=(10, 5))
  plt.title("Generator and Discriminator Loss During Training")
  plt.plot(g_losses, label="Generator")
  plt.plot(d_losses, label="Discriminator")
  plt.xlabel("iterations")
  plt.ylabel("Loss")
  plt.legend()
  plt.savefig(os.path.join(sample_dir, 'loss.png'))
Пример #5
0
def train(dataset, data):
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    sample_dir = os.path.join('samples', dataset)
    weights_dir = os.path.join('weights', dataset)
    os.makedirs(sample_dir, exist_ok=True)
    os.makedirs(weights_dir, exist_ok=True)

    if dataset == 'mnist':
        dataset = torchvision.datasets.MNIST(
            root=data,
            download=True,
            train=True,
            transform=transforms.Compose([
                transforms.ToTensor(),
                transforms.Normalize(  # [0,1] -> [-1, 1]
                    (0.5, ), (0.5, )),
            ]))
        params['nc'] = 1

    data_loader = torch.utils.data.DataLoader(dataset=dataset,
                                              batch_size=params['batch_size'],
                                              shuffle=True)

    D = models.Discriminator(params['ndf'], params['image_size'],
                             params['labels'])
    G = models.Generator(params['nz'], params['ngf'], params['image_size'],
                         params['labels'])

    D = D.to(device)
    G = G.to(device)

    criterion = nn.BCELoss()
    d_optimizer = utils.get_optim(params, D)
    g_optimizer = utils.get_optim(params, G)

    d_losses = []
    g_losses = []
    total_step = len(data_loader)
    for epoch in range(params['epochs']):
        for i, (images, labels) in enumerate(data_loader):
            b_size = images.size(0)
            images = images.reshape(b_size, -1).to(device)
            labels = labels.to(device)

            real_labels = torch.ones(b_size).to(device)
            fake_labels = torch.zeros(b_size).to(device)
            random_labels = torch.LongTensor(np.random.randint(
                0, 10, b_size)).to(device)

            # Train discriminator
            outputs = D(images, labels)
            d_loss_real = criterion(outputs, real_labels)
            real_score = outputs

            z = torch.randn(b_size, params['nz']).to(device)
            fake_images = G(z, random_labels)
            outputs = D(fake_images.detach(), random_labels)
            d_loss_fake = criterion(outputs, fake_labels)
            fake_score = outputs

            d_loss = d_loss_real + d_loss_fake
            d_optimizer.zero_grad()
            d_loss.backward()
            d_optimizer.step()

            # Train generator
            # ランダムなラベルを再定義
            random_labels = torch.LongTensor(np.random.randint(
                0, 10, b_size)).to(device)
            fake_images = G(z, random_labels)
            outputs = D(fake_images, random_labels)

            g_loss = criterion(outputs, real_labels)

            g_optimizer.zero_grad()
            g_loss.backward()
            g_optimizer.step()

            print(
                'Epoch [{}/{}], step [{}/{}], d_loss: {:.4f}, g_loss: {:.4f}, D(x): {:.2f}, D(G(z)): {:.2f}'
                .format(
                    epoch, params['epochs'], i + 1, total_step, d_loss.item(),
                    g_loss.item(),
                    real_score.mean().item(),
                    fake_score.mean().item()))  # .item():ゼロ次元Tensorから値を取り出す

            g_losses.append(g_loss.item())
            d_losses.append(d_loss.item())

        if (epoch + 1) == 1:
            images = images.reshape(b_size, 1, 28, 28)
            save_image(utils.denorm(images),
                       os.path.join(sample_dir, 'real_images.png'))
        fake_images = fake_images.reshape(b_size, 1, 28, 28)
        save_image(
            utils.denorm(fake_images),
            os.path.join(sample_dir, 'fake_images-{}.png'.format(epoch + 1)))

    torch.save(G.state_dict(), os.path.join(weights_dir, 'G.ckpt'))
    torch.save(D.state_dict(), os.path.join(weights_dir, 'D.ckpt'))

    plt.figure(figsize=(10, 5))
    plt.title("Generator and Discriminator Loss During Training")
    plt.plot(g_losses, label="Generator")
    plt.plot(d_losses, label="Discriminator")
    plt.xlabel("iterations")
    plt.ylabel("Loss")
    plt.legend()
    plt.savefig(os.path.join(sample_dir, 'loss.png'))