首页 > 解决方案 > 数学运算符或 tf.function - 应该使用哪一个?

问题描述

我正在尝试实现一个模型,就像我给出的这段代码

input_tensor = Input(shape=(256, 256, 3))
base_model = VGG16(input_tensor=input_tensor,weights='imagenet',pooling=None, include_top=False)

x = base_model.output

x = GlobalAveragePooling2D()(x)

x = tf.math.reduce_max(x,axis=0,keepdims=True)

x = Dense(512,activation='relu')(x)

output_1 = Dense(3, activation='sigmoid')(x)

sagittal_model_abn = Model(inputs=base_model.input, outputs=output_1)

for layer in base_model.layers:
    layer.trainable = True

在这段代码中,我习惯于tf.math.reduce_max对批次中的样本取最大值。

如果这个的输入形状tf.math.reduce_max是 (16,6,6,512) 那么输出是 (1,6,6,512)

帧上的 Max-Pooling 是所需的操作。我使用的 16 帧具有相同的标签,即 16 帧构成批次的单个样本。

Max Pooling over axis=0,即在帧上,是我的模型中需要做的事情。

这使得批量大小有效地为 1。但由于我无法将 5D 张量提供给模型,所以我将批量大小保持为 1 并将 4D 张量提供给模型,因为我使用的是 2D CNN。

现在,数据集是一个多标签的。所以我在最后一层使用 sigmoid 激活和二元交叉熵损失。

但是正在发生的问题是,对于所有样本,模​​型的所有预测在每次迭代中都在 0.49-0.51 的范围内。

[0.50119835 0.5004604  0.49988952]
[0.501212   0.5004502  0.49987414]
[0.50122344 0.5004629  0.49987343]

这表明该模型没有学到任何东西。

这是因为tf.math.reduce_max我使用的运营商吗?应该使用@tf.function做同样的操作来解决这个问题吗?

我正在使用初始 LR 为 0.00001 的 Adam 优化器。

学习率很小,因为我正在微调预训练的 VGG 网络。

标签: pythontensorflowkerasdeep-learningneural-network

解决方案


这可能是因为您使用的是 tf.math.reduce_max()。正如您所提到的,此方法转换形状为 (16, 6, 6, 512) => (1, 6, 6, 512) 的张量。因为这个形状的第一个暗淡是 BatchSize (batchsize, imgShape1, imgshape2, numOfFilters)

您的模型的一个小摘要看起来像:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 224, 224, 3)]     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      
_________________________________________________________________

-------
-------
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 7, 7, 512)         0         
_________________________________________________________________
tf_op_layer_Max (TensorFlowO [(1, 7, 7, 512)]          0         
_________________________________________________________________
global_average_pooling2d (Gl (1, 512)                  0         
_________________________________________________________________
dense (Dense)                (1, 512)                  262656    
_________________________________________________________________
dense_1 (Dense)              (1, 3)                    1539      
=================================================================
Total params: 14,978,883
Trainable params: 14,978,883
Non-trainable params: 0
_________________________________________________________________

现在您知道,一批 16 个(在您的情况下)意味着有 16 个不同的图像对应于不同的类,并且在您应用 <reduce_max> 方法之后,这批 16 个图像压缩到一个图像。现在,您如何使用一个标签对 16 个不同的图像进行分类。您的完整模型应保持 batch_size 暗淡

dense_1 (Dense)              (None, 3)           *****

代替

dense_1 (Dense)              (1, 3)               ****

您可以将 reduce_max 方法应用于其他暗淡(axis=1 或 2 或 3),但不建议用于批量暗淡。

希望你能明白。


推荐阅读