2017-11-13 6 views
15

私はGANを勉強しています入力した例に基づいて画像を生成するプログラムの例を教えてくれた1つのコースを修了しました。PyTorchで新しい画像を生成する

の例では、ここで見つけることができます:

https://github.com/davidsonmizael/gan 

は、だから私は、顔の正面写真のデータセットに基づいて新しい画像を生成するためにそれを使用することにしましたが、私は、任意の成功を持っていないです。上記の例とは異なり、コードはノイズだけを生成し、入力は実際の画像を持ちます。

実際には、コードポイントを正しい方向にして画像から学ぶために何を変えなければならないのか分かりません。私は、この例で提供されているコードで単一の値を変更していませんが、動作しません。

私がこれを理解するのを手伝ってくれれば、正しい方向に向いてくれれば助かります。前もって感謝します。

私の弁別:

class D(nn.Module): 

    def __init__(self): 
     super(D, self).__init__() 
     self.main = nn.Sequential(
       nn.Conv2d(3, 64, 4, 2, 1, bias = False), 
       nn.LeakyReLU(0.2, inplace = True), 
       nn.Conv2d(64, 128, 4, 2, 1, bias = False), 
       nn.BatchNorm2d(128), 
       nn.LeakyReLU(0.2, inplace = True), 
       nn.Conv2d(128, 256, 4, 2, 1, bias = False), 
       nn.BatchNorm2d(256), 
       nn.LeakyReLU(0.2, inplace = True), 
       nn.Conv2d(256, 512, 4, 2, 1, bias = False), 
       nn.BatchNorm2d(512), 
       nn.LeakyReLU(0.2, inplace = True), 
       nn.Conv2d(512, 1, 4, 1, 0, bias = False), 
       nn.Sigmoid() 
       ) 

    def forward(self, input): 
     return self.main(input).view(-1) 

マイジェネレータ:

class G(nn.Module): 

    def __init__(self): 
     super(G, self).__init__() 
     self.main = nn.Sequential(
       nn.ConvTranspose2d(100, 512, 4, 1, 0, bias = False), 
       nn.BatchNorm2d(512), 
       nn.ReLU(True), 
       nn.ConvTranspose2d(512, 256, 4, 2, 1, bias = False), 
       nn.BatchNorm2d(256), 
       nn.ReLU(True), 
       nn.ConvTranspose2d(256, 128, 4, 2, 1, bias = False), 
       nn.BatchNorm2d(128), 
       nn.ReLU(True), 
       nn.ConvTranspose2d(128, 64, 4, 2, 1, bias = False), 
       nn.BatchNorm2d(64), 
       nn.ReLU(True), 
       nn.ConvTranspose2d(64, 3, 4, 2, 1, bias = False), 
       nn.Tanh() 
       ) 

    def forward(self, input): 
     return self.main(input) 

My機能の重みを開始する:

def weights_init(m): 
    classname = m.__class__.__name__ 
    if classname.find('Conv') != -1: 
     m.weight.data.normal_(0.0, 0.02) 
    elif classname.find('BatchNorm') != -1: 
     m.weight.data.normal_(1.0, 0.02) 
     m.bias.data.fill_(0) 

完全なコードはここで見ることができます:

https://github.com/davidsonmizael/criminal-gan 

エポック番号25に発生するノイズ:実画像と Noise generated on epoch number 25

入力: Input with real images.

+1

あなたのコードとデータを試してみましたが、コードを実行しようとしましたが、gan.pyの80行目には 'target = Variable(torch.ones(input.size()[0])).cuda() ' - 必ずしも使用していなくても(したがってcuda()以外の他の変数)、常にcuda()を呼び出すときのように。 –

+0

意味のあるものを生成し始めるには、おそらく25エポック以上必要ですか? – vasia

+0

@KenSymeええ、クーダを忘れる。私はすべてを終えて追加しましたが、まだテストする機会はありませんでしたが、私はサポートを追加したかったのです。それは問題ではありません:/ – davis

答えて

2

コードは私に同じノイズを与えました。発電機の損失はあまりにも早く減少しました。

バグがいくつかありましたが、私はもはや何も分かりませんが、自分で違いを理解するのは簡単だと思います。比較のために、また、このチュートリアルを見て: GANs in 50 lines of PyTorch

.... same as your code 
print("# Starting generator and descriminator...") 
netG = G() 
netG.apply(weights_init) 

netD = D() 
netD.apply(weights_init) 

if torch.cuda.is_available(): 
    netG.cuda() 
    netD.cuda() 

#training the DCGANs 
criterion = nn.BCELoss() 
optimizerD = optim.Adam(netD.parameters(), lr = 0.0002, betas = (0.5, 0.999)) 
optimizerG = optim.Adam(netG.parameters(), lr = 0.0002, betas = (0.5, 0.999)) 

epochs = 25 

timeElapsed = [] 
for epoch in range(epochs): 
    print("# Starting epoch [%d/%d]..." % (epoch, epochs)) 
    for i, data in enumerate(dataloader, 0): 
     start = time.time() 
     time.clock() 

     #updates the weights of the discriminator nn 
     netD.zero_grad() 

     #trains the discriminator with a real image 
     real, _ = data 

     if torch.cuda.is_available(): 
      inputs = Variable(real.cuda()).cuda() 
      target = Variable(torch.ones(inputs.size()[0]).cuda()).cuda() 
     else: 
      inputs = Variable(real) 
      target = Variable(torch.ones(inputs.size()[0])) 

     output = netD(inputs) 
     errD_real = criterion(output, target) 
     errD_real.backward() #retain_graph=True 

     #trains the discriminator with a fake image 
     if torch.cuda.is_available(): 
      D_noise = Variable(torch.randn(inputs.size()[0], 100, 1, 1).cuda()).cuda() 
      target = Variable(torch.zeros(inputs.size()[0]).cuda()).cuda() 
     else: 
      D_noise = Variable(torch.randn(inputs.size()[0], 100, 1, 1)) 
      target = Variable(torch.zeros(inputs.size()[0])) 
     D_fake = netG(D_noise).detach() 
     D_fake_ouput = netD(D_fake) 
     errD_fake = criterion(D_fake_ouput, target) 
     errD_fake.backward() 

     # NOT:backpropagating the total error 
     # errD = errD_real + errD_fake 

     optimizerD.step() 

    #for i, data in enumerate(dataloader, 0): 

     #updates the weights of the generator nn 
     netG.zero_grad() 

     if torch.cuda.is_available(): 
      G_noise = Variable(torch.randn(inputs.size()[0], 100, 1, 1).cuda()).cuda() 
      target = Variable(torch.ones(inputs.size()[0]).cuda()).cuda() 
     else: 
      G_noise = Variable(torch.randn(inputs.size()[0], 100, 1, 1)) 
      target = Variable(torch.ones(inputs.size()[0])) 

     fake = netG(G_noise) 
     G_output = netD(fake) 
     errG = criterion(G_output, target) 

     #backpropagating the error 
     errG.backward() 
     optimizerG.step() 


     if i % 50 == 0: 
      #prints the losses and save the real images and the generated images 
      print("# Progress: ") 
      print("[%d/%d][%d/%d] Loss_D: %.4f Loss_G: %.4f" % (epoch, epochs, i, len(dataloader), errD_real.data[0], errG.data[0])) 

      #calculates the remaining time by taking the avg seconds that every loop 
      #and multiplying by the loops that still need to run 
      timeElapsed.append(time.time() - start) 
      avg_time = (sum(timeElapsed)/float(len(timeElapsed))) 
      all_dtl = (epoch * len(dataloader)) + i 
      rem_dtl = (len(dataloader) - i) + ((epochs - epoch) * len(dataloader)) 
      remaining = (all_dtl - rem_dtl) * avg_time 
      print("# Estimated remaining time: %s" % (time.strftime("%H:%M:%S", time.gmtime(remaining)))) 

     if i % 100 == 0: 
      vutils.save_image(real, "%s/real_samples.png" % "./results", normalize = True) 
      vutils.save_image(fake.data, "%s/fake_samples_epoch_%03d.png" % ("./results", epoch), normalize = True) 

print ("# Finished.") 

結果CIFAR-10上の25のエポック(バッチサイズ256)の後に:私は、ダウンロードするには、現時点では時間がない enter image description here

+0

ここで紹介したコードに変更を加えてみました。第10期には既に結果を見せ始めていました。ありがとうございました! – davis

1

GANトレーニングは非常に高速ではありません。私はあなたが事前に訓練されたモデルを使用していないと仮定していますが、最初から学びます。エポック25では、サンプルに意味のあるパターンが見られないことは全く正常です。 私は、githubプロジェクトでは25エポック後にすばらしいことが分かりますが、それはデータセットのサイズによっても異なります。 CIFAR-10(githubページで使用されていたもの)には60000個のイメージがあります。 エポックは、ネットがそれらのすべてを25回見たことを意味します。

使用しているデータセットがわかりませんが、それより小さい場合は、結果が表示されるまでにエポックがさらに長くなることがあります。データセット内の画像の解像度が高い場合は、時間がかかることもあります。

少なくとも数百のエポックではないにしても、少なくとも数百回確認してください。


など。 enter image description here

そして50後のエポック:25のエポック後の正面顔写真データセットであなたが示すように、あなたの一例(https://github.com/davidsonmizael/gan)から enter image description here

+0

これらのサンプルを生成するには、私と同じコードとデータセットを使用しましたか?私はちょうどそれを実行し、それは150エポック後にもノイズを生成しただけです。 – davis

関連する問題