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

昆山城市建设投资有限公司网站wordpress 全部设置

昆山城市建设投资有限公司网站,wordpress 全部设置,上海环球金融中心多少层,个人网站设计企业目录 一、项目简介 二、模型训练验证保存 三、模型测试保存csv文件 四、单张图片预测 五、模型评估 六、ONNX导出 七、ONNX推理 八、网络结构与数据增强可视化 上篇我介绍了具体步骤#xff0c;今天就以我实际开发的一个具体项目来讲#xff1a; 一、项目简介 苯人的…目录 一、项目简介 二、模型训练验证保存 三、模型测试保存csv文件 四、单张图片预测 五、模型评估 六、ONNX导出 七、ONNX推理 八、网络结构与数据增强可视化 上篇我介绍了具体步骤今天就以我实际开发的一个具体项目来讲 一、项目简介 苯人的项目是基于CNN实现香蕉成熟度的小颗粒度分类针对六种不同状态新鲜成熟的、新鲜未熟的、成熟的、腐烂的、过于成熟的、生的进行高精度视觉识别。由于香蕉的成熟度变化主要体现在颜色渐变、斑点分布及表皮纹理等细微差异上传统图像处理方法难以准确区分。因此本项目通过构建深层CNN模型利用卷积层的局部特征提取能力捕捉香蕉表皮的细微变化并结合高阶特征融合技术提升分类精度。 数据集长这样 苯人是在 https://universe.roboflow.com/ 这个网站上下载的kaggle我自己觉得不好用其实是看不来总之数据集有了再说一嘴苯人是引用的 ResNet18网络模型接下来就开始写代码吧 二、模型训练验证保存 这里我就不像上篇那样这么详细了主要是看流程 import torch import torch.nn as nn from torchvision import transforms from torchvision.datasets import ImageFolder from torch.utils.data import DataLoader from torchvision.models import resnet18 #导入网络结构 from torch import optim# 模型保存 last_model_path ./model/last.pth best_model_path ./model/best.pth#数据预处理 train_transforms transforms.Compose([transforms.Resize((256, 256)), # 先稍微放大点transforms.RandomCrop(224), # 随机裁剪出 224x224transforms.RandomHorizontalFlip(p0.5), # 左右翻转transforms.RandomRotation(degrees15), # 随机旋转 ±15°transforms.ColorJitter(brightness0.2, # 明亮度contrast0.2, # 对比度saturation0.2, # 饱和度hue0.1), # 色调transforms.ToTensor(),transforms.Normalize(mean[0.485, 0.456, 0.406], # ImageNet均值std[0.229, 0.224, 0.225]) # ImageNet标准差 ]) val_transforms transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize(mean[0.485, 0.456, 0.406],std[0.229, 0.224, 0.225]) ])#加载数据集 train_dataset ImageFolder(root./Bananas/train, transform train_transforms) valid_dataset ImageFolder(root./Bananas/valid, transform val_transforms)#数据加载器 train_loader DataLoader(train_dataset, batch_size64, shuffleTrue) valid_loader DataLoader(valid_dataset, batch_size64, shuffleFalse)#迁移模型结构 model resnet18(pretrained True) in_features model.fc.in_features #动态获得输入 model.fc nn.Linear(in_features, 6) #改成6分类 device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device)# 优化解冻最后两层和fc层更有学习能力 for name, param in model.named_parameters():if layer4 in name or fc in name:param.requires_grad Trueelse:param.requires_grad False#再用 filter 筛选需要梯度更新的参数 param_grad_true filter(lambda x:x.requires_grad, model.parameters())#实例化损失函数对象 criterion nn.CrossEntropyLoss() #优化器 这里使用AdamW optimizer optim.AdamW(param_grad_true, lr1e-3, weight_decay0.01) # 优化添加学习率调度器 scheduler optim.lr_scheduler.ReduceLROnPlateau(optimizer, max, patience5, factor0.5, verboseTrue)#开始训练每10个轮次验证一次 def train(model, train_loader, valid_loader, epochs, validate_every10):import os# 创建模型保存目录os.makedirs(./model, exist_okTrue)model.train()best_val_acc 0 #初始化最优准确率# 优化增加早停机制early_stopping_patience 10no_improve_epochs 0for epoch in range(epochs):running_loss 0 #初始化每轮训练的损失correct 0 #初始化正确数与总个数total 0for images, labels in train_loader:images, labels images.to(device), labels.to(device)output model(images) #得到预测值loss criterion(output, labels) #计算损失optimizer.zero_grad() #梯度清零loss.backward() #反向传播optimizer.step() #根据梯度更新参数running_loss loss.item() #当前epoch的总损失pred torch.argmax(output, dim1) #拿到当前图片预测是最大值的索引下标当做类别total labels.size(0)correct (pred labels).sum().item()train_acc correct/total * 100 #训练准确率print(f[Epoch {epoch 1}/{epochs}] Loss: {running_loss:.4f}, Accuracy: {train_acc:.2f}%)#验证部分if (epoch 1) % validate_every 0: #每10轮验证一次val_loss 0val_total 0val_correct 0model.eval()with torch.no_grad(): #逻辑与训练函数差不多for val_images, val_labels in valid_loader:val_images, val_labels val_images.to(device), val_labels.to(device)val_output model(val_images)val_loss (criterion(val_output, val_labels)).item()val_pred torch.argmax(val_output, dim1)val_total val_labels.size(0)val_correct (val_pred val_labels).sum().item()val_acc val_correct/val_total *100 #验证准确率# 优化根据验证准确率调整学习率scheduler.step(val_acc)print(f[Epoch {epoch 1}/{epochs}] Loss: {running_loss:.4f}, Accuracy: {train_acc:.2f}%)#保存最优模型参数if val_acc best_val_acc:best_val_acc val_acctorch.save(model.state_dict(), best_model_path)print(f保存了当前最优模型验证正确率{val_acc:.2f}%)# 优化早停法else:no_improve_epochs 1if no_improve_epochs early_stopping_patience:print(f验证准确率连续{early_stopping_patience}轮没有提升提前停止训练)break# 保存最近一次模型参数torch.save(model.state_dict(), last_model_path)model.train()train(model, train_loader, valid_loader, epochs50) #训练50次看看主要逻辑还是像上篇那样数据预处理--加载数据集--数据加载器--迁移模型结构--改变全连接层--配置训练细节损失优化--训练函数--每10轮训练后验证一次--保存最近一次训练模型参数以及最优模型参数 改全连接层那里说一下因为我做的是六分类原来的模型结构是千分类所以要把 out_features 改成6同时冻结其他层只训练全连接层就好但是因为第一次训练的效果不是很好所以在优化的时候我又解冻了最后两层增加了学习能力另外还有优化就是对学习率我增加了一个学习率调度器动态学习率对模型来说效果更好最后一个优化是增加了早停机制即在验证准确率连续多少轮没有提升时自动停止训练这样大大节省了训练时间 运行结果我就不贴了因为我搞忘截图了。。反正最后一轮准确率有98%模型参数也保存了   三、模型测试保存csv文件 import torch import os import torch.nn as nn from torchvision import transforms from torchvision.datasets import ImageFolder from torch.utils.data import DataLoader from torchvision.models import resnet18 import numpy as np import pandas as pd#最优模型参数路径 best_model_path ./model/best.pth#数据预处理 val_transforms transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize(mean[0.485, 0.456, 0.406],std[0.229, 0.224, 0.225]) ])#准备测试数据集 test_dataset ImageFolder(root./Bananas/test, transformval_transforms)#数据加载器 test_load DataLoader(test_dataset, batch_size64, shuffleFalse)#导入模型结构 model resnet18(pretrained False) #不用加载自带的参数 in_features model.fc.in_features #同样动态接受输入特征 model.fc nn.Linear(in_features, 6) #同样更改模型结构device torch.device(cuda if torch.cuda.is_available() else cpu)#加载之前保存的最优模型参数 model.load_state_dict(torch.load(best_model_path, map_location device)) model.to(device)#开始测试 model.eval() correct 0 total 0 with torch.no_grad():for images, labels in test_load:images, labels images.to(device), labels.to(device)out model(images) #得到预测值pred torch.argmax(out, dim1)correct (pred labels).sum().item()total labels.size(0) test_acc correct / total *100 print(f测试集测试的准确率为{test_acc:.2f}%)valid_dataset ImageFolder(root./Bananas/valid, transform val_transforms) valid_loader DataLoader(valid_dataset, batch_size64, shuffleFalse) classNames valid_dataset.classes #拿到类名model.eval() acc_total 0 val_dataloader DataLoader(valid_dataset, batch_size64, shuffleFalse) total_data np.empty((0,8)) with torch.no_grad():# 每个批次for x, y in val_dataloader:x x.to(device)y y.to(device)out model(x)# [10,3]pred torch.detach(out).cpu().numpy()# [10,]p1 torch.argmax(out, dim1)# 转化为numpyp2 p1.unsqueeze(dim1).detach().cpu().numpy()label y.unsqueeze(dim1).detach().cpu().numpy()batch_data np.concatenate([pred, p2, label],axis1)total_data np.concatenate([total_data, batch_data], axis0)# 构建csv文件的第一行列名 pd_columns [*classNames, pred, label]os.makedirs(./results, exist_okTrue) csv_path os.path.relpath(os.path.join(os.path.dirname(__file__), results, number.csv))pd.DataFrame(total_data, columnspd_columns).to_csv(csv_path, indexFalse) print(成功保存csv文件) 运行结果 测试集的准确率也有这么高说明没有过拟合我们可以打开csv文件看一下   预测的准确率还是挺高的这里也说明一下测试的时候是加载之前训练保存的模型参数所以 model resnet18(pretrained False)  这里的参数填false然后再加载保存的模型参数 model.load_state_dict(torch.load(best_model_path, map_location device)). 四、单张图片预测 这里我们可以从网上找几张图片来预测一下 import torch import torch.nn as nn from PIL import Image from torchvision import transforms from torchvision.datasets import ImageFolder from torchvision.models import resnet18#最优模型参数路径 best_model_path ./model/best.pth 10 #数据预处理 val_transforms transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize(mean[0.485, 0.456, 0.406],std[0.229, 0.224, 0.225]) ]) train_transforms transforms.Compose([transforms.Resize((256, 256)), # 先稍微放大点transforms.RandomCrop(224), # 随机裁剪出 224x224transforms.RandomHorizontalFlip(p0.5), # 左右翻转transforms.RandomRotation(degrees15), # 随机旋转 ±15°transforms.ColorJitter(brightness0.2, # 明亮度contrast0.2, # 对比度saturation0.2, # 饱和度hue0.1), # 色调transforms.ToTensor(),transforms.Normalize(mean[0.485, 0.456, 0.406], # ImageNet均值std[0.229, 0.224, 0.225]) # ImageNet标准差 ])#加载图片 img_path images/b8_rotten.jpg img Image.open(img_path).convert(RGB) # 确保是RGB三通道 img val_transforms(img) # 应用transform img img.unsqueeze(0) # 加上 batch 维度#导入模型结构 model resnet18(pretrained False) #不用加载自带的参数 in_features model.fc.in_features #同样动态接受输入特征 model.fc nn.Linear(in_features, 6) #同样更改模型结构device torch.device(cuda if torch.cuda.is_available() else cpu)#加载之前保存的最优模型参数 model.load_state_dict(torch.load(best_model_path, map_location device)) model.to(device)#模型预测 model.eval() with torch.no_grad():output model(img)pred_class torch.argmax(output, dim1).item()train_dataset ImageFolder(root./Bananas/train, transform train_transforms) idx_to_class {v: k for k, v in train_dataset.class_to_idx.items()} pred_label idx_to_class[pred_class] print(f模型预测这张图片是{pred_label}) 运行结果 注意要记得给原图片升维因为要求传入的图片形状是N, C, H, W 五、模型评估 在CNN项目中对模型评估的指标准确率、召回率、F1等应该基于测试集的结果进行最终评估因为模型在测试集上的表现是最接近于真实情况的 import pandas as pd import os from sklearn.metrics import classification_report from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay import matplotlib import matplotlib.pyplot as plt#设置中文字体 matplotlib.rcParams[font.sans-serif] [SimHei] matplotlib.rcParams[axes.unicode_minus] Falsecsv_path os.path.relpath(os.path.join(os.path.dirname(__file__), results, number.csv)) # 读取CSV数据 csvdata pd.read_csv(csv_path, index_col0) # 拿到真实标签 true_label csvdata[label].values # 拿到预测标签 true_pred csvdata[pred].values# 根据预测值和真实值生成分类报告 report classification_report(y_truetrue_label, y_predtrue_pred) print(report)# 混淆矩阵可视化 cm confusion_matrix(true_label, true_pred) disp ConfusionMatrixDisplay(confusion_matrixcm, display_labels[str(i) for i in range(6)]) disp.plot(cmapGreens, values_formatd) plt.title(训练结果混淆矩阵视图) plt.tight_layout() plt.savefig(confusion_matrix.png) plt.show()运行结果 可以看到f1分数比较高混淆矩阵的对角线数字也很大说明模型表现良好。 六、ONNX导出 导出为ONNX格式主要是它兼容性很高且可以被专用推理引擎优化减少计算开销代码如下 import torch from torchvision.models import resnet18 import torch.nn as nnbest_model_path ./model/best.pth onnx_path ./model/best.onnx #保存路径#加载模型结构与权重参数 model resnet18(pretrained False) in_features model.fc.in_features model.fc nn.Linear(in_features, 6) #同样修改全连接层device torch.device(cuda if torch.cuda.is_available() else cpu ) model.load_state_dict(torch.load(best_model_path, map_locationdevice))#创建实例输入 x torch.randn(1, 3, 224, 224) out model(x) # print(out.shape) #确认输出不是None torch.Size([1, 6])#导出onnx model.eval() torch.onnx.export(model, x, onnx_path, verboseFalse, input_names[input], output_names[output]) print(onnx导出成功)import onnx onnx_model onnx.load(onnx_path) onnx.checker.check_model(onnx_model) print(onnx模型检查通过) 导出后我们可以通过这个网站来可视化一下Netron打开刚刚保存的ONNX文件 然后就可以看到网络结构了这里我只截一部分 七、ONNX推理 代码如下 from torchvision.datasets import ImageFolder from torch.utils.data import DataLoader from torchvision import transforms from PIL import Image import onnxruntime as ort import torch#数据预处理 val_transforms transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize(mean[0.485, 0.456, 0.406],std[0.229, 0.224, 0.225]) ])#加载路径 img_path ./images/b8_rotten.jpg onnx_path ./model/best.onnx#加载并处理图片 img Image.open(img_path).convert(RGB) img_tensor val_transforms(img) #经过数据预处理后转为了tensor img_np img_tensor.unsqueeze(0).numpy() # print(img_tensor.shape) torch.Size([3, 32, 32])#加载onnx模型 sess ort.InferenceSession(onnx_path) out sess.run(None, {input: img_np}) # print(out) # [array([[-6.8998175, -8.683616 , -5.1299562, -2.8295422, 8.335733 , # -5.098113 ]], dtypefloat32)]#后处理 valid_dataset ImageFolder(root./Bananas/valid, transform val_transforms) valid_loader DataLoader(valid_dataset, batch_size64, shuffleFalse) classNames valid_dataset.classes #拿到类名 # print(classNames) # [freshripe, freshunripe, overripe, ripe, rotten, unripe]logits out[0] #用softmax函数将结果转成0-1之间的概率 probs torch.nn.functional.softmax(torch.tensor(logits), dim1) pred_index torch.argmax(probs).item() pred_label classNames[pred_index]print(f\n 预测类别为{pred_label}) print(各类别概率) for i, cls in enumerate(classNames):print(f{cls}: {probs[0][i]:.2%}) 注意传入ONNX模型的必须是numpy数组。 运行结果   其实感觉预测得有点绝对但是这个模型的准确率这么高我也是没想到 八、网络结构与数据增强可视化 如果想要更直观地看到训练变化的话可以加这一步 import torch from torch.utils.tensorboard import SummaryWriter from torchvision.utils import make_grid from torchvision import transforms from torchvision.datasets import ImageFolder from torchvision.models import resnet18 import torch.nn as nn# 可视化配置 writer SummaryWriter(runs/501_tensorboard)# 网络结构可视化 print(添加网络结构图) model resnet18() model.fc nn.Linear(model.fc.in_features, 6) input torch.randn(1, 3, 224, 224) # ResNet18的输入尺寸 writer.add_graph(model, input)# 数据增强效果可视化 print(添加数据增强图像) # 数据增强方式 train_transforms transforms.Compose([transforms.Resize((256, 256)), # 先稍微放大点transforms.RandomCrop(224), # 随机裁剪出 224x224transforms.RandomHorizontalFlip(p0.5), # 左右翻转transforms.RandomRotation(degrees15), # 随机旋转 ±15°transforms.ColorJitter(brightness0.2, # 明亮度contrast0.2, # 对比度saturation0.2, # 饱和度hue0.1), # 色调transforms.ToTensor(),transforms.Normalize(mean[0.485, 0.456, 0.406], # ImageNet均值std[0.229, 0.224, 0.225]) # ImageNet标准差 ])# 加载训练数据集 train_dataset ImageFolder(root./Bananas/train, transform train_transforms)# 写入3轮不同的数据增强图像 for step in range(3):imgs torch.stack([train_dataset[i][0] for i in range(64)]) # 取64张图grid make_grid(imgs, nrow8, normalizeTrue)writer.add_image(faugmented_mnist_step_{step}, grid, global_stepstep)writer.close() print(所有可视化完成)运行代码后在终端输入 tensorboard --logdirruns回车后可以看到生成了一个网址用浏览器直接访问即可如果不行的话就在 runs 后面加当前文件的绝对路径苯人的可视化是这样 数据增强可视化  最后我整个的项目文件夹长这样 对上篇的补充就到此为止下一篇写啥也没想好前面拖得太多了。。 以上有问题可以指出(๑•̀ㅂ•́)و✧
http://www.zqtcl.cn/news/249508/

相关文章:

  • dw属于什么的网页制作工具网络建站优化科技
  • 百度网站首页的设计理念南京高新区规划建设局网站
  • 虚拟机做实验的网站网站以个人名义备案
  • 自定义表单网站网站建设营销型号的区别
  • 有个网站做彩盒的贵阳网站建设托管
  • 网站制作属于什么专业做网站需要什么配置服务器吗
  • 网站开发学习培训广州网站优化关键词公司
  • 毕节金海湖新区城乡建设局网站企业网站的步骤
  • 网站后台设计教程网站建设判断题
  • 珠海网站建设 金蝶天元建设集团有限公司李华
  • 海安市建设局网站成都官网seo技术
  • 网站建设策划书结束语wordpress付费版
  • 进口网站建设做网站用什么格式的图片
  • 青海省住房和城乡建设部网站进入网站空间
  • 做公司简介的开源网站企业seo多少费用
  • 学校网站建设工作方案昆明做网站词排名优化
  • 镇江企业做网站针对人群不同,网站做细分
  • 个人单页网站建设台州网站建设惠店
  • 专做婚礼logo的网站做搜狗pc网站快速排
  • 北京网站建设公司分享网站改版注意事项做网站需要多大空间
  • 主机网站建设制作天津西青区天气预报
  • 网站没有内容可以备案吗横向网站源码
  • 做的网站浏览器提示不安全站优化
  • dede移动端网站源码电子商务网站建设开题报告
  • 做网站价格多少优质做网站哪家好
  • 网站建设及推广服务的合同范本留言网站建设的报告
  • 工程师招聘网站做网站需要公司资质吗
  • 苏州模板网站建站开网店如何运营和推广
  • 换空间网站备案北京网页设计平台
  • 德德模板网站建设步骤可信的品牌网站建设