我正在使用此模型从图像获取深度图:
def get_model(learning_rate=0.001, channels=2):
h = 128 # height of the image
w = 128 # width of the image
c = channels # no of channels
encoding_size = 512
# encoder
image = Input(shape=(c, h, w))
conv_1_1 = Conv2D(32, (3, 3), activation='relu', padding='same')(image)
conv_1_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv_1_1)
pool_1_2 = MaxPooling2D((2, 2))(conv_1_2)
conv_2_1 = Conv2D(64, (3, 3), activation='relu', padding='same')(pool_1_2)
conv_2_2 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv_2_1)
pool_2_2 = MaxPooling2D((2, 2))(conv_2_2)
conv_3_1 = Conv2D(128, (3, 3), activation='relu', padding='same')(pool_2_2)
conv_3_2 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv_3_1)
# pool_3_2 = MaxPooling2D((2, 2))(conv_3_2)
# conv_4_1 = Conv2D(256, (3, 3), activation='relu', padding='same')(pool_3_2)
# conv_4_2 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv_4_1)
# pool_4_3 = MaxPooling2D((2, 2))(conv_4_2)
# conv_5_1 = Conv2D(512, (3, 3), activation='relu', padding='same')(pool_4_3)
# conv_5_2 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv_5_1)
flat_5_2 = Flatten()(conv_3_2)
encoding = Dense(encoding_size, activation='tanh')(flat_5_2)
# decoder
reshaped_6_1 = Reshape((8, 8, 8))(encoding)
conv_6_1 = Conv2D(128, (3, 3), activation='relu', padding='same')(reshaped_6_1)
conv_6_2 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv_6_1)
upsample_6_2 = UpSampling2D((2, 2))(conv_6_2)
conv_7_1 = Conv2D(64, (3, 3), activation='relu', padding='same')(upsample_6_2)
conv_7_2 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv_7_1)
upsample_7_2 = UpSampling2D((2, 2))(conv_7_2)
conv_8_1 = Conv2D(32, (3, 3), activation='relu', padding='same')(upsample_7_2)
conv_8_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv_8_1)
upsample_8_2 = UpSampling2D((2, 2))(conv_8_2)
conv_9_1 = Conv2D(16, (3, 3), activation='relu', padding='same')(upsample_8_2)
conv_9_2 = Conv2D(16, (3, 3), activation='relu', padding='same')(conv_9_1)
upsample_9_2 = UpSampling2D((2, 2))(conv_9_2)
conv_10_1 = Conv2D(8, (3, 3), activation='relu', padding='same')(upsample_9_2)
conv_10_2 = Conv2D(1, (3, 3), activation='relu', padding='same')(conv_10_1)
output = Conv2D(1, (1, 1), activation=relu_normalized, padding='same')(conv_10_2)
model = Model(inputs=image, outputs=output)
model.compile(loss='mae', optimizer=Adam(learning_rate))
return model
注意:relu_normalized只是relu,然后将值压缩为0-1,以便获得适当的图像。乙状结肠似乎不符合这个标准。
当我添加更多层时,损耗变为常数,并且反向传播不会正确发生,因为输出和梯度都变为零(因此,更改学习速率并不会改变网络中的任何内容)
因此,如果我想更深入地进行概括,通过取消注释(当然将conv_5_2
与flat_5_2
连接起来),我缺少什么?
我的想法:
elu
或selu
都不会显示任何进展。为什么当我尝试再添加一个conv层和max_pooling时,为什么我的输出接近于零?
更新:
此处为relu_normalized
def relu_normalized(x):
epsilon = 1e-6
relu_x = relu(x)
relu_scaled_x = relu_x / (K.max(relu_x) + epsilon)
return relu_scaled_x
然后在获得范围为[0,1]的输出之后,我们简单地执行output_image = 255 *输出,现在就可以将其保存为黑白图像。
答案 0 :(得分:4)
在这种情况下,如果您想更深入一点,就必须添加一些批标准化层(在Keras https://keras.io/layers/normalization/#batchnormalization中)。 在伊恩·古德费洛(Ian Goodfellow)的书中,关于批次归一化章节:
非常深入的模型涉及几个功能或层的组成。的 梯度告诉我们如何在假设另一个参数的情况下更新每个参数 层不变。实际上,我们会同时更新所有层。 当我们进行更新时,可能会发生意外结果,因为许多功能 使用计算出的更新,可以同时更改组成在一起的数据 假设其他函数保持不变
此外, tanh
很容易饱和,因此仅在需要时使用:)
答案 1 :(得分:0)
当学习率太大时,“ relu”可能会发生问题。
所有激活都极有可能变为0,并且卡在该位置而不再更改。 (当它们为0时,其梯度也为0)。
由于我不是使用“ relu”来详细调整参数的专家,并且“ relu”的结果始终不好,因此我更喜欢使用“ Sigmoid”或“ tanh”。 (值得尝试,尽管那里可能会消失...)。我将图像的范围保持在0到1之间,并使用“ binary_crossentropy”作为损失,在这种情况下,它比“ mae / mse”要快得多。
发生在我身上的另一件事是一个“显然”的冻结损失函数。碰巧该值变化很小,以至于显示的小数位不足以查看变化,但是经过许多时期后,它找到了一种合理的降低方法。 (也许确实有某种饱和度,但是对我来说,这仍然比冻结或难过要好)
答案 2 :(得分:-1)
您可以引入像LSTM这样的循环层,这些层将通过选通“捕获”错误,从而可能改善情况。