简体   繁体   English

在 Tensorflow 中使用 Keras 的非常简单的 CNN model 精度太低

[英]Accuracy too low with very simple CNN model using Keras in Tensorflow

I'm new to TensorFlow so help is appreciated.我是 TensorFlow 的新手,因此不胜感激。 My output for the model is the same as the input, only in a different shape so I expect an accuracy of 1 but am instead getting 0.0062.我的 model 的 output 与输入相同,只是形状不同,所以我预计精度为 1,但我得到的是 0.0062。

Inputs输入

Each input of my dataset is in the shape of (19, 19, 1).我的数据集的每个输入都是 (19, 19, 1) 的形状。 For each of these inputs, only a random single value is set to 1 while the rest are 0. Example but with a (4, 4, 1):对于这些输入中的每一个,只有一个随机单个值设置为 1,而 rest 为 0。示例但带有 (4, 4, 1):

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

Outputs输出

Each output has a shape of (361) and is essentially the flattened version of its input so it shouldn't be a problem to reach an accuracy of 1 in theory.每个 output 的形状为 (361),本质上是其输入的扁平版本,因此理论上达到 1 的精度应该不是问题。 Example:例子:

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

My dataset consists of 2404 of these samples.我的数据集由 2404 个这些样本组成。

Here's my code.这是我的代码。 Note that I've tried a combination of different loss functions and optimizers:请注意,我尝试了不同损失函数和优化器的组合:

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
)

Result结果

It quickly reaches 0.0062 and remains there.它很快达到 0.0062 并保持在那里。

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

Update 1 - Slightly Better更新 1 - 稍微好一点

Thanks for the help.谢谢您的帮助。 After removing uses of random in my code and disabling shuffling it started hitting an accuracy of 1.00 50% of the time I ran the code.在我的代码中删除随机数的使用并禁用随机播放后,它开始在我运行代码的时间达到 1.00 50% 的准确度。 The other 50% was peaking at an accuracy of 0.0046.其他 50% 的峰值精度为 0.0046。 When I tried to initialize weights and biases at 0, it peaked at 0.0046 100% of the time.当我尝试将权重和偏差初始化为 0 时,它在 0.0046 100% 的时间达到峰值。 Updating all of my TF packages almost fixed the problem, with it now being successful 90% of the time.更新我所有的 TF 包几乎解决了这个问题,现在 90% 的时间都成功了。

Coming out of comments to an answer.从评论中得出答案。 You're convolving a 1x1 kernel, then passing that to a dense layer.您正在对 1x1 kernel 进行卷积,然后将其传递给密集层。 The ideal parameters that you want the network to learn is for all the weights in the dense layer to be the inverse of the kernel value.您希望网络学习的理想参数是密集层中的所有权重都是 kernel 值的倒数。 What's most important here though is that you're mostly passing zeroes.不过,这里最重要的是您通常会通过零。 Any weight value in the dense layer, applied to a zero results in another zero, so the zeroes are causing your gradient to vanish.密集层中的任何权重值,应用于零会导致另一个零,因此零会导致梯度消失。

When you initialize your weights as zeros, this turns your input vector to all zeroes, all zeros always ends learning.当您将权重初始化为零时,这会将您的输入向量变为全零,全零总是结束学习。 Can't backpropagate.不能反向传播。 When you don't do anything to the initialization, TF uses a normal distribution to initialize, centered around 0. Half the time, that initialized kernel value is negative.当您不对初始化做任何事情时,TF 使用正态分布进行初始化,以 0 为中心。一半时间,初始化的 kernel 值为负数。 After convolving, you have all zeroes and a negative number.卷积后,你得到全零和一个负数。 After relu you have all zeroes.在 relu 之后你全为零。 Half the time it can learn - because by chance it initialized with a positive kernel value, and half the time it can't.它可以学习的时间有一半——因为偶然它用正的 kernel 值初始化,而一半的时间不能。

Try this:尝试这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM