「弱小和无知不是生存的障碍,傲慢才是」|

shumei52

园龄:1年7个月粉丝:6关注:1

神经网络入门之二 网络搭建

此篇文章在2022年12月1日被记录

入门神经网络二

网络搭建

  • 使用哪种深度学习框架

目前主流的神经网络框架有tensorflow、kears,国产的有百度的PaddlePaddle,但是我是从yolov5入坑的,yolov5官方代码使用的是pytorch框架,所以我使用torch,而且torch框架上手很简单,资源较多坑较少。

  • 建立一个怎样的网络结构

  • 网络层
    网络层很简单,只有一个卷积层和一个全连接层,一个卷积层包括卷积、激活、下采样。我是用5个卷积核进行卷积,网络结构非常简单,是因为模型训练出来后需要部署在C平台上,作为一个新手,我想网络尽量简单从而避免过量的参数带来的工作量。
    self.conv1 = torch.nn.Conv2d(in_channels=1, out_channels=5, kernel_size=3, stride=(3, 1))  # 只进行横向卷积
    self.pooling = torch.nn.MaxPool2d(kernel_size=(1, 2))
    self.fc1 = torch.nn.Linear(in_features=5*1*24, out_features = 3)

  • 构建损失函数
    损失函数(loss function)就是用来度量模型的预测值与真实值的差异程度的运算函数,它是一个非负实值函数,损失函数越小,模型的鲁棒性就越好。损失函数使用主要是在模型的训练阶段,每个批次的训练数据送入模型后,通过前向传播输出预测值,然后损失函数会计算出预测值和真实值之间的差异值,也就是损失值。得到损失值之后,模型通过反向传播去更新各个参数,来降低真实值与预测值之间的损失,使得模型生成的预测值往真实值方向靠拢,从而达到学习的目的。
criterion = torch.nn.CrossEntropyLoss()
  • 构建优化器
    优化器就是需要根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值的作用,我在这里测试了torch的四种优化器,我暂时不了解四种优化器的原理,但是实际训练时差异较大(后面注释是在不同网络结构下的loss,可以看出RMSprop与Adam的优化器效果最好)。
#optimizer = torch.optim.SGD(model.parameters(),lr = 0.001,momentum=0.8) #0.4741 conv2
#optimizer = torch.optim.SGD(model.parameters(),lr = 0.001) #0.0037 conv2    0.4931 conv1
#optimizer = torch.optim.RMSprop(model.parameters(),lr=0.001,alpha=0.9)#0.0000 conv2    0.0000 conv1
optimizer = torch.optim.Adam(model.parameters(),lr=0.0001,betas=(0.9,0.99))#0.0000 conv2  0.0000 conv1

  • 开始训练

  • 读取数据
    上文中提到我们将采集到的样本保存为npy数据,本文来读取它
    rest_sample = np.load('sample/rest.npy')
    walk_sample = np.load('sample/walk.npy')
    run_sample = np.load('sample/run.npy')
    print(rest_sample.shape)
    print(walk_sample.shape)
    print(run_sample.shape)

  • 上文中提到我们采集到的每种姿态的样本数量是300帧,按照网络上传统的训练比重,我将训练样本与测试样本按照7:3分开,也就是210:90个样本比例,建立训练网络结构:
class Net(torch.nn.Module):#这个网络结构只有一层卷积
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = torch.nn.Conv2d(
          in_channels=1, out_channels=5, kernel_size=3, stride=(3, 1))  # 只进行横向卷积
        self.pooling = torch.nn.MaxPool2d(kernel_size=(1, 2))
        self.fc1 = torch.nn.Linear(in_features=5*1*24, out_features = 3)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.pooling(x)
        x = x.view(x.size(0), -1)
        x = self.fc1(x)
        return x

model = Net()
print(model)
#构建损失
criterion = torch.nn.CrossEntropyLoss()
#构建优化器
#optimizer = torch.optim.SGD(model.parameters(),lr = 0.001,momentum=0.8) #0.4741 conv2
#optimizer = torch.optim.SGD(model.parameters(),lr = 0.001) #0.0037 conv2    0.4931 conv1
#optimizer = torch.optim.RMSprop(model.parameters(),lr=0.001,alpha=0.9)#0.0000 conv2    0.0000 conv1
optimizer = torch.optim.Adam(model.parameters(),lr=0.0001,betas=(0.9,0.99))#0.0000 conv2  0.0000 conv1

def train():
    epoches = 100
    targets = torch.tensor([0,1,2])
    for epoch in range(epoches):
        for i in range(0,210):
            inputs= torch.Tensor(([rest_sample[i]],[walk_sample[i]],[run_sample[i]]))
            outputs = model(inputs)
            loss = criterion(outputs,targets)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            print('Epoch: ', epoch, '| train loss: %.10f' % loss.data.numpy())

这个训练过程,我们每次同时训练三个样本(batch = 3),循环迭代100次,得到best_model.pth模型文件,并将其保存在本地。

  • 模型测试

我们读取本地保存的模型,编写测试函数,其中pred_y为测试结果。实际测试中模型准确率在80%以上。也可以在这个网站查看我的网络结构示例如下图:
img

def test(model):
    for i in range(210,300):
        test_output = model(torch.Tensor(([rest_sample[i]],[walk_sample[i]],[run_sample[i]])))
        pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze()
        #print(test_output)
        print(pred_y)

整体网络代码如下:

import torch
import torch.nn.functional as F
import numpy as np

rest_sample = np.load('sample/rest.npy')
walk_sample = np.load('sample/walk.npy')
run_sample = np.load('sample/run.npy')
print(rest_sample.shape)
print(walk_sample.shape)
print(run_sample.shape)
#构建CNN模型
# class Net(torch.nn.Module):
#     def __init__(self):
#         super(Net, self).__init__()
#         self.conv1 = torch.nn.Conv2d(
#             in_channels=1, out_channels=5, kernel_size=3, stride=(3, 1), padding=1)  # 只进行横向卷积
#         self.conv2 = torch.nn.Conv2d(
#             in_channels=5, out_channels=10, kernel_size=3, stride=(3, 1), padding=1)  # 只进行横向卷积
#         self.pooling = torch.nn.MaxPool2d(kernel_size=(1, 2))
#         self.fc1 = torch.nn.Linear(in_features=10*1*12, out_features = 3)

#     def forward(self, x):
#         # 先做Relu在做pooling
#         x = self.pooling(F.relu(self.conv1(x)))
#         x = self.pooling(F.relu(self.conv2(x)))
#         x = x.view(x.size(0), -1)
#         x = self.fc1(x)
#         return x

class Net(torch.nn.Module):#这个网络结构只有一层卷积
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = torch.nn.Conv2d(
          in_channels=1, out_channels=5, kernel_size=3, stride=(3, 1))  # 只进行横向卷积
        self.pooling = torch.nn.MaxPool2d(kernel_size=(1, 2))
        self.fc1 = torch.nn.Linear(in_features=5*1*24, out_features = 3)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.pooling(x)
        x = x.view(x.size(0), -1)
        x = self.fc1(x)
        return x

model = Net()
print(model)

#构建损失
criterion = torch.nn.CrossEntropyLoss()
#构建优化器
#optimizer = torch.optim.SGD(model.parameters(),lr = 0.001,momentum=0.8) #0.4741 conv2
#optimizer = torch.optim.SGD(model.parameters(),lr = 0.001) #0.0037 conv2    0.4931 conv1
#optimizer = torch.optim.RMSprop(model.parameters(),lr=0.001,alpha=0.9)#0.0000 conv2    0.0000 conv1
optimizer = torch.optim.Adam(model.parameters(),lr=0.0001,betas=(0.9,0.99))#0.0000 conv2  0.0000 conv1

def train():
    epoches = 100
    targets = torch.tensor([0,1,2])
    for epoch in range(epoches):
        for i in range(0,210):
            inputs= torch.Tensor(([rest_sample[i]],[walk_sample[i]],[run_sample[i]]))
            outputs = model(inputs)
            loss = criterion(outputs,targets)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            print('Epoch: ', epoch, '| train loss: %.10f' % loss.data.numpy())
def test(model):
    for i in range(210,300):
        test_output = model(torch.Tensor(([rest_sample[i]],[walk_sample[i]],[run_sample[i]])))
        pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze()
        #print(test_output)
        print(pred_y)
if __name__ == '__main__':
    # train()
    # torch.save(model, 'best_model.pth')
    my_model = torch.load('best_model.pth')
    test(my_model)

    # print("parameters")
    # torch.set_printoptions(profile="full")
    # for parameters in my_model.parameters():
    #     print(parameters)
    # print("------------------------------------")
    # print("name,parameters")
    # for name,parameters in my_model.named_parameters():
    #     print(name,':',parameters.size())


后记

从代码中能看出来我曾经测试过两层的卷积网络,实际测试效果比单纯一层网络好很多,但是后续需要将其部署到C环境中,为了减少后续的工作量,只用了一层网络,并且这层的卷积核参数只有五个,所以说效果一般般。下一章讲一下如何将这个比较简单的网络结构:怎样读取模型数据,用C语言实现输入参数预测结果。

本文作者:shumei52

本文链接:https://www.cnblogs.com/shumei52/p/18599775

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   shumei52  阅读(10)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起