Compare commits

...

4 Commits

Author SHA1 Message Date
gpl 2a7b22261d doc
2 years ago
gpl 0020179263 flask
2 years ago
gpl a24a14ec18 flask
2 years ago
gpl 646cb3884c DL
2 years ago

Binary file not shown.

Binary file not shown.

@ -0,0 +1,81 @@
'''
数据样本分析
画出数据量条形图
画出图像分辨率散点图
'''
import os
import PIL.Image as Image
import matplotlib.pyplot as plt
import numpy as np
def plot_resolution(dataset_root_path):
img_size_list = [] # 存储图片长宽数据
for root, dirs, files in os.walk(dataset_root_path):
for file_i in files:
file_i_full_path = os.path.join(root, file_i)
img_i = Image.open(file_i_full_path)
img_i_size = img_i.size # 获取单张图像的长宽
img_size_list.append(img_i_size)
print(img_size_list) #
width_list = [img_size_list[i][0] for i in range(len(img_size_list))]#提取所有图片的宽度信息,构建一个新的列表
height_list = [img_size_list[i][1] for i in range(len(img_size_list))]#提取所有图片的高度信息,构建一个新的列表
# print(width_list) # 640
# print(height_list) # 346
plt.rcParams["font.sans-serif"] = ["SimHei"] # 设置中文字体
plt.rcParams["font.size"] = 8
plt.rcParams["axes.unicode_minus"] = False # 该语句解决图像中的“-”负号的乱码问题
plt.scatter(width_list, height_list, s=1)
plt.xlabel("")
plt.ylabel("")
plt.title("图像宽高分布")
plt.show()
# 画出条形图
def plot_bar(dataset_root_path):
file_name_list = []
file_num_list = []
for root, dirs, files in os.walk(dataset_root_path):
if len(dirs) != 0:
for dir_i in dirs:
file_name_list.append(dir_i)
file_num_list.append(len(files))
file_num_list = file_num_list[1:]
# 求均值,并把均值以横线形式显示出来
mean = np.mean(file_num_list)
print("mean = ", mean)
bar_positions = np.arange(len(file_name_list))
fig, ax = plt.subplots() # 定义画的区间和子画
ax.bar(bar_positions, file_num_list, 0.5) # 画柱图,参数:柱间的距离,柱的值,柱的宽度
ax.plot(bar_positions, [mean for i in bar_positions], color="red") # 显示平均值
plt.rcParams["font.sans-serif"] = ["SimHei"] # 设置中文字体
plt.rcParams["font.size"] = 8
plt.rcParams["axes.unicode_minus"] = False # 该语句解决图像中的“-”负号的乱码问题
ax.set_xticks(bar_positions) # 设置x轴的刻度
ax.set_xticklabels(file_name_list, rotation=90) # 设置x轴的标签
ax.set_ylabel("类别数量")
ax.set_title("数据分布图")
plt.show()
if __name__ == '__main__':
dataset_root_path = "dataset"
plot_resolution(dataset_root_path)
# plot_bar(dataset_root_path)

@ -0,0 +1,42 @@
from PIL import Image
import os
dataset_root_path = "dataset"
min = 200 # 短边
max = 2000 # 长边
ratio = 0.5 # 短边 / 长边
delete_list = [] # 所有图片的长宽数据
for root,dirs,files in os.walk(dataset_root_path):
for file_i in files:
file_i_full_path = os.path.join(root, file_i)#构建当前文件的完整路径
img_i = Image.open(file_i_full_path)#将其加载为一个图像对象
img_i_size = img_i.size # 获取单张图像的长宽
# 删除单边过短的图片
if img_i_size[0]<min or img_i_size[1]<min:
print(file_i_full_path, " 不满足要求")
delete_list.append(file_i_full_path)
# 删除单边过长的图片
if img_i_size[0] > max or img_i_size[1] > max:
print(file_i_full_path, " 不满足要求")
delete_list.append(file_i_full_path)
# 删除宽高比例不当的图片
long = img_i_size[0] if img_i_size[0] > img_i_size[1] else img_i_size[1]
short = img_i_size[0] if img_i_size[0] < img_i_size[1] else img_i_size[1]
if short / long < ratio:
print(file_i_full_path, " 不满足要求",img_i_size[0],img_i_size[1])
delete_list.append(file_i_full_path)
# print(delete_list)
for file_i in delete_list:
try:
print("正在删除",file_i)
os.remove(file_i)
except:
pass

@ -0,0 +1,49 @@
'''
使用翻转进行数据增强
'''
import os
import cv2
import numpy as np
# 水平翻转
def Horizontal(image):
return cv2.flip(image,1,dst=None) #水平镜像
# 垂直翻转
def Vertical(image):
return cv2.flip(image,0,dst=None) #垂直镜像
if __name__ == '__main__':
from_root = r"dataset"
save_root = r"enhance_dataset"
threshold = 200
for a,b,c in os.walk(from_root):
for file_i in c:
file_i_path = os.path.join(a,file_i)
split = os.path.split(file_i_path)
dir_loc = os.path.split(split[0])[1]
save_path = os.path.join(save_root,dir_loc)
print(file_i_path)
print(save_path)
if os.path.isdir(save_path) == False:
os.makedirs(save_path)
img_i = cv2.imdecode(np.fromfile(file_i_path, dtype=np.uint8),-1) # 读取图片
cv2.imencode('.jpg', img_i)[1].tofile(os.path.join(save_path, file_i[:-5] + "_original.jpg")) # 保存图片
if len(c) < threshold:
img_horizontal = Horizontal(img_i)
cv2.imencode('.jpg', img_horizontal)[1].tofile(os.path.join(save_path, file_i[:-5] + "_horizontal.jpg")) # 保存图片
img_vertical = Vertical(img_i)
cv2.imencode('.jpg', img_vertical)[1].tofile(os.path.join(save_path, file_i[:-5] + "_vertical.jpg")) # 保存图片
else:
pass

@ -0,0 +1,23 @@
import os
import random
img_root = r"enhance_dataset"
threshold = 300
for a,b,c in os.walk(img_root):
if len(c) > threshold:
delete_list = []
for file_i in c:
file_i_full_path = os.path.join(a,file_i)
delete_list.append(file_i_full_path)
random.shuffle(delete_list)
print(delete_list)
delete_list = delete_list[threshold:]
for file_delete_i in delete_list:
os.remove(file_delete_i)
print("将会删除",file_delete_i)

@ -0,0 +1,28 @@
from torchvision.datasets import ImageFolder
import torch
from torchvision import transforms as T
from tqdm import tqdm
transform = T.Compose([
T.RandomResizedCrop(224),
T.ToTensor(),
])
def getStat(train_data):
train_loader = torch.utils.data.DataLoader(
train_data, batch_size=1, shuffle=False, num_workers=0, pin_memory=True)
mean = torch.zeros(3)
std = torch.zeros(3)
for X, _ in tqdm(train_loader):
for d in range(3):
mean[d] += X[:, d, :, :].mean() # N, C, H ,W
std[d] += X[:, d, :, :].std()
mean.div_(len(train_data))
std.div_(len(train_data))
return list(mean.numpy()), list(std.numpy())
if __name__ == '__main__':
train_dataset = ImageFolder(root=r'enhance_dataset', transform=transform)
print(getStat(train_dataset))

@ -0,0 +1,40 @@
import os
import random
train_ratio = 0.9 #训练集比例
test_ratio = 1-train_ratio #测试集比例
rootdata = r"dataset"
train_list, test_list = [],[]
class_flag = -1#初始类别标签
t=1
for a,b,c in os.walk(rootdata):#目录路径,子目录名,文件名
# if t==1:
# # print(a)
# print(b)
# print(len(c))
# t=-1
for i in range(0, int(len(c)*train_ratio)):#根据训练集比例确定训练集的文件数量
train_data = os.path.join(a, c[i])+'\t'+str(class_flag)+'\n'
# print('666'+train_data)
train_list.append(train_data)
for i in range(int(len(c) * train_ratio), len(c)):
test_data = os.path.join(a, c[i]) + '\t' + str(class_flag)+'\n'
test_list.append(test_data)
class_flag += 1
random.shuffle(train_list)#随机打乱训练集列表 train_list 中的元素顺序
random.shuffle(test_list)
with open('train.txt','w',encoding='UTF-8') as f:
for train_img in train_list:
f.write(str(train_img))#将训练集中的文件路径和类别标签写入文件 'train.txt',将其转换为字符串形式并写入文件。
with open('test.txt','w',encoding='UTF-8') as f:
for test_img in test_list:
f.write(test_img)

@ -0,0 +1,124 @@
import time
import torch
from torch import nn
from torch.utils.data import DataLoader
from utils import LoadData,WriteData
from torchvision.models import resnet18
def train(dataloader, model, loss_fn, optimizer,device):
size = len(dataloader.dataset)
avg_loss = 0
# 从数据加载器中读取batch一次读取多少张即批次数X(图片数据)y图片真实标签
for batch, (X, y) in enumerate(dataloader):#固定格式batch第几批数据不是批次大小Xy数值用括号
# 将数据存到显卡
X, y = X.to(device), y.to(device)
# 得到预测的结果pred
pred = model(X)
loss = loss_fn(pred, y)
avg_loss += loss
# 反向传播,更新模型参数
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 每训练10次输出一次当前信息
if batch % 10 == 0:
loss, current = loss.item(), batch * len(X)
print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]")
# 当一个epoch完了后返回平均 loss
avg_loss /= size
avg_loss = avg_loss.detach().cpu().numpy()
return avg_loss
def validate(dataloader, model, loss_fn, device):
size = len(dataloader.dataset)
# 将模型转为验证模式
model.eval()
# 初始化test_loss 和 correct 用来统计每次的误差
test_loss, correct = 0, 0
# 测试时模型参数不用更新所以no_gard()
# 非训练, 推理期用到
with torch.no_grad():
# 加载数据加载器得到里面的X图片数据和y(真实标签)
for X, y in dataloader:
# 将数据转到GPU
X, y = X.to(device), y.to(device)
# 将图片传入到模型当中就得到预测的值pred
pred = model(X)
# 计算预测值pred和真实值y的差距
test_loss += loss_fn(pred, y).item()
# 统计预测正确的个数(针对分类)
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
test_loss /= size
correct /= size
print(f"correct = {correct}, Test Error: \n Accuracy: {(100 * correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
return correct, test_loss
if __name__=='__main__':
batch_size = 20#设置批次大小,每次训练时用于更新模型的样本数量
# # 给训练集和测试集分别创建一个数据集加载器
train_data = LoadData("train.txt", True)#true为训练集
valid_data = LoadData("test.txt", False)#false为测试集
#批量加载数据num_workers并行工作线程数
train_dataloader = DataLoader(dataset=train_data, num_workers=4, pin_memory=True, batch_size=batch_size, shuffle=True)
valid_dataloader = DataLoader(dataset=valid_data, num_workers=4, pin_memory=True, batch_size=batch_size)
# 如果显卡可用,则用显卡进行训练
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using {device} device")
#创建一个ResNet-18模型实例
model = resnet18(num_classes=55)
model = model.to(device)
state_dict = torch.load(r"output/resnet18_no_pretrain_best.pth")
# print("state_dict = ",state_dict)
model.load_state_dict(state_dict)
# 定义损失函数,计算相差多少,交叉熵,
loss_fn = nn.CrossEntropyLoss()
# 定义优化器,随机梯度下降法
learning_rate = 1e-3
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
#设置训练总轮数初始化变量loss用于跟踪最低的平均损失值
epochs = 50
loss_ = 10
save_root = "output/"
for t in range(epochs):
print(f"Epoch {t + 1}\n-------------------------------")
time_start = time.time()
avg_loss = train(train_dataloader, model, loss_fn, optimizer, device)
time_end = time.time()
print(f"train time: {(time_end - time_start)}")
# (dataloader, model, loss_fn, device)jif
#调用 validate 函数进行验证集上的性能评估,计算验证集的准确率和损失
val_accuracy, val_loss = validate(valid_dataloader, model,loss_fn, device)
# 将训练和验证的结果写入文件写入数据
WriteData(save_root + "resnet18_no_pretrain.txt",
"epoch", t,#epoch数
"train_loss", avg_loss,#训练损失
"val_loss", val_loss,#验证损失
"val_accuracy", val_accuracy)#验证准确率
#如果当前epoch是5的倍数保存模型参数文件以便后续恢复或继续训练。
if t % 5 == 0:
torch.save(model.state_dict(), save_root + "resnet18_no_pretrain_epoch" + str(t) + "_loss_" + str(avg_loss) + ".pth")
#每个epoch都保存模型参数文件以便后续分析和恢复。
torch.save(model.state_dict(), save_root + "resnet18_no_pretrain_last.pth")
#如果当前epoch的平均损失小于 loss_则更新 loss_ 为当前损失值,并保存当前模型参数作为最佳模型。
if avg_loss < loss_:
loss_ = avg_loss
torch.save(model.state_dict(), save_root + "resnet18_no_pretrain_best.pth")
torch.cuda.empty_cache()

@ -0,0 +1,77 @@
'''
单图测试
'''
import torch
from torchvision.models import resnet18
from PIL import Image
import torchvision.transforms as transforms
import os
transform_BZ= transforms.Normalize(
mean=[0.46402064, 0.45047238, 0.37801373], # 取决于数据集
std=[0.2007732, 0.196271, 0.19854763]
)
def padding_black(img,img_size = 512): # 如果尺寸太小可以扩充
w, h = img.size
scale = img_size / max(w, h)
img_fg = img.resize([int(x) for x in [w * scale, h * scale]])
size_fg = img_fg.size
size_bg = img_size
img_bg = Image.new("RGB", (size_bg, size_bg))
img_bg.paste(img_fg, ((size_bg - size_fg[0]) // 2,
(size_bg - size_fg[1]) // 2))
img = img_bg
return img
if __name__=='__main__':
img_path = r'enhance_dataset/有害垃圾_药片/img_药片_7_vertical.jpg'
#创建了一个图像转换操作的组合,该组合将应用于输入图像。
#这些操作包括将图像调整大小为512x512像素将图像转换为张量
val_tf = transforms.Compose([ ##简单把图片压缩了变成Tensor模式
transforms.Resize(512),
transforms.ToTensor(),
transform_BZ # 标准化操作
])
# 如果显卡可用,则用显卡进行训练
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using {device} device")
finetune_net = resnet18(num_classes=55).to(device)
#创建ResNet-18深度学习模型
#分类成55个不同的类别
state_dict = torch.load(r"output/resnet18_no_pretrain_best.pth")
# print("state_dict = ",state_dict)
finetune_net.load_state_dict(state_dict)
#最后,这一行将模型设置为评估模式,这表示模型将在推理模式下运行,不进行梯度计算。
#这对于推断和预测任务非常有用,因为在这些情况下不需要计算梯度。模型在评估模式下运行时,通常更加高效。
finetune_net.eval()
with torch.no_grad():
# finetune_net.to(device)
img = Image.open(img_path) # 打开图片
img = img.convert('RGB') # 转换为RGB 格式
img = padding_black(img)
img = val_tf(img)
img_tensor = torch.unsqueeze(img, 0) # N,C,H,W, ; C,H,W
img_tensor = img_tensor.to(device)
result = finetune_net(img_tensor)
# print("result = ",result.argmax(1))
id = result.argmax(1).item()
file_list=[]
for a,b,c in os.walk("dataset"):
if len(b) != 0:
file_list = b
print("预测结果为:",file_list[id])

@ -0,0 +1,135 @@
'''
加载pytorch自带的模型从头训练自己的数据
'''
import time
import torch
from torch import nn
from torch.utils.data import DataLoader
from utils import LoadData,WriteData
from torchvision.models import resnet18, resnet34,resnet50, resnet101, resnet152 ,mobilenet_v2 # ResNet系列
def train(dataloader, model, loss_fn, optimizer,device):
size = len(dataloader.dataset)
avg_loss = 0
# 从数据加载器中读取batch一次读取多少张即批次数X(图片数据)y图片真实标签
for batch, (X, y) in enumerate(dataloader):#固定格式batch第几批数据不是批次大小Xy数值用括号
# print(size)
# 将数据存到显卡
X, y = X.to(device), y.to(device)
# 得到预测的结果pred
pred = model(X)
loss = loss_fn(pred, y)
avg_loss += loss
# 反向传播,更新模型参数
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 每训练10次输出一次当前信息
if batch % 10 == 0:
loss, current = loss.item(), batch * len(X)
print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]")
# 当一个epoch完了后返回平均 loss
avg_loss /= size
avg_loss = avg_loss.detach().cpu().numpy()
return avg_loss
def validate(dataloader, model, loss_fn, device):
size = len(dataloader.dataset)
# 将模型转为验证模式
model.eval()
# 初始化test_loss 和 correct 用来统计每次的误差
test_loss, correct = 0, 0
# 测试时模型参数不用更新所以no_gard()
# 非训练, 推理期用到
with torch.no_grad():
# 加载数据加载器得到里面的X图片数据和y(真实标签)
for X, y in dataloader:
# 将数据转到GPU
X, y = X.to(device), y.to(device)
# 将图片传入到模型当中就得到预测的值pred
pred = model(X)
# 计算预测值pred和真实值y的差距
test_loss += loss_fn(pred, y).item()
# 统计预测正确的个数(针对分类)
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
test_loss /= size
correct /= size
print(f"correct = {correct}, Test Error: \n Accuracy: {(100 * correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
return correct, test_loss
if __name__=='__main__':
batch_size = 32
# # 给训练集和测试集分别创建一个数据集加载器
train_data = LoadData("train.txt", True)
valid_data = LoadData("test.txt", False)
train_dataloader = DataLoader(dataset=train_data, num_workers=4, pin_memory=True, batch_size=batch_size, shuffle=True)
valid_dataloader = DataLoader(dataset=valid_data, num_workers=4, pin_memory=True, batch_size=batch_size)
# 如果显卡可用,则用显卡进行训练
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using {device} device")
finetune_net = resnet18(pretrained=True)
finetune_net.fc = nn.Linear(finetune_net.fc.in_features, 55)
nn.init.xavier_normal_(finetune_net.fc.weight)
parms_1x = [value for name, value in finetune_net.named_parameters()
if name not in ["fc.weight", "fc.bias"]]
# 最后一层10倍学习率
parms_10x = [value for name, value in finetune_net.named_parameters()
if name in ["fc.weight", "fc.bias"]]
finetune_net = finetune_net.to(device)
# 定义损失函数,计算相差多少,交叉熵,
loss_fn = nn.CrossEntropyLoss()
# 定义优化器,用来训练时候优化模型参数,随机梯度下降法
learning_rate = 1e-4
optimizer = torch.optim.Adam([
{
'params': parms_1x
},
{
'params': parms_10x,
'lr': learning_rate * 10
}], lr=learning_rate)
epochs = 50
loss_ = 10
save_root = "output/"
for t in range(epochs):
print(f"Epoch {t + 1}\n-------------------------------")
time_start = time.time()
avg_loss = train(train_dataloader, finetune_net, loss_fn, optimizer, device)
time_end = time.time()
print(f"train time: {(time_end - time_start)}")
val_accuracy, val_loss = validate(valid_dataloader, finetune_net,loss_fn, device)
# 写入数据
WriteData(save_root + "resnet18_e.txt",
"epoch", t,
"train_loss", avg_loss,
"val_loss", val_loss,
"val_accuracy", val_accuracy)
if t % 5 == 0:
torch.save(finetune_net.state_dict(), save_root + "resnet18_e_epoch" + str(t) + "_loss_" + str(avg_loss) + ".pth")
torch.save(finetune_net.state_dict(), save_root + "resnet18_e_last.pth")
if avg_loss < loss_:
loss_ = avg_loss
torch.save(finetune_net.state_dict(), save_root + "resnet18_e_best.pth")

@ -0,0 +1,74 @@
# -*-coding:utf-8-*-
from matplotlib import pyplot as plt
import numpy as np
def ReadData(data_loc):
epoch_list = []
train_loss_list = []
test_loss_list = []
test_accuracy_list = []
# open(data_loc,"r").readlines()
with open(data_loc, "r") as f:
linedata = f.readlines()
for line_i in linedata:
data = line_i.split('\t')
print("data = ", data)
epoch_i , train_loss_i,test_loss_i,test_accuracy_i =data[1], data[3],data[5],data[7]
epoch_list.append(int(epoch_i))
train_loss_list.append(float(train_loss_i))
test_loss_list.append(float(test_loss_i))
test_accuracy_list.append(float(test_accuracy_i))
# print(epoch_list)
# print(train_loss_list)
# print(test_loss_list)
# print(test_accuracy_list)
return epoch_list, train_loss_list ,test_loss_list,test_accuracy_list
def DrawLoss(train_loss_list,train_loss_list_2):
plt.style.use('dark_background')
plt.title("Loss")
plt.xlabel("epoch")
plt.ylabel("loss")
train_loss_list = train_loss_list[:10]
epoch_list = [i for i in range(len(train_loss_list))]
p1, = plt.plot(epoch_list, train_loss_list, linewidth=3)
p2, = plt.plot(epoch_list, train_loss_list_2, linewidth=3)
plt.legend([p1, p2], ["with pretrain", "no pretrain"])
plt.show()
def DrawAcc(train_loss_list,train_loss_list_2):
plt.style.use('dark_background')
plt.title("Accuracy")
plt.xlabel("epoch")
plt.ylabel("accuracy")
train_loss_list = train_loss_list[:10]
epoch_list = [i for i in range(len(train_loss_list))]
p1, = plt.plot(epoch_list, train_loss_list, linewidth=3)
p2, = plt.plot(epoch_list, train_loss_list_2, linewidth=3)
plt.legend([p1, p2], ["with pretrain", "no pretrain"])
plt.show()
if __name__ == '__main__':
data_1_loc = "output/resnet18.txt"
data_2_loc = "output/resnet18_no_pretrain.txt"
_, train_loss_list ,test_loss_list,test_accuracy_list = ReadData(data_1_loc)
_, train_loss_list_2 ,test_loss_list_2,test_accuracy_list_2 = ReadData(data_2_loc)
DrawLoss(train_loss_list,train_loss_list_2)
DrawAcc(test_accuracy_list,test_accuracy_list_2)

@ -0,0 +1,75 @@
import torch
from torch.utils.data import DataLoader
from utils import LoadData,WriteData
import torch.nn as nn
from torchvision.models import resnet18
from tqdm import tqdm
import os
import pandas as pd
def test(dataloader, model, device):
pred_list = []
# 将模型转为验证模式
model.eval()
# 测试时模型参数不用更新所以no_gard()
# 非训练, 推理期用到
with torch.no_grad():
# 加载数据加载器得到里面的X图片数据和y(真实标签)
for X, y in tqdm(dataloader):
# 将数据转到GPU
X, y = X.to(device), y.to(device)
# 将图片传入到模型当中就得到预测的值pred
pred = model(X)
pred_softmax = torch.softmax(pred, 1).cpu().numpy()
pred_list.append(pred_softmax.tolist()[0])
return pred_list
if __name__=='__main__':
batch_size = 1
# # 给训练集和测试集分别创建一个数据集加载器
test_data = LoadData("test.txt", False)
test_dataloader = DataLoader(dataset=test_data, num_workers=4, pin_memory=True, batch_size=batch_size)
# 如果显卡可用,则用显卡进行训练
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using {device} device")
model = resnet18(num_classes=55)
model.load_state_dict(torch.load("output/resnet18_e_best.pth"))
model.to(device)
# 定义损失函数,计算相差多少,交叉熵,
# loss_fn = nn.CrossEntropyLoss()
'''
获取结果
'''
# 获取模型输出
pred_list = test(test_dataloader, model,device)
print("pred_list = ", pred_list)
'''
获取文件夹列表
'''
file_name_list = []
data_root = r"enhance_dataset"
for a,b,c in os.walk(data_root):
if len(b) != 0:
print(b)
file_name_list = b
df_pred = pd.DataFrame(data=pred_list, columns=file_name_list)
print(df_pred)
df_pred.to_csv('pred_result.csv', encoding='gbk', index=False)

@ -0,0 +1,78 @@
from sklearn.metrics import * # pip install scikit-learn
import matplotlib.pyplot as plt # pip install matplotlib
import pandas as pd # pip install pandas
import os
'''
读取数据
需要读取模型输出的标签predict_label以及原本的标签true_label
'''
target_loc = "./test.txt" # 真实标签所在的文件
target_data = pd.read_csv(target_loc, sep="\t", names=["loc","type"])
true_label = [i for i in target_data["type"]]
predict_loc = "./pred_result.csv" # 3.ModelEvaluate.py生成的文件
predict_data = pd.read_csv(predict_loc,encoding="GBK")#,index_col=0)
predict_label = predict_data.to_numpy().argmax(axis=1)
predict_score = predict_data.to_numpy().max(axis=1)
'''
常用指标精度查准率召回率F1-Score
'''
# 精度,准确率, 预测正确的占所有样本种的比例
accuracy = accuracy_score(true_label, predict_label)
print("精度: ",accuracy)
# 查准率P准确率precision(查准率)=TP/(TP+FP)
precision = precision_score(true_label, predict_label, labels=None, pos_label=1, average='macro') # 'micro', 'macro', 'weighted'
print("查准率P: ",precision)
# 查全率R召回率原本为对的预测正确的比例recall(查全率)=TP/(TP+FN)
recall = recall_score(true_label, predict_label, average='macro') # 'micro', 'macro', 'weighted'
print("召回率: ",recall)
# F1-Score
f1 = f1_score(true_label, predict_label, average='macro') # 'micro', 'macro', 'weighted'
print("F1 Score: ",f1)
'''
混淆矩阵
'''
label_names = []
data_root = r"./enhance_dataset"
for a,b,c in os.walk(data_root):
if len(b) != 0:
print(b)
label_names = b
confusion = confusion_matrix(true_label, predict_label, labels=[i for i in range(len(label_names))])
plt.matshow(confusion, cmap=plt.cm.Oranges) # Greens, Blues, Oranges, Reds
plt.rcParams["font.sans-serif"] = ["SimHei"] # 设置中文字体
plt.rcParams["font.size"] = 8
plt.rcParams["axes.unicode_minus"] = False # 该语句解决图像中的“-”负号的乱码问题
plt.colorbar()
for i in range(len(confusion)):
for j in range(len(confusion)):
plt.annotate(confusion[j,i], xy=(i, j), horizontalalignment='center', verticalalignment='center')
plt.ylabel('True label')
plt.xlabel('Predicted label')
plt.xticks(range(len(label_names)), label_names,rotation=270)
plt.yticks(range(len(label_names)), label_names)
plt.title("Confusion Matrix")
plt.show()

@ -0,0 +1,139 @@
import os
import requests
import json
import io
from flask import Flask, request
from urllib.parse import urlparse
from urllib.request import urlopen
from alibabacloud_imagerecog20190930.client import Client
from alibabacloud_imagerecog20190930.models import ClassifyingRubbishAdvanceRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions
import mysql.connector
from mysql.connector import Error
def insert_feedback(feedbackInfo,feedbackType):
try:
# 弹出文件选择对话框,选择要插入的图片文件
file_path = r'C:\Users\admin\Desktop\garbage.jpg'
# 读取图片文件并转换为字节数组
with open(file_path, "rb") as f:
image_data = f.read()
# files = {'file': open(file_path, 'rb')}
# 建立数据库连接
database_name = "garbage"
username = "root"
password = "root"
host = '127.0.0.1'
port = 3306
connection = mysql.connector.connect(
host=host,
port=port,
user=username,
password=password,
database=database_name
)
cursor = connection.cursor(prepared=True)
# 插入用户反馈信息数据到数据库
sql = "INSERT INTO feedback (feedbackInfo, feedbackType, feedbackPhoto) VALUES (%s, %s, %s)"
cursor.execute(sql, (feedbackInfo, feedbackType, image_data))
connection.commit()
print("信息上传成功!")
if cursor is not None:
cursor.close()
except FileNotFoundError as e:
print("未选择文件。")
except (Error, IOError) as e:
print(e)
finally:
if 'connection' in locals():
if connection.is_connected():
connection.close()
def recognition(url):
config = Config(
access_key_id='LTAI5tHR7LEUHziRSK4TLSnM',
access_key_secret='uq7sZKEixU5osl54GVzcj4Yb1Yb7XA',
endpoint='imagerecog.cn-shanghai.aliyuncs.com',
region_id='cn-shanghai'
)
# img = open(r'tmp.jpg', 'rb')
img = io.BytesIO(urlopen(url).read())
classifying_rubbish_request = ClassifyingRubbishAdvanceRequest()
classifying_rubbish_request.image_urlobject = img
runtime = RuntimeOptions()
try:
client = Client(config)
response = client.classifying_rubbish_advance(classifying_rubbish_request, runtime)
# result = response.body
category = response.body.data.elements[0].category;
return category
# return JsonResponse({'result': result})
except Exception as error:
print(error)
# print(error.code)
# return JsonResponse({'error': str(error)}, status=500)
#垃圾识别接口
app = Flask(__name__)
# 保存上传文件的目标目录
UPLOAD_FOLDER = 'C:/Users/admin/Desktop'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
@app.route('/upload_image', methods=['POST'])
def upload_image():
if 'file' not in request.files:
return 'No file part'
file = request.files['file']
if file.filename == '':
return 'No selected file'
if file:
# 保存上传的文件到指定目录
file.save(os.path.join(app.config['UPLOAD_FOLDER'], 'garbage.jpg'))
a = recognition(os.path.join(app.config['UPLOAD_FOLDER'], 'garbage.jpg'))
print(a)
return a
@app.route('/upload_text', methods=['POST'])
def upload_text():
data = request.data.decode('utf-8') # 解码接收到的数据
lst = data.split('|')
str = ''
if lst[0][0]:
str+='用户体验'
if lst[0][1]:
if len(str)>0:
str+=','
str+='识别偏差'
if lst[0][2]:
if len(str)>0:
str+=','
str+='功能建议'
if lst[0][3]:
if len(str)>0:
str+=','
str+='分类扩充'
if lst[0][4]:
if len(str)>0:
str+=','
str+='其他问题'
if lst[0][5]:
if len(str)>0:
str+=','
str+='好评推荐'
insert_feedback(str,lst[1])
return "Successfully"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Loading…
Cancel
Save