python - 训练 3dconv 神经网络失败;损失收敛于 .6931
问题描述
我编写了一个脚本来训练神经网络使用 .nii 文件作为输入,使用来自 TensorFlow 的教程https://www.tensorflow.org/tutorials/load_data/images。我稍微改变了它以使用 NiBabel 和 .nii 文件,但它仍然遵循相同的基本结构。然而,我遇到了一个问题,我的损失收敛到 0.6931,我认为这是因为模型开始猜测相同的东西,而不管输入、图像形状或批量大小。因此,我认为该模型没有学习。任何人都可以识别我的代码的任何致命缺陷吗?我已经累了:
- 更改 LR 的回调
- 更改数据、清理数据和重组数据
- 改变每类数量的比例
- 使用不同的优化器和损失函数
- 使用简单的密集、密集、密集模型,但这似乎不起作用,因为它甚至不想开始训练
- 使用重复数据集和固定大小(虽然我不清楚这有什么区别)
# Gets the label of the image, the label determines how tensorflow will classify the image
def get_label(file_path):
# Convert the path to a list of path components
parts = tf.strings.split(file_path, os.path.sep)
# The fourth last is the class-directory
return float(parts[-4] == "class1")
# Reads the data from a .nii file and returns a NumPy ndarray that is compatible with tensorflow
def decode_img(img):
img = nib.load(img.numpy().decode('utf-8'))
# convert the compressed string to a NumPy ndarray
data = img.get_fdata()
# Resize img
data = np.resize(data, imgshape)
# Normalize
max = np.amax(data)
min = np.amin(data)
data = ((data-min)/(max-min))
return data
# Processes a path to return a image data and label pair
def process_path(file_path):
# Gets the files label
label = get_label(file_path)
img = decode_img(file_path)
return img, label
我正在使用这些函数来处理我的数据并将其映射到我的列表文件数据集以处理我的数据。
def configure_for_performance(ds):
#ds = ds.cache(filename='cachefile')
ds = ds.cache()
ds = ds.shuffle(buffer_size=1000)
ds = ds.repeat()
ds = ds.batch(BATCH_SIZE)
ds = ds.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
return ds
我直接从 TensorFlow 教程中提取了这个。
# Create a sequential network
model = tf.keras.Sequential([
tf.keras.layers.Convolution3D(
4, 4, padding='same', data_format="channels_last", input_shape=imgshape, activation='tanh'),
tf.keras.layers.MaxPooling3D(padding='same'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Convolution3D(4, 4, padding='same', activation='tanh'),
tf.keras.layers.MaxPooling3D(padding='same'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Convolution3D(4, 4, padding='same', activation='tanh'),
tf.keras.layers.MaxPooling3D(padding='same'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Convolution3D(4, 4, padding='same', activation='tanh'),
tf.keras.layers.MaxPooling3D(padding='same'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(2048, activation='tanh'),
tf.keras.layers.Dense(1024, activation='tanh'),
tf.keras.layers.Dense(512, activation='tanh'),
tf.keras.layers.Dense(256, activation='tanh'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
model.fit(
train_ds,
validation_data=val_ds,
epochs=500,
steps_per_epoch=BATCH_SIZE,
validation_steps=BATCH_SIZE
)
这是我的模型,我使用 3dconv 类似于在传统图像分类中使用 2dconv。
任何意见,将不胜感激!
解决方案
如果你一直收敛到完全相同的损失,那么根据我的经验只有一种解释——你错误地编码了数据加载器。发生的事情是图像和标签不匹配。它试图学习纯粹的随机性。在这种情况下,它只会尽其所能,输出“平均”正确答案。我怀疑 0.69 值来自您的数据标签,例如您有 69% 的 1 类和 31% 的 0 类。
推荐阅读
- shell - 来自列表的 For 循环
- java - 如何停止 Spark RDD mapPartitions 在集群中复制数据?
- bash - 尝试使用“kubectl cp”将文件复制到 Pod,但出现错误:未知标志:--all-namespaces
- sql-server - 根据历史表创建日期范围报告
- c++ - 如何使用 std::cout 或 std::ofstream 作为单个函数的输入?
- php - 在 PHP 中设置自定义标头并在 htaccess 中检查
- date - Twig:无法检查日期是否在过去 2 年(prestashop)
- r - 从 R 中的 for 循环创建数据框
- java - 如何检查匿名来电显示是否启用?
- python - 如何对张量变量进行比较赋值?