python - 数学运算符或 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 网络。
解决方案
这可能是因为您使用的是 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),但不建议用于批量暗淡。
希望你能明白。
推荐阅读
- html - CSS3 移动多级菜单:无法显示第二级
- vba - 选择最后 1 行并自动填充到最后 +1 行
- javascript - 当观察到的节点被破坏时,MutationObserver 是否被破坏?
- python - QPixmap 损坏的图像
- elasticsearch - 在 ElasticSearch 中提交和刷新 translog - 误解
- node.js - 在 Web 服务器上部署的 Angular 2 在获取时抛出状态 0
- tsqlt - 带有输出参数的 tSQLt SpyProcedure
- ios - iPad iOS Safari getUserMedia 访问特定摄像头(正面或背面)
- javascript - 防止在大小更改时更改 html 选择的样式
- apache-spark - Spark 在加入后更改列可空性