去年指导计算机专业毕业设计时,遇到一个典型案例:某生选题是蔬菜识别系统,但面对PyTorch框架和机器学习算法无从下手。经过三周的密集开发,我们最终实现了一个准确率达92.3%的识别系统。这个项目完美融合了深度学习技术与实际应用场景,特别适合作为计算机专业的毕业设计选题。
蔬菜识别属于典型的图像分类任务,在智慧农业、生鲜分拣等领域有广泛应用。传统方法依赖人工特征提取,而基于深度学习的方案能自动学习特征表达。本系统采用PyTorch框架实现,相比TensorFlow更受学术界青睐——根据2023年CVPR论文统计,PyTorch在计算机视觉领域的采用率已达78%。
系统采用前后端分离架构:
这种架构的优势在于:
经过对比实验,最终选择ResNet-34作为基础模型:
python复制import torch
import torchvision.models as models
model = models.resnet34(pretrained=True)
num_ftrs = model.fc.in_features
model.fc = torch.nn.Linear(num_ftrs, len(classes)) # 修改最后一层
选择理由:
使用自建的蔬菜数据集(15类,每类500张):
python复制transform = transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ColorJitter(brightness=0.2, contrast=0.2),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
完整训练代码示例:
python复制# 超参数设置
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)
# 训练循环
for epoch in range(25):
model.train()
for inputs, labels in train_loader:
inputs = inputs.to(device)
labels = labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# 验证集评估
model.eval()
with torch.no_grad():
correct = 0
total = 0
for inputs, labels in val_loader:
inputs = inputs.to(device)
labels = labels.to(device)
outputs = model(inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Epoch {epoch}: Val Acc {100 * correct / total:.2f}%')
采用Flask搭建推理API:
python复制from flask import Flask, request, jsonify
import torch
from PIL import Image
import io
app = Flask(__name__)
model = load_model() # 加载训练好的模型
@app.route('/predict', methods=['POST'])
def predict():
if 'file' not in request.files:
return jsonify({'error': 'no file'})
file = request.files['file']
img_bytes = file.read()
img = Image.open(io.BytesIO(img_bytes))
# 预处理
img_tensor = transform(img).unsqueeze(0)
# 推理
with torch.no_grad():
output = model(img_tensor)
_, pred = torch.max(output, 1)
return jsonify({'class': classes[pred.item()]})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
前端调用示例(Vue + Axios):
javascript复制async function predictImage(file) {
const formData = new FormData()
formData.append('file', file)
try {
const res = await axios.post('/api/predict', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
})
return res.data
} catch (err) {
console.error('预测失败:', err)
return null
}
}
为提升推理速度,采用以下优化:
python复制model = torch.quantization.quantize_dynamic(
model, {torch.nn.Linear}, dtype=torch.qint8
)
python复制dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(model, dummy_input, "vegetable.onnx")
通过网格搜索确定最佳参数组合:
| 参数 | 搜索范围 | 最优值 |
|---|---|---|
| 学习率 | [1e-4, 1e-3] | 3e-4 |
| Batch Size | [16, 32, 64] | 32 |
| 优化器 | [SGD, Adam] | SGD |
| 动量 | [0.8, 0.9] | 0.9 |
不同增强方法对准确率的影响:
| 增强方法 | Val Acc | 训练时间 |
|---|---|---|
| 基础增强 | 89.2% | 2.1h |
| +CutMix | 90.7% | 2.4h |
| +AutoAugment | 91.5% | 2.8h |
| +MixUp | 92.3% | 3.2h |
Loss不下降:
过拟合:
CUDA内存不足:
python复制torch.cuda.empty_cache() # 显存释放
with torch.no_grad(): # 禁用梯度计算
模型加载失败:
python复制torch.save(model.state_dict(), 'model.pth') # 推荐
跨域问题:
python复制from flask_cors import CORS
CORS(app, resources={r"/api/*": {"origins": "*"}})
大文件上传:
python复制app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB
创新点挖掘:
实验设计:
在项目开发过程中,最深刻的体会是:理论理解和工程实现之间存在巨大鸿沟。比如论文中的CutMix数据增强,实际实现时需要处理标签平滑、图像混合比例等诸多细节。建议学弟学妹们在毕设中,尽早建立端到端的pipeline,先实现再优化。