根据题意给出完整的代码
时间: 2024-10-22 21:22:19 浏览: 22
根据提供的代码和错误信息,主要问题是 `ImageDataGenerator` 的 `flow` 方法不能直接处理字符串类型的图像路径。我们需要使用 `flow_from_directory` 方法来从目录中加载图像,或者手动将图像路径转换为图像数组。以下是修正后的完整代码:
```python
import json
import os
import pandas
from future.standard_library import install_aliases
install_aliases()
from pygame.examples.sprite_texture import load_img
# 读取 train_label.json 和 val_label.json
with open(r'C:\Users\24067\Desktop\train_label.json', 'r', encoding='utf-8') as f:
train_labels = json.load(f)
with open(r'C:\Users\24067\Desktop\val_label.json', 'r', encoding='utf-8') as f:
val_labels = json.load(f)
# 创建文件名到标签的映射
train_labels_dict = {item['文件名']: item['标签'] for item in train_labels}
val_labels_dict = {item['文件名']: item['标签'] for item in val_labels}
# 标签映射到类别索引
label_mapping = {"特级": 0, "一级": 1, "二级": 2, "三级": 3}
train_image_paths = []
train_image_labels = []
val_image_paths = []
val_image_labels = []
# 获取训练集的图片路径和标签
train_folder = r'C:\Users\24067\Desktop\peach_split\train'
for filename in os.listdir(train_folder):
if filename in train_labels_dict:
train_image_paths.append(os.path.join(train_folder, filename))
train_image_labels.append(label_mapping[train_labels_dict[filename]])
# 获取验证集的图片路径和标签
val_folder = r'C:\Users\24067\Desktop\peach_split\val'
for filename in os.listdir(val_folder):
if filename in val_labels_dict:
val_image_paths.append(os.path.join(val_folder, filename))
val_image_labels.append(label_mapping[val_labels_dict[filename]])
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array
# 将文件路径列表转换为图像数组
def load_images_from_paths(image_paths, target_size=(224, 224)):
images = []
for path in image_paths:
# 加载图片并调整大小
img = load_img(path, target_size=target_size)
img_array = img_to_array(img)
images.append(img_array)
return np.array(images)
# 加载训练集图片并转换为数组
train_images = load_images_from_paths(train_image_paths)
val_images = load_images_from_paths(val_image_paths)
# 将标签转换为 NumPy 数组
train_labels = np.array(train_image_labels)
val_labels = np.array(val_image_labels)
# 定义数据增强器
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True
)
val_datagen = ImageDataGenerator(rescale=1./255)
# 训练数据生成器
train_generator = train_datagen.flow(
x=train_images,
y=train_labels,
batch_size=32
)
# 验证数据生成器
val_generator = val_datagen.flow(
x=val_images,
y=val_labels,
batch_size=32
)
# 测试数据生成器 (注意:测试集没有类别标签)
test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(
directory=r'C:\Users\24067\Desktop\peach_split\test',
target_size=(224, 224),
batch_size=32,
class_mode=None, # 因为测试集没有标签
shuffle=False
)
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model
# 加载预训练的 ResNet50 模型,不包含顶层
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
# 构建自定义分类层
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
predictions = Dense(4, activation='softmax')(x) # 4类
# 构建模型
model = Model(inputs=base_model.input, outputs=predictions)
# 冻结预训练模型的卷积层
for layer in base_model.layers:
layer.trainable = False
# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
from tensorflow.keras.callbacks import EarlyStopping
# 提前停止回调,当验证损失在 3 个 epoch 内没有改善时停止训练
early_stopping = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)
# 训练模型
history = model.fit(
train_generator,
epochs=3, # 设置为你需要的迭代次数
validation_data=val_generator,
callbacks=[early_stopping]
)
```
### 主要修改点:
1. **使用 `load_images_from_paths` 函数**:将图像路径列表转换为图像数组,这样可以直接传递给 `ImageDataGenerator` 的 `flow` 方法。
2. **删除重复的数据生成器创建**:避免了重复创建 `train_generator` 和 `val_generator`。
3. **修复导入语句**:确保所有必要的模块都正确导入。
希望这些修改能解决你的问题。如果有任何其他问题或需要进一步的帮助,请告诉我。
阅读全文