人工智能实践之基于CNN的街区餐饮图片识别案例实践

一、项目背景与目标

街区餐饮场景中,存在大量的菜品图片、门店招牌图片、食材图片等视觉数据。传统人工分类标注效率低、成本高,而卷积神经网络(CNN) 作为计算机视觉领域的核心算法,具备强大的图像特征提取与分类能力。

本实践以街区餐饮图片分类为目标,构建基于CNN的识别模型,实现三大类餐饮图片的自动分类:

  1. 菜品类:火锅、烧烤、奶茶、快餐等细分菜品;
  2. 门店招牌类:中餐厅、西餐厅、小吃店等门店标识;
  3. 食材类:蔬菜、肉类、海鲜等原材料。

通过该模型,可应用于街区餐饮智能推荐、食品安全巡检、餐饮大数据统计等场景。

二、技术选型与环境准备

1. 核心技术栈

技术模块 选型 说明
深度学习框架 TensorFlow 2.x/Keras 高层API简洁易用,适合快速构建CNN模型
数据预处理 OpenCV + PIL 实现图像的读取、缩放、增强等操作
模型训练 GPU(NVIDIA Tesla T4) 加速CNN卷积层、池化层的计算
部署工具 Flask 搭建轻量级API服务,支持图片在线识别

2. 环境配置(Linux/Windows通用)

(1)安装依赖库
bash 复制代码
# 安装TensorFlow与Keras
pip install tensorflow==2.15.0 keras==2.15.0

# 安装图像处理库
pip install opencv-python pillow matplotlib

# 安装数据处理与部署库
pip install pandas numpy flask
(2)验证环境
python 复制代码
import tensorflow as tf
import cv2
print("TensorFlow版本:", tf.__version__)
print("GPU是否可用:", tf.config.list_physical_devices('GPU'))
print("OpenCV版本:", cv2.__version__)

三、数据集构建与预处理

1. 数据集采集

本项目采用自建数据集+公开数据集的混合方案:

  • 公开数据集:下载Food-101、UEC-Food100等公开餐饮数据集,提取与街区餐饮相关的类别;
  • 自建数据集 :实地拍摄街区餐饮门店的菜品、招牌、食材图片,共采集 3000张有效图片,按类别划分如下:
分类 子类别 样本数量
菜品类 火锅、烧烤、奶茶、快餐 1200张
门店招牌类 中餐厅、西餐厅、小吃店 1000张
食材类 蔬菜、肉类、海鲜 800张
数据集目录结构
复制代码
street_food_dataset/
├── train/
│   ├── dish/
│   │   ├── hotpot/
│   │   ├── barbecue/
│   │   ├── milk_tea/
│   │   └── fast_food/
│   ├── signboard/
│   │   ├── chinese_restaurant/
│   │   ├── western_restaurant/
│   │   └── snack_bar/
│   └── ingredient/
│       ├── vegetable/
│       ├── meat/
│       └── seafood/
└── test/
    ├── dish/
    ├── signboard/
    └── ingredient/
  • 训练集与测试集按 7:3 比例划分,避免数据泄露。

2. 数据预处理

CNN模型对输入图像的尺寸、格式有严格要求,需执行以下预处理步骤:

(1)图像尺寸标准化

将所有图片统一缩放为 224×224×3(RGB三通道),匹配CNN模型输入尺寸。

(2)数据增强(解决过拟合)

对训练集图像执行随机增强,提升模型泛化能力:

  • 随机旋转(±15°)
  • 随机水平翻转(概率50%)
  • 随机亮度调整(±10%)
  • 像素值归一化(将像素值从0-255缩放到0-1)
(3)标签编码

将类别标签转换为one-hot编码,例如:

  • 火锅 → [1,0,0,0,0,0,0,0,0]
  • 中餐厅 → [0,0,0,0,1,0,0,0,0]

3. 数据加载

使用Keras的ImageDataGenerator实现数据批量加载:

python 复制代码
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# 训练集数据增强配置
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=15,
    width_shift_range=0.1,
    height_shift_range=0.1,
    horizontal_flip=True,
    fill_mode='nearest'
)

# 测试集仅做归一化
test_datagen = ImageDataGenerator(rescale=1./255)

# 加载训练集
train_generator = train_datagen.flow_from_directory(
    'street_food_dataset/train',
    target_size=(224, 224),
    batch_size=32,
    class_mode='categorical'  # 多分类任务
)

# 加载测试集
test_generator = test_datagen.flow_from_directory(
    'street_food_dataset/test',
    target_size=(224, 224),
    batch_size=32,
    class_mode='categorical'
)

# 获取类别标签映射
class_indices = train_generator.class_indices
labels = dict((v,k) for k,v in class_indices.items())
print("类别标签映射:", labels)

四、CNN模型构建与训练

1. 模型架构设计

采用迁移学习 方案,基于预训练模型MobileNetV2构建轻量化CNN模型(适合边缘设备部署),相比从零构建CNN,迁移学习可大幅提升训练效率和识别精度。

模型架构分为三部分:

  1. 特征提取层:使用MobileNetV2预训练权重,冻结前90%的层,仅训练顶层网络;
  2. 特征融合层:添加全局平均池化层(GAP),减少参数数量;
  3. 分类层:添加全连接层+Dropout层(防止过拟合)+Softmax输出层。

2. 模型代码实现

python 复制代码
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam

# 加载预训练模型MobileNetV2
base_model = MobileNetV2(
    input_shape=(224, 224, 3),
    include_top=False,  # 不包含顶层分类层
    weights='imagenet'  # 加载ImageNet预训练权重
)

# 冻结特征提取层(仅训练顶层)
for layer in base_model.layers[:int(len(base_model.layers)*0.9)]:
    layer.trainable = False

# 构建顶层分类网络
x = base_model.output
x = GlobalAveragePooling2D()(x)  # 全局平均池化
x = Dense(512, activation='relu')(x)  # 全连接层
x = Dropout(0.5)(x)  # Dropout层,抑制过拟合
predictions = Dense(9, activation='softmax')(x)  # 9分类输出

# 构建完整模型
model = Model(inputs=base_model.input, outputs=predictions)

# 模型编译
model.compile(
    optimizer=Adam(learning_rate=0.0001),  # 小学习率微调
    loss='categorical_crossentropy',  # 多分类损失函数
    metrics=['accuracy']  # 评估指标:准确率
)

# 查看模型结构
model.summary()

3. 模型训练

设置训练参数,启动模型训练,并使用ModelCheckpointEarlyStopping回调函数优化训练过程:

python 复制代码
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

# 回调函数配置
checkpoint = ModelCheckpoint(
    'street_food_cnn_model.h5',
    monitor='val_accuracy',
    save_best_only=True,
    mode='max',
    verbose=1
)

early_stopping = EarlyStopping(
    monitor='val_accuracy',
    patience=5,  # 5轮验证集准确率无提升则停止训练
    mode='max',
    verbose=1
)

# 启动训练
history = model.fit(
    train_generator,
    epochs=30,  # 最大训练轮数
    validation_data=test_generator,
    callbacks=[checkpoint, early_stopping]
)

4. 训练结果可视化

绘制训练过程中的准确率和损失曲线,分析模型训练状态:

python 复制代码
import matplotlib.pyplot as plt

# 绘制准确率曲线
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Val Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()

# 绘制损失曲线
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Val Loss')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.savefig('training_history.png')
plt.show()

5. 模型评估

使用测试集评估模型最终性能:

python 复制代码
# 加载最优模型
from tensorflow.keras.models import load_model
best_model = load_model('street_food_cnn_model.h5')

# 评估模型
test_loss, test_acc = best_model.evaluate(test_generator)
print(f"测试集损失:{test_loss:.4f}")
print(f"测试集准确率:{test_acc:.4f}")

本实践中,模型最终在测试集上的准确率可达 92.5%,满足街区餐饮图片识别的实际需求。

五、模型部署与实际应用

1. 单张图片识别测试

编写预测函数,实现单张街区餐饮图片的识别:

python 复制代码
import numpy as np
from PIL import Image

def predict_image(image_path, model, labels):
    # 加载并预处理图片
    img = Image.open(image_path).resize((224, 224))
    img_array = np.array(img) / 255.0
    img_array = np.expand_dims(img_array, axis=0)  # 增加batch维度

    # 模型预测
    predictions = model.predict(img_array)
    predicted_class = np.argmax(predictions, axis=1)[0]
    confidence = np.max(predictions, axis=1)[0]

    # 返回识别结果
    return labels[predicted_class], confidence

# 测试单张图片
image_path = "test_images/hotpot.jpg"
class_name, confidence = predict_image(image_path, best_model, labels)
print(f"识别结果:{class_name},置信度:{confidence:.2%}")

2. 搭建Flask在线识别服务

将模型部署为Web服务,支持用户上传图片并返回识别结果:

(1)编写Flask服务代码(app.py
python 复制代码
from flask import Flask, request, jsonify
from tensorflow.keras.models import load_model
import numpy as np
from PIL import Image
import io

app = Flask(__name__)

# 加载模型和标签
model = load_model('street_food_cnn_model.h5')
labels = {0: 'hotpot', 1: 'barbecue', 2: 'milk_tea', 3: 'fast_food',
          4: 'chinese_restaurant', 5: 'western_restaurant', 6: 'snack_bar',
          7: 'vegetable', 8: 'meat', 9: 'seafood'}

@app.route('/predict', methods=['POST'])
def predict():
    if 'file' not in request.files:
        return jsonify({'error': '未上传图片'})
    
    file = request.files['file']
    img = Image.open(io.BytesIO(file.read())).resize((224, 224))
    img_array = np.array(img) / 255.0
    img_array = np.expand_dims(img_array, axis=0)

    predictions = model.predict(img_array)
    predicted_class = np.argmax(predictions, axis=1)[0]
    confidence = float(np.max(predictions, axis=1)[0])

    return jsonify({
        'class_name': labels[predicted_class],
        'confidence': confidence
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=False)
(2)启动服务并测试
bash 复制代码
# 启动Flask服务
python app.py

# 使用curl测试接口
curl -X POST -F "file=@test_images/bbq.jpg" http://localhost:5000/predict

返回结果示例:

json 复制代码
{"class_name": "barbecue", "confidence": 0.9685}

3. 实际应用场景

  1. 街区餐饮智能推荐:结合识别结果,向用户推荐附近的火锅、奶茶等门店;
  2. 食品安全巡检:自动识别食材类别,判断是否存在变质风险;
  3. 餐饮大数据统计:统计街区内各类型餐饮的占比,为商业规划提供数据支持。

六、模型优化与改进方向

  1. 数据层面:增加更多样本(尤其是小众菜品),引入更多数据增强策略(如随机裁剪);
  2. 模型层面:尝试更轻量的模型(如MobileNetV3),或使用模型量化技术(TensorFlow Lite),降低部署资源消耗;
  3. 功能层面:扩展模型识别类别(如新增甜品、饮品),实现多标签识别(一张图片同时识别菜品和食材)。

七、总结

本实践基于CNN迁移学习技术,成功构建了街区餐饮图片识别模型,实现了菜品、门店招牌、食材三大类别的高精度分类。通过迁移学习,大幅缩短了模型训练时间;通过Flask部署,实现了模型的快速落地应用。该方案可广泛应用于街区餐饮智能化管理场景,提升运维效率和用户体验。

我可以帮你整理该项目的完整代码清单,包含数据预处理、模型训练和部署的全部脚本,需要吗?

相关推荐
刘懂Dawn15 小时前
07844_人工智能导论_复习资料
人工智能
北京耐用通信15 小时前
耐达讯自动化赋能:Canopen转Profibus网关水泵连接新范式
人工智能·科技·物联网·自动化·信息与通信
纪伊路上盛名在15 小时前
如何为我们的GPU设备选择合适的CUDA版本和Torch版本?
pytorch·深度学习·torch·cuda·英伟达
小途软件15 小时前
ssm327校园二手交易平台的设计与实现+vue
java·人工智能·pytorch·python·深度学习·语言模型
小咖自动剪辑15 小时前
小咖批量剪辑助手:Windows 视频批量自动剪辑与混剪工具
人工智能·音视频·语音识别·实时音视频·视频编解码
京东零售技术15 小时前
ACM Multimedia | 京东零售广告创意:统一的布局生成和评估模型
人工智能
阿东在coding15 小时前
MCP Skill Subagent 实战指南
人工智能
房产中介行业研习社15 小时前
嘉兴国商区2026年1月品质楼盘推荐
大数据·人工智能·房产直播技巧·房产直播培训
凤希AI伴侣15 小时前
从组装工到超级个体:AI伴侣开发中的工具整合与体验优化
人工智能·凤希ai伴侣