Keras模型拟合时报list index out of range错误(胸部X光迁移学习项目)
报错根因排查
- 最直接触发
IndexError: list index out of range的原因:调用tf.keras.preprocessing.image_dataset_from_directory时没有接收返回的TF Dataset对象,传入fit接口的train_dataset、validation_data本质是字符串路径,而非可迭代的张量数据集。Keras数据适配器在尝试解析输入数据的张量维度时,遇到无形状属性的字符串对象,直接触发列表索引越界。 - 数据集图像尺寸与模型输入不匹配:
image_dataset_from_directory配置的图像缩放尺寸为(256,256),但VGG16与模型输入层定义的输入形状为(150,150,3),尺寸错位会在数据集正确加载后触发形状不匹配报错。 - 任务配置逻辑错配:二分类任务下输出层为单神经元+sigmoid激活,却配置了
categorical_crossentropy损失函数,且label_mode为整数编码,该场景需使用binary_crossentropy损失。 - 网络层逻辑冗余:VGG16已配置
pooling='avg',输出为全局平均池化后的一维特征向量,后续拼接Flatten()层属于无意义操作,不会对模型效果产生正向增益。
测试目录的规范格式
- 测试目录无需特殊结构,仅需和训练集保持一致的层级:根目录下为每个类别建立单独的命名子文件夹,子文件夹内存放对应类别的.jpg格式图像,
image_dataset_from_directory会自动遍历识别类别标签,推断整数编码逻辑。 - 加载测试集时需强制指定
class_names和训练集完全一致,避免两个数据集的标签编码顺序错位,导致最终预测结果失真。
修正后的可运行代码参考
import os from PIL import Image import numpy as np import tensorflow as tf from tensorflow import keras # 定义数据集路径 test_path = 'C:\\Users\\arjun\\Desktop\\Rashmi\\Courses\\Deep Learning\\Project 2\\chest-xray-pneumonia\\chest_xray\\chest_xray\\test' train_path = 'C:\\Users\\arjun\\Desktop\\Rashmi\\Courses\\Deep Learning\\Project 2\\chest-xray-pneumonia\\chest_xray\\chest_xray\\train' batch_size = 8 # 正确加载训练集,图像尺寸对齐模型输入 train_dataset = tf.keras.preprocessing.image_dataset_from_directory( train_path, labels="inferred", label_mode="int", class_names=None, color_mode="rgb", batch_size=batch_size, image_size=(150, 150), shuffle=True, seed=123, interpolation="bilinear", ) # 正确加载测试集,类名顺序与训练集保持一致 test_dataset = tf.keras.preprocessing.image_dataset_from_directory( test_path, labels="inferred", label_mode="int", class_names=train_dataset.class_names, color_mode="rgb", batch_size=batch_size, image_size=(150, 150), shuffle=False, interpolation="bilinear", ) # 构建迁移学习模型 base_model = tf.keras.applications.VGG16( include_top=False, weights='imagenet', input_shape=(150,150,3), pooling='avg' ) base_model.trainable = False inputs = keras.Input(shape=(150,150,3)) x = base_model(inputs, training = False) x = keras.layers.Dense(512, kernel_initializer = 'he_normal', activation = 'relu')(x) predictions = keras.layers.Dense(1, activation = 'sigmoid')(x) transfer_model = keras.Model(inputs, predictions) # 匹配二分类任务的编译配置 transfer_model.compile( loss='binary_crossentropy', optimizer=keras.optimizers.SGD(learning_rate=1e-4,momentum=0.9), metrics=['accuracy'] ) # 传入合法的TF Dataset对象启动训练 transfer_model.fit( train_dataset, epochs = 2, validation_data = test_dataset )
内容的提问来源于stack exchange,提问作者Rashmi Rao Raghavendra
相关产品推荐
相关产品推荐

