基于RSS时间序列的室内定位(机器学习)

本文介绍了一种基于RSS时间序列数据的室内定位方法,利用PyTorch搭建简单神经网络模型进行训练和测试。在训练集上处理异常值后,模型在测试集上实现了约95%的正确率。
摘要由CSDN通过智能技术生成

前言:

如果你看过我的前两篇博客,就对我的前期数据处理工作有所了解,在前期工作中,我们已经得到了基于时间序列求均值归一化之后的RSS数据和相应label,而这篇博客主要讲述了,搭建简单神经网络模型,进行训练测试等环节。(训练集已经在上个博客中得到,测试集是直接随机从原始数据中提取,并进行归一化操作,细节部分在下文中会提到。)

1.导入模块和训练集和测试集

1.1导入模块

import torch
from torch import nn
import torch.utils.data as Data
from torch.utils.data import DataLoader
from torch.autograd import Variable
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

1.2导入训练集和测试集

train_file = pd.read_csv('H:/average_train_data/train_data.csv', header=None,
                         usecols=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))
test_file = pd.read_csv("H:/2-12/test_data_ann_1.csv", header=None, usecols=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))

导入之前处理好的训练集和测试集,训练集是5040×21的数据,其中0-19 列为0-1的数据,第20列为label列,有21个label,所有每个label有240行数据(5040=240*21),测试集是从原始数据中随机取得的,每个label20个,总计420行数据,所以测试集就是420×20的数据。

1.3测试集中的异常值处理
因为不同于训练集由取均值的方法得到,测试集是直接随机提取并归一化的,会出现不少的异常值,即存在不在[0,1]区间内的数,这些异常值会大大降低测试的准确度,所以接下来用numpy的方法处理这些异常值。

file = pd.read_csv("H:/test_data_dd.csv", header=None, usecols=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19))
data = np.array(file)
data = np.where(data > 1,random.randrange(0,1) , data)
data_f = pd.DataFrame(data)
data_f.to_csv("test_data_ann_1.csv")

将数据从dataframe类型转成np数组,再将数组中大于1的异常值,改成(0,1)的随机数,再在转换成dataframe,再输出成csv,就得到了测试集。

2.加载数据

接下来就是模型训练的正式开始,首先将数据加载,转换成tensor类型,让你的pytorch能够识别你的数据。

# 利用np数组转换成tensor类型
train_arr = np.array(train_file)  # 得到训练集
train_label = torch.LongTensor(train_arr[:, 20:21].astype(float))
train_arr = np.delete(train_arr, 20, axis=1)
train_data = torch.FloatTensor(train_arr)

# 利用np数组转换成tensor类型
test_arr = np.array(test_file)  # 得到测试集
test_label = torch.LongTensor(test_arr[:, 20:21].astype(float))
test_arr = np.delete(test_arr, 20, axis=1)
test_data = torch.FloatTensor(test_arr)
train_set = Data.TensorDataset(train_data, train_label)
train_set = DataLoader(dataset=train_set, batch_size=50, shuffle=True)
test_set = Data.TensorDataset(test_data, test_label)
test_set = DataLoader(dataset=test_set, batch_size=50, shuffle=False)

将数据的第0-19列和第20列分成两部分,分别作为输入和输出。以batchsize=50来加载(每次50行),shuffle=True表示每次随机加载,

3.搭建神经网络并训练、测试、输出结果

3.1搭建神经网络

# 使用 Sequential 定义 4 层神经网络
net = nn.Sequential(
    nn.Linear(20, 200),
    nn.ReLU(),
    nn.Linear(200, 100),
    nn.ReLU(),
    nn.Linear(100, 50),
    nn.ReLU(),
    nn.Linear(50, 21)
)

因为是最简单的模型,可以直接使用快速搭建方法,输入的20代表输入数据的20个特征,21代表输出的类别。

# 定义 loss 函数
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)  # 使用随机梯度下降,学习率 0.1

损失函数使用交叉熵函数nn.CrossEntropyLoss(),因为这是一个多分类问题。
优化器使用的是随机梯度下降,学习率lr=0.1。

3.2开始训练

# 开始训练
losses = []
acces = []
eval_losses = []
eval_acces = []

epoch = 50

for e in range(epoch):
    train_loss = 0
    train_acc = 0
    net.train()  # 训练模式
    for data_input, label in train_set:
        data_input = Variable(data_input)
        label = Variable(label)
        out = net(data_input)  # 前向传播
        label = label.squeeze()
        loss = criterion(out, label)
        optimizer.zero_grad()
        loss.backward()  # 反向传播
        optimizer.step()
        train_loss += loss.item()
        _, pred = out.max(1)
        num_correct = (pred == label).sum().item()
        acc = num_correct / out.shape[0]
        train_acc += acc
    losses.append(train_loss / len(train_set))
    acces.append(train_acc / len(train_set))

这是训练过程,输入为20个特征,输出为类别label,模型迭代次数为epoch=50,记录每次迭代之后的损失函数,和准确率。

3.3测试模型

net.eval()
eval_loss = 0
eval_acc = 0

for data_input, label in test_set:
    data_input = Variable(data_input)
    label = Variable(label)

    out = net(data_input)
    label = label.squeeze()

    eval_loss += loss.item()

    _, pred = out.max(1)
    num_correct = (pred == label).sum().item()
    acc = num_correct / out.shape[0]
    eval_acc += acc

eval_losses.append(eval_loss / len(test_set))
eval_acces.append(eval_acc / len(test_set))

print('epoch: {}, Train Loss: {:.6f}, Train Acc: {:.6f}, Eval Loss: {:.6f}, Eval Acc:{:.6f}'.format(
    e, train_loss / len(train_set), train_acc / len(train_set),
       eval_loss / len(test_set), eval_acc / len(test_set)))

输入为测试集的0-19列,输出为通过模型得到的label列,准确度是和原来测试集的label做比较。打印每一个epoch的相应参数

3.4输出结果
上一步打印出的结果
在这里插入图片描述

进行数据可视化

plt.title("Train_acc_ curve", fontsize=20)
# plt.xlim(left=0,right=5)
# plt.ylim(bottom=0,top=1)
plt.xlabel("epoch", fontsize=15)
plt.ylabel("train_acc", fontsize=15)
plt.plot(range(epoch), acces, c='b', linestyle='-', lw=2, label='Train acc')
plt.plot(range(epoch), eval_acces, c='r', linestyle='-', lw=2, label='Eval acc')
plt.legend()
plt.show()

在这里插入图片描述
损失函数输出的是差异程度,当然是越小,代表模型训练地相对来说越好了
在这里插入图片描述

可以看到模型的测试结果,还不错,可以达到95%左右的正确率。

4.总结

这是我的本科毕设题目中实现的第一种方法,后续还有两种方法,也在同一周通过了中期,目前进度emmm,依旧有点慢。(PS:论文还一字没写呢,0.0!)

之前虽然上过相关的理论课,但是做起来还是有点吃力,疫情期间一直在家云毕设,也是进度感人,总之第一次在博客上发自己的东西,若有错误,欢迎大家在评论区指点,最后也希望包括自己在内的苦逼20毕业生能顺利毕业了!

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值