今天想和大家分享一个基于Python和CNN的猫种类识别系统,这是我最近指导的一个本科毕业设计项目。这个项目结合了深度学习技术和Web开发,实现了从图像上传到种类识别的完整流程。对于计算机视觉入门或者想做一个综合性毕设的同学来说,这是个不错的选题方向。
这个系统主要解决了两个核心问题:一是如何准确识别不同品种的猫,二是如何将深度学习模型集成到Web应用中。项目采用了前后端分离的架构,前端使用Vue.js,后端采用Spring Boot,而核心的识别模型则是基于Python的CNN实现。整套系统从数据收集、模型训练到应用部署都包含在内,非常适合作为深度学习入门项目。
系统采用B/S架构,分为三个主要层次:
选择Vue.js主要基于以下考虑:
Spring Boot作为后端框架的优势:
CNN模型选择考虑因素:
我们使用了Kaggle上的公开猫品种数据集,包含12个常见品种:
数据集处理步骤:
采用迁移学习策略,基于预训练的ResNet50模型:
python复制from tensorflow.keras.applications import ResNet50
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224,224,3))
# 冻结预训练层
for layer in base_model.layers:
layer.trainable = False
# 添加自定义层
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
predictions = Dense(12, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)
训练参数配置:
训练技巧:
最终模型在测试集上达到92.3%的准确率,满足项目需求。
前端上传图像流程:
后端处理流程:
采用Flask搭建模型API服务:
python复制from flask import Flask, request, jsonify
import numpy as np
from PIL import Image
import io
import base64
from tensorflow.keras.models import load_model
app = Flask(__name__)
model = load_model('cat_breed_model.h5')
@app.route('/predict', methods=['POST'])
def predict():
# 获取Base64编码的图像
data = request.get_json()
image_data = data['image'].split(",")[1]
# 解码和预处理
image = Image.open(io.BytesIO(base64.b64decode(image_data)))
image = image.resize((224,224))
image_array = np.array(image) / 255.0
image_array = np.expand_dims(image_array, axis=0)
# 预测
predictions = model.predict(image_array)
predicted_class = np.argmax(predictions[0])
confidence = float(np.max(predictions[0]))
# 返回结果
breeds = ['波斯猫','布偶猫','英国短毛猫','暹罗猫','缅因猫',
'美国短毛猫','苏格兰折耳猫','俄罗斯蓝猫','孟加拉猫',
'埃及猫','阿比西尼亚猫','挪威森林猫']
return jsonify({
'breed': breeds[predicted_class],
'confidence': confidence
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
实现功能:
数据库表设计:
sql复制CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(100) NOT NULL,
email VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE recognition_history (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
image_path VARCHAR(255),
predicted_breed VARCHAR(50),
confidence FLOAT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
核心接口设计:
前端关键代码(Vue组件):
javascript复制<template>
<div class="upload-container">
<input type="file" @change="handleFileUpload" accept="image/*">
<button @click="submitImage">识别</button>
<div v-if="result">
<h3>识别结果: {{ result.breed }}</h3>
<p>置信度: {{ (result.confidence * 100).toFixed(2) }}%</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
selectedFile: null,
result: null
}
},
methods: {
handleFileUpload(event) {
this.selectedFile = event.target.files[0]
},
async submitImage() {
if (!this.selectedFile) return
const reader = new FileReader()
reader.onload = async (e) => {
const base64Image = e.target.result
try {
const response = await axios.post('/api/upload', {
image: base64Image
})
this.result = response.data
} catch (error) {
console.error(error)
}
}
reader.readAsDataURL(this.selectedFile)
}
}
}
</script>
推荐部署环境:
使用Docker编排示例:
dockerfile复制# 前端服务
FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 后端服务
FROM openjdk:11-jre-slim
COPY target/cat-classifier.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
# 模型服务
FROM python:3.8-slim
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py /app/
COPY cat_breed_model.h5 /app/
WORKDIR /app
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
问题1:模型过拟合
问题2:类别不平衡
问题1:Python与Java通信延迟
问题2:大文件上传失败
这个猫种类识别项目从技术层面涵盖了深度学习模型开发、Web前后端开发、系统集成等多个领域,是一个很好的全栈实践项目。在指导学生的过程中,我发现以下几个关键点特别重要:
数据质量决定上限:即使使用迁移学习,好的数据预处理和增强也能显著提升模型表现。建议花足够时间在数据准备阶段。
工程化思维:从Jupyter Notebook到生产可用的系统,需要考虑很多工程细节,比如异常处理、日志记录、性能监控等。
用户体验设计:即使是技术演示项目,良好的交互设计也能大大提升使用感受。比如添加上传进度条、结果可视化等。
文档完整性:完善的文档(API文档、部署手册、用户指南)能让项目更易于维护和扩展。
对于想尝试类似项目的同学,我的建议是从小规模开始,先实现核心的识别功能,再逐步扩展其他模块。同时要注重代码规范和模块化设计,这对团队协作和后期维护都非常重要。