加载数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#从torch这个大工具箱里的常用的工具区中关于数据的data区
from torch.utils.data import Dataset
#读取图片
from PIL import Image
#对文件以及文件夹操作
import os
####################################################第一种label和图片没有单独保存#################
#重写函数继承Dataset类

class MyData(Dataset):
#初始化 传入文件地址以及label名称 self相当于一个类中的全局变量
#方便后面的函数使用
def __init__(self,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)
#列出某目录下所有的文件和目录行成列表给img_path
self.img_path = os.listdir(self.path)

#这个方法的作用是,可以将类中的数据像数组一样读出
def __getitem__(self, idx):
#利用初始化中img_path[idx]使用索引寻找图片名字
img_name = self.img_path[idx]
#每一个图片的位置形式为self.root_dir/self.label_dir/img_name
img_item_path = os.path.join(self.root_dir,self.label_dir,img_name)
#读取图片
img = Image.open(img_item_path)
#label在这里就是数据的文件夹名
label = self.label_dir
#返回每张图片和label作为训练使用
return img,label
#数据集的长度
def __len__(self):
#路径的数量就是数据集的长度
return len(self.img_path)
#蚂蚁数据集
root_dir = "hymenoptera_data/train"
ants_label_dir = "ants"
ants_dataset = MyData(root_dir,ants_label_dir)
#展示图片
# img,label =ants_dataset[0]
# img.show()
#蜜蜂数据集
root_dir = "hymenoptera_data/train"
bees_label_dir = "bees"
bees_dataset = MyData(root_dir,bees_label_dir)
#展示图片
img,label =bees_dataset[0]
img.show()
#查看数据集数量
print(len(bees_dataset))
train_dataset = ants_dataset + bees_dataset



transforms图片类型转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from PIL import Image
##输入特定类型的图片 输出想要的结果
# 通过transforms.ToTensor 解决两个问题
# 1. transforms被如何使用
# 2. 为什么需要Tensor 数据类型 ---包含了机器学习需要的数据
#打开图片
img_path = "练习/train/ants_image/0013035.jpg"
img = Image.open(img_path)

# 1. transforms被如何使用
#把图片转化成Tensor数据类型
##实例化类
tensor_trans = transforms.ToTensor()
## 进行数据转换 参数为图片
tensor_img = tensor_trans(img)


# #通过opencv读取
# import cv2
# cv_img = cv2.imread(img_path)

#画图展示
writer = SummaryWriter("logs")

#参数为图像标题 图片 训练步数
writer.add_image("Tensor_img",tensor_img)
writer.close()

##查看事件文件 终端输入 参数为文件名以及自定义端口
#tensorboard --logdir=logs --port=6007









transforms应用1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
img = Image.open("images/roll05.jpg")
print(img)
##实例化类
tensor_trans = transforms.ToTensor()
## 进行数据转换 参数为图片
tensor_img = tensor_trans(img)

#画图展示
writer = SummaryWriter("logs")

#参数为图像标题 图片 训练步数
writer.add_image("Tensor_img",tensor_img)



#normalize的使用--把tensor类型的图像归一化
#归一化是为了消除奇异值,及样本数据中与其他数据相比特别大或特别小的数据 这样可以加快训练速度
##参数为均值和标准差 RGB图像需要三个均值三个标准差
trans_norm = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
img_norm = trans_norm(tensor_img)
writer.add_image("Normalize",img_norm)



#Resize的使用1 --把PIL类型的图像重新设置长宽尺寸,输出仍然为PIL类型
print(img.size)
##先从模板中生成一个自己的实例化对象trans_resize
trans_resize = transforms.Resize((512,512))
img_resize = trans_resize(img)

#转换为Tensor类型
##实例化类
trans_totensor = transforms.ToTensor()
img_resize = trans_totensor(img_resize)
print(img_resize)
writer.add_image("Resize",img_resize)


#Resize的使用2 --等比缩放
##将图片短边缩放至x,长宽比保持不变 transforms.Resize(x)
trans_resize_2 = transforms.Resize(512)
##transforms.Compose先进行缩放在进行转换类型 --组合技 参数为实例化对象
##Compose类,用于将多个数据预处理操作组合成一个整体的变换
# 具体而言,Compose 函数接受一个包含多个转换的列表,按顺序应用这些转换。 这些转换可以包括调整图像大小、裁剪、翻转、归一化等。
#PIL->PIL->tensor 实例化一个组合类
trans_compose = transforms.Compose([trans_resize_2,trans_totensor])
img_resize_2 = trans_compose(img)
writer.add_image("Resize2",img_resize_2,1)




writer.close()



##查看事件文件 终端输入 参数为文件名以及自定义端口
#tensorboard --logdir=logs --port=6007





Dataloader使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import torchvision
from torch.utils.tensorboard import SummaryWriter
#实例化对象进行数据类型转换
dataset_transform = torchvision.transforms.Compose([
torchvision.transforms.ToTensor()
])


#使用官方提供的CIFAR10数据集
#参数为 数据集存放位置 是否作为训练集(否则变成测试集) transform操作 是否下载数据集
##训练数据集
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)
##输出3代表属于第四类 cat
print(target)
##查看某一张图像所属分类
print(test_set.classes[target])
# img.show()



#画图展示
writer = SummaryWriter("logs")
#显示前10张
for i in range(10):
img,target = test_set[i]
writer.add_image("联合使用",img,i)

writer.close()




##查看事件文件 终端输入 参数为文件名以及自定义端口
#tensorboard --logdir=logs --port=6007
神经网络基本骨架-nn.Module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import torch
from torch import nn


# 输入经过模型(forward函数),然后输出
# 卷积 conv1() conv2()
# 非线性F.relu()

#重写类来继承nn.Module
class Module_1(nn.Module):
def __init__(self):
super().__init__()
def forward(self,input):
output = input + 1
return output
#实例化类
module_1 = Module_1()
x = torch.tensor(1.0)

#把输入放进神经网络中
output = module_1(x)
print(output)

卷积
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#卷积的作用是提取特征

#卷积核在输入图像上操作 且不断移动
# 对应位相乘在相加后输出


#参数 1. stride 卷积核每次移动步数 --横向步径和纵向步径


import torch
import torch.nn.functional as F
#把二维数组转化成tensor类型
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]])
print(input.shape)
print(kernel.shape)

#卷积操作需要输入的尺寸为为四个数据 minibatch 通道个数,高,宽
#修改输入的尺寸
input = torch.reshape(input,(1,1,5,5))
kernel = torch.reshape(kernel,(1,1,3,3))
print(input.shape)
print(kernel.shape)


#卷积操作
##参数为输入、 卷积核、 卷积核每次移动步数 --横向步径和纵向步径
##对输入 左右填充一列 上下填充一行 的数据的内容 padding 默认为0
output = F.conv2d(input,kernel,stride=1,padding=1)
print(output)





卷积层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.nn import Conv2d
from torch.utils.tensorboard import SummaryWriter

#下载训练数据集

train_set = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=torchvision.transforms.ToTensor() ,
download=True)
#加载数据集
dataloader = DataLoader(dataset=train_set,batch_size=64)

#编写神经网络基本骨架
#重写类来继承nn.Module

#重写类来继承nn.Module
class Module_1(nn.Module):
def __init__(self):
super().__init__()
#Conv2d卷积参数:输入通道个数 输出通道个数 卷积核大小(3代表3*3大小)
#卷积核每次移动步数 输入填充数据内容
#实例化卷积对象
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
##实例化类
module_1 = Module_1()

step = 0
#创建实例 把事件文件存放在logs文件夹
writer = SummaryWriter("logs")


#提取加载器中的数据
for data in dataloader:
imgs,targrts = data
#把输入放进神经网络中
output = module_1(imgs)
# print(output.shape)
#显示图像
writer.add_images("input",imgs,step)
#修改输出图像的尺寸
#torch.Size([64,6,30,30]) -> [xxx,3,30,30]
#-1代表未知,计算机自己计算
output_imgs = torch.reshape(output,(-1,3,30,30))
writer.add_images("output",output_imgs,step)
step = step + 1
##关闭实例
writer.close()
##查看事件文件 终端输入 参数为文件名以及自定义端口
#tensorboard --logdir=logs --port=6007



最大池化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#最大池化的目的是保留输入特征同时减少数据量

#池化核覆盖在输入图像上,在覆盖区域取最大值作为输出--降采样
#池化层默认步长为核大小,卷积层默认步长为1
#Ceil_model=True则保留输入的边缘池化
import torch
import torchvision
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

#池化输入不能为整型


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)



#编写神经网络基本骨架
#重写类来继承nn.Module

#重写类来继承nn.Module
class Module_1(nn.Module):
def __init__(self):
super().__init__()
#MaxPool2d最大池化参数:池化核尺寸,是否保留输入的边缘池化
#实例化池化对象
self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)
def forward(self,input):
output = self.maxpool1(input)
return output
##实例化类
module_1 = Module_1()

#给神经网络传入输入
output = module_1(input)
# print(output)




dataset = torchvision.datasets.CIFAR10(root="./dataset",train=False,
transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset=dataset,batch_size=64)


step = 0
#从加载器DataLoader中提取数据
for data in dataloader:
imgs, targets = data
# print(imgs.shape)
# print(targets)
# 画图展示
writer = SummaryWriter("logs")
writer.add_images("input", imgs, step)
output = module_1(imgs)
writer.add_images("output",output,step)
step = step + 1

writer.close()

##查看事件文件 终端输入 参数为文件名以及自定义端口
# tensorboard --logdir=logs --port=6007

非线性激活
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#引入非线性特质
# ReLU激活函数的功能就是这个,小于0的数返回0,不小于0的数返回原值
import torch
import torchvision
from torch import nn
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]])
#引入relu非线性需要指定bash_size
#改变输入的形状 bash_size机器自己算 一维,2x2的数据

input = torch.reshape(input,(-1,1,2,2))
print(input)


#神经网络
#重写类来继承nn.Module
class Module_1(nn.Module):
def __init__(self):
super().__init__()
#实例化relu
self.relu1 = ReLU()
#实例化sigmoid非线性激活函数
self.sigmoid1 = Sigmoid()
def forward(self,input):
#参数为inplace:是否改变输入的值 默认False
output = self.sigmoid1(input)
return output
#实例化类
module_1 = Module_1()

#把输入放进神经网络中
output = module_1(input)
print(output)

#下载训练数据集

train_set = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=torchvision.transforms.ToTensor() ,
download=True)
#加载数据集
dataloader = DataLoader(dataset=train_set,batch_size=64)

#创建实例 把事件文件存放在logs文件夹
writer = SummaryWriter("logs")
step = 0

#提取加载器中的数据
for data in dataloader:
imgs,targrts = data
# 显示图像
writer.add_images("input", imgs, step)
#把输入放进神经网络中
output = module_1(imgs)
# print(output.shape)
writer.add_images("output", output, step)
step = step + 1


##关闭实例
writer.close()
##查看事件文件 终端输入 参数为文件名以及自定义端口
#tensorboard --logdir=logs --port=6007

线性层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader




#下载训练数据集


train_set = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=torchvision.transforms.ToTensor() ,
download=True)
#加载数据集
dataloader = DataLoader(dataset=train_set,batch_size=64)


#神经网络
#重写类来继承nn.Module
class Module_1(nn.Module):
def __init__(self):
super().__init__()
#实例化Linear
##参数为输入个数 隐藏层个数(输出个数)
self.linear1 = Linear(196608,10)
def forward(self,input):
#参数为inplace:是否改变输入的值 默认False
output = self.linear1(input)
return output
#实例化类
module_1 = Module_1()


#提取加载器中的数据
for data in dataloader:
imgs,targrts = data
#做线性运算需要把图片拉直成一排
# print(imgs.shape)
# 1:batch_size变为1,1:通道数变为1,1:高变为1,-1:宽度自己计算,总的来说就是把图拉直开了
# output = torch.reshape(imgs,(1,1,1,-1))
# 图像展平
output = torch.flatten(imgs)
print(output.shape)
# 把输入放进神经网络中
output = module_1(output)
print(output.shape)


实战Sequential
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import torch
from torch import nn


#神经网络
#重写类来继承nn.Module
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.tensorboard import SummaryWriter


class Module_1(nn.Module):
def __init__(self):
super().__init__()
# Conv2d卷积参数:输入通道个数 输出通道个数 卷积核大小(3代表3*3大小)
# 卷积核每次移动步数 输入填充数据
# 实例化卷积对象
self.conv1 = Conv2d(in_channels=3, out_channels=32, kernel_size=3, stride=1, padding=2)
# 实例化最大池化对象
self.maxpool1 = MaxPool2d(2)
# 实例化卷积对象
self.conv2 = Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2)
# 实例化最大池化对象
self.maxpool2 = MaxPool2d(2)
# 实例化卷积对象
self.conv3 = Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2)
# 实例化最大池化对象
self.maxpool3 = MaxPool2d(2)
# 实例化展平对象
self.flatten = Flatten()
# 实例化线性层 输入个数 输出个数
self.linear1 = Linear(1024,64)
self.linear2 = Linear(64, 10)
# 实例化Sequential 相当于顺序执行程序
self.model1 = Sequential(
Conv2d(3,32,5,padding=2),
MaxPool2d(2),
Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
MaxPool2d(2),
Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
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)
x = self.model1(x)
return x
#实例化类
module_1 = Module_1()
#检验网络
input = torch.ones((64,3,32,32))
output = module_1(input)
print(output.shape)


#显示网络
#画图展示
writer = SummaryWriter("logs")

#参数为模型实例化的名字 模型的输入
writer.add_graph(module_1,input)
writer.close()

##查看事件文件 终端输入 参数为文件名以及自定义端口
#tensorboard --logdir=logs --port=6007


损失函数与反向传播
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#损失函数  --预测值与真实值的偏差
#为更新输出提供依据(反向传播)
# loss函数是找最小值的,要求导,在计算机里面计算导数是倒着来的,所以叫反向传播。

import torch
from torch.nn import L1Loss
from torch import nn

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))
targets = torch.reshape(targets,(1,1,1,3))

#实例化loss函数 --参数为计算损失的方式
loss = L1Loss(reduction='sum')
result = loss(inputs,targets)

#平方差
loss_mse = nn.MSELoss()
result_mse = loss_mse(inputs,targets)

print(result)
print(result_mse)

#交叉熵
##某东西在三个分类里的得分
x = torch.tensor([0.1,0.2,0.3])
##某东西所属的分类编号
y = torch.tensor([1])
##输入必须为 N(数据个数) 分类个数
x = torch.reshape(x,(1,3))
loss_cross = nn.CrossEntropyLoss()
result_cross = loss_cross(x,y)
print(result_cross)


优化器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader

#下载训练数据集

train_set = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=torchvision.transforms.ToTensor() ,
download=True)
#加载数据集
dataloader = DataLoader(dataset=train_set,batch_size=64)



#神经网络
#重写类来继承nn.Module
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.tensorboard import SummaryWriter


class Module_1(nn.Module):
def __init__(self):
super().__init__()

# 实例化Sequential 相当于顺序执行程序
self.model1 = Sequential(
Conv2d(3,32,5,padding=2),
MaxPool2d(2),
Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
MaxPool2d(2),
Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)

def forward(self,x):
x = self.model1(x)
return x

loss = nn.CrossEntropyLoss()
#实例化类
module_1 = Module_1()

#设置优化器 --参数:模型参数,学习速率
optim = torch.optim.SGD(module_1.parameters(),lr=0.01)

#读取加载器数据--两次读取 = 两轮学习
for epoch in range(20):
#每轮学习的偏差
running_loss = 0.0
for data in dataloader:
imgs,targets = data
outputs = module_1(imgs)
result_loss = loss(outputs,targets)
#调用优化器
#把所有梯度优化参数置为0 --一定注意 不然内存爆炸
optim.zero_grad()
#使用反向传播获得可调参数的梯度
result_loss.backward()
#对每个参数调优
optim.step()
# print("ok")
running_loss = running_loss + result_loss
print(running_loss)


网络模型的使用和修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import torchvision


#下载模型
from torch import nn

vgg16_false = torchvision.models.vgg16(weights=None)
vgg16_true = torchvision.models.vgg16(weights='DEFAULT')
print("ok")
#查看模型结构
print(vgg16_true)

#给模型增加线性层 --参数 层名字(自定义) 增加的模型种类
vgg16_true.add_module('add_linear',nn.Linear(1000,10))
#输出添加后的网络
print(vgg16_true)
#给模型里的classifier这一层模型添加模型
vgg16_true.classifier.add_module('add_linear',nn.Linear(1000,10))
#给模型里的classifier这一层模型的第七个模型修改为其他模型
vgg16_true.classifier[6] = nn.Linear(4096,10)
print(vgg16_true)
模型的保存与加载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#下载模型
import torch
import torchvision
from torch import nn
#下载模型
vgg16_false = torchvision.models.vgg16(weights=None)
vgg16_true = torchvision.models.vgg16(weights='DEFAULT')
print("ok")

#保存模型1 --参数 模型 模型路径
torch.save(vgg16_false,"vgg16_method1.pth")
#加载模型1 --参数 模型路径
model = torch.load("vgg16_method1.pth")
print(model)

#推荐
#保存模型2 --参数state_dict()方法 模型路径
torch.save(vgg16_false.state_dict(),"vgg16_method2.pth")
#加载模型2 --参数 模型路径
vgg16_false.load_state_dict("vgg16_method2.pth")
print(model)

完整的模型训练
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import torch


#准备数据集
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

from model import *

train_data = torchvision.datasets.CIFAR10(root="./dataset",train=True,transform=torchvision.transforms.ToTensor() ,
download=True)
test_data = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=torchvision.transforms.ToTensor() ,
download=True)

#求数据集的长度
train_data_size = len(train_data)
test_data_size = len(test_data)

print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))

#加载数据集
train_dataloader = DataLoader(dataset=train_data,batch_size=64)
#加载数据集
test_dataloader = DataLoader(dataset=test_data,batch_size=64)

#搭建神经网络

module_1 = Module_1()

#创建损失函数
##交叉熵
loss_fn = nn.CrossEntropyLoss()

#定义优化器
##随机梯度下降 --参数:网络模型,学习速率,
##1e-2=1x(10)^(-2)=0.01
learning_rate = 0.001
optimizer = torch.optim.SGD(module_1.parameters(),lr=learning_rate)

#设置训练网络的一些参数
##训练次数
total_train_step = 0
##测试次数
total_test_step = 0
#训练轮数
epoch = 10

# 创建实例 把事件文件存放在logs文件夹
writer = SummaryWriter("logs")

for i in range(epoch):
print("---------第{}轮训练开始-------".format(i+1))
#训练开始
module_1.train()
for data in train_dataloader:
imgs,target = data
outputs = module_1(imgs)
loss = loss_fn(outputs,target)

#使用优化器优化模型 梯度清零
optimizer.zero_grad()
#使用损失和反向传播求取梯度值
loss.backward()
#梯度优化
optimizer.step()
total_train_step = total_train_step + 1
if total_train_step % 100 ==0:
print("训练次数:{},loss: {}".format(total_train_step,loss.item()))
writer.add_scalar("train_loss",loss.item(),total_train_step)
#测试模型的准确性
#测试开始
module_1.eval()
total_test_loss = 0
##模型正确率
total_accuracy = 0
#关闭梯度计算减少内存消耗
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
outputs = module_1(imgs)
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss
#找每个数据中分类最大的得分的分类编号与本来的数据的分类编号对比 看看正确的个数
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_test_step + 1

#保存模型
torch.save(module_1,'module_1_{}.pth'.format(i))
print("模型已保存")


##关闭实例
writer.close()
##查看事件文件 终端输入 参数为文件名以及自定义端口
# tensorboard --logdir=logs --port=6007

GPU训练方式一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#输入可以是网络模型 ,数据(输入,标注),损失函数,然后调用.cuda()




import torch


#准备数据集
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter



train_data = torchvision.datasets.CIFAR10(root="./dataset",train=True,transform=torchvision.transforms.ToTensor() ,
download=True)
test_data = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=torchvision.transforms.ToTensor() ,
download=True)

#求数据集的长度
train_data_size = len(train_data)
test_data_size = len(test_data)

print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))

#加载数据集
train_dataloader = DataLoader(dataset=train_data,batch_size=64)
#加载数据集
test_dataloader = DataLoader(dataset=test_data,batch_size=64)

#搭建神经网络

class Module_1(nn.Module):
def __init__(self):
super().__init__()
# 实例化Sequential 相当于顺序执行程序
self.model1 = Sequential(
nn.Conv2d(3,32,5,1,padding=2),
nn.MaxPool2d(2),
nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
nn.MaxPool2d(2),
nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(1024, 64),
nn.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)
x = self.model1(x)
return x
module_1 = Module_1()
#模型放入cuda
if torch.cuda.is_available():
module_1 = module_1.cuda()
#创建损失函数
##交叉熵
loss_fn = nn.CrossEntropyLoss()
#损失量放入cuda
loss_fn = loss_fn.cuda()

#定义优化器
##随机梯度下降 --参数:网络模型,学习速率,
##1e-2=1x(10)^(-2)=0.01
#改变学习率可以提供模型精度
learning_rate = 0.01
optimizer = torch.optim.SGD(module_1.parameters(),lr=learning_rate)

#设置训练网络的一些参数
##训练次数
total_train_step = 0
##测试次数
total_test_step = 0
#训练轮数
epoch = 10

# 创建实例 把事件文件存放在logs文件夹
writer = SummaryWriter("logs")

for i in range(epoch):
print("---------第{}轮训练开始-------".format(i+1))
#训练开始
module_1.train()
for data in train_dataloader:
imgs,targets = data
# 数据放入cuda
imgs = imgs.cuda()
targets = targets.cuda()
outputs = module_1(imgs)
loss = loss_fn(outputs,targets)

#使用优化器优化模型 梯度清零
optimizer.zero_grad()
#使用损失和反向传播求取梯度值
loss.backward()
#梯度优化
optimizer.step()
total_train_step = total_train_step + 1
if total_train_step % 100 ==0:
print("训练次数:{},loss: {}".format(total_train_step,loss.item()))
writer.add_scalar("train_loss",loss.item(),total_train_step)
#测试模型的准确性
#测试开始
module_1.eval()
total_test_loss = 0
##模型正确率
total_accuracy = 0
#关闭梯度计算减少内存消耗
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
# 数据放入cuda
imgs = imgs.cuda()
targets = targets.cuda()
outputs = module_1(imgs)
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss
#找每个数据中分类最大的得分的分类编号与本来的数据的分类编号对比 看看正确的个数
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_test_step + 1

#保存模型
torch.save(module_1,'module_1_{}.pth'.format(i))
print("模型已保存")


##关闭实例
writer.close()
##查看事件文件 终端输入 参数为文件名以及自定义端口
# tensorboard --logdir=logs --port=6007

GPU训练方式二
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#输入可以是网络模型 ,数据(输入,标注),损失函数,
#定义训练的设备 device = torch.device("cuda") 然后调用.to(device)




import torch


#准备数据集
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

#定义训练的设备
device = torch.device("cuda")

train_data = torchvision.datasets.CIFAR10(root="./dataset",train=True,transform=torchvision.transforms.ToTensor() ,
download=True)
test_data = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=torchvision.transforms.ToTensor() ,
download=True)

#求数据集的长度
train_data_size = len(train_data)
test_data_size = len(test_data)

print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))

#加载数据集
train_dataloader = DataLoader(dataset=train_data,batch_size=64)
#加载数据集
test_dataloader = DataLoader(dataset=test_data,batch_size=64)

#搭建神经网络

class Module_1(nn.Module):
def __init__(self):
super().__init__()
# 实例化Sequential 相当于顺序执行程序
self.model1 = Sequential(
nn.Conv2d(3,32,5,1,padding=2),
nn.MaxPool2d(2),
nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
nn.MaxPool2d(2),
nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(1024, 64),
nn.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)
x = self.model1(x)
return x
module_1 = Module_1()
#模型放入cuda
if torch.cuda.is_available():
module_1 = module_1.to(device)
#创建损失函数
##交叉熵
loss_fn = nn.CrossEntropyLoss()
#损失量放入gpu
loss_fn = loss_fn.to(device)

#定义优化器
##随机梯度下降 --参数:网络模型,学习速率,
##1e-2=1x(10)^(-2)=0.01
#改变学习率可以提供模型精度
learning_rate = 0.01
optimizer = torch.optim.SGD(module_1.parameters(),lr=learning_rate)

#设置训练网络的一些参数
##训练次数
total_train_step = 0
##测试次数
total_test_step = 0
#训练轮数
epoch = 10

# 创建实例 把事件文件存放在logs文件夹
writer = SummaryWriter("logs")

for i in range(epoch):
print("---------第{}轮训练开始-------".format(i+1))
#训练开始
module_1.train()
for data in train_dataloader:
imgs,targets = data
# 数据放入cuda
imgs = imgs.to(device)
targets = targets.to(device)
outputs = module_1(imgs)
loss = loss_fn(outputs,targets)

#使用优化器优化模型 梯度清零
optimizer.zero_grad()
#使用损失和反向传播求取梯度值
loss.backward()
#梯度优化
optimizer.step()
total_train_step = total_train_step + 1
if total_train_step % 100 ==0:
print("训练次数:{},loss: {}".format(total_train_step,loss.item()))
writer.add_scalar("train_loss",loss.item(),total_train_step)
#测试模型的准确性
#测试开始
module_1.eval()
total_test_loss = 0
##模型正确率
total_accuracy = 0
#关闭梯度计算减少内存消耗
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
# 数据放入cuda
imgs = imgs.to(device)
targets = targets.to(device)
outputs = module_1(imgs)
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss
#找每个数据中分类最大的得分的分类编号与本来的数据的分类编号对比 看看正确的个数
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_test_step + 1

#保存模型
torch.save(module_1,'module_1_{}.pth'.format(i))
print("模型已保存")


##关闭实例
writer.close()
##查看事件文件 终端输入 参数为文件名以及自定义端口
# tensorboard --logdir=logs --port=6007

完整的模型验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential


#验证图片的路径
import torchvision
from PIL import Image

image_path = "imgs/dog.jpg"

#定义训练的设备
device = torch.device("cuda")

#读取PIL图片
image = Image.open(image_path)

#输入模型的图片必须为32x32 所以修改图片尺寸 然后转成tensor类型
transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),
torchvision.transforms.ToTensor()])
#开始转换
image = transform(image)
print(image.shape)


#搭建神经网络
class Module_1(nn.Module):
def __init__(self):
super().__init__()
# 实例化Sequential 相当于顺序执行程序
self.model1 = Sequential(
nn.Conv2d(3,32,5,1,padding=2),
nn.MaxPool2d(2),
nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
nn.MaxPool2d(2),
nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(1024, 64),
nn.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)
x = self.model1(x)
return x

#加载模型 gpu的模型使用cpu运行时候加上参数 map_location=torch.device('cpu')
model = torch.load("module_1_29.pth")
print(model)

#图片放入模型
image = torch.reshape(image,(1,3,32,32))
#因为模型是cuda训练 所以改变输入类型
image = image.to(device)

model.eval()
with torch.no_grad():
output = model(image)
print(output)
#查看所属类别
print(output.argmax(1))
model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#搭建神经网络
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
class Module_1(nn.Module):
def __init__(self):
super().__init__()
# 实例化Sequential 相当于顺序执行程序
self.model1 = Sequential(
nn.Conv2d(3,32,5,1,padding=2),
nn.MaxPool2d(2),
nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
nn.MaxPool2d(2),
nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(1024, 64),
nn.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)
x = self.model1(x)
return x

#测试网络正确性
if __name__ == '__main__':
# 实例化类
module_1 = Module_1()
# 创建输入尺寸
input = torch.ones(64,3,32,32)
output = module_1(input)
print(output.shape)
配置环境
  1. 下载源码并解压 https://github.com/ultralytics/yolov5/tree/v5.0
  2. pycharm打开后命令终端输入
    1
    pip install -r requirements.txt
detect.py解读
  1. 输入图片在data/images 输出在runs\detect\exp
  2. 没有出现标注 修改参数device一行为cpu如下图
  3. 参数解读
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    #默认权重模型为yolov5s.pt
    parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')
    #输入的资源在data/images文件夹中 可以是图片或者视频
    parser.add_argument('--source', type=str, default='data/images', help='source') # file/folder, 0 for webcam
    #修改输入资源的尺寸为适合神经网络的尺寸
    parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
    #置信度 --概率大于某值后再显示
    parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
    #非最大抑制 -- IOU=交集区域/并集区域 多个框相交时满足条件则选择最优框 不满足则保留所有框
    parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
    #运行方式 cuda或者cpu
    parser.add_argument('--device', default='cpu', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    #显示结果 默认不显示 命令行带上参数view-img时则显示 比如 python detect.py --view-img
    #用处2 实时显示输出结果 --点击pycharm右上角detect.py文件 点击编辑配置 在参数一行输入--view-img
    parser.add_argument('--view-img', action='store_true', help='display results')
    #把结果保存为txt形式 命令行带上参数save-txt时则保存 数据为 类别 x y height width
    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
    parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
    #只显示某类别的显示 例如 参数--classes 0 这里0是人类别
    parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
    parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
    #增强检测功能
    parser.add_argument('--augment', action='store_true', help='augmented inference')
    parser.add_argument('--update', action='store_true', help='update all models')
    #项目保存结果的位置project/name
    parser.add_argument('--project', default='runs/detect', help='save results to project/name')
    parser.add_argument('--name', default='exp', help='save results to project/name')
    #覆盖原来的项目结果
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
云端GPU训练yolov5神经网络
  1. https://colab.research.google.com/
  2. 笔记本修改为GPU
  3. 点击文件夹上传打包的项目压缩包
  4. %是用户权限 !是root权限
  5. 命令行解压缩
    1
    !unzip /content/yolov5-5.0.zip -d /content/yolov5
  6. 进入项目文件夹里
    1
    %cd /content/yolov5/yolov5-5.0
  7. 安装需要的环境
    1
    !pip install -r requirements.txt
  8. 添加tensorboard插件
    1
    %load_ext tensorboard
  9. 启动tensorboard
    1
    %tensorboard --logdir=runs/train
  10. 启动训练文件
    1
    !python train.py --rect
自制数据集和训练数据集
  1. action->edit labels 添加类别
  2. 右边点击rect进行矩形标注
  3. action->load AI model使用模型帮助标注
  4. action->export rect annotation导出标注的数据集
  5. pycharm建立数据集 建立data文件夹 下面建立一个images文件夹和labels文件夹 images文件夹->test train labels文件夹->test train
  6. 建立yaml文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #训练数据集的路径
    train: ../coco/train2017.txt # 118287 images
    #验证数据集的路径
    val: ../coco/val2017.txt # 5000 images
    #测试数据集的路径
    test: ../coco/test-dev2017.txt # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794

    # 类别的数量
    nc: 80

    # 类别的名字
    names: [ 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
    'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
    'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
    'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
    'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
    'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
    'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
    'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
    'hair drier', 'toothbrush' ]

    # Print classes
    # with open('data/coco.yaml') as f:
    # d = yaml.load(f, Loader=yaml.FullLoader) # dict
    # for i, x in enumerate(d['names']):
    # print(i, x)

  7. 在train.py中主函数中修改数据集yaml为自己新建立的
    1
    2
    3
    4
    5
    if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='', help='model.yaml path')
    parser.add_argument('--data', type=str, default='data/coco128.yaml', help='data.yaml path')
VOC数据集
  1. Annotations 文件夹是一些标注信息 ,xml是该图片的各种描述信息。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    <annotation>
    <!-- 所在文件夹的名字 -->
    <folder>VOC2007</folder>
    <!-- 描述的是哪张图片 -->
    <filename>000032.jpg</filename>
    <source>
    <database>The VOC2007 Database</database>
    <annotation>PASCAL VOC2007</annotation>
    <image>flickr</image>
    <flickrid>311023000</flickrid>
    </source>
    <owner>
    <flickrid>-hi-no-to-ri-mo-rt-al-</flickrid>
    <name>?</name>
    </owner>
    <!-- 图片尺寸 -->
    <size>
    <width>500</width>
    <height>281</height>
    <depth>3</depth>
    </size>
    <segmented>1</segmented>
    <!-- 包含的物体 -->
    <object>
    <!-- 第一个物体是飞机 -->
    <name>aeroplane</name>
    <!-- 飞机拍摄的角度是前向 -->
    <pose>Frontal</pose>
    <!-- 图片是完整的 -->
    <truncated>0</truncated>
    <!-- 识别不困难 -->
    <difficult>0</difficult>
    <!-- 该物体的边框位置 -->
    <bndbox>
    <xmin>104</xmin>
    <ymin>78</ymin>
    <xmax>375</xmax>
    <ymax>183</ymax>
    </bndbox>
    </object>
    <object>
    <name>aeroplane</name>
    <pose>Left</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
    <xmin>133</xmin>
    <ymin>88</ymin>
    <xmax>197</xmax>
    <ymax>123</ymax>
    </bndbox>
    </object>
    <object>
    <name>person</name>
    <pose>Rear</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
    <xmin>195</xmin>
    <ymin>180</ymin>
    <xmax>213</xmax>
    <ymax>229</ymax>
    </bndbox>
    </object>
    <object>
    <name>person</name>
    <pose>Rear</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
    <xmin>26</xmin>
    <ymin>189</ymin>
    <xmax>44</xmax>
    <ymax>238</ymax>
    </bndbox>
    </object>
    </annotation>

  2. ImageSets 图片集合 其中Main文件夹是分类和目标检测 Layout文件夹是预测布局 Segmentation文件夹是语义分割
    Main文件夹中txt文件名字为类别名,txt存储了两列 ,第一列为图片编号,第二列为是否有该类别的判断值 1代表有 -1代表没有
  3. JPEGImages 图片
  4. SegmentationClass 按不同类别分割后的图片
  5. SegmentationObject 按不同对象分割后的图片
COCO数据集
  1. 读取COCO数据集
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import torchvision
    from PIL import ImageDraw
    #参数为 root数据集的文件夹-照片 annFile标注信息的json文件
    coco_dataset = torchvision.CocoDetection(root="../val2017",
    annFile="../annotations/instances_val2017.json")
    print(coco_dataset[0])
    #获取图片
    image,info = coco_dataset[0]
    #展示图片
    image.show()
    #获取图片句柄方便对图片操作
    image_handler = ImageDraw.ImageDraw(image)
    #取出info中的所有信息
    for annotation in info:
    #标注框信息 -列表形式
    x_min,y_min,width,height = annotation['bbox']
    print(x_min)
    #把标注框画到图片上 传入一个标注框坐标的列表
    image_handler.rectangle(((x_min),(y_min),(x_min+width),(y_min+height)))
    #展示图片
    image.show()

视频:【Python深度学习:安装Anaconda、PyTorch(GPU版)库与PyCharm】 https://www.bilibili.com/video/BV1cD4y1H7Tk/?share_source=copy_web&vd_source=3a4f02434e353296deced7b70d6b1042

安装pytorch