当前位置: 首页 > news >正文

flask搭建微服务器并训练CNN水果识别模型应用于网页

一. 搭建flask环境

概念

  • flask:一个轻量级 Web 应用框架,被设计为简单、灵活,能够快速启动一个 Web 项目。
  • CNN:深度学习模型,用于处理具有网格状拓扑结构的数据,如图像(2D网格)和视频(3D网格)。
  • PyTorch:开源的机器学习库,应用于如计算机视觉和自然语言处理等领域的深度学习。

flask环境搭建操作步骤: 

  1. pycharm终端创建新的虚拟环境:python -m venv virtualName 。
  2. 激活虚拟环境。
  3. 在虚拟环境中安装flask。
  4. 运行第一个前端网页。
流程图例

1.

2.

3.

4.

步骤4代码:
from flask import Flask
app = Flask(__name__)@app.route('/')
def hello_world():return "<h1>hello world!</h1>"if __name__ == '__main__':app.run(debug=True)

二. 训练水果模型

水果识别CNN训练操作步骤: 

  1. 准备数据集(kaggle官网可下载)。
  2. 安装pyrorch。
  3. 使用pytorch的nn模型定义参数。
  4. 训练模型。
  5. 得到训练好的pth模型。
流程图例

1.

2.

5.

步骤3代码:
import torch
from torch import nn# 水果分类模型参数配置class NumberNet(nn.Module):def __init__(self, device, classes=10):super().__init__()if device is None:device = torch.device("cpu")if torch.cuda.is_available():device = torch.device("cuda:0")self.cnn = nn.Sequential(nn.Conv2d(3, 16, 3),  # 100x100 -> 98x98nn.ReLU(),nn.MaxPool2d(2, 2),  # 98x98 -> 49x49nn.Conv2d(16, 32, 3, padding=1),  # 49x49 -> 49x49nn.ReLU(),nn.MaxPool2d(2, 2),  # 49x49 -> 24x24nn.Conv2d(32, 64, 3, padding=1),  # 24x24 -> 24x24nn.ReLU(),nn.MaxPool2d(2, 2),  # 24x24 -> 12x12nn.Flatten(),nn.Dropout(),nn.Linear(64 * 12 * 12, 1024),  # 调整线性层的输入特征数量nn.ReLU(),nn.Dropout(),nn.Linear(1024, classes),nn.LogSoftmax(dim=-1))def forward(self, X):return self.cnn(X)
步骤4代码:
import torch
from torch import nn
from NumberNet import NumberNet
from torchvision import transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import random_split# 水果分类训练
# 数据集配置
# 假设 NumberNet 模型期望的输入是 3 通道彩色图像
transform = transforms.Compose([transforms.ToTensor(),  # 这将把 PIL 图像或 NumPy 数组转换为张量,并且范围从 [0, 255] 标准化到 [0.0, 1.0]# transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # 可选:标准化
])# 加载项目目录下的水果文件夹
img_dataset = ImageFolder("../fruits", transform=transform)
len_dataset = len(img_dataset)
train_size = int(len_dataset * 0.8)
valid_size = len_dataset - train_size
train_dataset, valid_dataset = random_split(img_dataset, [train_size, valid_size])# 数据加载器
train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=1000, shuffle=True)
valid_dataloader = torch.utils.data.DataLoader(valid_dataset, batch_size=1000)
# batch_total 应该是 dataloader 的总批次数量,这里计算方式不正确
batch_total = len(train_dataloader)  # 应该直接使用 len(dataloader)# 使用conda或者cpu开始训练
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
epochs = 10
model = NumberNet(device)
criterion = nn.CrossEntropyLoss()
adam = torch.optim.Adam(model.parameters(), lr=0.01)for epoch in range(epochs):losses = []for batch_num, (images, labels) in enumerate(train_dataloader, start=1):  # 使用 enumerate 来获取批次编号adam.zero_grad()predict = model(images.to(device))loss = criterion(predict, labels.to(device))print(f"batch size: {batch_num} / {batch_total} -- loss: {loss.item():.4f} ")losses.append(loss.item())loss.backward()adam.step()acc_list = []with torch.no_grad():for images, labels in valid_dataloader:predict = model(images.to(device))result = torch.argmax(predict, dim=-1)acc = (result == labels.to(device)).float().mean()  # 使用 torch 的函数来计算准确率acc_list.append(acc.item())total_acc = sum(acc_list) / len(acc_list)total_loss = sum(losses) / batch_totalprint(f"epoch: {epoch + 1} / {epochs} -- loss: {total_loss:.4f} -- acc: {total_acc:.4f} ")# 保存模型参数,而不是整个模型
torch.save(model, "../readyModel/model.pth")

 三. 将训练好的模型嵌入flask后端

实现水果识别web操作步骤: 

  1. 在虚拟化环境下创建.py后端启动文件,并且创建模型实例,同时将训练好的.pth文件放入代码对应的文件路径。
  2. 创建index.html文件,作为后续前端文件。
  3. 在前端代码和后端代码使用Jason进行路由。
  4. 启动项目,实现功能。
 步骤1代码:
from flask import Flask, render_template, request, jsonify
import time
import torch
import cv2
import numpy as np
from FruitNet import FruitNet  # 确保FruitNet定义是正确的app = Flask(__name__)# 定义设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 创建模型实例
model = FruitNet(device=device, classes=5)  # 确保类别数与训练时一致
model.to(device)# 加载训练好的权重
model.load_state_dict(torch.load("static/fruit_model.pth"))  # 确保权重文件名为fruit_model.pth
model.eval()  # 设置模型为评估模式def predict_image(image_data):# 通过cv2加载图片数据img = cv2.imdecode(np.frombuffer(image_data, np.uint8), cv2.IMREAD_COLOR)# 将图像从BGR转换为RGB格式(因为OpenCV默认加载的是BGR格式)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 调整图片大小到100x100(与训练时的输入大小一致)img = cv2.resize(img, (100, 100))# 在第一个位置增加一个维度,形成batch大小为1img = np.expand_dims(img, 0)# 将numpy对象转化为pytorch的tensor对象img = torch.from_numpy(img)# 调整图像通道顺序img = torch.permute(img, [0, 3, 1, 2])  # 转换为 (batch_size, channels, height, width)# 测试最终的结果with torch.no_grad():  # 关闭梯度计算img = img.to(device).float()  # 确保输入是float类型,并发送到指定设备predict = model(img)predicted_class = torch.argmax(predict, dim=-1).item()# 定义水果类别标签fruit_classes = ["Apple Golden 1", "Banana", "Pear Red", "Tomato Heart", "Watermelon"]  # 根据你的数据集定义类别标签# 输出预测的水果种类predicted_fruit = fruit_classes[predicted_class]return predicted_fruit
 步骤2代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>水果识别</title><link rel="stylesheet" href="./static/css/index.css"><script src="./static/js/jquery-3.7.1.min.js"></script>
</head>
<body>
<div class="main"><div><!-- 显示上传的图片 --><div class="upload-img"><img id="upload-img" src="" alt="请上传图片"/></div><!-- 表单用于上传图片 --><form   id="upload-btn" action="/upload" method="post" enctype="multipart/form-data"><input style="margin-left: 120px" type="file" name="the_file" id="selectImg"> <br/><input type="submit" value="识别该水果"></form></div><!-- 显示识别结果 --><div class="result"><h2 id="result-show"></h2></div>
</div><script>// 将文件转为 Base64 用于图片预览function convertToBase64(file, callback) {const reader = new FileReader();reader.onload = function(e) {callback(e.target.result);};reader.readAsDataURL(file);}$(function(){// 处理图片选择后的显示$("#selectImg").change(function(ev){const file = $(this)[0].files[0];if (file) {convertToBase64(file, function(base64Img){$("#upload-img").attr("src", base64Img);  // 更新图片预览});}});// 处理表单提交$('#upload-btn').submit(function(ev){ev.preventDefault();  // 阻止默认表单提交var formData = new FormData(this);  // 获取表单数据$.ajax({url: '/upload',  // 请求的后端地址type: 'POST',data: formData,contentType: false,processData: false,success: function(response){console.log('文件上传成功');console.log(response);// 更新识别结果$('#result-show').text('识别结果:' + response.result);  // 显示识别结果},error: function(error){console.error('文件上传失败');console.error(error);}});});});
</script>
</body>
</html>
 步骤3代码:
<script>// 将文件转为 Base64 用于图片预览function convertToBase64(file, callback) {const reader = new FileReader();reader.onload = function(e) {callback(e.target.result);};reader.readAsDataURL(file);}$(function(){// 处理图片选择后的显示$("#selectImg").change(function(ev){const file = $(this)[0].files[0];if (file) {convertToBase64(file, function(base64Img){$("#upload-img").attr("src", base64Img);  // 更新图片预览});}});// 处理表单提交$('#upload-btn').submit(function(ev){ev.preventDefault();  // 阻止默认表单提交var formData = new FormData(this);  // 获取表单数据$.ajax({url: '/upload',  // 请求的后端地址type: 'POST',data: formData,contentType: false,processData: false,success: function(response){console.log('文件上传成功');console.log(response);// 更新识别结果$('#result-show').text('识别结果:' + response.result);  // 显示识别结果},error: function(error){console.error('文件上传失败');console.error(error);}});});});
</script>
@app.route("/")
def home():return render_template("index.html")@app.route('/upload', methods=['POST'])
def upload_file():if request.method == 'POST':f = request.files['the_file']# 保存图片到静态目录timestamp = time.strftime("%Y%m%d%H%M%S")file_path = f'./static/uploads/{timestamp}.png'f.save(file_path)# 读取保存后的图片数据并预测with open(file_path, 'rb') as image_file:image_data = image_file.read()predicted_fruit = predict_image(image_data)# 返回JSON数据return jsonify({'file_id': timestamp,'result': predicted_fruit,'img_path': f'/static/uploads/{timestamp}.png'})
  步骤4实现效果:

相关文章:

flask搭建微服务器并训练CNN水果识别模型应用于网页

一. 搭建flask环境 概念 flask:一个轻量级 Web 应用框架&#xff0c;被设计为简单、灵活&#xff0c;能够快速启动一个 Web 项目。CNN:深度学习模型&#xff0c;用于处理具有网格状拓扑结构的数据&#xff0c;如图像&#xff08;2D网格&#xff09;和视频&#xff08;3D网格&a…...

数据篇| 关于Selenium反爬杂谈

友情提示:本章节只做相关技术讨论, 爬虫触犯法律责任与作者无关。 LLM虽然如火如荼进行着, 但是没有数据支撑, 都是纸上谈兵, 人工智能的三辆马车:算法-数据-算力,缺一不可。之前写过关于LLM微调文章《微调入门篇:大模型微调的理论学习》、《微调实操一: 增量预训练(Pretrai…...

MySQL高阶1890-2020年最后一次登录

目录 题目 准备数据 分析数据 题目 编写解决方案以获取在 2020 年登录过的所有用户的本年度 最后一次 登录时间。结果集 不 包含 2020 年没有登录过的用户。 返回的结果集可以按 任意顺序 排列。 准备数据 Create table If Not Exists Logins (user_id int, time_stamp …...

update-alternatives官方手册

下述手册超链接都是英文&#xff0c;内容差不多&#xff0c;看一个就行 Debian系统的Ubuntu系统的《The Linux Programming Interface》图书上的...

cesium.js 入门到精通(5-2)

在cesium 的配置中 有一些参数 可以配置地图的显示 显示出 水的动态显示 山的效果 相当于一些动画显示的效果 var viewer new Cesium.Viewer("cesiumContainer", {infoBox: false,terrainProvider: await Cesium.createWorldTerrainAsync({requestWaterMask: tru…...

LINUX的PHY抽象层——PAL

英文原文参考&#xff1a; https://www.kernel.org/doc/html/latest/networking/phy.html 中文翻译参考&#xff1a;有关PHY抽象层的总结 https://blog.csdn.net/eydwyz/article/details/124753313 目录 1 前言2 PHY接口模式3 尽量使用PHY端的延时而不是MAC或PCB4 其他方式实现…...

优先级队列(堆)

目录 优先级队列 堆的概念 堆的创建 堆的向下调整 堆的插入 完整代码 优先级队列 队列是一种先进先出的数据结构&#xff0c;有些时候操作的数据可能带有优先级&#xff0c;出队列时就需要优先级高的数据先出队列。 在这种情况下&#xff0c;数据结构应该提供两个最基本…...

帧率和丢帧分析理论

一、丢帧问题概述 应用丢帧通常指的是在应用程序的界面绘制过程中&#xff0c;由于某些原因导致界面绘制的帧率下降&#xff0c;从而造成界面卡顿、动画不流畅等问题。以60Hz刷新率为例子&#xff0c;想要达到每秒60帧&#xff08;即60fps&#xff09;的流畅体验&#xff0c;每…...

solidwork找不到曲面

如果找不到曲面 则右键找到选项卡&#xff0c;选择曲面...

mac安装JetBtains全家桶新版本时报错:Cannot start the IDE

mac安装JetBtains全家桶新版本时报错&#xff1a;Cannot start the IDE 前言报错信息解决方法 前言 作者使用的是Mac电脑&#xff0c;最近想要更新JetBrains相关工具的软件版本&#xff0c;但是在安装时突然报错&#xff0c;导致安装失败&#xff0c;现在将报错信息以及解决方…...

MVCC机制解析:提升数据库并发性能的关键

MVCC机制解析&#xff1a;提升数据库并发性能的关键 MVCC&#xff08;Multi-Version Concurrency Control&#xff09; 多版本并发控制 。 MVCC只在事务隔离级别为读已提交(Read Committed)和可重复读(Repeated Read)下生效。 MVCC是做什么用的 MVCC是为了处理 可重复读 和…...

如何使用Postman搞定带有token认证的接口实战!

现在许多项目都使用jwt来实现用户登录和数据权限&#xff0c;校验过用户的用户名和密码后&#xff0c;会向用户响应一段经过加密的token&#xff0c;在这段token中可能储存了数据权限等&#xff0c;在后期的访问中&#xff0c;需要携带这段token&#xff0c;后台解析这段token才…...

Linux Vim编辑器常用命令

目录 一、命令模式快捷键 二、编辑/输入模式快捷键 三、编辑模式切换到命令模式 四、搜索命令 注&#xff1a;本章内容全部基于Centos7进行操作&#xff0c;查阅本章节内容前请确保您当前所在的Linux系统版本&#xff0c;且具有足够的权限执行操作。 一、命令模式快捷键 二…...

【Android】浅析MVC与MVP

【Android】浅析MVC与MVP 什么是架构&#xff1f; 架构&#xff08;Architecture&#xff09;在软件开发中指的是软件系统的整体设计和结构&#xff0c;它描述了系统的高层组织方式&#xff0c;包括系统中各个组件之间的关系、依赖、交互方式&#xff0c;以及这些组件如何协同…...

spark 面试题

spark 面试题 1、spark 任务如何解决第三方依赖 比如机器学习的包&#xff0c;需要在本地安装&#xff1f;--py-files 添加 py、zip、egg 文件不需要在各个节点安装 2、spark 数据倾斜怎么解决 spark 中数据倾斜指的是 shuffle 过程中出现的数据倾斜&#xff0c;主要是由于…...

青柠视频云——如何开启HTTPS服务?

前言 由于青柠视频云的语音对讲会使用到HTTPS服务&#xff0c;这里我们说一下如何申请证书以及如何在实战中部署并且配置使用。 一、证书申请 1、进入控制台 我们拿阿里云的免费个人证书为例&#xff0c;首先登录阿里云&#xff0c;在控制台找到数字证书管理服务&#xff0c;进…...

2016年国赛高教杯数学建模A题系泊系统的设计解题全过程文档及程序

2016年国赛高教杯数学建模 A题 系泊系统的设计 近浅海观测网的传输节点由浮标系统、系泊系统和水声通讯系统组成&#xff08;如图1所示&#xff09;。某型传输节点的浮标系统可简化为底面直径2m、高2m的圆柱体&#xff0c;浮标的质量为1000kg。系泊系统由钢管、钢桶、重物球、…...

vue-使用refs取值,打印出来是个数组??

背景&#xff1a; 经常使用$refs去获取组件实例&#xff0c;一般都是拿到实例对象&#xff0c;这次去取值的时候发现&#xff0c;拿到的竟然是个数组。 原因&#xff1a; 这是vue的特性,自动把v-for里面的ref展开成数组的形式&#xff0c;哪怕你的ref名字是唯一的&#xff01…...

微服务_入门1

文章目录 一、 认识微服务二、 微服务演变2.1、 单体架构2.2、 分布式架构2.3、 微服务2.4、 微服务方案对比 三、 注册中心3.1、 Eureka3.2、 Nacos3.2.1、服务分级存储模型3.2.2、权重配置3.2.3、环境隔离 一、 认识微服务 二、 微服务演变 随着互联网行业的发展&#xff0c;…...

【学习资料】袋中共36个球,红白黑格12个,问能一次抽到3个红4个白5个黑的概率是多少?

1、公式计算 1.1 题目1 袋中共 36 36 36个球&#xff0c; 红 \fcolorbox{red}{#FADADE}{\color{red}{红}} 红​ 白 \fcolorbox{white}{#808080}{\color{white}{白}} 白​ 黑 \fcolorbox{#808080}{#0D0D0D}{\color{#808080}{黑}} 黑​各 12 12 12个&#xff0c;问能一次抽到 3…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...