Tensorflow 二元分类训练不正确

Tensorflow 二元分类训练不正确,tensorflow,neural-network,conv-neural-network,training-data,Tensorflow,Neural Network,Conv Neural Network,Training Data,我一直在研究一种神经网络,它可以对两组天文数据进行分类。我相信我的神经网络正在挣扎,因为这两组数据非常相似,但即使数据发生了重大变化,它的精度历史似乎仍与我认为的不一样 以下是来自每个数据集的示例图像: 我目前正在使用每种类型的10000张图像,其中20%用于验证数据,因此有16000张培训图像和4000张验证图像。由于内存限制,我无法增加更多的数据集 这是我目前的型号: model.add(layers.Conv2D(64, (3, 3), padding="valid"

我一直在研究一种神经网络,它可以对两组天文数据进行分类。我相信我的神经网络正在挣扎,因为这两组数据非常相似,但即使数据发生了重大变化,它的精度历史似乎仍与我认为的不一样

以下是来自每个数据集的示例图像:

我目前正在使用每种类型的10000张图像,其中20%用于验证数据,因此有16000张培训图像和4000张验证图像。由于内存限制,我无法增加更多的数据集

这是我目前的型号:

model.add(layers.Conv2D(64, (3, 3), padding="valid", activation='relu', input_shape=(192, 192, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (7, 7), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (9, 9), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (7, 7), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(2, activation="sigmoid"))
我正在用它编译:

opt = SGD(lr=0.1)
model.compile(optimizer=opt,
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
以及使用以下装置进行安装:

history = model.fit(train, train_labels, batch_size=200, epochs=15, validation_data=(validation, validation_labels))
如果我向数据中添加了一些东西,使数据集变得不现实(例如,在数据的中间添加一个随机矩形,或者在其中一个数据集上添加一个掩码,但在另一个数据集上不添加掩码),我会得到一个精度历史,如下所示:

model.add(layers.Dense(1)) # no activation, linear.

(请注意,训练数据的精度历史记录向左移动了半个历元,以说明在验证精度之前的半个历元平均测量的训练精度。)

如果我使数据集非常相似(例如,不向数据集添加任何内容或对两个数据集应用相同的掩码),我将获得如下所示的精度历史:

model.add(layers.Dense(1)) # no activation, linear.

或者偶尔在一个历元的验证精度上出现一个大的峰值,比如:

查看不同的网站和其他StackOverflow页面,我尝试了:

  • 更改过滤器的数量和大小
  • 加或减卷积层
  • 更改优化器功能(它最初是“adam”,因此它具有自适应学习速率,我将其切换到上面的状态,以便手动调整学习速率)
  • 增加批量大小
  • 增加数据集(最初每个数据集只有5000张图像,而不是10000张)
  • 增加纪元的数量(从10个增加到15个)
  • 从卷积层中添加或减去填充
  • 更改最后一层中的激活功能

我错过什么了吗?这些数据集是否过于相似,无法实现二进制分类网络?

如果这是二进制分类,则需要更改:

model.add(layers.Dense(2, activation="sigmoid"))
进入:

Sigmoid表示,如果输出大于某个阈值(大多数情况下为0.5),则它属于第二类等。此外,由于您在最后一个密集层中指定了激活,因此确实不需要使用
from_logits=True

请记住,您的损失还应包括:

tf.keras.losses.BinaryCrossentropy(from_logits = False)
如果要从_logits=True设置
,则最后一个密集层应如下所示:

model.add(layers.Dense(1)) # no activation, linear.


您也可以在最后一个密集层中使用2个神经元,但随后您需要使用
softmax
激活并进行分类丢失。

谢谢您的回复!我把最后的图层改成了
图层。密集(1)
。我尝试使用
from_logits=False
和一个sigmoid激活函数运行它,然后再次使用
from_logits=True
和无激活函数运行它,但两者都返回了类似的验证精度,由于各个时期的验证准确率都保持在50%,而且训练准确率在100%和50%之间跳跃0.1 LR太高了,我会先尝试降低它。然后随着图像尺寸的减小,增加CNN中过滤器的大小和数量。像
Conv2D(32,(3,3))。。Conv2D(64,(3,3)
等等。谢谢!!这看起来好多了。最后一个问题让我明白了发生了什么:在确定为100%准确度之前,验证准确度仍然在50%和100%准确度之间跳跃。我认为这是正常的吗?我希望准确度会缓慢提高,而不是像我们在这里看到的那样上下交错的增加。也许可以试试adam optimiz呃,在学习率较低的情况下,我认为会出现较少的振荡。我认为这不正常,实际上可能与您的数据有关。根据我的建议,模型应该不会有任何问题。如果答案有用,如果您能接受,我会很高兴。