CNN之战:ResNet vs. MobileNet vs. EfficientNet 用于水果疾病检测
Source: Dev.to
介绍
我一直对深度学习如何解决现实世界的问题感到着迷,而水果病害检测似乎是一个完美的挑战——既不过于简单,也不至于复杂到不可实现,并且对与作物损失作斗争的农民真正有用。
我构建了 FruitScan‑AI 并测试了三种不同的神经网络架构,以找出哪一种表现最佳。剧透一下:每种模型都有其优势,而“最佳”模型完全取决于你的具体需求。
为什么要进行水果病害检测?
农民每年因病虫害损失 20 %–40 % 的作物。传统的检查方式——在田间走动,手动检查每株植物,期望及早发现问题——既慢又不稳定,而且需要并非所有人都具备的专业知识。
如果我们只需拍一张照片就能获得即时诊断会怎样?这正是 FruitScan‑AI 的用武之地。
我构建的内容
FruitScan‑AI 是一个深度学习系统,能够查看水果图像并告诉你两件事:
- 它是什么水果
- 它是健康的还是患病的
我没有只停留在单一模型;我使用 EfficientNet、MobileNetV2 和 ResNet50 构建了三个版本,以便并排比较它们。
数据集
- 包含 15+ 种水果的图像(苹果、香蕉、葡萄、芒果、西红柿、辣椒,…)
- 每个类别均包括 健康 与 病害 标本(细菌斑点、真菌感染、腐烂等)
- 高分辨率图像,捕捉用于精确分类的细微细节
三种架构(以及我为何选择它们)
EfficientNet – 平衡之选
EfficientNet 通过 compound scaling 同时缩放深度、宽度和分辨率,能够在不成为计算怪兽的情况下提供出色的准确率。我选择它是因为它的高效性以及在图像分类任务中的强大表现。
MobileNetV2 – 轻量冠军
MobileNetV2 为移动设备设计,使用 depthwise separable convolutions 以更少的资源实现更多功能。非常适合在手机或农场中的 Raspberry Pi 上部署。如果我要为农民构建现场应用,这将是我的首选。
ResNet50 – 重量级选手
ResNet50 引入了 skip connections,使得非常深的网络在没有梯度消失的情况下也能训练。它更深、更强大,并提供了一个可靠的基准用于比较。
实际工作原理
所有三个模型都使用 transfer learning——它们在 ImageNet 上预训练,因此已经掌握了边缘、纹理和形状。
# Freeze the pretrained layers at first
base_model = EfficientNetB0(weights='imagenet', include_top=False)
base_model.trainable = False
# Add custom classification layers on top
model = Sequential([
base_model,
GlobalAveragePooling2D(),
Dense(256, activation='relu'),
Dropout(0.5),
Dense(num_classes, activation='softmax')
])
为什么使用迁移学习?
- 训练更快
- 所需数据更少
- 结果更好
训练流程
- Resize 将图像调整为每个模型期望的输入尺寸(通常为 224×224)。
- Normalize 使用 ImageNet 统计数据。
- Data augmentation(翻转、旋转、亮度调整)以防止记忆化。
- Batch training 以保持 GPU 高效运行。
我跟踪了常见指标:accuracy, precision, recall, F1‑score, 和 confusion matrices,以查看每个模型的薄弱之处。
入门指南(如果你想尝试)
需求
pip install tensorflow keras numpy pandas matplotlib scikit-learn
获取代码
git clone https://github.com/sisodiajatin/FruitScan-AI.git
cd FruitScan-AI
仓库结构
FruitScan-AI/
├── EfficientNet/ # EfficientNet notebooks
├── MobileNetV2/ # MobileNetV2 experiments
└── ResNet50/ # ResNet50 implementation
运行 Notebook
cd EfficientNet # or whichever model you want
jupyter notebook
# Open the training notebook and run it cell by cell
进行预测
# Load your model
model = tf.keras.models.load_model('fruit_disease_model.h5')
# Prepare the image
img = tf.keras.utils.load_img('suspicious_apple.jpg', target_size=(224, 224))
img_array = tf.keras.utils.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0)
img_array = tf.keras.applications.efficientnet.preprocess_input(img_array)
# Get prediction
predictions = model.predict(img_array)
class_idx = np.argmax(predictions[0])
print(f"This looks like: {class_labels[class_idx]}")
print(f"Confidence: {predictions[0][class_idx] * 100:.2f}%")
简单的 Flask 包装器(API)
from flask import Flask, request, jsonify
import tensorflow as tf
app = Flask(__name__)
model = tf.keras.models.load_model('best_model.h5')
@app.route('/predict', methods=['POST'])
def predict():
# Expect an image file under the key 'file'
file = request.files['file']
img = tf.keras.utils.load_img(file, target_size=(224, 224))
img_array = tf.keras.utils.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0)
img_array = tf.keras.applications.efficientnet.preprocess_input(img_array)
preds = model.predict(img_array)
class_idx = np.argmax(preds[0])
confidence = preds[0][class_idx] * 100
return jsonify({
'class': class_labels[class_idx],
'confidence': f'{confidence:.2f}%'
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
结束语
每种架构在不同场景下各有优势:
- EfficientNet – 最佳的整体准确率与效率比。
- MobileNetV2 – 在资源受限的设备上进行推理的理想选择。
- ResNet50 – 提供强大的基线,并在计算资源充足时表现出色。
欢迎随意探索、微调并将代码应用于您自己的水果病害检测项目!
def predict():
file = request.files['image']
img = preprocess_image(file)
prediction = model.predict(img)
return jsonify({
'fruit': get_fruit_name(prediction),
'status': 'healthy' if is_healthy(prediction) else 'diseased',
'confidence': float(np.max(prediction))
})
那么…哪个模型赢了?
老实说? 这取决于你的优化目标。
| Model | Accuracy | Speed (per image) | Size / Use‑case |
|---|---|---|---|
| EfficientNet | 92 % – 95 % | 30 ms – 50 ms | 表现均衡 |
| MobileNetV2 | 88 % – 91 % | 10 ms – 20 ms | 快速且体积小——非常适合移动应用 |
| ResNet50 | 90 % – 93 % | 50 ms – 80 ms | 速度较慢且体积更大——适合研究或对精度要求极高的场景 |
试一试!
如果这听起来很有趣:
⭐ 给仓库加星 –