logo

用Keras和Streamlit构建人脸验证系统:从模型训练到Web部署全流程指南

作者:JC2025.09.18 15:58浏览量:0

简介:本文详细介绍如何使用Keras构建人脸识别模型,并结合Streamlit创建交互式Web应用实现人脸验证功能。内容涵盖数据准备、模型训练、应用开发及部署全流程,提供完整代码示例和优化建议。

一、技术选型与系统架构设计

1.1 Keras与Streamlit的核心优势

Keras作为高级神经网络API,提供简洁的模型构建接口和预训练模型支持,特别适合快速实现人脸识别任务。其优势在于:

  • 丰富的预训练模型库(如VGG16、ResNet50)
  • 便捷的迁移学习接口
  • 高效的GPU加速支持

Streamlit作为轻量级Web框架,具有以下特点:

  • 纯Python开发,无需前端知识
  • 实时重载功能加速开发
  • 丰富的UI组件库
  • 部署简单(支持Heroku、AWS等)

1.2 系统架构

典型架构包含三个模块:

  1. 数据预处理模块:人脸检测与对齐
  2. 特征提取模块:深度学习模型
  3. 验证模块:相似度计算与阈值判断

二、基于Keras的人脸识别模型实现

2.1 环境准备

  1. # 基础环境配置
  2. !pip install tensorflow keras opencv-python streamlit face-recognition
  3. import tensorflow as tf
  4. from tensorflow.keras import layers, models
  5. import cv2
  6. import numpy as np

2.2 数据集准备

推荐使用LFW(Labeled Faces in the Wild)数据集,包含13,233张1680人的人脸图像。数据预处理步骤:

  1. 人脸检测:使用OpenCV的DNN模块

    1. def detect_face(image_path):
    2. # 加载预训练的人脸检测模型
    3. prototxt = "deploy.prototxt"
    4. model = "res10_300x300_ssd_iter_140000.caffemodel"
    5. net = cv2.dnn.readNetFromCaffe(prototxt, model)
    6. # 读取并预处理图像
    7. image = cv2.imread(image_path)
    8. (h, w) = image.shape[:2]
    9. blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0,
    10. (300, 300), (104.0, 177.0, 123.0))
    11. # 检测人脸
    12. net.setInput(blob)
    13. detections = net.forward()
    14. # 返回检测到的人脸区域
    15. if len(detections) > 0:
    16. i = np.argmax(detections[0, 0, :, 2])
    17. confidence = detections[0, 0, i, 2]
    18. if confidence > 0.5:
    19. box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
    20. (startX, startY, endX, endY) = box.astype("int")
    21. return image[startY:endY, startX:endX]
    22. return None
  2. 数据增强:

    1. from tensorflow.keras.preprocessing.image import ImageDataGenerator
    2. datagen = ImageDataGenerator(
    3. rotation_range=20,
    4. width_shift_range=0.2,
    5. height_shift_range=0.2,
    6. horizontal_flip=True,
    7. zoom_range=0.2)

2.3 模型构建

采用Siamese网络架构实现人脸验证:

  1. def build_siamese_model(input_shape=(160, 160, 3)):
  2. # 基础网络(使用预训练的VGG16)
  3. base_model = tf.keras.applications.VGG16(
  4. include_top=False,
  5. weights='imagenet',
  6. input_shape=input_shape)
  7. # 冻结部分层
  8. for layer in base_model.layers[:-4]:
  9. layer.trainable = False
  10. # 定义两个输入分支
  11. input_a = layers.Input(shape=input_shape)
  12. input_b = layers.Input(shape=input_shape)
  13. # 共享权重
  14. x1 = base_model(input_a)
  15. x2 = base_model(input_b)
  16. # 特征扁平化
  17. x1 = layers.Flatten()(x1)
  18. x2 = layers.Flatten()(x2)
  19. # 合并特征
  20. merged = layers.concatenate([x1, x2])
  21. # 全连接层
  22. dense = layers.Dense(4096, activation='relu')(merged)
  23. dense = layers.Dropout(0.5)(dense)
  24. dense = layers.Dense(1024, activation='relu')(dense)
  25. # 输出层
  26. output = layers.Dense(1, activation='sigmoid')(dense)
  27. return models.Model([input_a, input_b], output)

2.4 模型训练

训练技巧:

  1. 使用三元组损失(Triplet Loss)或对比损失(Contrastive Loss)
  2. 采用学习率调度器:
    1. lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(
    2. monitor='val_loss',
    3. factor=0.1,
    4. patience=3)
  3. 混合精度训练加速:
    1. policy = tf.keras.mixed_precision.Policy('mixed_float16')
    2. tf.keras.mixed_precision.set_global_policy(policy)

三、Streamlit人脸验证应用开发

3.1 基础界面设计

  1. import streamlit as st
  2. from PIL import Image
  3. import face_recognition
  4. st.title("人脸验证系统")
  5. st.markdown("基于Keras和Streamlit实现")
  6. # 文件上传组件
  7. uploaded_file1 = st.file_uploader("上传第一张人脸照片", type=["jpg", "png"])
  8. uploaded_file2 = st.file_uploader("上传第二张人脸照片", type=["jpg", "png"])

3.2 核心验证逻辑

  1. def verify_faces(img1, img2, threshold=0.6):
  2. # 加载并编码人脸
  3. img1_encoding = face_recognition.face_encodings(img1)[0]
  4. img2_encoding = face_recognition.face_encodings(img2)[0]
  5. # 计算欧式距离
  6. distance = face_recognition.face_distance([img1_encoding], img2_encoding)[0]
  7. # 判断是否为同一人
  8. return distance < threshold, distance
  9. if uploaded_file1 and uploaded_file2:
  10. # 读取图像
  11. image1 = Image.open(uploaded_file1)
  12. image2 = Image.open(uploaded_file2)
  13. # 转换为numpy数组
  14. img1 = np.array(image1.convert('RGB'))
  15. img2 = np.array(image2.convert('RGB'))
  16. # 执行验证
  17. is_match, distance = verify_faces(img1, img2)
  18. # 显示结果
  19. col1, col2 = st.columns(2)
  20. with col1:
  21. st.image(image1, caption='第一张人脸')
  22. with col2:
  23. st.image(image2, caption='第二张人脸')
  24. st.write(f"验证结果: {'匹配' if is_match else '不匹配'}")
  25. st.write(f"相似度距离: {distance:.4f}")

3.3 高级功能扩展

  1. 实时摄像头验证:
    ```python
    import cv2
    from streamlit_webrtc import webrtc_streamer

def video_frame_callback(frame):

  1. # 在此实现实时人脸验证逻辑
  2. img = frame.to_ndarray(format="bgr24")
  3. # 人脸检测和验证代码...
  4. return img

st.header(“实时人脸验证”)
webrtc_streamer(key=”face-verification”, video_frame_callback=video_frame_callback)

  1. 2. 数据库集成:
  2. ```python
  3. import sqlite3
  4. # 初始化数据库
  5. conn = sqlite3.connect('faces.db')
  6. c = conn.cursor()
  7. c.execute('''CREATE TABLE IF NOT EXISTS users
  8. (id INTEGER PRIMARY KEY, name TEXT, encoding BLOB)''')
  9. def save_face_encoding(name, encoding):
  10. # 将face_recognition的128维编码转换为SQLite可存储格式
  11. encoding_bytes = encoding.tobytes()
  12. c.execute("INSERT INTO users (name, encoding) VALUES (?, ?)",
  13. (name, encoding_bytes))
  14. conn.commit()

四、部署与优化

4.1 性能优化策略

  1. 模型量化:

    1. converter = tf.lite.TFLiteConverter.from_keras_model(model)
    2. converter.optimizations = [tf.lite.Optimize.DEFAULT]
    3. tflite_model = converter.convert()
  2. 缓存机制:
    ```python
    from functools import lru_cache

@lru_cache(maxsize=32)
def get_face_encoding(image_path):
image = face_recognition.load_image_file(image_path)
return face_recognition.face_encodings(image)[0]

  1. ## 4.2 部署方案
  2. 1. **本地部署**:
  3. ```bash
  4. streamlit run app.py --server.port 8501
  1. 云部署(Heroku示例)
  • 创建requirements.txt
  • 创建Procfile:
    1. web: sh setup.sh && streamlit run app.py
  • 使用Heroku CLI部署

4.3 安全考虑

  1. 数据加密:

    1. from cryptography.fernet import Fernet
    2. key = Fernet.generate_key()
    3. cipher_suite = Fernet(key)
    4. encrypted = cipher_suite.encrypt(b"Sensitive face data")
  2. 访问控制:
    ```python
    import streamlit as st

def check_password():
“””Returns True if the user had the correct password.”””

  1. def password_entered():
  2. """Checks whether a password entered by the user is correct."""
  3. if st.session_state["password"] == st.secrets["password"]:
  4. st.session_state["password_correct"] = True
  5. del st.session_state["password"] # Don't store the password
  6. else:
  7. st.session_state["password_correct"] = False
  8. if "password_correct" not in st.session_state:
  9. # First run, show input for password
  10. st.text_input(
  11. "Password", type="password", on_change=password_entered, key="password"
  12. )
  13. return False
  14. elif not st.session_state["password_correct"]:
  15. # Password not correct, show input + error
  16. st.text_input(
  17. "Password", type="password", on_change=password_entered, key="password"
  18. )
  19. st.error("😕 Password incorrect")
  20. return False
  21. else:
  22. # Password correct.
  23. return True

if not check_password():
st.stop()

  1. # 五、完整案例实现
  2. ## 5.1 端到端示例代码
  3. ```python
  4. import streamlit as st
  5. import face_recognition
  6. import numpy as np
  7. from PIL import Image
  8. import sqlite3
  9. import os
  10. # 初始化数据库
  11. if not os.path.exists('faces.db'):
  12. conn = sqlite3.connect('faces.db')
  13. c = conn.cursor()
  14. c.execute('''CREATE TABLE users
  15. (id INTEGER PRIMARY KEY, name TEXT, encoding BLOB)''')
  16. conn.commit()
  17. conn.close()
  18. def main():
  19. st.title("人脸验证系统")
  20. menu = ["注册新用户", "人脸验证", "管理用户"]
  21. choice = st.sidebar.selectbox("菜单", menu)
  22. if choice == "注册新用户":
  23. st.subheader("用户注册")
  24. name = st.text_input("姓名")
  25. uploaded_file = st.file_uploader("上传人脸照片", type=["jpg", "png"])
  26. if st.button("注册") and uploaded_file is not None:
  27. image = Image.open(uploaded_file)
  28. img_array = np.array(image.convert('RGB'))
  29. try:
  30. encoding = face_recognition.face_encodings(img_array)[0]
  31. # 存储到数据库
  32. conn = sqlite3.connect('faces.db')
  33. c = conn.cursor()
  34. c.execute("INSERT INTO users (name, encoding) VALUES (?, ?)",
  35. (name, encoding.tobytes()))
  36. conn.commit()
  37. conn.close()
  38. st.success("用户注册成功")
  39. except IndexError:
  40. st.error("未检测到人脸,请重试")
  41. elif choice == "人脸验证":
  42. st.subheader("人脸验证")
  43. uploaded_file1 = st.file_uploader("上传第一张人脸照片", type=["jpg", "png"])
  44. uploaded_file2 = st.file_uploader("上传第二张人脸照片", type=["jpg", "png"])
  45. if uploaded_file1 and uploaded_file2:
  46. image1 = Image.open(uploaded_file1)
  47. image2 = Image.open(uploaded_file2)
  48. img1 = np.array(image1.convert('RGB'))
  49. img2 = np.array(image2.convert('RGB'))
  50. try:
  51. enc1 = face_recognition.face_encodings(img1)[0]
  52. enc2 = face_recognition.face_encodings(img2)[0]
  53. distance = face_recognition.face_distance([enc1], enc2)[0]
  54. is_match = distance < 0.6
  55. col1, col2 = st.columns(2)
  56. with col1:
  57. st.image(image1, caption='第一张人脸')
  58. with col2:
  59. st.image(image2, caption='第二张人脸')
  60. st.write(f"验证结果: {'匹配' if is_match else '不匹配'}")
  61. st.write(f"相似度距离: {distance:.4f}")
  62. except IndexError:
  63. st.error("至少一张图片未检测到人脸")
  64. elif choice == "管理用户":
  65. st.subheader("用户管理")
  66. conn = sqlite3.connect('faces.db')
  67. c = conn.cursor()
  68. users = c.execute("SELECT id, name FROM users").fetchall()
  69. if st.button("显示所有用户"):
  70. df = pd.DataFrame(users, columns=["ID", "姓名"])
  71. st.dataframe(df)
  72. conn.close()
  73. if __name__ == '__main__':
  74. main()

5.2 运行与测试

  1. 安装依赖:

    1. pip install -r requirements.txt
  2. 运行应用:

    1. streamlit run app.py
  3. 测试流程:

  • 注册新用户(上传照片并输入姓名)
  • 进行人脸验证(上传两张照片)
  • 管理用户数据

六、常见问题与解决方案

6.1 性能问题

问题:验证速度慢
解决方案

  1. 使用更轻量的模型(如MobileNet)
  2. 实现特征缓存
  3. 使用多线程处理

6.2 准确率问题

问题:误识别率高
解决方案

  1. 增加训练数据多样性
  2. 调整相似度阈值
  3. 使用多模型集成

6.3 部署问题

问题:Heroku部署失败
解决方案

  1. 检查Procfile格式
  2. 确保所有依赖在requirements.txt中
  3. 调整构建包大小限制

七、未来发展方向

  1. 3D人脸验证:集成深度传感器数据
  2. 活体检测:防止照片攻击
  3. 多模态验证:结合语音、行为特征
  4. 边缘计算:在移动端实现实时验证

本指南提供了从模型开发到Web部署的完整流程,开发者可根据实际需求调整模型架构和验证阈值。实际应用中建议结合具体场景进行优化,如金融场景需要更高的安全阈值,而社交场景可适当降低阈值以提高用户体验。

相关文章推荐

发表评论