用Keras实现简单一维卷积 ,亲测可用一维卷积实例,及Kaggle竞赛代码解读

2,667 阅读3分钟
原文链接: nooverfit.com

记得我们之前讲过1D卷积在自然语言处理中的应用:

但是读者中对如何应用一维卷积呼声太高,David 9 有必要再用一篇幅来讲1D卷积实战。这次我们拿kaggle上叶子分类预测问题做例子,讲解1D卷积网络如何实现。

我的数据集来自:www.kaggle.com/alexanderla…

如果懒得去原链接下载,可以直接戳下面链接:

   train.csv     test.csv   

train.csv 是训练集数据,test.csv 是验证数据集。 这个数据集是叶子leaf 品种的分类问题,有三个通道, 每个通道64个比特位,一个通道代表边界特征,一个通道代表形状特征,最后一个通道代表材质特征。(这些特征都是kaggle已经帮你提取了)。输出是叶子特征标签的预测。

下面废话少说,直接上代码及详细注释(亲测可用):

  1. # -*- coding: utf-8 -*-
  2. # 导入一些基本库
  3. import numpy as np
  4. import pandas as pd
  5. # LabelEncoder 用来编码输出标签
  6. from sklearn.preprocessing import LabelEncoder
  7. from sklearn.preprocessing import StandardScaler
  8. # StratifiedShuffleSplit可以用来把数据集洗牌,并拆分成训练集和验证集
  9. from sklearn.model_selection import StratifiedShuffleSplit
  10. # 我们用的Keras版本是 2.0.1
  11. from keras.models import Sequential
  12. from keras.layers import Dense, Activation, Flatten, Convolution1D, Dropout
  13. from keras.optimizers import SGD
  14. from keras.utils import np_utils
  15. # 这个数据集是叶子leaf 品种的分类问题,有三个通道,
  16. # 每个通道64个比特位,一个通道代表边界特征,一个通道代表形状特征,最后一个通道代表材质特征,
  17. # 输出是叶子特征标签的预测
  18. train = pd.read_csv('./train.csv')
  19. test = pd.read_csv('./test.csv')
  20. def encode(train, test):
  21. # 用LabelEncoder为叶子的种类标签编码,labels对象是训练集上的标签列表
  22. label_encoder = LabelEncoder().fit(train.species)
  23. labels = label_encoder.transform(train.species)
  24. classes = list(label_encoder.classes_)
  25. # 此处把不必要的训练集和测试集的列删除
  26. train = train.drop(['species', 'id'], axis=1)
  27. test = test.drop('id', axis=1)
  28. return train, labels, test, classes
  29. train, labels, test, classes = encode(train, test)
  30. # 这里只是标准化训练集的特征值
  31. scaler = StandardScaler().fit(train.values)
  32. scaled_train = scaler.transform(train.values)
  33. # 把数据集拆分成训练集和测试集,测试集占10%
  34. sss = StratifiedShuffleSplit(test_size=0.1, random_state=23)
  35. for train_index, valid_index in sss.split(scaled_train, labels):
  36. X_train, X_valid = scaled_train[train_index], scaled_train[valid_index]
  37. y_train, y_valid = labels[train_index], labels[valid_index]
  38. # 每个输入通道的大小是64位,一共3个通道
  39. nb_features = 64
  40. nb_class = len(classes)
  41. # 把输入数据集reshape成keras喜欢的格式:(样本数,通道大小,通道数)
  42. X_train_r = np.zeros((len(X_train), nb_features, 3))
  43. # 这里的做法是先把所有元素初始化成0之后,再把刚才的数据集中的数据赋值过来
  44. X_train_r[:, :, 0] = X_train[:, :nb_features]
  45. X_train_r[:, :, 1] = X_train[:, nb_features:128]
  46. X_train_r[:, :, 2] = X_train[:, 128:]
  47. # 验证集也要reshape一下
  48. X_valid_r = np.zeros((len(X_valid), nb_features, 3))
  49. X_valid_r[:, :, 0] = X_valid[:, :nb_features]
  50. X_valid_r[:, :, 1] = X_valid[:, nb_features:128]
  51. X_valid_r[:, :, 2] = X_valid[:, 128:]
  52. # 下面是Keras的一维卷积实现,原作者尝试过多加一些卷积层,
  53. # 结果并不能提高准确率,可能是因为其单个通道的信息本来就太少,深度太深的网络本来就不适合
  54. model = Sequential()
  55. # 一维卷积层用了512个卷积核,输入是64*3的格式
  56. # 此处要注意,一维卷积指的是卷积核是1维的,而不是卷积的输入是1维的,1维指的是卷积方式
  57. model.add(Convolution1D(nb_filter=512, filter_length=1, input_shape=(nb_features, 3)))
  58. model.add(Activation('relu'))
  59. model.add(Flatten())
  60. model.add(Dropout(0.4))
  61. model.add(Dense(2048, activation='relu'))
  62. model.add(Dense(1024, activation='relu'))
  63. model.add(Dense(nb_class))
  64. # softmax经常用来做多类分类问题
  65. model.add(Activation('softmax'))
  66. y_train = np_utils.to_categorical(y_train, nb_class)
  67. y_valid = np_utils.to_categorical(y_valid, nb_class)
  68. sgd = SGD(lr=0.01, nesterov=True, decay=1e-6, momentum=0.9)
  69. model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])
  70. model.summary()
  71. nb_epoch = 15
  72. model.fit(X_train_r, y_train, nb_epoch=nb_epoch, validation_data=(X_valid_r, y_valid), batch_size=16)

下面是模型summary的输出参考:

  1. Layer (type) Output Shape Param #
  2. =================================================================
  3. conv1d_1 (Conv1D) (None, 64, 512) 2048
  4. _________________________________________________________________
  5. activation_1 (Activation) (None, 64, 512) 0
  6. _________________________________________________________________
  7. flatten_1 (Flatten) (None, 32768) 0
  8. _________________________________________________________________
  9. dropout_1 (Dropout) (None, 32768) 0
  10. _________________________________________________________________
  11. dense_1 (Dense) (None, 2048) 67110912
  12. _________________________________________________________________
  13. dense_2 (Dense) (None, 1024) 2098176
  14. _________________________________________________________________
  15. dense_3 (Dense) (None, 99) 101475
  16. _________________________________________________________________
  17. activation_2 (Activation) (None, 99) 0
  18. =================================================================
  19. Total params: 69,312,611.0
  20. Trainable params: 69,312,611.0
  21. Non-trainable params: 0.0

 

参考文献:

  1. www.kaggle.com/alexanderla…

本文采用署名 – 非商业性使用 – 禁止演绎 3.0 中国大陆许可协议进行许可。著作权属于“David 9的博客”原创,如需转载,请联系微信: david9ml,或邮箱:yanchao727@gmail.com

或直接扫二维码:

赶快成为第一个赞的人吧 The following two tabs change content below.

    David 9

    邮箱:yanchao727@gmail.com 微信: david9ml