二元分类训练不正确
Binary classification not training correctly
我一直在研究可以对两组天文数据进行分类的神经网络。我相信我的神经网络正在苦苦挣扎,因为这两组数据非常相似,但即使对数据进行了重大更改,准确率历史似乎仍然不像我想象的那样。
这些是来自每个数据集的示例图像:
我目前使用每种类型的 10,000 张图像,其中 20% 用于验证数据,因此有 16,000 张训练图像和 4,000 张验证图像。由于内存限制,我无法将数据集增加太多。
这是我目前的型号:
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))
如果我向数据中添加一些内容以使数据集变得不切实际(例如,向数据中间添加一个随机矩形,或者向一个矩形而不是另一个添加掩码),我得到的准确度历史看起来像这样:
(请注意,训练数据的准确度历史记录向左移动了半个纪元,以说明被测量的训练准确度,平均比验证准确度早半个纪元。)
如果我使数据集非常相似(例如,不向数据集添加任何内容或对两者应用相同的掩码),我得到的准确度历史记录如下所示:
或者偶尔在一个时期的验证准确率出现大幅上升,如下所示:
查看不同的网站和其他 Whosebug 页面,我尝试过:
- 更改过滤器的数量和大小
- 添加或减去卷积层
- 更改优化器函数(它最初是“adam”,所以它具有自适应学习率,我将其切换到上面以便我可以手动调整学习率)
- 增加批量大小
- 增加数据集(最初每个只有 5,000 张图像,而不是 10,000 张),
- 增加纪元数(从 10 到 15)
- 从卷积层中添加或减去填充
- 改变最后一层的激活函数
我错过了什么吗?这些数据集是否太相似而无法实现二元分类网络?
如果这是二进制 class化,那么您需要更改:
model.add(layers.Dense(2, activation="sigmoid"))
进入:
model.add(layers.Dense(1, activation="sigmoid"))
Sigmoid 表示如果输出大于某个阈值(大多数时候是 0.5)那么它属于第二个 class 等。而且你真的不需要使用 from_logits = True
因为你在最后一个密集层指定了一个激活。
回想一下,你的损失也应该是:
tf.keras.losses.BinaryCrossentropy(from_logits = False)
如果你想设置from_logits = True
,那么你的最后一个密集层应该是这样的:
model.add(layers.Dense(1)) # no activation, linear.
您也可以在最后一个致密层使用 2 个神经元,但是您需要使用 softmax
具有分类损失的激活。
我一直在研究可以对两组天文数据进行分类的神经网络。我相信我的神经网络正在苦苦挣扎,因为这两组数据非常相似,但即使对数据进行了重大更改,准确率历史似乎仍然不像我想象的那样。
这些是来自每个数据集的示例图像:
我目前使用每种类型的 10,000 张图像,其中 20% 用于验证数据,因此有 16,000 张训练图像和 4,000 张验证图像。由于内存限制,我无法将数据集增加太多。
这是我目前的型号:
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))
如果我向数据中添加一些内容以使数据集变得不切实际(例如,向数据中间添加一个随机矩形,或者向一个矩形而不是另一个添加掩码),我得到的准确度历史看起来像这样:
(请注意,训练数据的准确度历史记录向左移动了半个纪元,以说明被测量的训练准确度,平均比验证准确度早半个纪元。)
如果我使数据集非常相似(例如,不向数据集添加任何内容或对两者应用相同的掩码),我得到的准确度历史记录如下所示:
或者偶尔在一个时期的验证准确率出现大幅上升,如下所示:
查看不同的网站和其他 Whosebug 页面,我尝试过:
- 更改过滤器的数量和大小
- 添加或减去卷积层
- 更改优化器函数(它最初是“adam”,所以它具有自适应学习率,我将其切换到上面以便我可以手动调整学习率)
- 增加批量大小
- 增加数据集(最初每个只有 5,000 张图像,而不是 10,000 张),
- 增加纪元数(从 10 到 15)
- 从卷积层中添加或减去填充
- 改变最后一层的激活函数
我错过了什么吗?这些数据集是否太相似而无法实现二元分类网络?
如果这是二进制 class化,那么您需要更改:
model.add(layers.Dense(2, activation="sigmoid"))
进入:
model.add(layers.Dense(1, activation="sigmoid"))
Sigmoid 表示如果输出大于某个阈值(大多数时候是 0.5)那么它属于第二个 class 等。而且你真的不需要使用 from_logits = True
因为你在最后一个密集层指定了一个激活。
回想一下,你的损失也应该是:
tf.keras.losses.BinaryCrossentropy(from_logits = False)
如果你想设置from_logits = True
,那么你的最后一个密集层应该是这样的:
model.add(layers.Dense(1)) # no activation, linear.
您也可以在最后一个致密层使用 2 个神经元,但是您需要使用 softmax
具有分类损失的激活。