1模型训练的要求
模型训练的数据源、使模型适应训练数据的优化器、以及将模型和数据传到硬件的方法、硬件用于执行模型训练所需的计算。
2训练过程
1首先需要进行数据处理
从存储中获取数据,将数据中样本转换成可处理的张量形式,数据预处理作为自定义数据与Dataset类提供的标准张量的桥梁。使用并行化数据加载,多个进程加载数据,组装成一个批次——一个包含多个样本的张量。Dataloader类实现并行处理。
2评估模型
我们使用损失函数将模型的输出与期望的输出进行比较,修改模型,使其更接近目标。
3优化器
使用优化器进行更新
2.1 数据预处理
2.1.1模型的导入和图像的载入
import torch
from torchvision import models
from PIL import Image
from torchvision import transforms
x=dir(models)
img=Image.open("img/K1+216.jpg")#打开一张图片
# img.show()
proprocess=transforms.Compose(
[
transforms.Resize(256),#缩放到256
transforms.CenterCrop(224),#围绕中心裁剪
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485,0.456,0.406],
std=[0.229,0.224,0.225]
)
]
)
img_t=proprocess(img)
batch_t=torch.unsqueeze(img_t,0)#维度提升 0行方向扩 1列方向扩 -1最后一维
#y = torch.squeeze(x,dim=-1)#维度压缩 返回一个张量 把输入中第0维删去
resnet=models.resnet50(pretrained=False)
resnet.eval()#使网络处于eval状态,进行变量形式的转换
out=resnet(batch_t)
print(out)
2.1.2加载标签文件
import os#程序与操作系统的接口 用处:可以跨目录写文件和调用模块,可以切换当前目录进行访问其下目录的文件内容
VOCdevkit_path = 'VOCdevkit'
with open(os.path.join(VOCdevkit_path, "VOC2007/ImageSets/Segmentation/train.txt"), "r") as f:#拼接路径的方法
train_lines = f.readlines()#
with open(os.path.join(VOCdevkit_path, "VOC2007/ImageSets/Segmentation/val.txt"), "r") as f:
val_lines = f.readlines()
num_train = len(train_lines)#计算个数
num_val = len(val_lines)
读取方式read/readline
read(size)从当前位置读取size个字节 返回字符串对象
readline用于从文件读取整行,附带\n,返回字符串
2.1.3索引的获取
2.1.4模型的权重文件
模型的权重文件保存在pth文件中
使用加载到网络中
model_path='log/best_epoch_weights.pth'
model_data=torch.load(model_path)
resnet.load_state_dict(model_data)
3从张量开始
学习用张量处理torch中的浮点数
深度学习网络通常在不同阶段将数据转换,各阶段数据是一个中间表征序列。早期表征是边缘和纹理,深层表征有复杂的结构。
这些表征是浮点数,用于描述输入的特征,以神经网络的描述输入到输出的结构。
0维是标量,1维是向量,2维是矩阵,3维是张量。
3.1张量的本质
列表或元组属于内存单独分配的对象集合,张量属于连续的内存块。
3.1.1初始化张量
使用0,1初始化张量
Y=torch.zeros(5,4)
Z=torch.ones(5,4)
3.1.2访问张量
使用两个索引访问张量中的单个元素
Y[2,3]
Z[3,4]
a=some_list[:]#全部元素
b=some_list[1:4]
c=some_list[1:]
d=some_list[:4]
3.1.3命名张量
torch.randn(2,3,5,5)#batch,channels,row,columns
3.1.4张量的dtype
张量分配数字类型,
torch.float16 32 64 16位半精度浮点数 32位浮点数 64位双精度浮点数
int8 16 32 64有符号整数
uint8无符号整数
bool布尔
给张量分配数字类型
A=torch.ones(10,2,dtype=torch.double)
B=torch.tensor([[1,2],[3,4]],dtype=torch.short)
换为其他类型
C=torch.zeros(10,2).double()
D=torch.ones(10,2).short()
3.1.5张量的操作
张量的操作通过transpose函数
1创建操作:用于构建张量的函数:ones()和from_numpy()
2索引、切片、连接、转换操作:用于改变张量的形状、步长内容的函数,如transpose
3数学操作:通过运算操作张量内容的函数:
逐点操作——通过对每个元素分别应用函数来获得一个新张量,如abs()和cos()
归约操作——通过迭代张量来计算聚合值的函数,如equal()和max()
4随机采样——从概率分布中随机生成值,如randn()和normal()
5序列化——保存或者加载张量的函数,load()和save()
6并行化——控制CPU线程的函数set_num_threads()
3.1.6张量的存储
张量的值被分配到torch.Storage实例所管理的连续内存块中,使用Storage访问储存区
data=torch.tensor([[4,1],[2,4],[4,5]])
c=data.storage()
手动索引
c[1],c[2]
3.1.7张量的元数据
为了在存储区建立索引,张量依赖明确定义的信息——大小、偏移量、步长
1大小:一个元组,表示张量在每个维度有多少个元素。A.size()
2偏移量:存储区中元素相对第一个元素的索引。
A=A[1]
C=A.storage_offset()
3步长:为了获得下个元素需要跳过的元素数量。A.stride()
3.1.8张量储存到GPU
张量的设备属性(device),张量数据在计算机中的位置。
A=torch.tensor([[4,1],[1,4],[4,5]])
通过构造函数在GPU上创建一个张量
A_GPU = torch.tensor([[4, 1], [2, 4], [4, 5]], device='cuda')
使用to方法将cpu张量复制到GPU
A_GPU=A.to(device='cuda')
从0开始存储张量GPU
A_GPU=A.to(device='cuda:0')
使用简写的cpu和cuda方法替代to()
A_GPU=A.cuda()
A_GPU=A.cuda(0)
A_CPU=A_GPU.cpu()
3.1.9序列化张量(保存)
保存张量,使快速加载使用,用pickle来序列化张量对象,保存到文件中
torch.save(A,'wbwj/ourpoints.txt')
with open('wbwj/ourpoints.txt','wb')as f:
torch.save(A,f)
加载张量
A=torch.load('wbwj/ourpoints.txt')
with open('wbwj/ourpoints.txt','wb')as f:
A=torch.load(f)