dataset类学习 ---自己导入数据集
from torch.utils.data import Dataset #导入了Dataset类(用于创建自定义数据集)
from PIL import Image #读取图片
import os #os模块(用于文件路径操作)
class MyData(Dataset): #创建了一个继承自Dataset的新类MyData
def __init__(self,root_dir,label_dir):#构造函数接受两个参数 root_dir 和 label_dir,它们分别表示数据集的根目录和标签目录。
self.root_dir=root_dir
self.label_dir=label_dir
self.path=os.path.join(self.root_dir,self.label_dir) #完整路径
self.img_path=os.listdir(self.path)
def __getitem__(self, idx):#用于获取数据集中的单个样本。它接受一个索引 idx,根据索引加载相应的图像文件和标签。
img_name=self.img_path[idx]
img_item_path=os.path.join(self.root_dir,self.label_dir,img_name)
img=Image.open(img_item_path) #使用PIL库打开图像文件
label=self.label_dir
return img,label
def __len__(self):#用于返回数据集的总样本数量
return len(self.img_path)
root_dir="hymenoptera_data/train"
ants_label_dir="ants"
bees_label_dir="bees"
ants_dataset=MyData(root_dir,ants_label_dir)
bees_dataset=MyData(root_dir,bees_label_dir)
train_dataset=ants_dataset+bees_dataset #数据集合并
Tensorboard的使用
选择解释器
安装时 使用清华镜像源
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.douban.com
打开tensorboard的指令(在终端中):(pytorch) F:\pythonProject2>tensorboard --logdir=logs
from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Image
writer=SummaryWriter("logs")
image_path="hymenoptera_data/train/ants/0013035.jpg"
img_PIL=Image.open(image_path)
img_array=np.array(img_PIL)
print(type(img_array))
print(img_array.shape)
writer.add_image("text",img_array,1,dataformats='HWC')
#Y=x
for i in range(100):
writer.add_scalar("y=x",i,i)
writer.close()
Transforms的使用 (工具箱)
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
#Python的用法 tensor数据类型
#1.transforms在python中如何使用
#2.为什么需要tensor数据类型
img_path="hymenoptera_data/train/ants/0013035.jpg"
img=Image.open(img_path)
writer=SummaryWriter("logs")
#1.transforms在python中如何使用
tensor_trans=transforms.ToTensor()
tensor_img=tensor_trans(img)
writer.add_image("Tensor_img",tensor_img)
writer.close()
常见的Transforms 关注输入输出类型 多看官方文档
图片格式 PIL tensor narrays
打开方式 Image.open() ToTensor() cv.imread()
上下对应
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer=SummaryWriter("logs")
img=Image.open("hymenoptera_data/train/ants/0013035.jpg")
print(img)
#ToTensor
trans_totensor=transforms.ToTensor()
img_tensor=trans_totensor(img)
writer.add_image("ToTensor",img_tensor)
#Normalize
print(img_tensor[0][0][0])
trans_norm=transforms.Normalize([4,8,2],[9,5,3])
img_norm=trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalize",img_norm,1)
#Resize
print(img.size)
trans_resize=transforms.Resize((512,512))
#Img PIL->resize->img_resize PIL
img_resize=trans_resize(img)
#img_resize PIL ->totensor->img_resize tensor
img_resize=trans_totensor(img_resize)
writer.add_image("Resize",img_resize,0)
print(img_resize)
#compose的使用
trans_resize_2=transforms.Resize(512)
trans_compose=transforms.Compose([trans_resize_2,trans_totensor])
img_resize_2=trans_compose(img)
writer.add_image("Resize",img_resize_2,1)
writer.close()
#RandomCrop随机裁剪
trans_random=transforms.RandomCrop(512)
trans_compose_2=transforms.Compose([trans_random,trans_totensor])
for i in range(10):
img_crop=trans_compose_2(img)
writer.add_image("RandomCrop",img_crop,i)
writer.close()
torchvision中的数据集使用
import torchvision #torchvision中常见数据集
from torch.utils.tensorboard import SummaryWriter
dataset_transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor() #将图片转化为tensor数据类型
])
train_set=torchvision.datasets.CIFAR10(root="./dataset",train=True,transform=dataset_transform,download=True) #下载数据集
test_set=torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=dataset_transform,download=True)
#print(test_set[0])
#print(test_set.classes)
#img,target=test_set[0]
#print(img)
#print(target)
#print(test_set.classes[target])
#img.show()
#print(test_set[0])
writer=SummaryWriter("p10") #利用tensorboard进行显示
for i in range(10):
img,target=test_set[i]
writer.add_image("test_set",img,i)
writer.close()
dataloader的使用
import torchvision #torchvision中常见数据集
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
#准备的测试数据集
test_data=torchvision.datasets.CIFAR10(".\dataset",train=False,download=True,transform=torchvision.transforms.ToTensor())
test_loader=DataLoader(dataset=test_data,batch_sized=4,shuffle=True,num_workers=0,drop_last=True)
#batch_size 为抓取数量 num_workers为设置多进程,=0即为只有一个主进程 shuffle为洗牌操作 为true时会打乱顺序
img,target=test_data[0]#测试数据集第一张图片
print(img.shape)
print(target)
writer=SummaryWriter("dataloader") #利用tensorboard进行显示
for epoch in range(2):
step=0
for data in test_loader:
imgs,targets=data
#print(imgs.shape)
#print(targets)
writer.add_images("test_data_drop_last",imgs,step)
step=step+1
writer.close()
神经网络的搭建
#搭建自己的神经网络
import torch
from torch import nn
class Yu(nn.Module):
def __init__(self):
super().__init__()
def forward(self,input):
output=input+1
return output
yu=Yu()
x=torch.tensor(1.0)
output=yu(x)
print(output)
卷积操作---stride 、padding
import torch
import torch.nn.functional as F
input=torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]]) #二维矩阵
kernel=torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]]) #卷积核
input=torch.reshape(input,(1,1,5,5))
kernel=torch.reshape(kernel,(1,1,3,3))
print(input.shape)
print(kernel.shape)
output=F.conv2d(input,kernel,stride=1)
print(output)
output2=F.conv2d(input,kernel,stride=2) #stride为平移的量
print(output2)
output3=F.conv2d(input,kernel,stride=1,padding=1) #padding为填充 (充分利用边缘信息)
print(output3)
神经网络-卷积层
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset=torchvision.datasets.CIFAR10("./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader=DataLoader(dataset,batch_size=64)
class Yu(nn.Module):
def __init__(self): #初始化
super(Yu,self).__init__()
self.conv1=Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0)
def forward(self,x):
x=self.conv1(x)
return x
yu=Yu()
writer=SummaryWriter("./logs") #使用tensorboard显示图像
step=0
for data in dataloader:
imgs,targets=data
output=yu(imgs)
print(imgs.shape)
print(output.shape)
writer.add_image("input",imgs,step)
output= torch.reshape(output,(-1,3,30,30)) #-1为一个占位符,可进行自动计算
writer.add_images("output",output,step)
step=step+1
神经网络-池化层 最大池化减少数据量,加快训练
#最大池化
import torch
from torch import nn
from torch.nn import MaxPool2d
input=torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]],dtype=torch.float32) #输入图像 并转为浮点数
input=torch.reshape(input,(-1,1,5,5))
print(input.shape)
class Yu(nn.Module):
def __init__(self):
super(Yu,self).__init__()
self.maxpoo1=MaxPool2d(kernel_size=3,ceil_mode=True) #ceil_mode为True即在边界处数不够时依然可以取出最大值,若为False则在数不够时无法取出最大值
def forward(self,input):
output=self.maxpoo1(input)
return output
yu=Yu()#搭建神经网络
output=yu(input)
print(output)
带入图片
#最大池化
import torch
import torchvision.datasets
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset=torchvision.datasets.CIFAR10("./data",train=False,download=True,transform=torchvision.transforms.ToTensor())
dataloader=DataLoader(dataset,batch_size=64)
class Yu(nn.Module):
def __init__(self):
super(Yu,self).__init__()
self.maxpoo1=MaxPool2d(kernel_size=3,ceil_mode=True) #ceil_mode为True即在边界处数不够时依然可以取出最大值,若为False则在数不够时无法取出最大值
def forward(self,input):
output=self.maxpoo1(input)
return output
yu=Yu()#搭建神经网络
writer=SummaryWriter("logs_maxpool")
step=0
for data in dataloader:
imgs,targets=data
writer.add_images("input",imgs,step)
output=yu(imgs)
writer.add_images("output",output,step)
step=step+1
writer.close()
output=yu(input)
print(output)
神经网络-非线性激活
给神经网络引入非线性特质
#非线性激活
import torch
from torch import nn
from torch.nn import ReLU
input=torch.tensor([[1,-0.5],
[-1,3]])
output=torch.reshape(input,(-1,1,2,2)) #-1即为自己计算batchsize 1维 2×2
print(input.shape)
class Yu(nn.Module): #搭建网络
def __init__(self):
super(Yu,self).__init__()
self.reLu1=ReLU()#inplace作用为是否对原来的值直接进行替换 一般采用inplace=False
def forward(self,input):
output=self.reLu1(input)
return output
yu=Yu() #创建网络
output=yu(input)
print(output)
非线性变换目的是给网络引入非线性特征
#非线性激活
import torch
import torchvision.datasets
from torch import nn, sigmoid
from torch.nn import ReLU, Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
input=torch.tensor([[1,-0.5],
[-1,3]])
output=torch.reshape(input,(-1,1,2,2)) #-1即为自己计算batchsize 1维 2×2
print(input.shape)
dataset=torchvision.datasets.CIFAR10("./data",train=False,download=True,transform=torchvision.transforms.ToTensor())
dataloader=DataLoader(dataset,batch_size=64)
class Yu(nn.Module): #搭建网络
def __init__(self):
super(Yu,self).__init__()
self.reLu1=ReLU()#inplace作用为是否对原来的值直接进行替换 一般采用inplace=False
self.sigmoid1=Sigmoid() #不同于relu的另一个公式
def forward(self,input):
output=self.sigmoid1(input)
return output
yu=Yu() #创建网络
writer=SummaryWriter("./logs_relu")
step=0
for data in dataloader:
imgs,targets=data
writer.add_images("input",imgs,global_step=step)
output=yu(imgs)
writer.add_images("output",output,step)
step=step+1
writer.close()
神经网络-线性层
import torch
import torchvision.datasets
from torch import nn
from torch.nn import Linear
from torch.nn.functional import linear
from torch.utils.data import DataLoader
dataset=torchvision.datasets.CIFAR10("./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader=DataLoader(dataset,batch_size=64,drop_last=True)
class Yu(nn.Module):
def __init__(self):
super(Yu,self).__init__()
self.Linear1=Linear(196608,10)
def forward(self,input):
output=self.Linear1(input)
return output
yu=Yu()
for data in dataloader:
imgs,targets=data
print(imgs.shape)
output= torch.flatten(imgs)
print(output.shape)
output=yu(output)
print(output.shape)
神经网络-Sequential 的使用
#搭建网络模型 使用sequential 有什么变化
#未使用sequential
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
class Yu(nn.Module):
def __init__(self):
super(Yu,self).__init__()
self.conv1=Conv2d(3,32,5,padding=2)
self.maxpool1=MaxPool2d(2)
self.conv2=Conv2d(32,32,5,padding=2)
self.maxpool2=MaxPool2d(2)
self.conv3=Conv2d(32,64,5,padding=2)
self.maxpool3=MaxPool2d(2)
self.flatten=Flatten() #展平
self.linear1=Linear(1024,64)
self.linear2=Linear(64,10)
def forward(self,x):
x=self.conv1(x)
x=self.maxpool1(x)
x = self.conv2(x)
x = self.maxpool2(x)
x = self.conv3(x)
x = self.maxpool3(x)
x=self.flatten(x)
x=self.linear1(x)
x=self.linear2(x)
return x
yu=Yu()
print(yu)
input=torch.ones((64,3,32,32))
output=yu(input)
print(output.shape)
#搭建网络模型 使用sequential 有什么变化
#使用sequential
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
class Yu(nn.Module):
def __init__(self):
super(Yu,self).__init__()
self.conv1=Conv2d(3,32,5,padding=2)
self.maxpool1=MaxPool2d(2)
self.conv2=Conv2d(32,32,5,padding=2)
self.maxpool2=MaxPool2d(2)
self.conv3=Conv2d(32,64,5,padding=2)
self.maxpool3=MaxPool2d(2)
self.flatten=Flatten() #展平
self.linear1=Linear(1024,64)
self.linear2=Linear(64,10)
self.model1 = Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self,x):
x=self.model1(x)
return x
yu=Yu()
print(yu)
input=torch.ones((64,3,32,32))
output=yu(input)
print(output.shape)
损失函数与反向传播
1.计算实际输出与目标之间的差距
2.为更新输出提供一定的依据(反向传播)
import torch
from torch import nn
from torch.nn import L1Loss
inputs=torch.tensor([1,2,3],dtype=torch.float32)
targets=torch.tensor([1,2,5],dtype=torch.float32)
inputs=torch.reshape(inputs,(1,1,1,3)) #batchsize=1,chanel=1,1行3列
targets=torch.reshape(targets,(1,1,1,3))
#L1Loss
loss=L1Loss()
result=loss(inputs,targets)
#MSELoss
loss_mse=nn.MSELoss()
result_mse=loss_mse(inputs,targets)
print(result) #=((1-1)+(2-2)+(5-3))/3=0.6667
print(loss_mse) #=((1-1)+(2-2)+(5-3)^2)/3=1.333
#
x=torch.tensor([0.1,0.2,0.3])
y=torch.tensor([1])
x=torch.reshape(x,(1,3)) #batchsize=1 ,3类
loss_cross=nn.CrossEntropyLoss()
result_cross=loss_cross(x,y)
print(result_cross)
#在一个具体的神经网络中 以之前的神经网络为例
#写一个神经网络
import torchvision.datasets
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Linear, Flatten
from torch.utils.data import DataLoader
dataset=torchvision.datasets.CIFAR10("./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader=DataLoader(dataset,batch_size=1)
class Yu(nn.Module): #搭建网络
def __init__(self):
super(Yu,self).__init__()
self.model1=Sequential(
Conv2d(3,32,5,padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024,64),
Linear(64,10)
)
def forward(self,x):
x=self.model1(x)
return x
loss=nn.CrossEntropyLoss()
yu=Yu() #创建网络
for data in dataloader:
imgs,targets=data
outputs=yu(imgs)
result_loss=loss(outputs,targets)
# result_loss.backward() #反向传播 计算出每个节点的参数
print(result_loss)
优化器
#写一个神经网络
import torch.optim
import torchvision.datasets
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Linear, Flatten
from torch.utils.data import DataLoader
dataset=torchvision.datasets.CIFAR10("./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader=DataLoader(dataset,batch_size=1) #加载数据集
class Yu(nn.Module): #搭建网络
def __init__(self):
super(Yu,self).__init__()
self.model1=Sequential(
Conv2d(3,32,5,padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024,64),
Linear(64,10)
)
def forward(self,x):
x=self.model1(x)
return x
loss=nn.CrossEntropyLoss()
yu=Yu() #创建网络
optim=torch.optim.SGD(yu.parameters(),lr=0.01) #优化器
for epoch in range(20):
running_loss=0.0
for data in dataloader:
imgs,targets=data
outputs=yu(imgs)
result_loss=loss(outputs,targets)
optim.zero_grad() #梯度清0 grad=none
result_loss.backward() #反向传播 计算出每个节点的参数 grad会有计算出的参数
optim.step()
running_loss=running_loss+result_loss
print(running_loss)
现有网络模型的使用和修改--分类模型
import torchvision
from torch import nn
#对比VGG16中 pretrained为true和false时参数的不同
vgg16_false=torchvision.models.vgg16(pretrained=False)#网络模型中的参数是初始化的
vgg16_true=torchvision.models.vgg16(pretrained=True)#网络模型中的参数是训练好的
print(vgg16_true)
vgg16_true.classifier.add_module('add_linear',nn.Linear(1000,10)) #添加
print(vgg16_true)
print(vgg16_false)
vgg16_false.classifier[6]=nn.Linear(4096,10) #修改
print(vgg16_false)
模型的保存和加载
#模型的保存
import torch
import torchvision
from torch import nn
vgg16=torchvision.models.vgg16(pretrained=False) #参数是未经过训练的
#保存方式1 模型结构+模型参数
torch.save(vgg16,"vgg16_method1.pth")
#保存方式2 模型参数
torch.save(vgg16.state_dict(),"vgg16_method2.pth")
#模型的加载
import torch
import torchvision
#保存方式1,加载模型
model=torch.load("vgg16_method1.pth")
print(model)
#保存方式2 加载模型
vgg16=torchvision.models.vgg16(pretrained=False)
vgg16.load_state_dict(torch.load("vgg16_method2.pth"))
model=torch.load("vgg16_method2.pth")
print(model)
完整的模型·训练套路(以CIFAR10数据集)
所用的网络模型结构:
train.py
import torchvision
from model import *
from torch import nn
from torch.utils.data import DataLoader
#准备数据集
train_data=torchvision.datasets.CIFAR10(root="./data",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data=torchvision.datasets.CIFAR10(root="./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
#length长度
train_data_size=len(train_data)
test_data_size=len(test_data)
#如果train_data_size=10,训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))
#利用Dataloader来加载数据集
train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)
#创建网络模型
yu=Yu()
#损失函数
loss_fn=nn.CrossEntropyLoss()#交叉熵
#优化器
learning_rate=0.01 #学习速率
optimizer=torch.optim.SGD(yu.parameters(),lr=learning_rate)
#设置训练的一些参数
#记录训练的次数
total_train_step=0
#记录测试的次数
total_test_step=0
#训练的轮数
epoch=10
for i in range(epoch):
print("-------第{}论训练开始--------".format(i+1)) #i从0开始
#训练网络模型 训练步骤开始:
for data in train_dataloader:
imgs,targets=data
outputs=yu(imgs)
loss=loss_fn(outputs,targets)
#优化器优化模型
optimizer.zero_grad() #优化器梯度清0
loss.backward() #反向传播 得到每个参数节点的梯度
optimizer.step()#对参数节点进行优化
total_train_step=total_train_step+1
print("训练次数:{},loss:{}".format(total_train_step,loss.item()))
model.py
import torch
from torch import nn
class Yu(nn.Module):
def __init__(self):
super(Yu,self).__init__()
self.model=nn.Sequential(
nn.Conv2d(3,32,5,1,2), #第一张为3,卷积后的为32;kernel=5,stride=1,padding=2
nn.MaxPool2d(2),
nn.Conv2d(32,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,64,5,1,2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64*4*4,64),
nn.Linear(64,10)
)
def forward(self,x):
self.model(x)
return self.model(x)
if __name__=='__main__':
yu=Yu()
input=torch.ones((64,3,32,32)) #64张图片
output=yu(input)
print(output.shape)
train.py修改版
import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter
from model import *
from torch import nn
from torch.utils.data import DataLoader
#准备数据集
train_data=torchvision.datasets.CIFAR10(root="./data",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data=torchvision.datasets.CIFAR10(root="./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
#length长度
train_data_size=len(train_data)
test_data_size=len(test_data)
#如果train_data_size=10,训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))
#利用Dataloader来加载数据集
train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)
#创建网络模型
yu=Yu()
#损失函数
loss_fn=nn.CrossEntropyLoss()#交叉熵
#优化器
learning_rate=0.01 #学习速率
optimizer=torch.optim.SGD(yu.parameters(),lr=learning_rate)
#设置训练的一些参数
#记录训练的次数
total_train_step=0
#记录测试的次数
total_test_step=0
#添加tensorboard
writer=SummaryWriter("../logs_train")
#训练的轮数
epoch=10
for i in range(epoch):
print("-------第{}论训练开始--------".format(i+1)) #i从0开始
#训练网络模型 训练步骤开始:
for data in train_dataloader:
imgs,targets=data
outputs=yu(imgs)
loss=loss_fn(outputs,targets)
#优化器优化模型
optimizer.zero_grad() #优化器梯度清0
loss.backward() #反向传播 得到每个参数节点的梯度
optimizer.step()#对参数节点进行优化
total_train_step=total_train_step+1
print("训练次数:{},loss:{}".format(total_train_step,loss.item()))
writer.add_scalar("train_loss",loss.item(),total_train_step)
#测试步骤开始
total_test_step=0
total_accuracy=0
with torch.no_grad():
for data in test_dataloader:
imgs,targets=data
outputs=yu(imgs)
loss=loss_fn(outputs,targets)
total_test_loss=total_test_loss+loss.item()
accuracy=(output.argmax(1)==targets).sum()
total_accuracy=total_accuracy+accuracy
print("整体测试集上的loss:{}",format(total_test_loss))
print("整体测试集上的正确率:{}",format(total_accuracy/test_data_size))
writer.add_scalar("test_loss",total_test_loss,total_test_step)
writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)
total_test_step=total_train_step+1
torch.save(yu,"yu_{}.pth".format(i))
print("模型已保存")
writer.close()
使用GPU进行训练(方式1)---找到网络模型、数据(输入、标注)、损失函数 .cuda()
在Google colab中可以免费使用GPU -新建笔记本-文件-修改-笔记本设置-GPU
import time
import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter
#from model import *
from torch import nn
from torch.utils.data import DataLoader
#准备数据集
train_data=torchvision.datasets.CIFAR10(root="./data",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data=torchvision.datasets.CIFAR10(root="./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
#length长度
train_data_size=len(train_data)
test_data_size=len(test_data)
#如果train_data_size=10,训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))
#利用Dataloader来加载数据集
train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)
#创建网络模型
import torch
from torch import nn
class Yu(nn.Module):
def __init__(self):
super(Yu,self).__init__()
self.model=nn.Sequential(
nn.Conv2d(3,32,5,1,2), #第一张为3,卷积后的为32;kernel=5,stride=1,padding=2
nn.MaxPool2d(2),
nn.Conv2d(32,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,64,5,1,2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64*4*4,64),
nn.Linear(64,10)
)
def forward(self,x):
self.model(x)
return self.model(x)
yu=Yu()
if torch.cuda.is_available()
yu=yu.cuda()
#损失函数
loss_fn=nn.CrossEntropyLoss()#交叉熵
if torch.cuda.is_available()
loss_fn=loss_fn.cuda()
#优化器
learning_rate=0.01 #学习速率
optimizer=torch.optim.SGD(yu.parameters(),lr=learning_rate)
#设置训练的一些参数
#记录训练的次数
total_train_step=0
#记录测试的次数
total_test_step=0
#添加tensorboard
writer=SummaryWriter("../logs_train")
start_time=time.time()
#训练的轮数
epoch=10
for i in range(epoch):
print("-------第{}论训练开始--------".format(i+1)) #i从0开始
#训练网络模型 训练步骤开始:
for data in train_dataloader:
imgs,targets=data
if torch.cuda.is_available():
imgs=imgs.cuda()
targets=targets.cuda()
assert targets.dim() == 1 # 检查目标张量的维度是否为1
outputs=yu(imgs)
loss=loss_fn(outputs,targets)
#优化器优化模型
optimizer.zero_grad() #优化器梯度清0
loss.backward() #反向传播 得到每个参数节点的梯度
optimizer.step()#对参数节点进行优化
total_train_step=total_train_step+1
end_time=time.time()
print(end_time-start_time)
print("训练次数:{},loss:{}".format(total_train_step,loss.item()))
writer.add_scalar("train_loss",loss.item(),total_train_step)
#测试步骤开始
total_test_step=0
total_accuracy=0
total_test_loss=0
with torch.no_grad():
for data in test_dataloader:
imgs,targets=data
if torch.cuda.is_available():
imgs = imgs.cuda()
targets = targets.cuda()
outputs=yu(imgs)
loss=loss_fn(outputs,targets)
total_test_loss=total_test_loss+loss.item()
accuracy=(outputs.argmax(1)==targets).sum()
total_accuracy=total_accuracy+accuracy
print("整体测试集上的loss:{}",format(total_test_loss))
print("整体测试集上的正确率:{}",format(total_accuracy/test_data_size))
writer.add_scalar("test_loss",total_test_loss,total_test_step)
writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)
total_test_step=total_train_step+1
torch.save(yu,"yu_{}.pth".format(i))
print("模型已保存")
writer.close()
方式2 .to(device) 更常用
import time
import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter
#from model import *
from torch import nn
from torch.utils.data import DataLoader
#定义训练的设备
device=torch.device("cuda"if torch.cuda.is_available()else"cpu")
#准备数据集
train_data=torchvision.datasets.CIFAR10(root="./data",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data=torchvision.datasets.CIFAR10(root="./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
#length长度
train_data_size=len(train_data)
test_data_size=len(test_data)
#如果train_data_size=10,训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))
#利用Dataloader来加载数据集
train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)
#创建网络模型
import torch
from torch import nn
class Yu(nn.Module):
def __init__(self):
super(Yu,self).__init__()
self.model=nn.Sequential(
nn.Conv2d(3,32,5,1,2), #第一张为3,卷积后的为32;kernel=5,stride=1,padding=2
nn.MaxPool2d(2),
nn.Conv2d(32,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,64,5,1,2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64*4*4,64),
nn.Linear(64,10)
)
def forward(self,x):
self.model(x)
return self.model(x)
yu=Yu()
yu=yu.to(device)
#损失函数
loss_fn=nn.CrossEntropyLoss()#交叉熵
loss_fn=loss_fn.to(device)
#优化器
learning_rate=0.01 #学习速率
optimizer=torch.optim.SGD(yu.parameters(),lr=learning_rate)
#设置训练的一些参数
#记录训练的次数
total_train_step=0
#记录测试的次数
total_test_step=0
#添加tensorboard
writer=SummaryWriter("../logs_train")
start_time=time.time()
#训练的轮数
epoch=10
for i in range(epoch):
print("-------第{}论训练开始--------".format(i+1)) #i从0开始
#训练网络模型 训练步骤开始:
for data in train_dataloader:
imgs,targets=data
imgs=imgs.to(device)
targets=targets.to(device)
assert targets.dim() == 1 # 检查目标张量的维度是否为1
outputs=yu(imgs)
loss=loss_fn(outputs,targets)
#优化器优化模型
optimizer.zero_grad() #优化器梯度清0
loss.backward() #反向传播 得到每个参数节点的梯度
optimizer.step()#对参数节点进行优化
total_train_step=total_train_step+1
end_time=time.time()
print(end_time-start_time)
print("训练次数:{},loss:{}".format(total_train_step,loss.item()))
writer.add_scalar("train_loss",loss.item(),total_train_step)
#测试步骤开始
total_test_step=0
total_accuracy=0
total_test_loss=0
with torch.no_grad():
for data in test_dataloader:
imgs,targets=data
imgs = imgs.to(device)
targets = targets.to(device)
outputs=yu(imgs)
loss=loss_fn(outputs,targets)
total_test_loss=total_test_loss+loss.item()
accuracy=(outputs.argmax(1)==targets).sum()
total_accuracy=total_accuracy+accuracy
print("整体测试集上的loss:{}",format(total_test_loss))
print("整体测试集上的正确率:{}",format(total_accuracy/test_data_size))
writer.add_scalar("test_loss",total_test_loss,total_test_step)
writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)
total_test_step=total_train_step+1
torch.save(yu,"yu_{}.pth".format(i))
print("模型已保存")
writer.close()