赛题介绍
赛题名:室内用户运动时序数据分类
赛道:训练赛道
背景:随着数据量的不断积累,海量时序信息的处理需求日益凸显。作为时间序列数据分析中的重要任务之一,时间序列分类应用广泛且多样。时间序列分类旨在赋予序列某个离散标记。传统特征提取算法使用时间序列中的统计信息作为分类的依据。近年来,基于深度学习的时序分类取得了较大进展。基于端到端的特征提取方式,深度学习可以避免繁琐的人工特征设计。如何对时间序列中进行有效的分类,从繁芜丛杂的数据集中将具有某种特定形态的序列归属到同一个集合,对于学术研究及工业应用具有重要意义。
任务:基于上述实际需求以及深度学习的进展,本次训练赛旨在构建通用的时间序列分类算法。通过本赛题建立准确的时间序列分类模型,希望大家探索更为鲁棒的时序特征表述方法。
具体内容就不介绍了,这里是官方网址:https://www.datafountain.cn/competitions/484/datasets
直接说解题思路。
分析:
1.看了介绍之后,就知道这个题目并不难,因为你说是分类或者预测都可以,分类是因为有明确的标签,预测是因为时序数据,这两种都可以试试,我也两种都试过了。
2.下载了数据之后,可以发现该训练赛的数据量只有100左右,模型的训练数据太少,很有可能会发生过拟合的情况。
3.接下来就是进行上述实验,因为是训练赛,我尽可能的写明白些,确保一些根本没有才加过此类比赛的同学也能看懂代码以及思路。
使用的模型有:
循环神经网络模型:LSTM,BiGRU
卷积神经网络模型:1DCNN,2DCNN,VGG16,Inception,resnet,以及最后跑出最佳结果的SE-Inception。
因为其他的模型也没有什么好说的,我就不提了,直接就说跑出0.95的SE-Inception模型。
实验环境:Tensorflow2.0.0,Python的深度学习框架keras实现;仿真平台为Intel i7-6700 CPU 3.40GHz,24G内存,Win10 64位操作系统;不采用GPU加速。
接下来就一步一步进行实验。
1.读取数据
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
#分离数据集
X_train = train.drop(['ID', 'CLASS'], axis=1).values
Y_train = train['CLASS'].values
X_test = test.drop(['ID'], axis=1).values
print("test的类型:", X_test.shape)
print("x_train的类型:", X_train.shape)
print("y_train的类型:", Y_train.shape)
X_test = np.array(X_test)
X_train = np.array(X_train)
Y_train = np.array(Y_train)
首先读取数据,得到如下的截图。
2.维度转换
因为是一维的时序数据,所以本来想用一维卷积去跑,但是经过多次实验,一维卷积的效果并不是很理想,所以转为了二维卷积。
len_X_train = len(X_train)
len_X_test = len(X_test)
X_train = tf.expand_dims(X_train, axis=2) # 增加维度在最后
X_test = tf.expand_dims(X_test, axis=2) # 增加维度在最后
X_train = tf.reshape(X_train, (len_X_train, 16, 16, 1))
X_test = tf.reshape(X_test, (len_X_test, 16, 16, 1))
print("================================")
print("test的类型:", X_test.shape)
print("x_train的类型:", X_train.shape)
print("y_train的类型:", Y_train.shape)
可以得到如下截图:
本来在该过程严谨的话,需要做标准化或归一化,还有打乱训练数据的,但是经过实验,这些操作好像在该题目中,意义不大,所以就没加了,直接转的二维卷积。
3.模型搭建及训练(具体模型代码先不分享了,比赛结束可以分享交流学习)
因为其他模型较为简单,我就不写了就分享一下SE-Inception模型。
该模型使用了多尺度的Inception以及特征重标定的SEnet。实验证明,该模型虽然能够跑出0.95的效果,但是由于随机性,并不能确保每次都跑出这样的准确率,但是我还是保存了一份0.95的模型参数权重。因为训练数据实在太少,本来用过SVM以及其他机器学习的模型,但是准确率一直上不去,在75-85之间徘徊。
训练数据太少带来的问题:这个需要提及一下,因为就只有100左右的数据,很可能带来过拟合,深度学习就是用来训练大量样本数据的,如果加上划分训练集和测试集,就没多少的样本数据来学习。一般处理这样的问题主要是以下方法:数据增强(过采样,图像转换翻转),dropout等
模型参数也会影响模型性能,需要多次调优。
在使用机器学习SVM等模型时的提交截图。
后来转为深度学习,提交的结果也时好时坏。
我没记错的话,在提交0.95的时候,大概排名在前十,但是后来出现了很多1的成绩,排名就下去了。
下面是我今天刚跑的结果,可以看到,模型严重的过拟合了,但是在前面测试集也能有0.9以上的准确率。
因为数据量少,错位几个,就可能带来很大的变化。
4.实验结果
在进行实验结果时,我用的最佳模型保存算法,监控验证集的loss来保存模型。
class CustomModelCheckpoint(keras.callbacks.Callback):
def __init__(self, model, path):
self.model = model
self.path = path
self.best_loss = np.inf
def on_epoch_end(self, epoch, logs=None):
val_loss = logs['val_loss']
if val_loss < self.best_loss:
print("\nValidation loss decreased from {} to {}, saving model".format(self.best_loss, val_loss))
self.model.save_weights(self.path, overwrite=True)
self.best_loss = val_loss
训练模型结束后,直接调用模型即可得到结果,以下是保存文件代码
# 保存结果
# X_test = tf.cast(X_test, tf.float32)
# y_pre = model.predict(X_test)
# y_pre = argmax(y_pre, axis=1)
# y_pre = np.array(y_pre)
# res = pd.DataFrame()
# y_pre = list(y_pre)
# res['CLASS'] = y_pre
# res.to_csv('sample_submission1.csv', index=False)
# #
总结:
整个流程大概是这样,模型的好坏与模型参数与结构息息相关,因为是训练赛,可能主办方也是希望以此来进行学习交流,所以也就别较真了,乐乐呵呵的就行了。