基于深度学习的激光束识别(训练)

当我们完成了数据的准备工作后,接下来就是要训练了。训练之前,首先要设计好训练的网络,然后设计合适的损失函数,最后就是开始训练了。

网络设计

网络设计目前还没有啥可以依据的理论,大部分全靠经验和不断尝试来设计网络。在这里,我取输入的长宽都是1000的主要目的是为了后面进行归一化的时候能够整除,这样就减少了截断误差。网络的层数也是从小到大逐渐尝试慢慢得出最好的结果。然后卷积盒的大小我是从大到小来取的,个人感觉这样能够从大到小取到特征值。网络设计的代码如下:

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
import torch
import torch.nn as nn

class net(nn.Module):
def __init__(self):
super(net, self).__init__()

self.Conv_layers1 = nn.Sequential(
nn.Conv2d(3, 128, 10, 2),
nn.LeakyReLU(),
nn.MaxPool2d(2, 2)
)

self.Conv_layers2 = nn.Sequential(
nn.Conv2d(128, 256, 6, 2),
nn.LeakyReLU(),
nn.MaxPool2d(2, 2)
)

self.Conv_layers3 = nn.Sequential(
nn.Conv2d(256, 512, 3, 2),
nn.LeakyReLU(),
nn.MaxPool2d(2, 2)
)

self.Conn_layers1 = nn.Sequential(
nn.Linear(15 * 15 * 512, 2000),
nn.LeakyReLU()
)

self.Conn_layers2 = nn.Sequential(
nn.Linear(2000, 5),
nn.Sigmoid()
)

def forward(self, input):
input = self.Conv_layers1(input)
input = self.Conv_layers2(input)
input = self.Conv_layers3(input)

# 将数据的维度改为全连接层的输入维度
input = input.view(input.size()[0], -1)

input = self.Conn_layers1(input)
input = self.Conn_layers2(input)

# 将重置输出数据形状
output = input.reshape(-1, 5)

return 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
def loss_function(predict, labels):
'''
功能:计算损失值
参数:
——predict:net的预测结果(batchsize,5),其中predict为tensor
——labels:样本数据(batchsize,5),其中labels为tensor
返回值:
——loss:平均损失
'''
# 设置初始损失值
loss = 0.

# 获取batchsize
batch = labels.size()[0]

# 计算每个批次的总损失
for batch_size in range(batch):
if labels[batch_size, 4] == 1:
loss = loss + torch.sum((predict[batch_size, 0:5] - labels[batch_size, 0:5]) ** 2)
else:
loss = loss + 5 * torch.sum((predict[batch_size, 4] - labels[batch_size, 4]) ** 2)

# 求平均损失
loss = loss / batch

return loss

开始训练

终于要开始训练了,前面已经整合好了需要训练的一些文档和数据,所以直接训练就行。训练程序如下:

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
import torch
import dataset as D
import net as N
import loss_function as LF
from torch.utils.data import Dataset, DataLoader

# 设置迭代次数
epoch = 10

# 设置批量的大小
batch_size = 10

# 设置学习率
lr = 0.01

# 初始化数据对象
train_data = D.dataset(is_train = True)

# 加载数据
data = DataLoader(train_data, batch_size = batch_size, shuffle = True)

# 初始化一个网络对象
net = N.net()

# 优化函数为随机梯度下降
optimizer = torch.optim.SGD(net.parameters(), lr = lr, momentum = 0.9, weight_decay = 0.0005)

# 进行迭代运算
for e in range(epoch):
for i, (inputs, labels) in enumerate(data):

# 将输入值设置为浮点输入
inputs = inputs.float()

# 获取预测数据
predict = net(inputs)

# 计算损失
loss = LF.loss_function(predict, labels)

# 将梯度归零
optimizer.zero_grad()

# 进行反向传播运算
loss.backward()

# 更新参数
optimizer.step()

# 每迭代两次存一次训练好的参数模型
if (e + 1) % 2 == 0:

# 存参数模型
torch.save(net, "weight1/weight" + str(e + 1) + ".pkl")