最近跟导师做的项目是关于BP,LSTN神经网络的,数据集对象是一些Excel表格类型的,我使用pytorch进行训练,读取Excel表格数据的时候统一进行一些处理,所以我想把它封装到函数,以后处理其它数据集,直接调用函数实现,这不就方便了吗。
我将以鸢尾花数据集作为例子进行展示:
我已经编写了2.0版本,方法更加集成化,建议使用2.0版本:2.0
可以看到鸢尾花数据集有四个特征,分别是0,1,2,3,label是鸢尾花种类,共三种,分别以0,1,2表示。
首先第一部分是读取Excel数据(需要主要的是标签需要在最后一列,函数默认最后一列为标签,前边的为特征值):
def open_excel(filename):
"""
打开数据集,进行数据处理
:param filename:文件名
:return:特征集数据、标签集数据
"""
readbook = pd.read_excel(f'{filename}.xlsx', engine='openpyxl')
nplist = readbook.T.to_numpy()
data = nplist[0:-1].T
data = np.float64(data)
target = nplist[-1]
return data, target
def open_csv(filename):
"""
打开数据集,进行数据处理
:param filename:文件名
:return:特征集数据、标签集数据
"""
readbook = pd.read_csv(f'{filename}.csv')
nplist = readbook.T.to_numpy()
data = nplist[0:-1].T
data = np.float64(data)
target = nplist[-1]
return data, target
使用方法为feature, label = open_excel('iris')
,输入为Excel名字,返回值为numpy类型的特征值和标签。
第二个函数是将数据划分为训练集和测试集:
def random_number(data_size, key):
"""
使用shuffle()打乱
"""
number_set = []
for i in range(data_size):
number_set.append(i)
if key == 1:
random.shuffle(number_set)
return number_set
def split_data_set(data_set, target_set, rate, ifsuf):
"""
说明:分割数据集,默认数据集的rate是测试集
:param data_set: 数据集
:param target_set: 标签集
:param rate: 测试集所占的比率
:return: 返回训练集数据、测试集数据、训练集标签、测试集标签
"""
# 计算训练集的数据个数
train_size = int((1 - rate) * len(data_set))
# 随机获得数据的下标
data_index = random_number(len(data_set), ifsuf)
# 分割数据集(X表示数据,y表示标签),以返回的index为下标
# 训练集数据
x_train = data_set[data_index[:train_size]]
# 测试集数据
x_test = data_set[data_index[train_size:]]
# 训练集标签
y_train = target_set[data_index[:train_size]]
# 测试集标签
y_test = target_set[data_index[train_size:]]
return x_train, x_test, y_train, y_test
使用方法很简单,输入为特征值,标签,划分比例,是否打乱,返回值为训练集,测试集的特征值和标签。
# 数据划分为训练集和测试集和是否打乱数据集
split = 0.3 # 测试集占数据集整体的多少
ifshuffle = 1 # 1为打乱数据集,0为不打乱
x_train, x_test, y_train, y_test = split_data_set(feature, label, split, ifshuffle)
第三个函数为numpy转为tensor:
def inputtotensor(inputtensor, labeltensor):
"""
将数据集的输入和标签转为tensor格式
:param inputtensor: 数据集输入
:param labeltensor: 数据集标签
:return: 输入tensor,标签tensor
"""
inputtensor = np.array(inputtensor)
inputtensor = torch.FloatTensor(inputtensor)
labeltensor = np.array(labeltensor)
labeltensor = labeltensor.astype(float)
labeltensor = torch.LongTensor(labeltensor)
return inputtensor, labeltensor
输入为numpy的特征值和标签,返回值为tensor格式的特征值和标签。
# 将数据转为tensor格式
traininput, trainlabel = inputtotensor(x_train, y_train)
testinput, testlabel = inputtotensor(x_test, y_test)
第四部分是归一化处理,使用的是torch中的nn
# 归一化处理
traininput = nn.functional.normalize(traininput)
testinput = nn.functional.normalize(testinput)
你只需要调用函数就可以实现,可以说非常方便。
下面我用以上函数实现后实现一下BP神经网络:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import random
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
def open_excel(filename):
"""
打开数据集,进行数据处理
:param filename:文件名
:return:特征集数据、标签集数据
"""
readbook = pd.read_excel(f'{filename}.xlsx', engine='openpyxl')
nplist = readbook.T.to_numpy()
data = nplist[0:-1].T
data = np.float64(data)
target = nplist[-1]
return data, target
def open_csv(filename):
"""
打开数据集,进行数据处理
:param filename:文件名
:return:特征集数据、标签集数据
"""
readbook = pd.read_csv(f'{filename}.csv')
nplist = readbook.T.to_numpy()
data = nplist[0:-1].T
data = np.float64(data)
target = nplist[-1]
return data, target
def random_number(data_size, key):
"""
使用shuffle()打乱
"""
number_set = []
for i in range(data_size):
number_set.append(i)
if key == 1:
random.shuffle(number_set)
return number_set
def split_data_set(data_set, target_set, rate, ifsuf):
"""
说明:分割数据集,默认数据集的rate是测试集
:param data_set: 数据集
:param target_set: 标签集
:param rate: 测试集所占的比率
:return: 返回训练集数据、测试集数据、训练集标签、测试集标签
"""
# 计算训练集的数据个数
train_size = int((1 - rate) * len(data_set))
# 随机获得数据的下标
data_index = random_number(len(data_set), ifsuf)
# 分割数据集(X表示数据,y表示标签),以返回的index为下标
# 训练集数据
x_train = data_set[data_index[:train_size]]
# 测试集数据
x_test = data_set[data_index[train_size:]]
# 训练集标签
y_train = target_set[data_index[:train_size]]
# 测试集标签
y_test = target_set[data_index[train_size:]]
return x_train, x_test, y_train, y_test
def inputtotensor(inputtensor, labeltensor):
"""
将数据集的输入和标签转为tensor格式
:param inputtensor: 数据集输入
:param labeltensor: 数据集标签
:return: 输入tensor,标签tensor
"""
inputtensor = np.array(inputtensor)
inputtensor = torch.FloatTensor(inputtensor)
labeltensor = np.array(labeltensor)
labeltensor = labeltensor.astype(float)
labeltensor = torch.LongTensor(labeltensor)
return inputtensor, labeltensor
# 定义BP神经网络
class BPNerualNetwork(torch.nn.Module):
def __init__(self):
super().__init__()
self.model = nn.Sequential(nn.Linear(input_size, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, output_size),
nn.LogSoftmax(dim=1)
)
def forward(self, x):
x = self.model(x)
return x
def addbatch(data_train, data_test, batchsize):
"""
设置batch
:param data_train: 输入
:param data_test: 标签
:param batchsize: 一个batch大小
:return: 设置好batch的数据集
"""
data = TensorDataset(data_train, data_test)
data_loader = DataLoader(data, batch_size=batchsize, shuffle=False)
return data_loader
def train_test(traininput, trainlabel, testinput, testlabel, batchsize):
"""
函数输入为:训练输入,训练标签,测试输入,测试标签,一个batch大小
进行BP的训练,每训练一次就算一次准确率,同时记录loss
:return:训练次数list,训练loss,测试loss,准确率
"""
# 设置batch
traindata = addbatch(traininput, trainlabel, batchsize) # shuffle打乱数据集
for epoch in range(1001):
for step, data in enumerate(traindata):
net.train()
inputs, labels = data
# 前向传播
out = net(inputs)
# 计算损失函数
loss = loss_func(out, labels)
# 清空上一轮的梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 参数更新
optimizer.step()
# 测试准确率
net.eval()
testout = net(testinput)
testloss = loss_func(testout, testlabel)
prediction = torch.max(testout, 1)[1] # torch.max
pred_y = prediction.numpy() # 事先放在了GPU,所以必须得从GPU取到CPU中!!!!!!
target_y = testlabel.data.numpy()
j = 0
for i in range(pred_y.size):
if pred_y[i] == target_y[i]:
j += 1
acc = j / pred_y.size
if epoch % 10 == 0:
print("训练次数为", epoch, "的准确率为:", acc)
if __name__ == "__main__":
feature, label = open_excel('iris')
# 数据划分为训练集和测试集和是否打乱数据集
split = 0.3 # 测试集占数据集整体的多少
ifshuffle = 1 # 1为打乱数据集,0为不打乱
x_train, x_test, y_train, y_test = split_data_set(feature, label, split, ifshuffle)
# 将数据转为tensor格式
traininput, trainlabel = inputtotensor(x_train, y_train)
testinput, testlabel = inputtotensor(x_test, y_test)
# 归一化处理
traininput = nn.functional.normalize(traininput)
testinput = nn.functional.normalize(testinput)
Epoch = 1000
input_size = 4
hidden_size = 5
output_size = 3
LR = 0.005
batchsize = 30
net = BPNerualNetwork()
optimizer = torch.optim.Adam(net.parameters(), LR)
# 设定损失函数
loss_func = torch.nn.CrossEntropyLoss()
# 训练并且记录每次准确率,loss 函数输入为:训练输入,训练标签,测试输入,测试标签,一个batch大小
train_test(traininput, trainlabel, testinput, testlabel, batchsize)
轻轻松松到达0.9777,这不是主要的,本次主要是进行简化一下Excel数据集操作。
文章出处登录后可见!
已经登录?立即刷新