3D DCGAN无法按预期学习

时间:2019-09-19 03:22:28

标签: python tensorflow keras generative-adversarial-network dcgan

根据本文,我正在尝试在Keras中创建3D DCGan:http://3dgan.csail.mit.edu/papers/3dgan_nips.pdf

在我的用例中,我希望输出一个(16,16,16)整数数组。 当输入到模型中时,输入将在[-1,1]之间缩放,然后在可视化之前进行缩放和舍入。

为使学习可视化,我将阵列的第一个“切片”显示为图像。

生成器是这样制作的:

def build_generator():
    z_size = 200
    gen_filters = [64, 32, 16, 1]
    gen_kernel_sizes = [2, 4, 4, 4]
    gen_strides = [1, 2, 2, 2]
    gen_input_shape = (1, 1, 1, z_size)
    gen_activations = ['relu', 'relu', 'relu', 'tanh']
    gen_convolutional_blocks = 4

    input_layer = layers.Input(shape=gen_input_shape)

    a = layers.Conv3DTranspose(filters=gen_filters[0], 
                        kernel_size=gen_kernel_sizes[0],
                        strides=gen_strides[0])(input_layer)
    a = layers.BatchNormalization()(a, training=True)
    a = layers.Activation(activation='relu')(a)

    for i in range(gen_convolutional_blocks - 1):
        a = layers.Conv3DTranspose(filters=gen_filters[i + 1], 
                            kernel_size=gen_kernel_sizes[i + 1],
                            strides=gen_strides[i + 1], padding='same')(a)
        a = layers.BatchNormalization()(a, training=True)
        a = layers.Activation(activation=gen_activations[i + 1])(a)
    gen_model = Model(inputs=input_layer, outputs=a)
    gen_model.summary()
    return gen_model
Model: "model_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_3 (InputLayer)         [(None, 1, 1, 1, 200)]    0         
_________________________________________________________________
conv3d_transpose_4 (Conv3DTr (None, 2, 2, 2, 64)       102464    
_________________________________________________________________
batch_normalization_8 (Batch (None, 2, 2, 2, 64)       256       
_________________________________________________________________
activation_5 (Activation)    (None, 2, 2, 2, 64)       0         
_________________________________________________________________
conv3d_transpose_5 (Conv3DTr (None, 4, 4, 4, 32)       131104    
_________________________________________________________________
batch_normalization_9 (Batch (None, 4, 4, 4, 32)       128       
_________________________________________________________________
activation_6 (Activation)    (None, 4, 4, 4, 32)       0         
_________________________________________________________________
conv3d_transpose_6 (Conv3DTr (None, 8, 8, 8, 16)       32784     
_________________________________________________________________
batch_normalization_10 (Batc (None, 8, 8, 8, 16)       64        
_________________________________________________________________
activation_7 (Activation)    (None, 8, 8, 8, 16)       0         
_________________________________________________________________
conv3d_transpose_7 (Conv3DTr (None, 16, 16, 16, 1)     1025      
_________________________________________________________________
batch_normalization_11 (Batc (None, 16, 16, 16, 1)     4         
_________________________________________________________________
activation_8 (Activation)    (None, 16, 16, 16, 1)     0         
=================================================================
Total params: 267,829
Trainable params: 267,603
Non-trainable params: 226

鉴别符:

def build_discriminator():
    dis_input_shape = (16, 16, 16, 1)
    dis_filters = [16, 32, 64, 1]
    dis_kernel_sizes = [4, 4, 4, 4]
    dis_strides = [2, 2, 2, 2]
    dis_paddings = ['same', 'same', 'same', 'valid']
    dis_alphas = [0.2, 0.2, 0.2, 0.2, 0.2]
    dis_activations = ['leaky_relu', 'leaky_relu', 'leaky_relu', 
                       'sigmoid']
    dis_convolutional_blocks = 4

    dis_input_layer = layers.Input(shape=dis_input_shape)

    a = layers.Conv3D(filters=dis_filters[0],
               kernel_size=dis_kernel_sizes[0],
               strides=dis_strides[0],
               padding=dis_paddings[0])(dis_input_layer)
    a = layers.BatchNormalization()(a, training=True)
    a = layers.LeakyReLU(dis_alphas[0])(a)

    for i in range(dis_convolutional_blocks - 1):
        a = layers.Conv3D(filters=dis_filters[i + 1],
                   kernel_size=dis_kernel_sizes[i + 1],
                   strides=dis_strides[i + 1],
                   padding=dis_paddings[i + 1])(a)
        a = layers.BatchNormalization()(a, training=True)
        if dis_activations[i + 1] == 'leaky_relu':
            a = layers.LeakyReLU(dis_alphas[i + 1])(a)
        elif dis_activations[i + 1] == 'sigmoid':
            a = layers.Activation(activation='sigmoid')(a)

    dis_model = Model(inputs=dis_input_layer, outputs=a)
    print(dis_model.summary())
    return dis_model

_________________________________________________________________
Model: "model_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_4 (InputLayer)         [(None, 16, 16, 16, 1)]   0         
_________________________________________________________________
conv3d_4 (Conv3D)            (None, 8, 8, 8, 16)       1040      
_________________________________________________________________
batch_normalization_12 (Batc (None, 8, 8, 8, 16)       64        
_________________________________________________________________
leaky_re_lu_3 (LeakyReLU)    (None, 8, 8, 8, 16)       0         
_________________________________________________________________
conv3d_5 (Conv3D)            (None, 4, 4, 4, 32)       32800     
_________________________________________________________________
batch_normalization_13 (Batc (None, 4, 4, 4, 32)       128       
_________________________________________________________________
leaky_re_lu_4 (LeakyReLU)    (None, 4, 4, 4, 32)       0         
_________________________________________________________________
conv3d_6 (Conv3D)            (None, 2, 2, 2, 64)       131136    
_________________________________________________________________
batch_normalization_14 (Batc (None, 2, 2, 2, 64)       256       
_________________________________________________________________
leaky_re_lu_5 (LeakyReLU)    (None, 2, 2, 2, 64)       0         
_________________________________________________________________
conv3d_7 (Conv3D)            (None, 1, 1, 1, 1)        4097      
_________________________________________________________________
batch_normalization_15 (Batc (None, 1, 1, 1, 1)        4         
_________________________________________________________________
activation_9 (Activation)    (None, 1, 1, 1, 1)        0         
=================================================================
Total params: 169,525
Trainable params: 169,299
Non-trainable params: 226
_________________________________________________________________

然后创建一个对抗模型:

adversarial_model = tf.keras.models.Sequential()
adversarial_model.add(generator)
adversarial_model.add(discriminator)
adversarial_model.compile(loss="binary_crossentropy", optimizer=tf.keras.optimizers.Adam(lr=gen_learning_rate, beta_1=beta))

像这样对数据进行预处理:

processed_inputs = np.subtract(np.multiply(np.divide(dataset_list, scalar),2),1)

,然后像这样转换回来:

def generate_save_heatmaps(model, epoch, test_input):
  predictions = model(test_input, training=False)
  processed_predictions = np.divide(np.multiply(np.add(predictions, 1), scalar),2)
  processed_predictions = np.around(processed_predictions).astype(int)
  processed_predictions = np.squeeze(processed_predictions)
  generate_heatmap(processed_predictions[0][0], epoch, True)

通过此功能训练模型:

for epoch in range(epochs):
    gen_losses = []
    dis_losses = []
    number_of_batches = int(processed_inputs.shape[0] / batch_size)
    for index in range(number_of_batches):
        z_sample = np.random.normal(0, 0.33, size=[batch_size, 1, 1, 1, 
                            z_size]).astype(np.float32)
        struct_batch = processed_inputs[index * batch_size:(index + 1) * batch_size, :, :, :]
        gen_structs = generator.predict(z_sample)
        # Make the discriminator network trainable
        discriminator.trainable = True

        # Train the discriminator network
        loss_real = discriminator.train_on_batch(struct_batch, 
                                                 labels_real)
        loss_fake = discriminator.train_on_batch(gen_structs, 
                                                 labels_fake)        
        d_loss = 0.5 * np.add(loss_real, loss_fake)
        discriminator.trainable = False

        z = np.random.normal(0, 0.33, size=[batch_size, 1, 1, 1, z_size]).astype(np.float32)
        # Train the adversarial model
        g_loss = adversarial_model.train_on_batch(z, labels_real)

        gen_losses.append(g_loss)
        dis_losses.append(d_loss)

        write_log('g_loss', np.mean(gen_losses), counter)
        write_log('d_loss', np.mean(dis_losses), counter)

在所有训练数据中,第一个切片如下:

大多数数据看起来像这样,所以我希望网络能够迅速获得对数字12的亲和力。

但是,经过几百个历时的演变却显示出其他情况:

张量板损耗图如下所示:

我尝试了不同的学习率,更改了卷积块的数量,等等。目前我不知道该怎么办。

0 个答案:

没有答案