多输入输出训练模型报错:AttributeError: 'numpy.ndarray'无strip属性
解决fit_generator中numpy数组引发的AttributeError: 'numpy.ndarray' object has no attribute 'strip'问题
我帮你分析下这个问题:从你给出的X_train打印结果能看到,这个数组里混合了字符串类型的图片路径和数值类型的浮点数特征,而strip()是字符串专属的方法——报错的原因肯定是你的batcher生成器函数里,不小心对数值类型的元素调用了strip(),数值类型(比如float)根本没有这个方法,自然就抛出AttributeError了。
下面给你几个具体的解决思路:
1. 修正batcher函数的处理逻辑,区分不同类型的数据
你的batcher是负责生成训练批次的核心,必须针对性处理X_train里的两种数据:
- 对图片路径字符串:可以正常调用
strip()清理可能的空格,然后加载图片转成数组; - 对数值特征:直接保留原数值,绝对不要对它们调用字符串相关方法。
给你一个简单的修正示例(假设batcher原来的逻辑有误):
import os from tensorflow.keras.preprocessing.image import load_img, img_to_array import numpy as np def batcher(data_dir, X, y, batch_size, is_train): # 假设你的输入图片尺寸是(224,224,3),可根据实际调整 img_height, img_width = 224, 224 while True: # 按批次遍历数据 for i in range(0, len(X), batch_size): batch_X = X[i:i+batch_size] batch_y = y[i:i+batch_size] # 拆分图片路径和数值特征 batch_img_paths = batch_X[:, 0] batch_numeric_feats = batch_X[:, 1].astype(np.float32) # 处理图片路径:只对字符串调用strip() processed_imgs = [] for path in batch_img_paths: # 仅清理路径字符串的空格 clean_path = path.strip() img = load_img(os.path.join(data_dir, clean_path), target_size=(img_height, img_width)) img_array = img_to_array(img) processed_imgs.append(img_array) processed_imgs = np.array(processed_imgs) # 组合成多输入格式,适配你的多输入模型 inputs = [processed_imgs, batch_numeric_feats] yield inputs, batch_y
2. 改用model.fit()替代fit_generator(TF2.x版本推荐)
如果你用的是TensorFlow 2.x,fit_generator已经被官方弃用了,直接用model.fit()就能完美处理生成器,兼容性更好。注意要把原来的samples_per_epoch和nb_val_samples换成步数(总样本数除以批次大小):
# 替换原来的fit_generator调用 history = model.fit( batcher(data_dir, X_train, y_train, batch_size, True), steps_per_epoch=samples_per_epoch // batch_size, # 总样本数/批次大小=步数 epochs=nb_epoch, validation_data=batcher(data_dir, X_valid, y_valid, batch_size, False), validation_steps=len(X_valid) // batch_size, callbacks=[checkpoint], verbose=1 )
3. 提前拆分数据,避免混合类型数组的混淆
X_train是混合了字符串和数值的object类型numpy数组,这种类型很容易引发处理错误。建议提前把它拆成两个独立的数组:
def train_model(model, X_train, X_valid, y_train, y_valid): """ Train the model """ checkpoint = ModelCheckpoint('model-{epoch:03d}-Hunet-LSTM-Canny_Final_bc50.h5', monitor='val_loss', verbose=0, save_best_only=True, mode='auto') model.compile(loss='mse', optimizer=Adam(lr=0.0001)) # 拆分X为图片路径数组和数值特征数组 img_paths_train = X_train[:, 0] numeric_feats_train = X_train[:, 1].astype(np.float32) img_paths_valid = X_valid[:, 0] numeric_feats_valid = X_valid[:, 1].astype(np.float32) # 修改batcher函数,让它接收这两个独立的数组参数 history = model.fit( batcher(data_dir, img_paths_train, numeric_feats_train, y_train, batch_size, True), steps_per_epoch=samples_per_epoch // batch_size, epochs=nb_epoch, validation_data=batcher(data_dir, img_paths_valid, numeric_feats_valid, y_valid, batch_size, False), validation_steps=len(X_valid) // batch_size, callbacks=[checkpoint], verbose=1 )
这样batcher里处理数据时就不会再混淆字符串和数值,从根源上避免这类错误。
内容的提问来源于stack exchange,提问作者You Hur
相关产品推荐
相关产品推荐

