如何保存、恢复带Triplet Loss的Siamese Network并实现人脸验证预测?
Siamese Network 模型保存、恢复与预测实现指南
你好,针对你在Siamese Network训练后遇到的模型保存、恢复及预测实现的问题,我来给你一步步梳理解决方案:
核心思路梳理
你训练的siamese_model本质是基于共享的特征提取模型(也就是你定义的new_model,对应结构摘要里的model_1)构建的三元组输入模型。训练过程中只有new_model的最后一层是可训练的,所以核心需要保存的是这个共享的特征提取模型——它是你后续人脸验证/识别的关键,基于它可以轻松构建单输入(生成特征向量)或双输入(直接计算两张图距离)的预测模型。
一、训练完成后保存模型
你有两种简单的方式保存核心的特征提取模型:
方式1:直接保存new_model
训练完成后,直接保存你最初定义的new_model即可,因为训练时siamese_model共享了它的参数,训练后的参数已经同步更新:
# 训练完成后执行 new_model.save('siamese_feature_extractor.h5')
方式2:从训练好的siamese_model中提取并保存
如果之后你只保存了siamese_model,也可以从里面提取共享的特征提取层:
# 从训练后的siamese_model中获取共享特征模型 trained_feature_model = siamese_model.get_layer('model_1') trained_feature_model.save('siamese_feature_extractor.h5')
二、恢复模型并构建预测模型
保存好模型后,你可以根据需求构建两种预测模型:
1. 单输入模型:生成单张人脸的特征向量
这个模型用于提取单张图片的128维特征,后续可以把特征存入数据库,用于人脸识别时的比对:
from tensorflow.keras.models import load_model import numpy as np # 加载保存的特征提取模型 feature_model = load_model('siamese_feature_extractor.h5') # 定义特征提取函数 def extract_face_feature(img): # 注意:img需要提前预处理成(224, 224, 3)的张量,并且完成ImageNet的标准化(和训练时一致) # 添加batch维度后预测 feature = feature_model.predict(img[np.newaxis, ...], verbose=0) return feature[0] # 返回(128,)的特征向量
2. 双输入模型:直接计算两张人脸的距离
这个模型可以直接输入两张预处理后的人脸图片,输出它们的特征距离(因为你对特征做了L2归一化,这个距离可以直接用于验证判断):
from tensorflow.keras.models import load_model, Model from tensorflow.keras.layers import Input, Lambda import tensorflow.keras.backend as K import numpy as np # 加载特征提取模型 feature_model = load_model('siamese_feature_extractor.h5') # 定义双输入层 input_img1 = Input(shape=(224, 224, 3)) input_img2 = Input(shape=(224, 224, 3)) # 提取两张图的特征 feat1 = feature_model(input_img1) feat2 = feature_model(input_img2) # 计算L2距离(特征已归一化,该距离越小,两张图越相似) calculate_distance = Lambda(lambda x: K.sqrt(K.sum(K.square(x[0] - x[1]), axis=-1, keepdims=True))) distance = calculate_distance([feat1, feat2]) # 构建双输入预测模型 face_verify_model = Model(inputs=[input_img1, input_img2], outputs=distance) # 定义人脸验证函数 def verify_two_faces(img1, img2): # img1和img2都是预处理后的(224,224,3)张量 dist = face_verify_model.predict([img1[np.newaxis, ...], img2[np.newaxis, ...]], verbose=0) # 根据你的训练情况设定阈值,比如距离小于0.5则判定为同一人 return dist[0][0] < 0.5
关键注意事项
- 预处理一致性:预测时的图片预处理(尺寸、归一化等)必须和训练时完全一致,否则会导致特征提取失效。
- 自定义对象加载:如果你的模型中使用了自定义损失函数或层,加载模型时需要通过
custom_objects参数指定,比如load_model('xxx.h5', custom_objects={'triplet_loss': triplet_loss}),不过你保存的feature_model里没有自定义损失,所以不需要额外处理。
内容的提问来源于stack exchange,提问作者edn
相关产品推荐
相关产品推荐

