Keras: 在编译模型后更新 `trainable` 属性

我在 Keras 中有一个条件生成对抗网络 (CGAN) 模型:

from keras.datasets import mnistfrom keras.layers import Input, Dense, Reshape, Flatten, Embedding, BatchNormalization, Dropout, multiplyfrom keras.layers.advanced_activations import LeakyReLUfrom keras.models import Sequential, Modelfrom keras.optimizers import Adamimport matplotlib.pyplot as pltimport tensorflow as tfimport keras as Kimport numpy as npimport sys, osimport warningswarnings.filterwarnings('ignore')if not os.path.exists('images'): os.makedirs('images')class GAN(object):  def __init__(self, width=28, height=28, channels=1, latent_dim=100, lr=0.0002):    self.WIDTH = int(width) # 输入图像的宽度    self.HEIGHT = int(height) # 输入图像的高度    self.CHANNELS = int(channels) # 图像中的颜色通道数    self.SHAPE = (self.WIDTH, self.HEIGHT, self.CHANNELS)    self.LATENT_DIM = latent_dim # 用于建模潜在空间(=噪声)的向量长度    self.N_CLASSES = 10 # 数据中可能的总类别数    self.OPTIMIZER = Adam(lr, 0.5)    # 生成器    self.G = self.generator()    self.G.compile(loss='binary_crossentropy', optimizer=self.OPTIMIZER)    # 判别器    self.D = self.discriminator()    self.D.compile(loss='binary_crossentropy', optimizer=self.OPTIMIZER, metrics=['accuracy'])    self.D.trainable = False # 防止堆叠的 D 进行训练;https://github.com/eriklindernoren/Keras-GAN/issues/73    # 堆叠的生成器 + 判别器    self.stacked_G_D = self.stacked_G_D()    self.stacked_G_D.compile(loss='binary_crossentropy', optimizer=self.OPTIMIZER)  def generator(self):    noise = Input((self.LATENT_DIM,), name='generator_noise') # 允许 g 创建不同的输出     label = Input((1,), name='generator_conditional', dtype='int32') # 允许 g 从一个类别中创建样本    # 在潜在维度大小中嵌入标签    h = Embedding(self.N_CLASSES, self.LATENT_DIM, input_length=1)(label)    label_embedding = Flatten()(h)    # 统一模型    h = multiply([noise, label_embedding])    h = Dense(256)(h)    h = LeakyReLU(alpha=0.2)(h)    h = BatchNormalization(momentum=0.8)(h)    h = Dense(512)(h)    h = LeakyReLU(alpha=0.2)(h)    h = BatchNormalization(momentum=0.8)(h)    h = Dense(1024)(h)    h = LeakyReLU(alpha=0.2)(h)    h = BatchNormalization(momentum=0.8)(h)    h = Dense(np.prod(self.SHAPE), activation='tanh')(h)    o = Reshape((self.WIDTH, self.HEIGHT, self.CHANNELS))(h)    model = Model(inputs=[noise, label], outputs=[o])    model.summary()    return model  def discriminator(self):    image = Input((self.SHAPE))    label = Input((1,), dtype='int32')    # 在图像形状(平铺)中嵌入标签    h = Embedding(self.N_CLASSES, np.prod(self.SHAPE), input_length=1)(label)    label_embedding = Flatten()(h)    # 解析图像    img = Flatten()(image)    # 统一模型    h = multiply([img, label_embedding])    h = Dense(512)(h)    h = LeakyReLU(alpha=0.2)(h)    h = Dense(512)(h)    h = LeakyReLU(alpha=0.2)(h)    h = Dropout(0.4)(h)    h = Dense(512)(h)    h = LeakyReLU(alpha=0.2)(h)    h = Dropout(0.4)(h)    o = Dense(1, activation='sigmoid')(h)    model = Model(inputs=[image, label], outputs=[o])    model.summary()    return model  def stacked_G_D(self):    noise = Input((self.LATENT_DIM,)) # 噪声输入    label = Input((1,)) # 条件输入    img = self.G([noise, label])    valid = self.D([img, label])    model = Model(inputs=[noise, label], outputs=[valid])    model.summary()    return model  def train(self, X_train, Y_train, epochs=20000, batch=32, save_interval=100):    for i in range(epochs):      # 训练判别器      idx = np.random.randint(0, X_train.shape[0], batch)      imgs, labels = X_train[idx], Y_train[idx]      noise = np.random.normal(0, 1, (batch, self.LATENT_DIM))      fake_imgs = self.G.predict([noise, labels])      d_loss_real = self.D.train_on_batch([imgs, labels], np.ones((batch, 1)))      d_loss_fake = self.D.train_on_batch([fake_imgs, labels], np.zeros((batch, 1)))      d_loss = (np.add(d_loss_real, d_loss_fake)) * 0.5      # 训练生成器      sample_labels = np.random.randint(0, 10, batch).reshape(batch, 1)      g_loss = self.stacked_G_D.train_on_batch([noise, sample_labels], np.ones((batch, 1)))      if i % save_interval == 0:         print('epoch: {0} - disc loss: {1}, disc accuracy: {2}, gen loss: {2}'.format(i, d_loss[0], d_loss[1]*100, g_loss))        filename = 'mnist_{0}-{1}-{2}.png'.format(i, d_loss[0], g_loss)        self.plot_images(save_to_disk=True, filename=filename)  def plot_images(self, save_to_disk=False, n_images=10, filename=None, rows=2, size_scalar=4, class_arr=None):    if not filename: filename = 'mnist.png'    noise = np.random.normal(0, 1, (n_images, self.LATENT_DIM))    classes = class_arr if class_arr is not None else np.arange(0, n_images) % self.N_CLASSES    images = self.G.predict([noise, classes])    cols = np.ceil(n_images/rows) # 网格中的列数    fig = plt.figure(figsize=(cols*size_scalar, rows*size_scalar))        for i in range(n_images):      ax = fig.add_subplot(rows, np.ceil(n_images/rows), i+1)      image = np.reshape(images[i], [28, 28])        plt.imshow(image)    fig.subplots_adjust(hspace=0, wspace=0)    if save_to_disk:      fig.savefig(os.path.join('images', filename))      plt.close('all')    else:      fig.show()(X_train, Y_train), (_, _) = mnist.load_data()X_train = (X_train.astype(np.float32) - 127.5) / 127.5 # 重新缩放到 {-1 to 1}X_train = np.expand_dims(X_train, axis=3)gan = GAN()gan.train(X_train, Y_train)

我的目标是定期冻结判别器,使其无法学习。(这是为了进行一些实验性工作。)然而,我无法找到在编译模型后实际更新 gan.D.trainable 属性的方法。我尝试过定期手动更改该属性,但无论如何,判别器仍在继续学习。

实际上,在编译模型后可以更新模型的 trainable 属性吗?如果可以,我将非常感激能提供一个简单的示例来说明如何实现这一点!


回答:

啊,你可以在编译模型后更新模型的 .trainable 属性,你只需要重新编译模型即可:

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注