- 1 加载数据初识
- 2 TensorBorad的使用
- 2.1 add_scalar()的使用
- 2.1 add_image()的使用
- 2.3 torchvision 中的transforms
- 2.4 常见的Transforms
- 2.4.1 ToTensor Normalize
- 2.4.2 Resize Compose RandomCrop
- 3 torchvision中的数据集使用
- 4 DataLoader的使用
- 5 神经网络的基本骨架-nn.Module的使用
- 6 卷积操作
- 7 神经网络卷积层
- 8 完整的模型训练套路
- 9 利用GPU训练
- 9.1 第一种方式
- 9.2 第二种方式
- 10 完整的模型验证套路
from torch.utils.data import Dataset
from PIL import Image
import os
class MyData(Dataset):
def __init__(self,root_dir,label_dir,img_dir):
self.root_dir=root_dir
self.label_dir=label_dir
self.img_dir=img_dir
self.path=os.path.join(self.root_dir,self.img_dir)
self.img_path=os.listdir(self.path)
def __getitem__(self, idx):
img_name=self.img_path[idx]
img_item_path=os.path.join(self.path,img_name)
img=Image.open(img_item_path)
label=self.label_dir
return img,label
def __len__(self):
return len(self.img_path)
root_dir="dataset//train"
ants_label_dir="ants"
ants_img_dir="ants_image"
bees_label_dir="bees"
bees_img_dir="bees_image"
ants_dataset=MyData(root_dir,ants_label_dir,ants_img_dir)
bees_dataset=MyData(root_dir,bees_label_dir,bees_img_dir)
img,labe=ants_dataset[1]
#img.show()
train_dataset=ants_dataset+bees_dataset
2 TensorBorad的使用
2.1 add_scalar()的使用
from torch.utils.tensorboard import SummaryWriter
writer=SummaryWriter("logs")
#writer.add_image()
# y=2x
for i in range(100):
writer.add_scalar("y=2x",3*i,i)
writer.close()
PS D:pythonProject> tensorboard --logdir D:pythonProjectlogs --port=6007 TensorFlow installation not found - running with reduced feature set. Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all TensorBoard 2.8.0a20211112 at http://localhost:6007/ (Press CTRL+C to quit)2.1 add_image()的使用
从PIL到numpy,需要在add_image()中指定shape中每一个数字/维表示的含义,shape将变换为 HWC。
from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Image
writer=SummaryWriter("logs")
image_path="dataset/train/ants_image/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("train",img_array,1,dataformats='HWC')
2.3 torchvision 中的transforms
from PIL.Image import Image
from torchvision import transforms
# python的用法 -》 tensor数据类型
# 通过 transforms.ToTensor去看两个问题
# 1 transforms该如何使用(python)
# 2 为社么我们需要Tensor数据类型
img_path ="dataset/train/ants_image/0013035.jpg"
img =Image.open(img_path)
tensor_trans=transforms.ToTensor() #实例化
tensor_img=tensor_trans(img)
writer= SummaryWriter("logs")
writer.add_image("Tensor_img",tensor_img)
writer.close()
2.4 常见的Transforms
2.4.1 ToTensor Normalize
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer=SummaryWriter("logs")
img =Image.open("dataset/train/ants_image/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([0.5,0.5,0.5],[0.5,0.5,0.5])
img_norm =trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normlize",img_norm)
writer.close()
2.4.2 Resize Compose RandomCrop
#Resize
print(img.size)
trans_resize=transforms.Resize((512,512))
#img PIL ->resize ->img_resize PIL
img_resize=trans_resize(img)
print(img_resize)
print(type(img_resize))
# Compose -resize -2
trans_resize_2=transforms.Resize(512)
#PIL ->PIL ->tensor
trans_compose=transforms.Compose([trans_resize_2,trans_totensor,]) # 新版本Resize可以用tensor
img_resize_2=trans_compose(img)
writer.add_image("Resize",img_resize_2,1)
#RandomCrop
trans_random=transforms.RandomCrop((50,100))
trans_compose_2=transforms.Compose([trans_random,trans_totensor])
for i in range(10):
img_crop=trans_compose_2(img)
print(img_crop.shape)
writer.add_image("RandomCropHW",img_crop,i)
writer.close()
3 torchvision中的数据集使用
import torchvision
from torch.utils.tensorboard import SummaryWriter
dataset_transform=torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
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()
writer=SummaryWriter("p10")
for i in range(10):
img,target=test_set[i]
writer.add_image("test_set",img,i)
writer.close()
4 DataLoader的使用
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 准备的测试数据集
test_data =torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor())
test_loader=DataLoader(dataset=test_data,batch_size=4,shuffle=True,num_workers=0,drop_last=True)
# shuffle 打乱数据集的顺序 num_workers 多线程进行 drop_last 是否去除 数据集总数与batch_size的余数
#测试数据集中第一张图片及target
img,target=test_data[0]
print(img.shape)
print(target)
writer=SummaryWriter("dataloader")
for epoch in range(2):
step=0
for data in test_loader:
imgs,targets=data
#print(imgs,shape)
#print(targets)
writer.add_images("Epoch:{}".format(epoch),imgs,step)
step=step+1
writer.close()
5 神经网络的基本骨架-nn.Module的使用
import torch
from torch import nn
class Tudui(nn.Module):
def __init__(self) :
super().__init__()
def forward(self,input):
output =input+1
return output
tudui = Tudui()
x=torch.tensor(1.0)
output=tudui(x)
print(output)
#输出 tensor(2.)6 卷积操作
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)
output3=F.conv2d(input,kernel,stride=1,padding=1)
print(output3)
输出
torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
tensor([[[[10, 12, 12],
[18, 16, 16],
[13, 9, 3]]]])
tensor([[[[ 1, 3, 4, 10, 8],
[ 5, 10, 12, 12, 6],
[ 7, 18, 16, 16, 8],
[11, 13, 9, 3, 4],
[14, 13, 9, 7, 4]]]])
7 神经网络卷积层
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 Tudui(nn.Module):
def __init__(self) :
super(Tudui,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
writer=SummaryWriter("../logs")
step =0
for data in dataloader:
imgs,targets =data
output =Tudui(imgs)
#torch.Size([64,3,32,32])
writer.add_image("input",imgs,step)
#torch.Size([64,6,30,30]) -->[xxx,3,30,30]
output=torch.reshape(output,(-1,3,30,30))
writer.add_image("output",output,step)
step=step+1
8 完整的模型训练套路
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from model import *
#准备数据集
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)
writer=SummaryWriter("./logs_xxx")
#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)
#创建网络模型
tudui=Tudui()
#损失函数
loss_fn=nn.CrossEntropyLoss()
#优化器
#learning_rate=0.01
#1e-2=1x(10)^(-2)=0.01
learning_rate=1e-2
optimizer=torch.optim.SGD(tudui.parameters(),lr=learning_rate)
#设置训练网络的一些参数
#记录训练的次数
total_train_step=0
#记录测试的次数
total_test_step=0
#训练的轮数
epoch=10
for i in range(epoch):
print("------------第{}轮训练开始------------".format(i+1))
#训练步骤开始
tudui.train()
for data in train_dataloader:
imgs,targets=data
outputs=tudui(imgs)
loss=loss_fn(outputs,targets)
#优化器优化模型
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_train_step=total_train_step+1
print("训练次数:{},Loss:{}".format(total_train_step,loss.item()))
#测试步骤开始
tudui.eval()
total_test_loss=0
total_accuracy=0
with torch.no_grad():
for data in test_dataloader:
imgs,targets=data
outputs=tuidu(imgs)
loss=loss_fn(outputs,targets)
total_test_loss=total_test_loss+loss.item()
accuracy=(outputs.argmax(1)==targets).sum()#0为纵向最大值的索引,1为横向最大值的索引
total_accuracy=total_accuracy+accuracy
print("整体测试集上的Loss:{}".format(total_test_loss))
print("整体测试集上的正确率:{}".format(total_accuracy/test_data_size))
writer.add_scala("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_test_step+1
torch.save(tudui,"tudui_{}.pth".format(i))
#torch.save(tudui.state_dict(),"tudui_{}.pth".format(i))
print("模型已保存")
writer.close()
model.py
import torch
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Linear
from torch.nn.modules.flatten import Flatten
#搭建神经网络
class Tudui(nn.Module):
def __init__(self):
super(Tudui, 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
if __name__=='__main__':
tuidu=Tudui()
input=torch.ones((64,3,32,32))
output=tuidu(input)
print(output.shape)
9 利用GPU训练
9.1 第一种方式
#创建网络模型
tudui=Tudui()
if torch.cuda.is_available():
tudui=tudui.cuda()
#损失函数
loss_fn=nn.CrossEntropyLoss()
if torch.cuda.is_available():
loss_fn=loss_fn.cuda()
for i in range(epoch):
print("------------第{}轮训练开始------------".format(i+1))
#训练步骤开始
tudui.train()
for data in train_dataloader:
imgs,targets=data
if torch.cuda.is_available():
imgs=imgs.cuda()
targets=targets.cuda()
#测试步骤开始
tudui.eval()
total_test_loss=0
total_accuracy=0
with torch.no_grad():
for data in test_dataloader:
imgs,targets=data
if torch.cuda.is_available():
imgs=imgs.cuda()
targets=targets.cuda()
9.2 第二种方式
.to(device)
device=torch.device("cuda")
device=torch.device("cuda:0")
device=torch.device("cuda" if torch.cuda.is_availiable() else "cpu")
import time
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from model import *
#定义训练的设备
device=torch.device("cuda")
#准备数据集
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)
writer=SummaryWriter("./logs_xxx")
#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)
#创建网络模型
tudui=Tudui()
tudui=tudui.to(device)
#损失函数
loss_fn=nn.CrossEntropyLoss()
loss_fn=loss_fn.to(device)
#优化器
#learning_rate=0.01
#1e-2=1x(10)^(-2)=0.01
learning_rate=1e-2
optimizer=torch.optim.SGD(tudui.parameters(),lr=learning_rate)
#设置训练网络的一些参数
#记录训练的次数
total_train_step=0
#记录测试的次数
total_test_step=0
#训练的轮数
epoch=10
for i in range(epoch):
print("------------第{}轮训练开始------------".format(i+1))
#训练步骤开始
start_time=time.time()
tudui.train()
for data in train_dataloader:
imgs,targets=data
imgs=imgs.to(device)
targets=targets.to(device)
outputs=tudui(imgs)
loss=loss_fn(outputs,targets)
#优化器优化模型
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_train_step=total_train_step+1
end_time=time.time()
print("用时:{}".format(end_time-start_time))
print("训练次数:{},Loss:{}".format(total_train_step,loss.item()))
#测试步骤开始
tudui.eval()
total_test_loss=0
total_accuracy=0
with torch.no_grad():
for data in test_dataloader:
imgs,targets=data
imgs=imgs.to(device)
targets=targets.to(device)
outputs=tuidu(imgs)
loss=loss_fn(outputs,targets)
total_test_loss=total_test_loss+loss.item()
accuracy=(outputs.argmax(1)==targets).sum()#0为纵向最大值的索引,1为横向最大值的索引
total_accuracy=total_accuracy+accuracy
print("整体测试集上的Loss:{}".format(total_test_loss))
print("整体测试集上的正确率:{}".format(total_accuracy/test_data_size))
writer.add_scala("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_test_step+1
torch.save(tudui,"tudui_{}.pth".format(i))
#torch.save(tudui.state_dict(),"tudui_{}.pth".format(i))
print("模型已保存")
writer.close()
10 完整的模型验证套路
import torch
import torchvision.transforms
from PIL.Image import Image
image_path="../imgs/dog.png" #png图片有四个通道,image=image.convert('RGB')
image=Image.open(image_path)
transform=torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),torchvision.transforms.ToTensor()])
image=transform(image)
model=torch.load("tudui_29_gpu.pth",map_location=torch.device('cpu'))#如果在cpu上加载 gpu训练的模型
image=torch.reshape(image,(1,3,32,32))
model.eval()
with torch.no_grad():
output=model(image)
print(output)
print(output.argmax(1))#输出outpu最大值的索引



