使用DeepScores数据集训练模型时TypeError错误修复求助
问题分析
报错TypeError: string indices must be integers, not 'str'出现在image_id = annotation['image_id'],原因是train_data['annotations']是字典类型,直接遍历它会得到字典的键(字符串),而非包含注释信息的字典对象。此时annotation是字符串,自然无法使用['image_id']这种字符串索引。
修复后的完整代码
import json import numpy as np from PIL import Image from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D from keras.utils import to_categorical with open('deepscores_train.json', 'r') as f: train_data = json.load(f) with open('deepscores_test.json', 'r') as f: test_data = json.load(f) train_x = [] train_y = [] # 遍历annotations的value,获取实际注释对象 for annotation in train_data['annotations'].values(): # 获取图像ID image_id = annotation['image_id'] # 查找与当前注释匹配的图像 image = next((i for i in train_data['images'] if i['id'] == image_id), None) if image is None: continue # 从图像文件中加载图像数据 with Image.open(image['file_name']) as img: # 统一图像尺寸(可根据数据集实际情况调整) img = img.resize((224, 224)) img_data = np.array(img, dtype='float32') / 255.0 # 归一化处理 label = annotation['category_id'] train_x.append(img_data) train_y.append(label) train_x = np.array(train_x) # 转换为one-hot编码,适配categorical_crossentropy损失函数 train_y = to_categorical(train_y) test_x = [] test_y = [] # 测试集使用test_data的注释数据,而非train_data for annotation in test_data['annotations'].values(): image = next((i for i in test_data['images'] if i['id'] == annotation['image_id']), None) if image is None: continue # 统一使用file_name字段,和训练集保持一致 with Image.open(image['file_name']) as img: img = img.resize((224, 224)) img_data = np.array(img, dtype='float32') / 255.0 label = annotation['category_id'] test_x.append(img_data) test_y.append(label) test_x = np.array(test_x) test_y = to_categorical(test_y) model = Sequential() # 输入形状和resize后的图像尺寸一致 model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(224, 224, 3))) model.add(Conv2D(64, kernel_size=(3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) # 输出层神经元数量需和数据集类别数匹配,示例为10,可按需调整 model.add(Dense(10, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(train_x, train_y, batch_size=128, epochs=10, validation_data=(test_x, test_y)) model.save('music_model.h5')
关键修复点
- 注释遍历修正:将
for annotation in train_data['annotations']改为for annotation in train_data['annotations'].values(),确保拿到的是包含image_id的注释字典。 - 测试集数据混淆修复:原代码测试集错误使用了训练集的注释数据,改为
test_data['annotations'].values()。 - 图像尺寸统一:添加
resize操作,避免因图像尺寸不一致导致模型输入报错。 - 数据归一化:将图像数据除以255.0,归一化到0-1范围,加速模型收敛。
- 标签格式适配:使用
to_categorical转换标签为one-hot编码,匹配categorical_crossentropy损失函数要求。 - 输入形状匹配:模型输入形状调整为统一后的图像尺寸,需和实际图像通道数保持一致。
内容的提问来源于stack exchange,提问作者KLETIKA
相关产品推荐
相关产品推荐

