做电商在什么网站吗,个性化企业网站制作公司,互联网运营培训班哪个好,openwrt安装wordpress目录 1.作者介绍2.Cifar-10数据集介绍3.Densenet网络模型3.1网络背景3.2网络结构3.2.1Dense Block3.2.2Bottleneck层3.2.3Transition层3.2.4压缩 4.代码实现4.1数据加载4.2建立 DenseNet 网络模型4.3模型训练4.4训练代码4.5测试代码 参考链接 1.作者介绍
吴思雨#xff0c;女… 目录 1.作者介绍2.Cifar-10数据集介绍3.Densenet网络模型3.1网络背景3.2网络结构3.2.1Dense Block3.2.2Bottleneck层3.2.3Transition层3.2.4压缩 4.代码实现4.1数据加载4.2建立 DenseNet 网络模型4.3模型训练4.4训练代码4.5测试代码 参考链接 1.作者介绍
吴思雨女西安工程大学电子信息学院2023级研究生 研究方向机器视觉与人工智能 电子邮件2879944563qq.com 陈梦丹女西安工程大学电子信息学院2022级研究生 研究方向机器视觉与人工智能 电子邮件1169738496qq.com
2.Cifar-10数据集介绍
Cifar-10数据集由10个类别的60000张32x32彩色图像组成每个类别有6000张图像。有50000个训练图像和10000个测试图像。 数据集分为五个训练批次和一个测试批次每个批次有10000张图像。测试批次恰好包含从每个类别中随机选择的1000幅图像。训练批包含按随机顺序排列的剩余图像但某些训练批可能包含来自一个类的图像多于另一类的图像。在它们之间训练批次恰好包含每个类的5000个图像。 以下是数据集中的类以及每个类的10张随机图像 这些类是完全不同的。汽车和卡车之间没有重叠。“汽车”包括轿车SUV诸如此类的东西。“卡车”只包括大卡车。两者都不包括皮卡。 Cifar-10官网下载链接http://www.cs.toronto.edu/~kriz/cifar.html Cifar-10数据集有三个版本本文采用的是第一个版本Cifar-10 python version。
3.Densenet网络模型
3.1网络背景
DenseNet(《Densely connected convolutional networks》) 斩获CVPR 2017的最佳论文奖它的基本思路与ResNet一致但是在参数和计算成本更少的情形下实现了比ResNet更优的性能它建立的是前面所有层与后面层的密集连接即相加变连结它的名称也是由此而来。 DenseNet的另一大特色是通过特征在通道上的连接来实现特征重用。这些特点让DenseNet的参数量和计算成本都变得更少了效果也更好了。ResNet解决了深层网络梯度消失问题它是从深度方向研究的。宽度方向是GoogleNet的Inception。而DenseNet是从feature入手通过对feature的极致利用能达到更好的效果和减少参数。
3.2网络结构 上图是一个包含5layer的Dense Block。可以看出Dense Block互相连接所有的层具体来说就是每一层的输入都来自于它前面所有层的特征图每一层的输出均会直接连接到它后面所有层的输入。所以对于一个L层的DenseBlock共包含 L*(L1)/2 个连接如果是ResNet的话则为L-121。从这里可以看出相比ResNetDense Block采用密集连接。而且Dense Block是直接concat来自不同层的特征图这可以实现特征重用提升效率这一特点是DenseNet与ResNet最主要的区别。 Dense Net的网络结构主要由Dense Block和Transition*组成;如下图所示。一个DenseNet中有3个或4个DenseBlock。而一个DenseBlock中也会有多个Bottleneck layers。最后的DenseBlock之后是一个global AvgPooling层然后送入一个softmax分类器得到每个类别所属分数。
3.2.1Dense Block
1.Dense connective 为了进一步改善层之间的信息流提出了一种不同的连接模式引入了从任何层到所有后续层的直接连接。因此第l层接收所有先前层的特征图X0,X1,…Xl-1作为输入
2.Composite function—复合功能 将 Hℓ(⋅)定义为三个连续运算的复合函数批量归一化BN然后是 ReLU 和一个 3×3的卷积Conv。 其中ℓ表示第几层将第ℓ 层的输出表示为Xℓ [X0,X1,…]表示将第0,1…(ℓ-1)层的特征图进行组合。将非线性变换Hℓ(⋅)定义为三个连续操作的符合函数BNReLU一个3×3的Conv。 3.Growth rate—增长率 k–DenseNet中的growth rate(增长率)这是一个超参数。一般情况下使用较小的k就可以得到较佳的性能。假定输入层的特征图的通道数为k0那么L层输入的channel数为 k0k*(L-1)因此随着层数增加尽管k设定得较小DenseBlock中每一层输入依旧会越来越多。
3.2.2Bottleneck层
尽管每一层仅生成k个输出特征图但通常具有更多输入。可以在每次3×3卷积之前引入1×1卷积作为瓶颈层以减少输入特征图的数量从而提高计算效率。并且将具有此类瓶颈层的网络称为DenseNet-B瓶颈层如下图所示。
3.2.3Transition层
当特征图的大小改变时不能直接连接。然而卷积网络的重要组成部分是降低特征图大小的下采样层。为了便于在体系结构中进行下采样将网络划分为多个密集连接的密集块。如下图所示将块之间的层称为过渡层它们进行卷积和池化。实验中使用的过渡层包括批处理规范化层和1×1卷积层然后是一个 2×2的平均池化层。
3.2.4压缩
为了进一步提高模型的紧凑性可以减少转换层的特征图数量。引入一个压缩因子θ(0 θ ≤1)当θ1时转换层的输入和输出特征数不变也就是经过转换层后特征数不变当θ 1时输入特征图数为m时输出为⌊θm⌋。将θ1的DenseNet称为DenseNet-C 在实验中设置θ0.5。
4.代码实现
4.1数据加载
CIFAR 数据集可以从官网下载后使用也可以使用 datasets 类自动加载如果本地路径没有该文件则自动下载。大型训练数据集不能一次性加载全部样本来训练可以使用 Dataloader 类自动加载数据。Dataloader 是一个迭代器基本功能是传入一个 Dataset 对象根据参数 batch_size 生成一个 batch 的数据。
4.2建立 DenseNet 网络模型
建立一个 DenseNet 网络模型进行训练包括三个步骤 1.实例化 DenseNet 模型对象 2.设置训练的损失函数 3.设置训练的优化器。
4.3模型训练
在模型训练过程中可以使用验证集数据评价训练过程中的模型精度以便控制训练过程。模型验证就是用验证数据进行模型推理前向计算得到模型输出但不反向计算模型误差因此需要设置 torch.no_grad()。
4.4训练代码
# 经典模型: 使用 DenseNet 模型 进行 CIFAR10 图像分类使用 Torchvision 预定义模型
# 使用 torchvision.models.densenet.DenseNet 类
# Copyright: youcansqq.com
# Crated: Huang Shan, 2023/05/20# _*_coding:utf-8_*_
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
from torchvision import transforms, models
from matplotlib import pyplot as plt
import numpy as np# 优化结果写入数据文件
import pandas as pd
def WriteDataFile(epoch_list, loss_list, accu_list, filepath):# print(def WriteDataFile())optRecord {epoch: epoch_list,train_loss: loss_list,accuracy: accu_list}dfRecord pd.DataFrame(optRecord)dfRecord.to_csv(filepath, indexFalse, encodingutf_8_sig)print(写入数据文件: %s 完成。 % filepath)returnif __name__ __main__:device torch.device(cuda if torch.cuda.is_available() else cpu)print(device)# (1) 将[0,1]的PILImage 转换为[-1,1]的Tensortransform_train transforms.Compose([transforms.RandomHorizontalFlip(), # 随机水平翻转transforms.RandomRotation(10), # 随机旋转transforms.RandomAffine(0, shear10, scale(0.8, 1.2)),transforms.ColorJitter(brightness0.2, contrast0.2, saturation0.2),transforms.Resize((32, 32)), # 图像大小调整为 (w,h)(3232)transforms.ToTensor(), # 将图像转换为张量 Tensortransforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))])# 测试集不需要进行数据增强transform transforms.Compose([transforms.Resize((32, 32)), # 图像大小调整为 (w,h)(3232)transforms.ToTensor(), # 将图像转换为张量 Tensortransforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))])# (2) 加载 CIFAR10 数据集batchsize 128# 加载 CIFAR10 数据集, 如果 root 路径加载失败, 则自动在线下载# 加载 CIFAR10 训练数据集, 50000张训练图片train_set torchvision.datasets.CIFAR10(root, trainTrue,downloadTrue, transformtransform_train)train_loader torch.utils.data.DataLoader(train_set, batch_sizebatchsize)# 加载 CIFAR10 验证数据集, 10000张验证图片test_set torchvision.datasets.CIFAR10(root, trainFalse,downloadTrue, transformtransform)test_loader torch.utils.data.DataLoader(test_set, batch_size1000)# 创建生成器用 next 获取一个批次的数据valid_data_iter iter(test_loader) # _SingleProcessDataLoaderIter 对象valid_images, valid_labels next(valid_data_iter) # images: [batch,3,224,224], labels: [batch]valid_size valid_labels.size(0) # 验证数据集大小batchprint(valid_images.shape, valid_labels.shape)# 定义类别名称CIFAR10 数据集的 10个类别classes (plane, car, bird, cat, deer,dog, frog, horse, ship, truck)# (3) 从 torchvision.model 加载预定义模型 DenseNet (不加载模型权值)model models.DenseNet(num_init_features32, num_classes10) # 实例化 DenseNet 模型类model.to(device) # 将网络分配到指定的 device中# print(model)# 定义损失函数和优化器criterion nn.CrossEntropyLoss() # 定义损失函数 CrossEntropyoptimizer torch.optim.SGD(model.parameters(), momentum0.8, lr0.01) # 定义优化器 SGD# (4) 训练 DenseNet 网络模型epoch_list [] # 记录训练轮次loss_list [] # 记录训练集的损失值accu_list [] # 记录验证集的准确率num_epochs 99 # 训练轮次for epoch in range(num_epochs): # 训练轮次 epochrunning_loss 0.0 # 每个轮次的累加损失值清零for step, data in enumerate(train_loader, start0): # 迭代器加载数据optimizer.zero_grad() # 损失梯度清零inputs, labels data # inputs: [batch,3,224,224] labels: [batch]outputs model(inputs.to(device)) # 正向传播loss criterion(outputs, labels.to(device)) # 计算损失函数loss.backward() # 反向传播optimizer.step() # 参数更新# 累加训练损失值running_loss loss.item()# print(\t epoch {}, step {}: loss {:.4f}.format(epoch, step, loss.item()))if step%10099: # 每 100 个 step 打印一次训练信息print(\t epoch {}, step {}: loss {:.4f}.format(epoch, step, loss.item()))# 计算每个轮次的验证集准确率with torch.no_grad(): # 验证过程, 不计算损失函数梯度outputs_valid model(valid_images.to(device)) # 模型对验证集进行推理, [batch, 10]pred_labels torch.max(outputs_valid, dim1)[1] # 预测类别, [batch]accuracy torch.eq(pred_labels, valid_labels.to(device)).sum().item() / valid_size * 100 # 计算准确率print(Epoch {}: train loss{:.4f}, accuracy{:.2f}%.format(epoch, running_loss, accuracy))# 记录训练过程的统计数据epoch_list.append(epoch) # 记录迭代次数loss_list.append(running_loss) # 记录训练集的损失函数accu_list.append(accuracy) # 记录验证集的准确率# 训练结果可视化plt.figure(figsize(11, 5))plt.suptitle(DenseNet Model in CIFAR10)plt.subplot(121), plt.title(Train loss)plt.plot(epoch_list, loss_list)plt.xlabel(epoch), plt.ylabel(loss)plt.subplot(122), plt.title(Valid accuracy)plt.plot(epoch_list, accu_list)plt.xlabel(epoch), plt.ylabel(accuracy)plt.show()# 保存图像文件plt.savefig(/data/Users/wusy/myProject/efficient_densenet_pytorch-master/images)print(Plot saved to /data/Users/wusy/myProject/efficient_densenet_pytorch-master/images)# (5) 保存 DenseNet 网络模型save_path /data/Users/wusy/myProject/efficient_densenet_pytorch-master/dir1#model_cpu model.cpu() # 将模型移动到 CPUmodel_path save_path .pth # 模型文件路径torch.save(model.state_dict(), model_path) # 保存模型权值# 优化结果写入数据文件result_path save_path .csv # 优化结果文件路径WriteDataFile(epoch_list, loss_list, accu_list, result_path)经过 20 轮左右的训练使用验证集中的 1000 张图片进行验证模型准确率达到 80%。继续训练可以进一步降低训练损失函数值经过 100轮左右的训练验证集的准确率保持在 80%左右。 ## 4.4测试阶段 使用加载的 DenseNet 模型输入新的图片进行模型推理可以由模型输出结果确定输入图片所属的类别。从测试集中提取几张图片或者读取图像文件进行模型推理获得图片的分类类别。在提取图片或读取文件时要注意对图片格式和图片大小进行适当的转换。 从测试集中提取图片结果如下 读取图像文件结果如下
4.5测试代码
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
from torchvision import transforms, models
from matplotlib import pyplot as plt
import numpy as npdevice torch.device(cuda if torch.cuda.is_available() else cpu) # 检测并指定设备if __name__ __main__:device torch.device(cuda if torch.cuda.is_available() else cpu)print(device)# (1) 将[0,1]的PILImage 转换为[-1,1]的Tensortransform_train transforms.Compose([transforms.RandomHorizontalFlip(), # 随机水平翻转transforms.RandomRotation(10), # 随机旋转transforms.RandomAffine(0, shear10, scale(0.8, 1.2)),transforms.ColorJitter(brightness0.2, contrast0.2, saturation0.2),transforms.Resize((32, 32)), # 图像大小调整为 (w,h)(3232)transforms.ToTensor(), # 将图像转换为张量 Tensortransforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))])# 测试集不需要进行数据增强transform transforms.Compose([transforms.Resize((32, 32)), # 图像大小调整为 (w,h)(3232)transforms.ToTensor(), # 将图像转换为张量 Tensortransforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))])# (2) 加载 CIFAR10 数据集batchsize 128# 加载 CIFAR10 数据集, 如果 root 路径加载失败, 则自动在线下载# 加载 CIFAR10 训练数据集, 50000张训练图片# 加载 CIFAR10 验证数据集, 10000张验证图片test_set torchvision.datasets.CIFAR10(root/cifar-10-python.tar.gz, trainFalse,downloadTrue, transformtransform)test_loader torch.utils.data.DataLoader(test_set, batch_size1000)# 创建生成器用 next 获取一个批次的数据valid_data_iter iter(test_loader) # _SingleProcessDataLoaderIter 对象valid_images, valid_labels next(valid_data_iter) # images: [batch,3,224,224], labels: [batch]valid_size valid_labels.size(0) # 验证数据集大小batchprint(valid_images.shape, valid_labels.shape)# 定义类别名称CIFAR10 数据集的 10个类别classes (plane, car, bird, cat, deer,dog, frog, horse, ship, truck)# (3) 从 torchvision.model 加载预定义模型 DenseNet (不加载模型权值)model models.DenseNet(num_init_features32, num_classes10) # 实例化 DenseNet 模型类model.to(device) # 将网络分配到指定的 device中# print(model)# 定义损失函数和优化器criterion nn.CrossEntropyLoss() # 定义损失函数 CrossEntropyoptimizer torch.optim.SGD(model.parameters(), momentum0.8, lr0.01) # 定义优化器 SGD# 加载 DenseNet 预训练模型# model DenseNet(num_classes10) # 实例化 DenseNet 网络模型model models.DenseNet(num_init_features32, num_classes10) # 实例化 DenseNet 模型类model.to(device) # 将网络分配到指定的device中model_path /dir.pthmodel.load_state_dict(torch.load(model_path))model.eval() # 模型推理模式# 模型检测
correct 0
total 0
for data in test_loader: # 迭代器加载测试数据集imgs, labels data # torch.Size([batch,3,32,32) torch.Size([batch])# print(imgs.shape, labels.shape)outputs model(imgs.to(device)) # 正向传播, 模型推理, [batch, 10]labels_pred torch.max(outputs, dim1)[1] # 模型预测的类别 [batch]# _, labels_pred torch.max(outputs.data, 1)total labels.size(0)correct torch.eq(labels_pred, labels.to(device)).sum().item()
accuracy 100. * correct / total
print(Test samples: {}.format(total))
print(Test accuracy{:.2f}%.format(accuracy))# 提取测试集图片进行模型推理
batch 8 # 批次大小
data_set torchvision.datasets.CIFAR10(root/cifar-10-python.tar.gz, trainFalse, downloadTrue, transformNone)
plt.figure(figsize(9, 6))
for i in range(batch):imgPIL data_set[i][0] # 提取 PIL 图片label data_set[i][1] # 提取 图片标签# 预处理/模型推理/后处理imgTrans transform(imgPIL) # 预处理变换, torch.Size([3,32,32])imgBatch torch.unsqueeze(imgTrans, 0) # 转为批处理torch.Size([batch1,3,32,32])outputs model(imgBatch.to(device)) # 模型推理, 返回 [batch1, 10]indexes torch.max(outputs, dim1)[1] # 注意 [batch1], device deviceindex indexes[0].item() # 预测类别整数# 绘制第 i 张图片imgNP np.array(imgPIL) # PIL - Numpyout_text label:{}/model:{}.format(classes[label], classes[index])plt.subplot(2, 4, i1)plt.imshow(imgNP)plt.title(out_text)plt.axis(off)
plt.tight_layout()
plt.show()
plt.savefig(/images1)# 读取图像文件进行模型推理
from PIL import Image
filePath # 数据文件的地址和文件名
imgPIL Image.open(filePath) # PIL 读取图像文件, class PIL.Image.Image# 预处理/模型推理/后处理
imgTrans transform(imgPIL) # 预处理变换, torch.Size([3, 224, 224])
imgBatch torch.unsqueeze(imgTrans, 0) # 转为批处理torch.Size([batch1, 3, 224, 224])
outputs model(imgBatch.to(device)) # 模型推理, 返回 [batch1, 10]
indexes torch.max(outputs, dim1)[1] # 注意 [batch1], device device
percentages nn.functional.softmax(outputs, dim1)[0] * 100
index indexes[0].item() # 预测类别整数
percent percentages[index].item() # 预测类别的概率浮点数# 绘制第 i 张图片
imgNP np.array(imgPIL) # PIL - Numpy
out_text Prediction:{}, {}, {:.2f}%.format(index, classes[index], percent)
print(out_text)
plt.imshow(imgNP)
plt.title(out_text)
plt.axis(off)
plt.tight_layout()
# 保存图像到指定路径
output_image_path /prediction_result.jpg
plt.savefig(output_image_path, bbox_inchestight, pad_inches0)
plt.show()参考链接
[1]DenseNet 模型-CIFAR10图像分类: http://t.csdnimg.cn/InzLt [2]经典神经网络论文超详细解读: http://t.csdnimg.cn/jVmaw