You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TensorFlow训练Loss为NaN且Accuracy为0的问题排查求助

模型训练Loss为NaN、Accuracy维持0.0的问题排查与解决建议

问题背景

训练模型时出现Loss快速变为NaN、Accuracy降至0并维持的异常,相关代码与训练日志如下:

数据加载代码

def load_images_and_labels(folder_path, json_path):
    with open(json_path, 'r') as json_file:
        label_data = json.load(json_file)

    image_data = []
    labels = []
    boxes = []

    for image_info in label_data["images"]:
        image_id = image_info["id"]

        # Construct the full path to the file
        filename = image_info["file_name"]
        image_path = os.path.join(folder_path, filename)

        img = cv2.imread(image_path)

        img_grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        # Extract all labels and bounding boxes based on the image_id from the JSON data
        image_annotations = [item for item in label_data["annotations"] if item["image_id"] == image_id]

        # Check if there are annotations for the image
        if image_annotations:
            for annotation in image_annotations:
                # Extract label and bounding box information
                image_label = annotation["category_id"]
                bbox = annotation["bbox"]

                # Add the image, label, and bounding box to the arrays
                image_data.append(img_grey)
                labels.append(image_label)
                boxes.append(bbox)

    # Convert the lists to NumPy arrays
    image_array = np.array(image_data).astype('float32')
    label_array = np.array(labels)
    box_array = np.array(boxes).astype('float32')

    return image_array, label_array, box_array

模型结构与训练代码

input_image = Input(shape=(400, 400), name='image_input') 
input_bbox = Input(shape=(4,), name='bounding_box_input')  

# Flachklopfen des Bildes
flatten_image = Flatten()(input_image)

merged_input = Concatenate()([flatten_image, input_bbox])

x = Dense(64, activation='relu')(merged_input)
output_layer = Dense(28, activation='softmax')(x)

model = tf.keras.Model(inputs=[input_image, input_bbox], outputs=output_layer)
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# training
model.fit({'image_input': train_images, 'bounding_box_input': train_boxes}, train_labels, epochs=10)

训练日志

Epoch 1/10
112/112 [==============================] - 4s 15ms/step - loss: nan - accuracy: 2.8035e-04
Epoch 2/10
112/112 [==============================] - 2s 15ms/step - loss: nan - accuracy: 0.0000e+00
Epoch 3/10
112/112 [==============================] - 2s 15ms/step - loss: nan - accuracy: 0.0000e+00
Epoch 4/10
112/112 [==============================] - 2s 15ms/step - loss: nan - accuracy: 0.0000e+00

已完成排查

  • 验证数据与标签的正确性
  • 对图像像素值做了归一化处理(train_images = train_images / 255.0)

潜在原因分析

  1. 边界框数据未归一化:图像特征已缩放到0-1范围,但边界框是原始像素坐标(0-400),两者数值范围差异极大,拼接后会导致模型权重更新时梯度爆炸,最终Loss变为NaN。
  2. 类别标签不匹配:sparse_categorical_crossentropy要求标签是0到num_classes-1的整数(此处应为0-27),若标签从1开始或存在大于等于28的数值,会导致损失计算时出现无效值。
  3. 数据存在异常值:部分图像读取失败(cv2.imread返回None)、边界框坐标超出图像范围(如负坐标、宽高为0),会引入NaN或无效值进入训练流程。
  4. 学习率过高:Adam默认学习率0.001,在输入特征数值差异大的情况下,易引发梯度爆炸,导致权重出现NaN。

可行解决方法

  1. 归一化边界框数据:将边界框的x、y、w、h均除以图像尺寸(400),缩放到0-1范围,与图像特征数值范围对齐:
    box_array = np.array(boxes).astype('float32') / 400.0
    
  2. 修正类别标签:检查标签范围,若标签从1开始,统一减1:
    label_array = np.array(labels) - 1
    
    同时确认所有标签值在0-27之间,过滤或修正超出范围的标签。
  3. 添加数据校验逻辑:在load_images_and_labels函数中加入异常检查:
    # 检查图像是否读取成功
    if img is None:
        print(f"Failed to read image: {image_path}")
        continue
    # 检查边界框有效性
    x, y, w, h = bbox
    if x < 0 or y < 0 or w <=0 or h <=0 or x+w > 400 or y+h >400:
        print(f"Invalid bbox {bbox} for image {image_path}")
        continue
    
  4. 降低学习率并添加梯度裁剪:调整Adam优化器参数,限制梯度大小:
    optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001, clipnorm=1.0)
    model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    
  5. 检查输入维度匹配:确认train_images形状为(样本数,400,400),train_boxes为(样本数,4),train_labels为(样本数,),避免维度不匹配导致的计算错误。

内容的提问来源于stack exchange,提问作者metal-lode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:07:03