【问题标题】:Accuracy too low with very simple CNN model using Keras in Tensorflow在 Tensorflow 中使用 Keras 的非常简单的 CNN 模型的准确性太低
【发布时间】:2021-08-03 15:47:52
【问题描述】:

我是 TensorFlow 新手,非常感谢您的帮助。我的模型输出与输入相同,只是形状不同,所以我希望准确度为 1,但实际得到的是 0.0062。

输入

我的数据集的每个输入都是 (19, 19, 1) 的形状。对于这些输入中的每一个,只有一个随机的单个值设置为 1,而其余的为 0。示例但带有 (4, 4, 1):

# [[0, 0, 0, 0],
#  [0, 1, 0, 0],
#  [0, 0, 0, 0],
#  [0, 0, 0, 0]

输出

每个输出的形状为 (361),本质上是其输入的扁平化版本,因此理论上达到 1 的精度应该不成问题。示例:

# [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

我的数据集包含 2404 个这样的样本。

这是我的代码。请注意,我尝试了不同损失函数和优化器的组合:

model = models.Sequential()
model.add(layers.Conv2D(1, (1, 1), activation='relu', padding='same', input_shape=(19, 19, 1)))
model.add(layers.Flatten())
model.add(layers.Dense(19 * 19, activation='softmax'))
model.compile(
    optimizer='adam',
    loss=tf.keras.losses.Huber(),
    metrics=['accuracy']
)

dataset = Dataset()
inputs = dataset.input
outputs = dataset.output

model.fit(
    inputs, # (2404, 19, 19, 1)
    outputs, # (2404, 361)
    epochs=1000,
    shuffle=True,
    verbose=1
)

结果

它很快达到 0.0062 并保持在那里。

Epoch 10/1000
76/76 [==============================] - 0s 2ms/step - loss: 0.0014 - accuracy: 0.0062

更新 1 - 稍微好一点

感谢您的帮助。在我的代码中删除随机数的使用并禁用随机播放后,它开始在我运行代码的时间达到 1.00 50% 的准确度。其他 50% 的峰值精度为 0.0046。 当我尝试将权重和偏差初始化为 0 时,它在 0.0046 100% 的时间达到峰值。更新我所有的 TF 包几乎解决了这个问题,现在成功率达到了 90%。

【问题讨论】:

  • 问题可能出在您的数据集源中。您是否尝试过明确使用数据集输入作为数据集输出(自己重塑)?如果您的输出是单独打乱的,那么您将有效地尝试使您的 CNN 预测随机。
  • 谢谢。我禁用了改组并删除了所有对随机的引用,现在它成功了,并且在我单击运行的大约 50% 的时间中,它的准确度为 1.00,但其他时候,它的峰值为 0.0046。对于成功和不成功的运行,TF 的输出是相同的,数据集也是如此。我对相同的代码如何产生不同的结果感到非常困惑。
  • 你为什么使用huber loss?这就是回归损失,这里有一个分类问题。
  • @Dr.Snoopy 我会记住这一点,谢谢。
  • 这不是要记住的事情,这可能是您的模型训练失败的原因。

标签: python tensorflow machine-learning keras conv-neural-network


【解决方案1】:

从 cmets 出来回答。您正在卷积一个 1x1 内核,然后将其传递给密集层。您希望网络学习的理想参数是密集层中的所有权重都是内核值的倒数。不过,这里最重要的是您通常会通过零。密集层中的任何权重值,应用于零会导致另一个零,因此零会导致梯度消失。

当您将权重初始化为零时,这会将您的输入向量变为全零,全零总是结束学习。不能反向传播。当您不对初始化做任何事情时,TF 使用正态分布进行初始化,以 0 为中心。一半时间,初始化的内核值是负数。卷积后,你得到全零和一个负数。在 relu 之后你全为零。一半的时间它可以学习 - 因为它偶然初始化为一个正内核值,而一半的时间它不能。

试试这个:

initializer = tf.keras.initializer.Ones()
model.add(layers.Conv2D(1, (1, 1), kernel_initializer=initializer, activation='relu', padding='same', input_shape=(19, 19, 1)))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 2018-02-09
    • 2021-10-14
    • 2019-02-12
    相关资源
    最近更新 更多