CNN 模型的损失收敛性和准确性差
Poor loss convergence and accuracy with CNN model
我使用 TF 构建了一个二元分类器,它将 16x16 灰度图像分类为分布为 87-13 的两个 类 之一。我遇到的问题是模型的 log loss converges to ~0.4,它比随机的要好,但我无法让它超越这个。
视觉问题属于视频编码领域,This image should provide some understanding to the problem,其中根据图像的同质性来分割或不分割 (0/1) 图像。注意边缘附近的方块更有可能被细分为较小的方块。
验证模型(1.1e7 示例,87-13 分布)时,我无法实现 F1-score better than ~50%。
我的训练数据由 2.2e8 个示例组成,这些示例 oversampled/undersampled 以实现 50-50 分布。我使用的批大小为 1024 的大量洗牌缓冲区(数据未按顺序排列)。使用 Adam 进行优化,使用默认的超参数。
我尝试提高性能的事情(测试(结果)):
- 更大的网络,不断变化的层数、激活、卷积核大小和步幅等(相同的收敛)
- 密集层之间的Dropout(与大网性能相同,小网性能较差)
- 其他 Adam 超参数(最终都导致相同的收敛)
- 其他优化器(同上)
- 使用非常小的数据集进行训练以测试收敛性(损失饱和为 0)
- 正则化输入(无效)
- 不同的批量大小(仅影响损失和收敛时间中的噪声)
我一直在努力提高性能,我想我已经阅读了我能找到的所有 SO 问题。任何建议都会有很大的帮助。
def cnn_model(features, labels, mode):
# downsample to 8x8 using 2x2 local averaging
features_8x8 = tf.nn.avg_pool(
value=tf.cast(features["x"], tf.float32),
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding="SAME",
data_format='NHWC'
)
conv2d_0 = tf.layers.conv2d(inputs=features_8x8,
filters=6,
kernel_size=[3, 3],
strides=(1, 1),
activation=tf.nn.relu,
name="conv2d_0")
pool0 = tf.layers.max_pooling2d(
inputs=conv2d_0,
pool_size=(2, 2),
strides=(2, 2),
padding="SAME",
data_format='channels_last'
)
conv2d_1 = tf.layers.conv2d(inputs=pool0,
filters=16,
kernel_size=[3, 3],
strides=(3, 3),
activation=tf.nn.relu,
name="conv2d_1")
reshape1 = tf.reshape(conv2d_1, [-1, 16])
dense0 = tf.layers.dense(inputs=reshape1,
units=10,
activation=tf.nn.relu,
name="dense0")
logits = tf.layers.dense(inputs=dense0,
units=1,
name="logits")
# ########################################################
predictions = {
"classes": tf.round(tf.nn.sigmoid(logits)),
"probabilities": tf.nn.sigmoid(logits)
}
# ########################################################
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode=mode,
predictions=predictions)
# ########################################################
cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits(
labels=tf.cast(labels['y'], tf.float32),
logits=logits
)
loss = tf.reduce_mean(cross_entropy)
# ########################################################
# Configure the Training Op (for TRAIN mdoe)
if mode == tf.estimator.ModeKeys.TRAIN:
optimiser = tf.train.AdamOptimizer(learning_rate=0.001,
beta1=0.9,
beta2=0.999,
epsilon=1e-08)
train_op = optimiser.minimize(
loss=loss,
global_step=tf.train.get_global_step())
return tf.estimator.EstimatorSpec(mode=mode,
loss=loss,
train_op=train_op)
# Add evalutation metrics (for EVAL mode)
eval_metric_ops = {
"accuracy": tf.metrics.accuracy(
labels=labels["y"],
predictions=predictions["classes"]),
}
return tf.estimator.EstimatorSpec(mode=mode,
loss=loss,
eval_metric_ops=eval_metric_ops)
看来你已经做了很多了。我的下一步是
的可视化
- 数据集:人类能区分类吗?
- 权重:它们在训练期间收敛/变化吗
- fine-tuned 像 VGG 这样的模型是如何工作的?
可能,您问的是一个非常困难的视力问题。我们可以查看图像或获取数据样本吗?然后,有经验的人可以尝试提出一个(希望)有效的基本模型...
我使用 TF 构建了一个二元分类器,它将 16x16 灰度图像分类为分布为 87-13 的两个 类 之一。我遇到的问题是模型的 log loss converges to ~0.4,它比随机的要好,但我无法让它超越这个。
视觉问题属于视频编码领域,This image should provide some understanding to the problem,其中根据图像的同质性来分割或不分割 (0/1) 图像。注意边缘附近的方块更有可能被细分为较小的方块。
验证模型(1.1e7 示例,87-13 分布)时,我无法实现 F1-score better than ~50%。
我的训练数据由 2.2e8 个示例组成,这些示例 oversampled/undersampled 以实现 50-50 分布。我使用的批大小为 1024 的大量洗牌缓冲区(数据未按顺序排列)。使用 Adam 进行优化,使用默认的超参数。
我尝试提高性能的事情(测试(结果)):
- 更大的网络,不断变化的层数、激活、卷积核大小和步幅等(相同的收敛)
- 密集层之间的Dropout(与大网性能相同,小网性能较差)
- 其他 Adam 超参数(最终都导致相同的收敛)
- 其他优化器(同上)
- 使用非常小的数据集进行训练以测试收敛性(损失饱和为 0)
- 正则化输入(无效)
- 不同的批量大小(仅影响损失和收敛时间中的噪声)
我一直在努力提高性能,我想我已经阅读了我能找到的所有 SO 问题。任何建议都会有很大的帮助。
def cnn_model(features, labels, mode):
# downsample to 8x8 using 2x2 local averaging
features_8x8 = tf.nn.avg_pool(
value=tf.cast(features["x"], tf.float32),
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding="SAME",
data_format='NHWC'
)
conv2d_0 = tf.layers.conv2d(inputs=features_8x8,
filters=6,
kernel_size=[3, 3],
strides=(1, 1),
activation=tf.nn.relu,
name="conv2d_0")
pool0 = tf.layers.max_pooling2d(
inputs=conv2d_0,
pool_size=(2, 2),
strides=(2, 2),
padding="SAME",
data_format='channels_last'
)
conv2d_1 = tf.layers.conv2d(inputs=pool0,
filters=16,
kernel_size=[3, 3],
strides=(3, 3),
activation=tf.nn.relu,
name="conv2d_1")
reshape1 = tf.reshape(conv2d_1, [-1, 16])
dense0 = tf.layers.dense(inputs=reshape1,
units=10,
activation=tf.nn.relu,
name="dense0")
logits = tf.layers.dense(inputs=dense0,
units=1,
name="logits")
# ########################################################
predictions = {
"classes": tf.round(tf.nn.sigmoid(logits)),
"probabilities": tf.nn.sigmoid(logits)
}
# ########################################################
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode=mode,
predictions=predictions)
# ########################################################
cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits(
labels=tf.cast(labels['y'], tf.float32),
logits=logits
)
loss = tf.reduce_mean(cross_entropy)
# ########################################################
# Configure the Training Op (for TRAIN mdoe)
if mode == tf.estimator.ModeKeys.TRAIN:
optimiser = tf.train.AdamOptimizer(learning_rate=0.001,
beta1=0.9,
beta2=0.999,
epsilon=1e-08)
train_op = optimiser.minimize(
loss=loss,
global_step=tf.train.get_global_step())
return tf.estimator.EstimatorSpec(mode=mode,
loss=loss,
train_op=train_op)
# Add evalutation metrics (for EVAL mode)
eval_metric_ops = {
"accuracy": tf.metrics.accuracy(
labels=labels["y"],
predictions=predictions["classes"]),
}
return tf.estimator.EstimatorSpec(mode=mode,
loss=loss,
eval_metric_ops=eval_metric_ops)
看来你已经做了很多了。我的下一步是
的可视化- 数据集:人类能区分类吗?
- 权重:它们在训练期间收敛/变化吗
- fine-tuned 像 VGG 这样的模型是如何工作的?
可能,您问的是一个非常困难的视力问题。我们可以查看图像或获取数据样本吗?然后,有经验的人可以尝试提出一个(希望)有效的基本模型...