飞道的博客

『AI实践学』使用一维卷积神经网络处理时间序列数据(基于Keras Conv1D)

1462人阅读  评论(0)

为了方便读者理解一维卷积应用,请配合笔者的实战文章一起食用:

1.[深度应用]·首届中国心电智能大赛初赛开源Baseline(基于Keras val_acc: 0.88)

2.[深度应用]·DC竞赛轴承故障检测开源Baseline(基于Keras1D卷积 val_acc:0.99780)

3.https://github.com/xiaosongshine/bearing_detection_by_conv1d

4.『带你学AI』带你学AI与TensorFlow2实战之入门初探:如何速成深度学习开发

5.笔者深度学公众号《极简AI》:

极简AI公众号

 

概述

许多技术文章都关注于二维卷积神经网络(2D CNN)的使用,特别是在图像识别中的应用。而一维卷积神经网络(1D CNNs)只在一定程度上有所涉及,比如在自然语言处理(NLP)中的应用。目前很少有文章能够提供关于如何构造一维卷积神经网络来解决你可能正面临的一些机器学习问题。

本文试图补上这样一个短板。

 

 

 

 

何时应用 1D CNN?

CNN 可以很好地识别出数据中的简单模式,然后使用这些简单模式在更高级的层中生成更复杂的模式。当你希望从整体数据集中较短的(固定长度)片段中获得感兴趣特征,并且该特性在该数据片段中的位置不具有高度相关性时,1D CNN 是非常有效的。

1D CNN 可以很好地应用于传感器数据的时间序列分析(比如陀螺仪或加速度计数据);同样也可以很好地用于分析具有固定长度周期的信号数据(比如音频信号)。此外,它还能应用于自然语言处理的任务(由于单词的接近性可能并不总是一个可训练模式的好指标,因此 LSTM 网络在 NLP 中的应用更有前途)。

 

1D CNN 和 2D CNN 之间有什么区别?

 

无论是一维、二维还是三维,卷积神经网络(CNNs)都具有相同的特点和相同的处理方法。关键区别在于输入数据的维数以及特征检测器(或滤波器)如何在数据之间滑动:

 

 

 

 

 

问题描述

在本文中,我们将专注于基于时间片的加速度传感器数据的处理,这些数据来自于用户的腰带式智能手机设备。基于 x、y 和 z 轴的加速度计数据,1D CNN 用来预测用户正在进行的活动类型(比如“步行”、“慢跑”或“站立”)。你可以在我的另外两篇文章中找到更多的信息 这里 和 这里。对于各种活动,在每个时间间隔上的数据看起来都与此类似。

 

来自加速度计数据的时间序列样例

 

如何在 PYTHON 中构造一个 1D CNN?

 

目前已经有许多得标准 CNN 模型可用。我选择了 Keras 网站 上描述的一个模型,并对它进行了微调,以适应前面描述的问题。下面的图片对构建的模型进行一个高级概述。其中每一层都将会进一步加以解释。

 

 

 

让我们先来看一下对应的 Python 代码,以便构建这个模型:


  
  1. model_m = Sequential()
  2. model_m.add(Reshape((TIME_PERIODS, num_sensors), input_shape=(input_shape,)))
  3. model_m.add(Conv1D( 100, 10, activation= 'relu', input_shape=(TIME_PERIODS, num_sensors)))
  4. model_m.add(Conv1D( 100, 10, activation= 'relu'))
  5. model_m.add(MaxPooling1D( 3))
  6. model_m.add(Conv1D( 160, 10, activation= 'relu'))
  7. model_m.add(Conv1D( 160, 10, activation= 'relu'))
  8. model_m.add(GlobalAveragePooling1D())
  9. model_m.add(Dropout( 0.5))
  10. model_m.add(Dense(num_classes, activation= 'softmax'))
  11. print(model_m.summary())

运行这段代码将得到如下的深层神经网络:


  
  1. _________________________________________________________________
  2. Layer ( type)                 Output Shape              Param #   
  3. =================================================================
  4. reshape_45 (Reshape)         (None, 80, 3)             0         
  5. _________________________________________________________________
  6. conv1d_145 (Conv1D)          (None, 71, 100)           3100      
  7. _________________________________________________________________
  8. conv1d_146 (Conv1D)          (None, 62, 100)           100100    
  9. _________________________________________________________________
  10. max_pooling1d_39 (MaxPooling (None, 20, 100)           0         
  11. _________________________________________________________________
  12. conv1d_147 (Conv1D)          (None, 11, 160)           160160    
  13. _________________________________________________________________
  14. conv1d_148 (Conv1D)          (None, 2, 160)            256160    
  15. _________________________________________________________________
  16. global_average_pooling1d_29  (None, 160)               0         
  17. _________________________________________________________________
  18. dropout_29 (Dropout)         (None, 160)               0         
  19. _________________________________________________________________
  20. dense_29 (Dense)             (None, 6)                 966       
  21. =================================================================
  22. Total params: 520,486
  23. Trainable params: 520,486
  24. Non-trainable params: 0
  25. _________________________________________________________________
  26. None

让我们深入到每一层中,看看到底发生了什么:

  • 输入数据: 数据经过预处理后,每条数据记录中包含有 80 个时间片(数据是以 20Hz 的采样频率进行记录的,因此每个时间间隔中就包含有 4 秒的加速度计数据)。在每个时间间隔内,存储加速度计的 x 轴、 y 轴和 z 轴的三个数据。这样就得到了一个 80 x 3 的矩阵。由于我通常是在 iOS 系统中使用神经网络的,所以数据必须平展成长度为 240 的向量后传入神经网络中。网络的第一层必须再将其变形为原始的 80 x 3 的形状。

  • 第一个 1D CNN 层: 第一层定义了高度为 10(也称为卷积核大小)的滤波器(也称为特征检测器)。只有定义了一个滤波器,神经网络才能够在第一层中学习到一个单一的特征。这可能还不够,因此我们会定义 100 个滤波器。这样我们就在网络的第一层中训练得到 100 个不同的特性。第一个神经网络层的输出是一个 71 x 100 的矩阵。输出矩阵的每一列都包含一个滤波器的权值。在定义内核大小并考虑输入矩阵长度的情况下,每个过滤器将包含 71 个权重值。

  • 第二个 1D CNN 层: 第一个 CNN 的输出结果将被输入到第二个 CNN 层中。我们将在这个网络层上再次定义 100 个不同的滤波器进行训练。按照与第一层相同的逻辑,输出矩阵的大小为 62 x 100。

  • 最大值池化层: 为了减少输出的复杂度和防止数据的过拟合,在 CNN 层之后经常会使用池化层。在我们的示例中,我们选择了大小为 3 的池化层。这意味着这个层的输出矩阵的大小只有输入矩阵的三分之一。

  • 第三和第四个 1D CNN 层: 为了学习更高层次的特征,这里又使用了另外两个 1D CNN 层。这两层之后的输出矩阵是一个 2 x 160 的矩阵。

  • 平均值池化层: 多添加一个池化层,以进一步避免过拟合的发生。这次的池化不是取最大值,而是取神经网络中两个权重的平均值。输出矩阵的大小为 1 x 160 。每个特征检测器在神经网络的这一层中只剩下一个权重。

  • Dropout 层: Dropout 层会随机地为网络中的神经元赋值零权重。由于我们选择了 0.5 的比率,则 50% 的神经元将会是零权重的。通过这种操作,网络对数据的微小变化的响应就不那么敏感了。因此,它能够进一步提高对不可见数据处理的准确性。这个层的输出仍然是一个 1 x 160 的矩阵。

  • 使用 Softmax 激活的全连接层: 最后一层将会把长度为 160 的向量降为长度为 6 的向量,因为我们有 6 个类别要进行预测(即 “慢跑”、“坐下”、“走路”、“站立”、“上楼”、“下楼”)。这里的维度下降是通过另一个矩阵乘法来完成的。Softmax 被用作激活函数。它强制神经网络的所有六个输出值的加和为一。因此,输出值将表示这六个类别中的每个类别出现的概率。

 

训练和测试该神经网络

 

下面是一段用以训练模型的 Python 代码,批大小为 400,其中训练集和验证集的分割比例是 80 比 20。

 


  
  1. callbacks_list = [
  2.     keras.callbacks.ModelCheckpoint(
  3.         filepath= 'best_model.{epoch:02d}-{val_loss:.2f}.h5',
  4.         monitor= 'val_loss', save_best_only= True),
  5.     keras.callbacks.EarlyStopping(monitor= 'acc', patience= 1)
  6. ]
  7. model_m.compile(loss= 'categorical_crossentropy',
  8.                 optimizer= 'adam', metrics=[ 'accuracy'])
  9. BATCH_SIZE = 400
  10. EPOCHS = 50
  11. history = model_m.fit(x_train,
  12.                       y_train,
  13.                       batch_size=BATCH_SIZE,
  14.                       epochs=EPOCHS,
  15.                       callbacks=callbacks_list,
  16.                       validation_split= 0.2,
  17.                       verbose= 1)

该模型在训练数据上的准确率可达 97%。


  
  1. ...
  2. Epoch 9/50
  3. 16694/16694 [==============================] - 16s 973us/step - loss: 0.0975 - acc: 0.9683 - val_loss: 0.7468 - val_acc: 0.8031
  4. Epoch 10/50
  5. 16694/16694 [==============================] - 17s 989us/step - loss: 0.0917 - acc: 0.9715 - val_loss: 0.7215 - val_acc: 0.8064
  6. Epoch 11/50
  7. 16694/16694 [==============================] - 17s 1ms/step - loss: 0.0877 - acc: 0.9716 - val_loss: 0.7233 - val_acc: 0.8040
  8. Epoch 12/50
  9. 16694/16694 [==============================] - 17s 1ms/step - loss: 0.0659 - acc: 0.9802 - val_loss: 0.7064 - val_acc: 0.8347
  10. Epoch 13/50
  11. 16694/16694 [==============================] - 17s 1ms/step - loss: 0.0626 - acc: 0.9799 - val_loss: 0.7219 - val_acc: 0.8107

根据测试集数据进行测试,其准确率为 92%。


  
  1. Accuracy on test data: 0.92
  2. Loss on test data: 0.39

 

 

总结

本文通过以智能手机的加速度计数据来预测用户的行为为例,绍了如何使用 1D CNN 来训练网络。

 

补充阅读

 

1.[深度应用]·首届中国心电智能大赛初赛开源Baseline(基于Keras val_acc: 0.88)

2.[深度应用]·DC竞赛轴承故障检测开源Baseline(基于Keras1D卷积 val_acc:0.99780)

3.https://github.com/xiaosongshine/bearing_detection_by_conv1d

 

欢迎Fork+Star,觉得有用的话,麻烦小小鼓励一下 ><

 

欢迎大家关注小宋公众号《极简AI》带你学深度学习:

基于深度学习的理论学习与应用开发技术分享,笔者会经常分享深度学习干货内容,大家在学习或者应用深度学习时,遇到什么问题也可以与我在上面交流知无不答。

出自CSDN博客专家&知乎深度学习专栏作家@小宋是呢


转载:https://blog.csdn.net/xiaosongshine/article/details/88614450
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场