60行代码徒手实现深度神经网络
2012 年 4 月 13 日
01
准备数据集
采用的数据集是sklearn中的breast cancer数据集,30维特征,569个样本。训练前进行MinMax标准化缩放至[0,1]区间。按照75/25比例划分成训练集和验证集。
# 获取数据集 import numpy as np import pandas as pd from sklearn import datasets from sklearn import preprocessing from sklearn.model_selection import train_test_split breast = datasets.load_breast_cancer() scaler = preprocessing.MinMaxScaler() data = scaler.fit_transform(breast['data']) target = breast['target'] X_train,X_test,y_train,y_test = train_test_split(data,target)
02
模型结构图
03
正反传播公式
04
NN实现代码
import numpy as np import pandas as pd #定义激活函数 ReLu = lambda z:np.maximum(0.0,z) d_ReLu = lambda z:np.where(z<0,0,1) LeakyReLu = lambda z:np.maximum(0.01*z,z) d_LeakyReLu = lambda z:np.where(z=0.5] = 1 Y_test[Y_prob< 0.5] = 0 return(Y_test)
05
单隐层神经网络
设置1个隐藏层,隐藏层节点数为5,隐藏层使用Sigmoid激活函数。
# 采用Sigmoid激活函数 NN = NNClassifier(n = [np.nan,5,1],alpha = 0.02, ITERNUM = 200000, gfunc = 'Sigmoid') NN.fit(X_train,y_train) # 绘制目标函数迭代曲线 %matplotlib inline NN.dfJ.plot(figsize = (12,8)) # 测试在验证集的auc得分 from sklearn.metrics import roc_auc_score Y_prob = NN.predict_prob(X_test) roc_auc_score(list(y_test),list(Y_prob))
隐藏层使用Tanh激活函数。
# 采用 Tanh激活函数 NN = NNClassifier(n = [np.nan,5,1],alpha = 0.02, ITERNUM = 200000, gfunc = 'Tanh') NN.fit(X_train,y_train) # 绘制目标函数迭代曲线 %matplotlib inline NN.dfJ.plot(figsize = (12,8)) # 测试在验证集的auc得分 from sklearn.metrics import roc_auc_score Y_prob = NN.predict_prob(X_test) roc_auc_score(list(y_test),list(Y_prob))
隐藏层使用ReLu激活函数。
# 采用 ReLu激活函数 NN = NNClassifier(n = [np.nan,5,1],alpha = 0.02, ITERNUM = 200000, gfunc = 'ReLu') NN.fit(X_train,y_train) # 绘制目标函数迭代曲线 %matplotlib inline NN.dfJ.plot(figsize = (12,8)) # 测试在验证集的auc得分 from sklearn.metrics import roc_auc_score Y_prob = NN.predict_prob(X_test) roc_auc_score(list(y_test),list(Y_prob))
隐藏层使用LeakyReLu激活函数。
# 采用 LeakyReLu激活函数 NN = NNClassifier(n = [np.nan,5,1],alpha = 0.02, ITERNUM = 200000, gfunc = 'LeakyReLu') NN.fit(X_train,y_train) # 绘制目标函数迭代曲线 %matplotlib inline NN.dfJ.plot(figsize = (12,8)) # 测试在验证集的auc得分 from sklearn.metrics import roc_auc_score Y_prob = NN.predict_prob(X_test) roc_auc_score(list(y_test),list(Y_prob))
以上试验似乎表明,在当前的数据集上,隐藏层采用ReLu激活函数是一个最好的选择,AUC最高得分为0.99958。
06
双隐层神经网络
设置2个隐藏层,隐藏层节点数都为5,隐藏层都使用ReLu激活函数。
# 设置两个隐藏层,采用ReLu激活函数 NN = NNClassifier(n = [np.nan,5,5,1],alpha = 0.02, ITERNUM = 200000, gfunc = 'ReLu') NN.fit(X_train,y_train) # 绘制目标函数迭代曲线 %matplotlib inline NN.dfJ.plot(figsize = (12,8)) # 测试在验证集的auc得分 from sklearn.metrics import roc_auc_score Y_prob = NN.predict_prob(X_test) roc_auc_score(list(y_test),list(Y_prob))
AUC得分0.99874比采用单隐藏层的最优得分0.99958有所降低,可能是模型复杂度过高,我们尝试减少隐藏层节点的个数至3以降低模型复杂度。
# 双隐藏层,隐藏层节点数为3 NN = NNClassifier(n = [np.nan,3,3,1],alpha = 0.02, ITERNUM = 200000, gfunc = 'ReLu') NN.fit(X_train,y_train) # 绘制目标函数迭代曲线 %matplotlib inline NN.dfJ.plot(figsize = (12,8)) # 测试在验证集的auc得分 from sklearn.metrics import roc_auc_score Y_prob = NN.predict_prob(X_test) roc_auc_score(list(y_test),list(Y_prob))
AUC得分0.99979,又有所提高。
和sklearn中自带的神经网络分类器进行对比。
# 和sklearn中的模型对比 from sklearn.neural_network import MLPClassifier # 第一隐藏层神经元个数为3,第二隐藏层神经元个数为3 MLPClf = MLPClassifier(hidden_layer_sizes=(3,3),max_iter=200000,activation='relu') MLPClf.fit(X_train,y_train) # 绘制目标函数迭代曲线 dfJ = pd.DataFrame(data = np.array(MLPClf.loss_curve_),columns = ['J']) dfJ.plot(figsize = (12,8)) # 测试在验证集的auc得分 from sklearn.metrics import roc_auc_score Y_prob = MLPClf.predict_proba(X_test)[:,1] roc_auc_score(list(y_test),list(Y_prob))
以上试验表明,针对当前数据数据集,选择ReLu激活函数,采用双隐藏层,每个隐藏层节点数设置为3是一个不错的选择,AUC得分为0.99979。该得分高于采用CV交叉验证优化超参数后的逻辑回归模型的0.99897的AUC得分。