所以我正在做这个项目,这个项目生成水果的图像,到目前为止,我已经编写了大部分实际代码,但我遇到了这个非常奇怪的问题。我遵循了https://towardsdatascience.com/gan-by-example-using-keras-on-tensorflow-backend-1a6d515a60d0关于手写数字的教程,虽然我可以弄乱它,但我的代码给了我错误,不知何故,输出形状(28,28,1)仍然显示在生成器模型中,而不是我的(100,100,3),有人能解释我的这个奇怪的问题吗?
下面是我的代码:
import numpy as np;
import time;
#import training data
from keras.models import Sequential;
from keras.layers import Dense, Activation, Flatten, Reshape;
from keras.layers import Conv2D, Conv2DTranspose, UpSampling2D;
from keras.layers import LeakyReLU, Dropout;
from keras.layers import BatchNormalization;
from keras.optimizers import Adam, RMSprop;
class GAN(object):
def __init__(self, img_rows, img_cols, channel):
self.img_rows = img_rows;
self.img_cols = img_cols;
self.channel = channel;
self.D = None;
self.G = None;
self.AM = None;
self.DM = None;
def discriminator(self):
if self.D:
return self.D;
self.D = Sequential();
depth = 64;
dropout = 0.4;
input_shape = (self.img_rows, self.img_cols, self.channel);
self.D.add(Conv2D(depth*1, 5, strides=2, input_shape=input_shape, padding='same'));
self.D.add(LeakyReLU(alpha=0.2));
self.D.add(Dropout(dropout));
self.D.add(Conv2D(depth*2, 5, strides=2, padding='same'));
self.D.add(LeakyReLU(alpha=0.2));
self.D.add(Dropout(dropout));
self.D.add(Conv2D(depth*4, 5, strides=2, padding='same'));
self.D.add(LeakyReLU(alpha=0.2));
self.D.add(Dropout(dropout));
self.D.add(Conv2D(depth*8, 5, strides=1, padding='same'));
self.D.add(LeakyReLU(alpha=0.2));
self.D.add(Dropout(dropout));
self.D.add(Flatten());
self.D.add(Dense(1));
self.D.add(Activation('sigmoid'));
self.D.summary();
return self.D;
def generator(self):
if self.G:
return self.G;
self.G = Sequential();
dropout = 0.4;
depth = 64+64+64+64;
dim = 7;
self.G.add(Dense(dim*dim*depth, input_dim=100));
self.G.add(BatchNormalization(momentum=0.9));
self.G.add(Activation('relu'));
self.G.add(Reshape((dim, dim, depth)));
self.G.add(Dropout(dropout));
self.G.add(UpSampling2D());
self.G.add(Conv2DTranspose(int(depth/2), 5, padding='same'));
self.G.add(BatchNormalization(momentum=0.9));
self.G.add(Activation('relu'));
self.G.add(UpSampling2D());
self.G.add(Conv2DTranspose(int(depth/4), 5, padding='same'));
self.G.add(BatchNormalization(momentum=0.9));
self.G.add(Activation('relu'));
self.G.add(Conv2DTranspose(int(depth/8), 5, padding='same'));
self.G.add(BatchNormalization(momentum=0.9));
self.G.add(Activation('relu'));
self.G.add(Conv2DTranspose(1, 5, padding='same'));
self.G.add(Activation('sigmoid'));
self.G.summary();
return self.G;
def discriminator_model(self):
if self.DM:
return self.DM;
optimizer = RMSprop(lr=0.0002, decay=6e-8);
self.DM = Sequential();
self.DM.add(self.discriminator());
self.DM.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy']);
return self.DM;
def adversarial_model(self):
if self.AM:
return self.AM;
optimizer = RMSprop(lr=0.0001, decay=3e-8);
self.AM = Sequential();
self.AM.add(self.generator());
self.AM.add(self.discriminator());
self.AM.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy']);
return self.AM;
class Fruit_GAN:
def __init__(self):
self.img_rows = 28;
self.img_cols = 28;
self.channel = 1;
print('\nstarting\n');
self.GAN = GAN(self.img_rows, self.img_cols, self.channel);
print('\nGAN setup succeded\n');
self.discriminator = self.GAN.discriminator_model();
print('\ndiscriminator setup succeded\n');
self.adversarial = self.GAN.adversarial_model();
print('\nadversarial setup succeded\n');
self.generator = self.GAN.generator();
print('\ngenerator setup succeded\n');
def Train(self, train_steps=2000, batch_size=256, save_interval=0):
noise_input = None;
if save_interval>0:
noise_input = np.random.uniform(-1.0, 1.0, size=[16, 100]);
for i in range(train_steps):
# training images:
images_train = 0
# random noise for generator:
noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100]);
# generator generated fake images:
images_fake = self.generator.predict(noise);
# train data formating for discriminator:
x = np.concatenate((images_train, images_fake));
y = np.ones([2*batch_size, 1]);
y[batch_size:, :] = 0;
# training_discriminator:
d_loss = self.discriminator.train_on_batch(x, y);
# train data reformatting for generator:
y = np.ones([batch_size, 1]);
noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100]);
a_loss = self.adversarial.train_on_batch(noise, y);
log_msg = "%d: [D loss: %f, acc: %f]" % (i, d_loss[0], d_loss[1]);
log_msg = "%s: [A loss: %f, acc: %f]" % (log_mesg, a_loss[0], a_loss[1]);
print(log_msg);
if save_interval > 0:
if (i+1) % save_interval == 0:
# save data
pass;
class ElapsedTimer(object):
def __init__(self):
self.start_time = time.time()
def elapsed(self,sec):
if sec < 60:
return str(sec) + " sec"
elif sec < (60 * 60):
return str(sec / 60) + " min"
else:
return str(sec / (60 * 60)) + " hr"
def elapsed_time(self):
print("Elapsed: %s " % self.elapsed(time.time() - self.start_time) );
if __name__ == '__main__':
f = Fruit_GAN();发布于 2021-05-19 11:09:38
这是因为您指定了生成器的形状,我随意更改了代码以修复您的输出形状:(100,100,3)
G = tf.keras.Sequential()
dropout = 0.4
depth = 64+64+64+64
# I've change this to 25 as its a multiple of 7 before (7 * 4 = 28)
# So to fix that i've changed it to 25 (25 * 4 = 100)
dim = 25
# In: 100
# Out: dim x dim x depth
G.add(tf.keras.layers.Dense(dim*dim*depth, input_dim=100))
G.add(tf.keras.layers.BatchNormalization(momentum=0.9))
G.add(tf.keras.layers.Activation('relu'))
G.add(tf.keras.layers.Reshape((dim, dim, depth)))
G.add(tf.keras.layers.Dropout(dropout))
# In: dim x dim x depth
# Out: 2*dim x 2*dim x depth/2
G.add(tf.keras.layers.UpSampling2D()) # Your upsampling layer is multiple of 2
G.add(tf.keras.layers.Conv2DTranspose(int(depth/2), 5, padding='same'))
G.add(tf.keras.layers.BatchNormalization(momentum=0.9))
G.add(tf.keras.layers.Activation('relu'))
G.add(tf.keras.layers.UpSampling2D())
G.add(tf.keras.layers.Conv2DTranspose(int(depth/4), 5, padding='same'))
G.add(tf.keras.layers.BatchNormalization(momentum=0.9))
G.add(tf.keras.layers.Activation('relu'))
G.add(tf.keras.layers.Conv2DTranspose(int(depth/8), 5, padding='same'))
G.add(tf.keras.layers.BatchNormalization(momentum=0.9))
G.add(tf.keras.layers.Activation('relu'))
# Out: 100 x 100 x 3 rgb image [0.0,1.0] per pix
G.add(tf.keras.layers.Conv2DTranspose(3, 5, padding='same')) # Previously 1 representing 1 channel change to suit your rgb channel
G.add(tf.keras.layers.Activation('sigmoid'))
G.summary()
'''Final layer shape
activation_14 (Activation) (None, 100, 100, 3) 0
================================================================='''发布于 2021-05-19 12:07:07
您需要修改生成器部分。
首先把你的眼睛放在代码行上:

然后,...and将您的手指放到行上:

..。然后开始调整生成器的调光(尝试不同的调光值,并检查生成器的输出形状),这样就可以看到调光对生成器输出的影响。如果需要,也可以调整生成器的其他层。这样,当图像大小发生变化时,您就会发现需要调整生成器参数。
代码的调试版本,现在产生大小为(100,100,1)的输出是:
import numpy as np;
import time;
#Those two imports were missing to reproduce and debug the problem...added...
import tensorflow as tf
from tensorflow import keras
#import training data
from keras.models import Sequential;
from keras.layers import Dense, Activation, Flatten, Reshape;
from keras.layers import Conv2D, Conv2DTranspose, UpSampling2D;
from keras.layers import LeakyReLU, Dropout;
from keras.layers import BatchNormalization;
from keras.optimizers import Adam, RMSprop;
class GAN(object):
def __init__(self, img_rows, img_cols, channel):
self.img_rows = img_rows;
self.img_cols = img_cols;
self.channel = channel;
self.D = None;
self.G = None;
self.AM = None;
self.DM = None;
def discriminator(self):
if self.D:
return self.D;
self.D = Sequential();
depth = 64;
dropout = 0.4;
input_shape = (self.img_rows, self.img_cols, self.channel);
print("Input shape nayttaa talta: ",input_shape)
self.D.add(Conv2D(depth*1, 5, strides=2, input_shape=input_shape, padding='same'));
self.D.add(LeakyReLU(alpha=0.2));
self.D.add(Dropout(dropout));
self.D.add(Conv2D(depth*2, 5, strides=2, padding='same'));
self.D.add(LeakyReLU(alpha=0.2));
self.D.add(Dropout(dropout));
self.D.add(Conv2D(depth*4, 5, strides=2, padding='same'));
self.D.add(LeakyReLU(alpha=0.2));
self.D.add(Dropout(dropout));
self.D.add(Conv2D(depth*8, 5, strides=1, padding='same'));
self.D.add(LeakyReLU(alpha=0.2));
self.D.add(Dropout(dropout));
self.D.add(Flatten());
self.D.add(Dense(1));
self.D.add(Activation('sigmoid'));
print("Diskriminaattori:")
self.D.summary();
print("Let's test it, note the shape of test input...")
testitulos=self.D(tf.random.uniform((1,100,100,1)))
print(testitulos)
return self.D;
def generator(self):
if self.G:
return self.G;
self.G = Sequential();
dropout = 0.4;
depth = 64+64+64+64;
#Let's modify the dim...
dim = 25 #7;
self.G.add(Dense(dim*dim*depth, input_dim=100));
self.G.add(BatchNormalization(momentum=0.9));
self.G.add(Activation('relu'));
self.G.add(Reshape((dim, dim, depth)));
self.G.add(Dropout(dropout));
self.G.add(UpSampling2D());
self.G.add(Conv2DTranspose(int(depth/2), 5, padding='same'));
self.G.add(BatchNormalization(momentum=0.9));
self.G.add(Activation('relu'));
self.G.add(UpSampling2D());
self.G.add(Conv2DTranspose(int(depth/4), 5, padding='same'));
self.G.add(BatchNormalization(momentum=0.9));
self.G.add(Activation('relu'));
self.G.add(Conv2DTranspose(int(depth/8), 5, padding='same'));
self.G.add(BatchNormalization(momentum=0.9));
self.G.add(Activation('relu'));
self.G.add(Conv2DTranspose(1, 5, padding='same'));
self.G.add(Activation('sigmoid'));
print("Generaattori:")
self.G.summary();
print("Let's test it, note the shape of the output of the generator...")
testitulos=self.G(tf.random.uniform((1,100)))
print(testitulos.shape)
return self.G;
def discriminator_model(self):
if self.DM:
return self.DM;
optimizer = RMSprop(lr=0.0002, decay=6e-8);
self.DM = Sequential();
self.DM.add(self.discriminator());
self.DM.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy']);
return self.DM;
def adversarial_model(self):
if self.AM:
return self.AM;
optimizer = RMSprop(lr=0.0001, decay=3e-8);
self.AM = Sequential();
self.AM.add(self.generator());
self.AM.add(self.discriminator());
self.AM.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy']);
return self.AM;
class Fruit_GAN:
def __init__(self):
self.img_rows = 100;
self.img_cols = 100;
self.channel = 1;
print('\nstarting\n');
self.GAN = GAN(self.img_rows, self.img_cols, self.channel);
print('\nGAN setup succeded\n');
self.discriminator = self.GAN.discriminator_model();
print('\ndiscriminator setup succeded\n');
self.adversarial = self.GAN.adversarial_model();
print('\nadversarial setup succeded\n');
self.generator = self.GAN.generator();
print('\ngenerator setup succeded\n');
def Train(self, train_steps=2000, batch_size=256, save_interval=0):
noise_input = None;
if save_interval>0:
noise_input = np.random.uniform(-1.0, 1.0, size=[16, 100]);
for i in range(train_steps):
# training images:
images_train = 0
# random noise for generator:
noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100]);
# generator generated fake images:
images_fake = self.generator.predict(noise);
# train data formating for discriminator:
x = np.concatenate((images_train, images_fake));
y = np.ones([2*batch_size, 1]);
y[batch_size:, :] = 0;
# training_discriminator:
d_loss = self.discriminator.train_on_batch(x, y);
# train data reformatting for generator:
y = np.ones([batch_size, 1]);
noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100]);
a_loss = self.adversarial.train_on_batch(noise, y);
log_msg = "%d: [D loss: %f, acc: %f]" % (i, d_loss[0], d_loss[1]);
log_msg = "%s: [A loss: %f, acc: %f]" % (log_mesg, a_loss[0], a_loss[1]);
print(log_msg);
if save_interval > 0:
if (i+1) % save_interval == 0:
# save data
pass;
class ElapsedTimer(object):
def __init__(self):
self.start_time = time.time()
def elapsed(self,sec):
if sec < 60:
return str(sec) + " sec"
elif sec < (60 * 60):
return str(sec / 60) + " min"
else:
return str(sec / (60 * 60)) + " hr"
def elapsed_time(self):
print("Elapsed: %s " % self.elapsed(time.time() - self.start_time) );
if __name__ == '__main__':
f = Fruit_GAN();https://stackoverflow.com/questions/67596192
复制相似问题