目录
1. 介绍
2. 搭建LeNet 预测网络
3. 搭建本地的web
error
4. 部署到cloud上
之前做的用PyQT做的GUI窗口分类图像,然后打包成exe的方法有些过时了
这次用的方法时用streamlit将神经网络部署成一个web
项目包含的文件:

参考的是这篇文章:pytorch 实现图像分类+web部署
网站的链接为:图像分类
github 的链接为:LeNet-classification
最后实现的效果展示:
默认打开网站显示:

上传图片后显示:

大概的实现思路为:
1. 用pytorch搭建一个预测网络
2. 用streamlit 搭建一个本地的web
3. 用streamlit cloud 将本地的 web 发布出去
代码为:
import torchvision.transforms as transforms
import torch.nn as nn # 神经网络库
import torch.nn.functional as F # 函数功能库,如relu、sigmoid等等
import torch
from PIL import Imageclass LeNet(nn.Module): # 继承父类def __init__(self):super(LeNet,self).__init__() #涉及到多继承需要,这个记住就行self.conv1 = nn.Conv2d(3,6,5) # 输入(3,32,32) 输出(6,28,28)self.conv2 = nn.Conv2d(6,16,5) # 输入(6,14,14) 输出(16,10,10)self.fc1 = nn.Linear(16*5*5,120) # 输入16*5*5,输出120self.fc2 = nn.Linear(120,84)self.fc3 = nn.Linear(84,10)# 定义前向传播过程def forward(self,x): # 输入x == 【batch,channel,height,width】# conv -> 激活函数 -> 池化x = F.max_pool2d(F.relu(self.conv1(x)),2) # 输入(3,32,32)-> (6,28,28)-> 输出(6,14,14)x = F.max_pool2d(F.relu(self.conv2(x)),2) # 输入(6,14,14)-> (16,10,10)-> 输出(16,5,5)x = x.view(x.shape[0],-1) # -->output (1,16*5*5) * (16*5*5,120) = (1,120)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x) # 不需要softmax,交叉熵损失函数里面有return xdef predict(img):transform = transforms.Compose([transforms.Resize((32,32)),transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])classes = ('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')net = LeNet()net.load_state_dict(torch.load('LeNet.pth')) # 加载网络训练的参数im = Image.open(img)im = transform(im) # 图像维度 (C,H,W)im = torch.unsqueeze(im,dim = 0) # 增加维度,第0维增加1 ,维度(1,C,H,W)with torch.no_grad():outputs = net(im)predict = torch.max(outputs,dim = 1)[1].data.numpy()pro = torch.softmax(outputs, dim=1)rate = pro.max().numpy() * 100return classes[int(predict)] , str(rate) + '%'
这里不对LeNet网络的搭建和训练做介绍,具体的可以看之前的文章:
pytorch 搭建 LeNet 网络对 CIFAR-10 图片分类
因为网络训练好了之后,只需要将网络和权重参数保存就好了。
然后为了方便调用,将预测的部分封装成了一个predict函数
main里面存放的是web的部分,代码为:
import streamlit as st
from PIL import Image
from predict import predictst.set_option('deprecation.showfileUploaderEncoding', False)st.title("CIFAR10 Image Classification App")
st.write("")
st.write("")file_up = st.file_uploader("Upload an image") # 上传图片if file_up is None:image = 'image/dog.jpg' # 默认读取的图像img = Image.open(image)st.image(img, caption='Uploaded Image.', use_column_width=True) # 显示图像st.write("")st.write("Just a second...")labels, ret = predict(image) # 预测图像st.success('successful prediction')st.write("Prediction ", labels, ", Score: ", ret) # 给出预测结果st.write("")else:image = Image.open(file_up) # 从上传图像里面取出图像st.image(image, caption='Uploaded Image.', use_column_width=True) # 显示图像st.write("")st.write("Just a second...")labels,ret = predict(file_up) # 预测图像st.success('successful prediction')st.write("Prediction ", labels, ", Score: ", ret)st.write("")
可以直接拷贝就行了,将对应的图片改一下就行。
需要注意的地方是下面

这里image 存放的是图片的路径,img是打开的图片,所以显示的时候传入的是img图片
而预测的时候,传入的是图片的路径image
然后运行正确的时候,是这样的

将command 下面的代码拷贝到cmd里面运行即可

这里出现了一个问题,暂时还没有解决,打开后会出现找不到image文件夹

因为 streamlit 没有学过,所以这个问题不知道为啥,但是可以通过更改路径的方式解决
只需要将image 里面的相对路径,改成绝对路径就可以了
- 要把默认读取的image文件夹里面dog换成绝对路径
- 然后将predict预测里面读取网络参数LeNet.pth 换成绝对路径
这样运行出来的是对的
本地web搭建成功之后就可以部署到cloud上了
首先进入streamlit cloud 网站,然后用github登录
然后直接点New App创建就行了
这里需要先将本地搭建好web代码,上传到github上,这样New App的时候就会自动关联。
因为刚刚搭建本地web的时候,改成绝对路径才可以,上传的时候要改回相对路径。
注意第三个Main file path 在这里是main.py

最后建立好的就是这个样子

将网站的链接copy下来,就可以让别人访问了
