gpt4 book ai didi

python - 将类信息添加到 keras 网络

转载 作者:行者123 更新时间:2023-12-03 23:50:20 26 4
gpt4 key购买 nike

我想弄清楚如何将数据集的标签信息与生成对抗网络一起使用。我正在尝试使用以下条件 GAN 实现 can be found here .我的数据集包含两个不同的图像域(真实物体和草图),具有共同的类信息(椅子、树、橙色等)。我选择了这个实现,它只将两个不同的域视为对应的不同“类”(训练样本 X 对应于真实图像,而目标样本 y 对应于草图图像)。

有没有办法修改我的代码并考虑我整个架构中的类信息(椅子、树等)?我实际上希望我的鉴别器预测我从生成器生成的图像是否属于特定类别,而不仅仅是它们是否真实。事实上,使用当前的架构,系统学会在所有情况下创建类似的草图。

更新:鉴别器返回一个大小为 1x7x7 的张量然后两者 y_truey_pred在计算损失之前通过一个扁平层:

def discriminator_loss(y_true, y_pred):
BATCH_SIZE=100
return K.mean(K.binary_crossentropy(K.flatten(y_pred), K.concatenate([K.ones_like(K.flatten(y_pred[:BATCH_SIZE,:,:,:])),K.zeros_like(K.flatten(y_pred[:BATCH_SIZE,:,:,:])) ]) ), axis=-1)

以及判别器在生成器上的损失函数:
def discriminator_on_generator_loss(y_true,y_pred):
BATCH_SIZE=100
return K.mean(K.binary_crossentropy(K.flatten(y_pred), K.ones_like(K.flatten(y_pred))), axis=-1)

此外,我对输出 1 层的鉴别器模型的修改:
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
#model.add(Activation('sigmoid'))

现在鉴别器输出 1 层。如何相应地修改上述损失函数?对于 n_classes = 6,我应该有 7 而不是 1 + 一个用于预测真假配对的类(class)?

最佳答案

建议的解决方案

重用来自 repository you shared 的代码,这里有一些建议的修改,以沿着您的生成器和鉴别器训练分类器(它们的架构和其他损失保持不变):

from keras import backend as K
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D

def lenet_classifier_model(nb_classes):
# Snipped by Fabien Tanc - https://www.kaggle.com/ftence/keras-cnn-inspired-by-lenet-5
# Replace with your favorite classifier...
model = Sequential()
model.add(Convolution2D(12, 5, 5, activation='relu', input_shape=in_shape, init='he_normal'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(25, 5, 5, activation='relu', init='he_normal'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(180, activation='relu', init='he_normal'))
model.add(Dropout(0.5))
model.add(Dense(100, activation='relu', init='he_normal'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes, activation='softmax', init='he_normal'))

def generator_containing_discriminator_and_classifier(generator, discriminator, classifier):
inputs = Input((IN_CH, img_cols, img_rows))
x_generator = generator(inputs)

merged = merge([inputs, x_generator], mode='concat', concat_axis=1)
discriminator.trainable = False
x_discriminator = discriminator(merged)

classifier.trainable = False
x_classifier = classifier(x_generator)

model = Model(input=inputs, output=[x_generator, x_discriminator, x_classifier])

return model


def train(BATCH_SIZE):
(X_train, Y_train, LABEL_train) = get_data('train') # replace with your data here
X_train = (X_train.astype(np.float32) - 127.5) / 127.5
Y_train = (Y_train.astype(np.float32) - 127.5) / 127.5
discriminator = discriminator_model()
generator = generator_model()
classifier = lenet_classifier_model(6)
generator.summary()
discriminator_and_classifier_on_generator = generator_containing_discriminator_and_classifier(
generator, discriminator, classifier)
d_optim = Adagrad(lr=0.005)
g_optim = Adagrad(lr=0.005)
generator.compile(loss='mse', optimizer="rmsprop")
discriminator_and_classifier_on_generator.compile(
loss=[generator_l1_loss, discriminator_on_generator_loss, "categorical_crossentropy"],
optimizer="rmsprop")
discriminator.trainable = True
discriminator.compile(loss=discriminator_loss, optimizer="rmsprop")
classifier.trainable = True
classifier.compile(loss="categorical_crossentropy", optimizer="rmsprop")

for epoch in range(100):
print("Epoch is", epoch)
print("Number of batches", int(X_train.shape[0] / BATCH_SIZE))
for index in range(int(X_train.shape[0] / BATCH_SIZE)):
image_batch = Y_train[index * BATCH_SIZE:(index + 1) * BATCH_SIZE]
label_batch = LABEL_train[index * BATCH_SIZE:(index + 1) * BATCH_SIZE] # replace with your data here

generated_images = generator.predict(X_train[index * BATCH_SIZE:(index + 1) * BATCH_SIZE])
if index % 20 == 0:
image = combine_images(generated_images)
image = image * 127.5 + 127.5
image = np.swapaxes(image, 0, 2)
cv2.imwrite(str(epoch) + "_" + str(index) + ".png", image)
# Image.fromarray(image.astype(np.uint8)).save(str(epoch)+"_"+str(index)+".png")

# Training D:
real_pairs = np.concatenate((X_train[index * BATCH_SIZE:(index + 1) * BATCH_SIZE, :, :, :], image_batch),
axis=1)
fake_pairs = np.concatenate(
(X_train[index * BATCH_SIZE:(index + 1) * BATCH_SIZE, :, :, :], generated_images), axis=1)
X = np.concatenate((real_pairs, fake_pairs))
y = np.zeros((20, 1, 64, 64)) # [1] * BATCH_SIZE + [0] * BATCH_SIZE
d_loss = discriminator.train_on_batch(X, y)
print("batch %d d_loss : %f" % (index, d_loss))
discriminator.trainable = False

# Training C:
c_loss = classifier.train_on_batch(image_batch, label_batch)
print("batch %d c_loss : %f" % (index, c_loss))
classifier.trainable = False

# Train G:
g_loss = discriminator_and_classifier_on_generator.train_on_batch(
X_train[index * BATCH_SIZE:(index + 1) * BATCH_SIZE, :, :, :],
[image_batch, np.ones((10, 1, 64, 64)), label_batch])
discriminator.trainable = True
classifier.trainable = True
print("batch %d g_loss : %f" % (index, g_loss[1]))
if index % 20 == 0:
generator.save_weights('generator', True)
discriminator.save_weights('discriminator', True)

理论细节

我相信对于条件 GAN 的工作原理以及在此类方案中鉴别器的作用是什么,存在一些误解。

鉴别器的作用

在 GAN 训练 [4] 的 min-max 游戏中,判别器 D正在与生成器对战 G (你真正关心的网络)所以下 D的审查, G在输出现实结果方面变得更好。

为此, D经过训练以区分来自 G 的样本和真实样本;而 G训练有素 D通过按照目标分布生成现实结果/结果。

Note: in the case of conditional GANs, i.e. GANs mapping an input sample from one domain A (e.g. real picture) to another domain B (e.g. sketch), D is usually fed with the pairs of samples stacked together and has to discriminate "real" pairs (input sample from A + corresponding target sample from B) and "fake" pairs (input sample from A + corresponding output from G) [1, 2]



针对 D 训练条件生成器(与仅训练 G 不同,只有 L1/L2 损失,例如 DAE)提高了 G 的采样能力,迫使它输出清晰、真实的结果,而不是试图平均分布。

尽管鉴别器可以有多个子网络来覆盖其他任务(见下一段), D应该至少保留一个子网络/输出来覆盖其主要任务: 区分真实样本和生成样本 .询问 D同时回归进一步的语义信息(例如类)可能会干扰这个主要目的。

Note: D output is often not a simple scalar / boolean. It is common to have a discriminator (e.g. PatchGAN [1, 2]) returning a matrix of probabilities, evaluating how realistic patches made from its input are.



条件 GAN

传统的 GAN 以无监督的方式训练,以从随机噪声向量作为输入生成真实数据(例如图像)。 [4]

如前所述,条件 GAN 具有进一步的输入条件。沿着/而不是噪声向量,他们将来自域 A 的样本作为输入。并从域 B 返回相应的样本. A可以是完全不同的模式,例如 B = sketch imageA = discrete label ; B = volumetric dataA = RGB image等[3]

这种 GAN 也可以由多个输入来调节,例如 A = real image + discrete labelB = sketch image .介绍这种方法的著名著作是 InfoGAN [5]。它介绍了如何在多个连续或离散输入(例如 A = digit class + writing typeB = handwritten digit image)、 上调节 GANs使用更高级的鉴别器,它对第二个任务强制G最大化其调节输入与其对应输出之间的互信息 .

最大化 cGAN 的互信息

InfoGAN 鉴别器有 2 个头/子网络来覆盖它的 2 个任务 [5]:
  • 一个头D1传统的真实/生成歧视 - G必须最小化这个结果,即它必须愚弄 D1使其无法区分真实形式生成的数据;
  • 另一个头D2 (也称为 Q 网络)尝试回归输入 A信息--G必须最大化这个结果,即它必须输出“显示”请求的语义信息的数据(参见 G 条件输入及其输出之间的互信息最大化)。

  • 您可以在此处找到 Keras 实现,例如: https://github.com/eriklindernoren/Keras-GAN/tree/master/infogan .

    一些作品正在使用类似的方案来改进对 GAN 生成内容的控制,方法是使用提供的标签并最大化这些输入和 G 之间的互信息。输出 [6, 7]。基本思想总是相同的:
  • 火车G生成域的元素 B ,给定域的一些输入 A ;
  • 火车D区分“真实”/“虚假”结果 -- G必须尽量减少这种情况;
  • 火车Q (例如分类器;可以与 D 共享层)来估计原始 A来自 B 的输入 sample -- G必须最大化这一点)。


  • 包起来

    在您的情况下,您似乎有以下训练数据:
  • 真实图片Ia
  • 相应的草图图像Ib
  • 对应的类标签c

  • 并且你想训练一个生成器 G以便给定图像 Ia及其类标签 c ,它输出一个合适的草图图像 Ib' .

    总而言之,这是您拥有的大量信息,您可以在条件图像和条件标签上监督您的训练......
    受上述方法 [1, 2, 5, 6, 7] 的启发,这里有一种可能的方法来使用所有这些信息来训练您的条件 G :

    网络G :
  • 输入:Ia + c
  • 输出:Ib'
  • 架构:由您决定(例如 U-Net、ResNet 等)
  • 损失:Ib'之间的L1/L2损失& Ib , -D损失,Q亏损

  • 网络D :
  • 输入:Ia + Ib (真对), Ia + Ib' (假双)
  • 输出:“虚假”标量/矩阵
  • 架构:由您决定(例如 PatchGAN)
  • 损失:“虚假”估计的交叉熵

  • 网络Q :
  • 输入:Ib (真实样本,用于训练 Q)、Ib' (假样本,当通过 G 反向传播时)
  • 输出:c' (估计类(class))
  • 架构:由您决定(例如 LeNet、ResNet、VGG 等)
  • 损失:c之间的交叉熵和 c'

  • 训练阶段:
  • 火车D在一批真实货币对上 Ia + Ib然后在一批假对Ia + Ib' ;
  • 火车Q在一批真实 sample 上Ib ;
  • 修复 DQ重量;
  • 火车G ,传递其生成的输出 Ib'DQ通过它们反向传播。

  • Note: this is a really rough architecture description. I'd recommend going through the literature ([1, 5, 6, 7] as a good start) to get more details and maybe a more elaborate solution.



    引用
  • 伊索拉、菲利普等人。 “使用条件对抗网络进行图像到图像转换。” arXiv 预印本(2017 年)。 http://openaccess.thecvf.com/content_cvpr_2017/papers/Isola_Image-To-Image_Translation_With_CVPR_2017_paper.pdf
  • 朱军燕等。 “使用循环一致对抗网络的非配对图像到图像转换。” arXiv 预印本 arXiv:1703.10593 (2017)。 http://openaccess.thecvf.com/content_ICCV_2017/papers/Zhu_Unpaired_Image-To-Image_Translation_ICCV_2017_paper.pdf
  • 米尔扎、迈赫迪和西蒙·奥辛德罗。 “条件生成对抗网络。” arXiv 预印本 arXiv:1411.1784 (2014)。 https://arxiv.org/pdf/1411.1784
  • Goodfellow、伊恩等人。 “生成对抗网络。”神经信息处理系统的进展。 2014. http://papers.nips.cc/paper/5423-generative-adversarial-nets.pdf
  • 陈,席,等。 “Infogan:通过信息最大化生成对抗网络进行可解释的表征学习。”神经信息处理系统的进展。 2016. http://papers.nips.cc/paper/6399-infogan-interpretable-representation-learning-by-information-maximizing-generative-adversarial-nets.pdf
  • 李、敏赫和俊熙。 “可控生成对抗网络。” arXiv 预印本 arXiv:1708.00598 (2017)。 https://arxiv.org/pdf/1708.00598.pdf
  • 奥德纳、奥古斯都、克里斯托弗·奥拉和乔纳森·施伦斯。 “使用辅助分类器 gans 进行条件图像合成。” arXiv 预印本 arXiv:1610.09585 (2016)。 http://proceedings.mlr.press/v70/odena17a/odena17a.pdf
  • 关于python - 将类信息添加到 keras 网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50909007/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com