Tensorflow: .Pb模型合并(子图合并成大图)

本文详细介绍如何将多个独立的机器学习模型,如检测模型和分类模型,通过子图合并的方法融合成一个大型模型,并生成新的.pb文件,以实现模型间的串联或并行工作,提高实际应用的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有时我们训练了多个模型,想合并使用它们:如检测模型和分类模型,pose模型和分类模型等,实际应用时模型之前存在着先后的串联关系或者并行关系等。

解决方法:

  • 需要建立多个图,然后每个图导入一个模型,再针对每个图创建一个会话
  • 用简单的串联合并关系创建新图
  • 子图合并为大图(跟上面一种方法类似,但子图间没有任何关联,减少了模型之间的束缚,但也可以让它们存在关系)

这里主要介绍最后一种方法:

with tf.Graph().as_default() as g_combined:
	with tf.Session(graph=g_combined) as sess:
		graph_def_detect = load_def(detect_pb_path)
		graph_def_seg= load_def(seg_pb_path)
		input_image = tf.placeholder(dtype=tf.uint8,shape=[1,None,None,3], name="image")#定义新的网络输入
		input_image1 = tf.placeholder(dtype=tf.float32,shape=[1,None,None,3], name="image1")
		#将原始网络的输入映射到input_image(节点为:新的输入节点“image”)
		detection = tf.import_graph_def(graph_def_detect, input_map={'image_tensor:0': input_image},return_elements=['detection_boxes:0', 'detection_scores:0','detection_classes:0','num_detections:0' ])
                #新的输出节点为“detect”
		tf.identity(detection, 'detect')
		# second graph load
		seg_predict = tf.import_graph_def(graph_def_seg, input_map={"create_inputs/batch:0": input_image1}, return_elements=["conv6/out_1:0"])
		tf.identity(seg_predict, "seg_predict")

		# freeze combined graph
		g_combined_def = graph_util.convert_variables_to_constants(sess, sess.graph_def, ["seg_predict","detect"])
                #合成大图,生成新的pb
		tf.train.write_graph(g_combined_def, out_pb_path, 'merge_model.pb', as_text=False)

 最后调用新生成的.pb 即可。

 

如何调用tensorflow训练完的模型# 导入必要的库 import os # 用于文件和目录操作 import ast # 用于解析字符串形式的Python数据结构 import numpy as np # 用于数值计算 import tensorflow as tf # 深度学习框架 import matplotlib # 用于数据可视化 # 强制设置后端为'Agg'(非交互式,适合服务器环境保存片) matplotlib.use('Agg') import sklearn # 导入机器学习工具库 # 强制使用CPU,禁用GPU加速(如果需要GPU加速可移除这些代码) os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # 设置环境变量,指定不可用的GPU设备 tf.config.set_visible_devices([], "GPU") # 显式设置不可用的GPU设备 # 关键修改:禁用分布式检测(适用于TensorFlow 2.19.0版本) import tensorflow.python.keras.engine.data_adapter as data_adapter # 导入数据适配器模块 def is_distributed_dataset_patch(ds): return False # 强制返回非分布式数据集,解决某些版本的兼容性问题 data_adapter._is_distributed_dataset = is_distributed_dataset_patch # 替换原有函数 # 从Keras导入模型和层相关组件 from keras.models import Sequential # 导入顺序模型 from keras.layers import Dense, Dropout # 导入全连接层和Dropout层 from keras.callbacks import EarlyStopping # 导入早停回调函数 from sklearn.model_selection import train_test_split # 导入数据划分函数 from sklearn.preprocessing import StandardScaler # 导入数据标准化工具 import matplotlib.pyplot as plt # 导入绘模块 # 设置中文字体,确保中文能正常显示 plt.rcParams["font.family"] = ["SimHei"] # 使用黑体 plt.rcParams["axes.unicode_minus"] = False # 正确显示负号 # 数据处理函数定义 def process_data(file_path): """处理单个数据文件,提取前19列和最后一列""" with open(file_path, 'r', encoding='utf-8') as file: file_content = file.read() # 读取文件内容 file_content = ''.join(file_content.split('\n')) # 移除换行符 file_content = file_content.replace(' ', '') # 移除多余空格 try: data = ast.literal_eval(file_content) # 解析字符串为Python数据结构 except Exception as e: print(f"解析数据时出错 ({file_path}): {e}") # 打印错误信息 return None, None # 解析失败返回None first_19_columns = [] # 存储前19列数据 last_column = [] # 存储最后一列数据 for row in data: first_19 = row[:19] # 提取前19个元素 first_19_columns.append(first_19) # 添加到列表 last = row[-1] # 提取最后一个元素 last_column.append(last) # 添加到列表 first_19_array = np.array(first_19_columns) # 转换为NumPy数组 last_column_array = np.array(last_column) # 转换为NumPy数组 return first_19_array, last_column_array # 返回处理后的数据 def process_multiple_files(file_paths): """处理多个数据文件,合并所有文件的数据""" all_first_19 = [] # 存储所有文件的前19列数据 all_last_col = [] # 存储所有文件的最后一列数据 for file_path in file_paths: first_19, last_col = process_data(file_path) # 处理单个文件 if first_19 is not None and last_col is not None: print(f"功处理文件: {file_path}") # 打印功信息 all_first_19.append(first_19) # 添加到列表 all_last_col.append(last_col) # 添加到列表 if all_first_19: # 垂直堆叠数组(合并行)和水平堆叠数组(合并列) combined_first_19 = np.vstack(all_first_19) combined_last_col = np.hstack(all_last_col) return combined_first_19, combined_last_col # 返回合并后的数据 else: print("没有功处理任何文件") # 打印错误信息 return None, None # 没有功处理任何文件返回None def get_txt_files_in_directory(directory): """获取指定目录下的所有txt文件路径""" if not os.path.exists(directory): print(f"错误:目录 {directory} 不存在") # 打印错误信息 return [] # 目录不存在返回空列表 # 生目录下所有txt文件的完整路径 return [os.path.join(directory, f) for f in os.listdir(directory) if f.endswith('.txt') and os.path.isfile(os.path.join(directory, f))] # 模型构建函数 def build_neural_network(input_dim): """构建神经网络模型""" model = Sequential([ # 创建顺序模型 Dense(128, activation='relu', input_shape=(input_dim,)), # 输入层和第一个隐藏层 Dropout(0.2), # 防止过拟合的Dropout层,随机丢弃20%的神经元 Dense(64, activation='relu'), # 第二个隐藏层 Dropout(0.2), # 防止过拟合的Dropout层 Dense(32, activation='relu'), # 第三个隐藏层 Dense(1) # 输出层,单个神经元用于回归预测 ]) model.compile( # 编译模型 optimizer='adam', # 使用Adam优化器 loss='mse', # 均方误差损失函数,适合回归问题 metrics=['mae'] # 平均绝对误差,评估预测准确性 ) return model # 返回构建好的模型 # 主函数,程序入口 def main(): # 自动获取目录下的所有txt文件 directory = r"D:\4_python_code\02_BP神经网络" # 设置数据目录路径 file_paths = get_txt_files_in_directory(directory) # 获取所有txt文件路径 if not file_paths: print(f"在目录 {directory} 中未找到txt文件") # 打印错误信息 return # 没有找到文件则退出 # 处理多个文件并获取合并数据 X, y = process_multiple_files(file_paths) # 处理数据 if X is None or y is None: print("没有可用的数据进行训练") # 打印错误信息 return # 没有可用数据则退出 print(f"合并后的数据形状 - 输入: {X.shape}, 输出: {y.shape}") # 打印数据形状 # 数据预处理 - 标准化输入特征 scaler = StandardScaler() # 创建标准化器 X_scaled = scaler.fit_transform(X) # 拟合数据并转换 # 划分训练集和测试集 (80% 训练, 20% 测试) X_train, X_test, y_train, y_test = train_test_split( X_scaled, y, test_size=0.2, random_state=42 # 随机种确保结果可复现 ) print(f"训练集形状: {X_train.shape}, {y_train.shape}") # 打印训练集形状 print(f"测试集形状: {X_test.shape}, {y_test.shape}") # 打印测试集形状 # 构建神经网络模型 model = build_neural_network(X.shape[1]) # 构建模型 model.summary() # 打印模型结构摘要 # 早停策略 - 防止过拟合 early_stopping = EarlyStopping( monitor='val_loss', # 监控验证损失 patience=10, # 连续10轮没有改善则停止 restore_best_weights=True # 恢复最佳权重 ) # 训练模型 history = model.fit( X_train, y_train, # 训练数据 epochs=100, # 最大训练轮次 batch_size=32, # 批次大小 validation_split=0.2, # 划分20%的训练数据作为验证集 callbacks=[early_stopping], # 早停回调 verbose=1 # 训练过程显示模式 ) # 评估模型 evaluation = model.evaluate(X_test, y_test) # 在测试集上评估模型 print(f"\n测试集评估 - 损失: {evaluation[0]}, MAE: {evaluation[1]}") # 打印评估结果 # 预测测试集 y_pred = model.predict(X_test).flatten() # 对测试集进行预测并展平结果 # 绘制训练过程(确保后端已设置) plt.figure(figsize=(12, 4)) # 创建绘窗口 plt.subplot(1, 2, 1) # 创建第一个 plt.plot(history.history['loss'], label='训练损失') # 绘制训练损失 plt.plot(history.history['val_loss'], label='验证损失') # 绘制验证损失 plt.title('模型损失') # 设置标题 plt.xlabel('训练轮次') # 设置x轴标签 plt.ylabel('损失') # 设置y轴标签 plt.legend() # 显示例 plt.subplot(1, 2, 2) # 创建第二个 plt.scatter(y_test, y_pred, alpha=0.5) # 绘制预测值与实际值的散点 plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--') # 绘制对角线 plt.title('预测值 vs 实际值') # 设置标题 plt.xlabel('实际值') # 设置x轴标签 plt.ylabel('预测值') # 设置y轴标签 plt.tight_layout() # 自动调整间距 # 保存片(非交互式后端需要显式保存) plt.savefig('training_results.png') # 保存训练结果 # plt.show() # 非交互式后端不支持show(),如需显示可改用TkAgg后端 # 保存模型 model.save("neural_network_model.h5") # 保存模型到文件 print("模型已保存为 neural_network_model.h5") # 打印保存功信息 print("训练结果已保存为 training_results.png") # 打印保存功信息 if __name__ == "__main__": main() # 调用主函数,启动程序如何调用训练好的模型预测
05-30
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值