根据本文,我正在尝试在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的亲和力。
但是,经过几百个历时的演变却显示出其他情况:
张量板损耗图如下所示:
我尝试了不同的学习率,更改了卷积块的数量,等等。目前我不知道该怎么办。