动手学习深度学习常见错误一:调用inputs.mean()出现TypeError: can only concatenate str (not “int“) to str

李沐老师源代码,可能由于版本问题会报错
李沐老师源代码,可能由于版本问题会报错。报错的原因是inputs.mean()的方法还包含了第二列的字符串,不能处理字符串与数字相结合,所以只针对第一列进行处理即可。增加一个可以选择位置的函数。

inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs.iloc[:,0] = inputs.fillna(inputs.iloc[:,0].mean())
print(inputs)```

TypeError: in user code: TypeError: outer_factory.<locals>.inner_factory.<locals>.tf__combine_features() takes 1 positional argument but 2 were given,下面是这个出现这个问题的原代码,你帮我修改下import os import re import glob import tensorflow as tf import numpy as np from tqdm import tqdm import matplotlib.pyplot as plt import matplotlib as mpl from sklearn.model_selection import train_test_split import imageio import sys from skimage.transform import resize import traceback from tensorflow.keras import layers, models, Input, Model from tensorflow.keras.optimizers import Adam from pathlib import Path from tensorflow.keras.losses import MeanSquaredError from tensorflow.keras.metrics import MeanAbsoluteError from skimage import measure, morphology, filters # =============== 配置参数===================================== BASE_DIR = "F:/2025.7.2wavelengthtiff" # 根目录路径 START_WAVELENGTH = 788.55500 # 起始波长 END_WAVELENGTH = 788.55600 # 结束波长 STEP = 0.00005 # 波长步长 BATCH_SIZE = 8 # 批处理大小 IMAGE_SIZE = (256, 256) # 图像尺寸 TARGET_CHANNELS = 1 # 目标通道数 - 使用灰度图像 TEST_SIZE = 0.2 # 测试集比例 RANDOM_SEED = 42 # 随机种子 MODEL_SAVE_PATH = Path.home() / "Documents" / "wavelength_model.keras" # 修改为.keras格式 # ================================================================ # 设置中文字体支持 try: mpl.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体 mpl.rcParams['axes.unicode_minus'] = False # 解决负号显示问题 print("已设置中文字体支持") except: print("警告:无法设置中文字体,图表可能无法正确显示中文") def generate_folder_names(start, end, step): """生成波长文件夹名称列表""" num_folders = int((end - start) / step) + 1 folder_names = [] for i in range(num_folders): wavelength = start + i * step folder_name = f"{wavelength:.5f}" folder_names.append(folder_name) return folder_names def find_best_match_file(folder_path, target_wavelength): """在文件夹中找到波长最接近目标值的TIFF文件""" tiff_files = glob.glob(os.path.join(folder_path, "*.tiff")) + glob.glob(os.path.join(folder_path, "*.tif")) if not tiff_files: return None best_match = None min_diff = float('inf') for file_path in tiff_files: filename = os.path.basename(file_path) match = re.search(r'\s*([\d.]+)_', filename) if not match: continue try: file_wavelength = float(match.group(1)) diff = abs(file_wavelength - target_wavelength) if diff < min_diff: min_diff = diff best_match = file_path except ValueError: continue return best_match def extract_shape_features(binary_image): """从二值化图像中提取形状和边界特征""" features = np.zeros(6, dtype=np.float32) # 初始化特征向量 try: contours = measure.find_contours(binary_image, 0.5) if not contours: return features main_contour = max(contours, key=len) contour_length = len(main_contour) label_image = morphology.label(binary_image) region = measure.regionprops(label_image)[0] contour_area = region.area hull = morphology.convex_hull_image(label_image) hull_area = np.sum(hull) solidity = region.solidity eccentricity = region.eccentricity orientation = region.orientation features[0] = contour_length / 1000 # 归化 features[1] = contour_area / 1000 # 归化 features[2] = solidity features[3] = eccentricity features[4] = orientation features[5] = hull_area / 1000 # 凸包面积 except Exception as e: print(f"形状特征提取错误: {e}") traceback.print_exc() return features def load_and_preprocess_image(file_path): """加载并预处理TIFF图像""" try: image = imageio.imread(file_path) if image.dtype == np.uint16: image = image.astype(np.float32) / 65535.0 elif image.dtype == np.uint8: image = image.astype(np.float32) / 255.0 else: image = image.astype(np.float32) if np.max(image) > 1.0: image = image / np.max(image) if len(image.shape) == 3 and image.shape[2] > 1: image = 0.299 * image[:, :, 0] + 0.587 * image[:, :, 1] + 0.114 * image[:, :, 2] image = np.expand_dims(image, axis=-1) image = resize(image, (IMAGE_SIZE[0], IMAGE_SIZE[1]), anti_aliasing=True) blurred = filters.gaussian(image[..., 0], sigma=1.0) thresh = filters.threshold_otsu(blurred) binary = blurred > thresh * 0.8 return image, binary except Exception as e: print(f"图像加载失败: {e}, 使用空白图像代替") return np.zeros((IMAGE_SIZE[0], IMAGE_SIZE[1], 1), dtype=np.float32), np.zeros((IMAGE_SIZE[0], IMAGE_SIZE[1]), dtype=np.bool) def create_tiff_dataset(file_paths): """从文件路径列表创建TensorFlow数据集""" dataset = tf.data.Dataset.from_tensor_slices(file_paths) def load_wrapper(file_path): file_path_str = file_path.numpy().decode('utf-8') image, binary = load_and_preprocess_image(file_path_str) features = extract_shape_features(binary) return image, features def tf_load_wrapper(file_path): result = tf.py_function( func=load_wrapper, inp=[file_path], Tout=(tf.float32, tf.float32) ) image = result[0] features = result[1] image.set_shape((IMAGE_SIZE[0], IMAGE_SIZE[1], 1)) # 单通道 features.set_shape((6,)) # 6个形状特征 return image, features dataset = dataset.map(tf_load_wrapper, num_parallel_calls=tf.data.experimental.AUTOTUNE) dataset = dataset.batch(BATCH_SIZE).prefetch(tf.data.experimental.AUTOTUNE) return dataset def load_and_prepare_data(): """加载所有数据并准备训练/测试集""" folder_names = generate_folder_names(START_WAVELENGTH, END_WAVELENGTH, STEP) print(f"\n生成的文件夹数量: {len(folder_names)}") print(f"起始文件夹: {folder_names[0]}") print(f"结束文件夹: {folder_names[-1]}") valid_files = [] wavelengths = [] print("\n扫描文件夹并匹配文件...") for folder_name in tqdm(folder_names, desc="处理文件夹"): folder_path = os.path.join(BASE_DIR, folder_name) if not os.path.isdir(folder_path): continue try: target_wavelength = float(folder_name) file_path = find_best_match_file(folder_path, target_wavelength) if file_path: valid_files.append(file_path) wavelengths.append(target_wavelength) except ValueError: continue print(f"\n找到的有效文件: {len(valid_files)}/{len(folder_names)}") if not valid_files: raise ValueError("未找到任何有效文件,请检查路径和文件夹名称") wavelengths = np.array(wavelengths) min_wavelength = np.min(wavelengths) max_wavelength = np.max(wavelengths) wavelength_range = max_wavelength - min_wavelength wavelengths_normalized = (wavelengths - min_wavelength) / wavelength_range print(f"波长范围: {min_wavelength:.6f} 到 {max_wavelength:.6f}, 范围大小: {wavelength_range:.6f}") train_files, test_files, train_wavelengths, test_wavelengths = train_test_split( valid_files, wavelengths_normalized, test_size=TEST_SIZE, random_state=RANDOM_SEED ) print(f"训练集大小: {len(train_files)}") print(f"测试集大小: {len(test_files)}") train_dataset = create_tiff_dataset(train_files) test_dataset = create_tiff_dataset(test_files) train_labels = tf.data.Dataset.from_tensor_slices(train_wavelengths) test_labels = tf.data.Dataset.from_tensor_slices(test_wavelengths) # 修复后的 combine_features 函数 def combine_features(data): """将图像特征和标签组合成模型需要的格式""" image_features, label = data image, shape_features = image_features return (image, shape_features), label train_dataset_unet = tf.data.Dataset.zip((train_dataset, train_labels)).map( combine_features, num_parallel_calls=tf.data.experimental.AUTOTUNE ) test_dataset_unet = tf.data.Dataset.zip((test_dataset, test_labels)).map( combine_features, num_parallel_calls=tf.data.experimental.AUTOTUNE ) train_dataset_cnn_dense = tf.data.Dataset.zip((train_dataset.map(lambda x: x[0]), train_labels)) test_dataset_cnn_dense = tf.data.Dataset.zip((test_dataset.map(lambda x: x[0]), test_labels)) return train_dataset_unet, test_dataset_unet, train_dataset_cnn_dense, test_dataset_cnn_dense, valid_files, min_wavelength, wavelength_range def build_unet_model(input_shape, shape_feature_size): """构建 U-Net 模型,同时接受图像输入和形状特征输入""" # 图像输入 image_input = Input(shape=input_shape, name='image_input') # Encoder conv1 = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(image_input) conv1 = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(conv1) pool1 = layers.MaxPooling2D(pool_size=(2, 2))(conv1) conv2 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(pool1) conv2 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(conv2) pool2 = layers.MaxPooling2D(pool_size=(2, 2))(conv2) conv3 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(pool2) conv3 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(conv3) pool3 = layers.MaxPooling2D(pool_size=(2, 2))(conv3) # Bottleneck conv4 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(pool3) conv4 = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(conv4) drop4 = layers.Dropout(0.5)(conv4) # Decoder up5 = layers.Conv2D(128, (2, 2), activation='relu', padding='same')(layers.UpSampling2D(size=(2, 2))(drop4)) merge5 = layers.Concatenate()([conv3, up5]) conv5 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(merge5) conv5 = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(conv5) up6 = layers.Conv2D(64, (2, 2), activation='relu', padding='same')(layers.UpSampling2D(size=(2, 2))(conv5)) merge6 = layers.Concatenate()([conv2, up6]) conv6 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(merge6) conv6 = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(conv6) up7 = layers.Conv2D(32, (2, 2), activation='relu', padding='same')(layers.UpSampling2D(size=(2, 2))(conv6)) merge7 = layers.Concatenate()([conv1, up7]) conv7 = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(merge7) conv7 = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(conv7) # 形状特征输入 shape_input = Input(shape=(shape_feature_size,), name='shape_input') shape_dense = layers.Dense(128, activation='relu')(shape_input) shape_dense = layers.Dense(64, activation='relu')(shape_dense) # 合并图像特征和形状特征 flat = layers.GlobalAveragePooling2D()(conv7) combined = layers.Concatenate()([flat, shape_dense]) # 输出层 outputs = layers.Dense(1, activation='linear')(combined) model = Model(inputs=[image_input, shape_input], outputs=outputs) model.compile(optimizer=Adam(learning_rate=1e-4), loss='mean_squared_error', metrics=['mae']) return model def build_dense_model(input_shape): """构建简单的全连接网络""" inputs = Input(shape=input_shape) x = layers.Flatten()(inputs) x = layers.Dense(128, activation='relu')(x) x = layers.Dense(64, activation='relu')(x) outputs = layers.Dense(1, activation='linear')(x) model = Model(inputs=[inputs], outputs=[outputs]) model.compile(optimizer=Adam(learning_rate=1e-4), loss='mean_squared_error', metrics=['mae']) return model def build_cnn_model(input_shape): """构建传统的 CNN 模型""" inputs = Input(shape=input_shape) x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(inputs) x = layers.MaxPooling2D((2, 2))(x) x = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(x) x = layers.MaxPooling2D((2, 2))(x) x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x) x = layers.MaxPooling2D((2, 2))(x) x = layers.Conv2D(256, (3, 3), activation='relu', padding='same')(x) x = layers.GlobalAveragePooling2D()(x) x = layers.Dense(256, activation='relu')(x) outputs = layers.Dense(1, activation='linear')(x) model = Model(inputs=[inputs], outputs=[outputs]) model.compile(optimizer=Adam(learning_rate=1e-4), loss='mean_squared_error', metrics=['mae']) return model def train_models(train_dataset_unet, test_dataset_unet, train_dataset_cnn_dense, test_dataset_cnn_dense, input_shape, shape_feature_size, wavelength_range): """训练多个模型""" unet_model = build_unet_model(input_shape, shape_feature_size) dense_model = build_dense_model(input_shape) cnn_model = build_cnn_model(input_shape) unet_model.summary() dense_model.summary() cnn_model.summary() callbacks = [ tf.keras.callbacks.EarlyStopping(patience=30, restore_best_weights=True, monitor='val_loss', min_delta=1e-6), tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=10, min_lr=1e-7) ] unet_history = unet_model.fit(train_dataset_unet, epochs=300, validation_data=test_dataset_unet, callbacks=callbacks, verbose=2) dense_history = dense_model.fit(train_dataset_cnn_dense, epochs=300, validation_data=test_dataset_cnn_dense, callbacks=callbacks, verbose=2) cnn_history = cnn_model.fit(train_dataset_cnn_dense, epochs=300, validation_data=test_dataset_cnn_dense, callbacks=callbacks, verbose=2) return unet_model, dense_model, cnn_model def predict_with_voting(models, test_image_path, min_wavelength, wavelength_range): """使用多个模型进行预测,并通过投票机制决定最终结果""" image, binary = load_and_preprocess_image(test_image_path) image = np.expand_dims(image, axis=0) shape_features = extract_shape_features(binary) shape_features = np.expand_dims(shape_features, axis=0) predictions = [] for model in models: if model.name == 'unet_model': predicted_normalized = model.predict([image, shape_features], verbose=0)[0][0] else: predicted_normalized = model.predict(image, verbose=0)[0][0] predicted_wavelength = predicted_normalized * wavelength_range + min_wavelength predictions.append(predicted_wavelength) # 使用投票机制(例如取平均值) final_prediction = np.mean(predictions) print(f"最终预测波长: {final_prediction:.8f} 纳米") return final_prediction def main(): """主函数""" print(f"TensorFlow 版本: {tf.__version__}") try: train_dataset_unet, test_dataset_unet, train_dataset_cnn_dense, test_dataset_cnn_dense, all_files, min_wavelength, wavelength_range = load_and_prepare_data() print(f"最小波长: {min_wavelength:.6f}, 波长范围: {wavelength_range:.6f}") except Exception as e: print(f"数据加载失败: {str(e)}") traceback.print_exc() return print("\n开始训练模型...") try: unet_model, dense_model, cnn_model = train_models(train_dataset_unet, test_dataset_unet, train_dataset_cnn_dense, test_dataset_cnn_dense, (IMAGE_SIZE[0], IMAGE_SIZE[1], 1), 6, wavelength_range) except Exception as e: print(f"模型训练失败: {str(e)}") traceback.print_exc() return print("\n从测试集中随机选择张图片进行预测...") try: for (images, features), labels in test_dataset_unet.take(1): if images.shape[0] > 0: test_image = images[0].numpy() test_features = features[0].numpy() labels_np = labels.numpy() if labels_np.ndim == 0: true_wavelength_normalized = labels_np.item() else: true_wavelength_normalized = labels_np[0] true_wavelength = true_wavelength_normalized * wavelength_range + min_wavelength test_image_path = "f:/phD/代码/test_image.tiff" imageio.imwrite(test_image_path, (test_image[..., 0] * 255).astype(np.uint8)) predicted_wavelength = predict_with_voting([unet_model, dense_model, cnn_model], test_image_path, min_wavelength, wavelength_range) print(f"真实波长: {true_wavelength:.6f} 纳米") print(f"预测波长: {predicted_wavelength:.6f} 纳米") print(f"绝对误差: {abs(predicted_wavelength - true_wavelength):.8f} 纳米") print(f"相对误差: {abs(predicted_wavelength - true_wavelength) / wavelength_range * 100:.4f}%") else: print("错误:测试批次中没有样本") except Exception as e: print(f"测试失败: {str(e)}") traceback.print_exc() print("\n您可以使用自己的图片进行测试:") model = tf.keras.models.load_model(MODEL_SAVE_PATH) image_path = input("请输入您要测试的图片路径(例如:'test_image.tiff'): ") predicted = predict_with_voting([unet_model, dense_model, cnn_model], image_path, min_wavelength, wavelength_range) print(f"预测波长: {predicted:.6f} 纳米") print("\n程序执行完成。") if __name__ == "__main__": os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' try: from skimage import filters, measure, morphology except ImportError: print("安装必要的库...") import subprocess subprocess.run([sys.executable, "-m", "pip", "install", "scikit-image", "imageio"]) from skimage import filters, measure, morphology main()
最新发布
07-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值