01 データセットの準備 使用されるデータセットは、30 次元の特徴と 569 個のサンプルを含む、sklearn の乳がんデータセットです。トレーニングの前に、[0,1]間隔にスケーリングするためにMinMax正規化が実行されます。データセットは、75/25 の比率でトレーニング セットと検証セットに分割されます。 - # データセットを取得する
- numpyをnpとしてインポートする
- pandasをpdとしてインポートする
- sklearnからデータセットをインポートする
- sklearnインポート前処理から
- sklearn.model_selection からtrain_test_splitをインポートします
- 乳房 = datasets.load_breast_cancer()
- スケーラー = preprocessing.MinMaxScaler()
- データ = scaler.fit_transform(breast[ 'data' ])
- ターゲット = 乳房[ 'ターゲット' ]
- X_train、X_test、y_train、y_test = train_test_split(データ、ターゲット)
02 モデル構造図 03 順方向および逆方向の伝播式 04 NN実装コード - numpyをnpとしてインポートする
- pandasをpdとしてインポートする
- #活性化関数を定義する
- ReLu = ラムダ z:np.maximum( 0.0 ,z)
- d_ReLu = lambda z:np.where(z< 0 , 0 , 1 )
- LeakyReLu = ラムダ z:np.maximum( 0.01 *z,z)
- d_LeakyReLu = lambda z:np.where(z< 0 , 0.01 , 1 )
- シグモイド = ラムダ z: 1 /( 1 +np.exp(-z))
- d_Sigmoid = ラムダ z: Sigmoid(z)*( 1- Sigmoid(z)) #d_Sigmoid = a( 1 -a)
- 正接 = np.tanh
- d_Tanh = ラムダ z: 1 - Tanh(z)** 2 #d_Tanh = 1 - a** 2
- クラスNNClassifier(オブジェクト):
- def __init__(self,n = [np.nan, 5 , 5 , 1 ],alpha = 0.1 ,ITERNUM = 50000 , gfunc = 'ReLu' ):
- self.n = n #各層のノード数
- self.gfunc = gfunc #隠れ層の活性化関数
- self.alpha,self.ITERNUM = alpha,ITERNUM
- self.dfJ = pd.DataFrame(データ = np.zeros((ITERNUM, 1 )), 列 = [ 'J' ])
- 自己.W、自己.b = np.nan、np.nan
- # 各層の活性化関数を決定する
- self.g = [eval(self.gfunc) for i in range(len(n))];
- self.g[- 1 ] = シグモイド; self.g[ 0 ] = np.nan
- # 隠れ層の活性化関数の導関数を決定する
- self.d_gfunc = eval( 'd_' + self.gfunc)を実行します。
- def fit(self,X_train,y_train):
- X、Y = X_train.T、y_train.reshape( 1 、- 1 )
- m = X.shape[ 1 ] #サンプル数
- n = self.n; n[ 0 ] = X.shape[ 0 ] # 各層のノード数
- # ノード値とパラメータの初期化
- A = [np.zeros((ni,m)) for ni in n]; A[ 0 ] = X # 各層ノードの出力値を初期化する
- Z = [np.zeros((ni,m)) for ni in n]; Z[ 0 ] = np.nan # 各層ノードの中間値を初期化する
- W = [np.nan] + [np.random.randn(n[i],n[i- 1 ]) * 0.01 for i in range( 1 ,len(n))] # 各層の係数パラメータ
- b = [np.zeros((ni, 1 )) for ni in n]; b[ 0 ] = np.nan #n 各層のバイアスパラメータ
- # 導関数を初期化する
- dA = [np.zeros(Ai.shape) AiがAにある場合]
- dZ = [np.zeros(Ai.shape) A 内の Aiの場合]
- dW = [np.zeros(Wi.shape)、 isinstance(Wi,np.ndarray)、そうでない場合はnp.nan 、Wiが W の場合]
- db = [np.zeros(bi.shape)、 isinstance(bi、np.ndarray)、そうでない場合は、biがb 内にある場合np.nan ]
- k が範囲内にある場合(self.ITERNUM):
- # ---------前方伝播----------
- iが範囲( 1 ,len(n))内にある場合:
- Z[i] = np.dot(W[i],A[i- 1 ]) + b[i]
- A[i] = 自己.g[i](Z[i])
- J = ( 1 /m) * np.sum(- Y*np.log(A[len(n)- 1 ]) -( 1 -Y)*np.log( 1 -A[len(n)- 1 ]))
- self.dfJ.loc[k][ 'J' ] = J
- # ----------後方伝播---------
- hmax = 長さ(n) - 1
- dA[hmax] = 1 /m*(-Y/A[hmax] + ( 1 -Y)/( 1 -A[hmax]))
- dZ[hmax] = 1 /m*(A[hmax]-Y)
- dW[hmax] = np.dot(dZ[hmax],A[hmax- 1 ].T)
- db[hmax] = np.dot(dZ[hmax],np.ones((m, 1 )))
- iが範囲(len(n)-2,0 , -1 )内にある場合:
- dA[i] = np.dot(W[i+ 1 ].T,dZ[i+ 1 ])
- dZ[i] = dA[i]* self.d_gfunc(Z[i])
- dW[i] = np.dot(dZ[i],A[i- 1 ].T) です。
- db[i] = np.dot(dZ[i],np.ones((m, 1 )))
- #-----------勾配降下法---------
- iが範囲( 1 ,len(n))内にある場合:
- W[i] = W[i] - 自己.alpha*dW[i]
- b[i] = b[i] - self.alpha*db[i]
- # 進行状況を表示
- (k+ 1 )% 1000 == 0の場合:
- print( '進捗率: {}/{}' .format(k+ 1 ,self.ITERNUM),end = '\r' )
- 自己.W,自己.b = W,b
- def predict_prob(self, X_test):
- # ---------前方伝播----------
- W,b = 自分.W,自分.b
- Ai = X_test.T
- i が範囲( 1 、len(self.n))内にある場合:
- Zi = np.dot(W[i],Ai) + b[i]
- Ai = 自己.g[i](Zi)
- 戻り値(Ai.reshape(- 1 ))
- def predict(self,X_test):
- Y_prob = 自己予測確率(X_test)
- Y_テスト = Y_prob.copy()
- Y_テスト[Y_確率>= 0.5 ] = 1
- Y_テスト[Y_確率< 0.5 ] = 0
- 戻り値(Y_test)
05 単一隠れ層ニューラルネットワーク 隠し層を 1 に設定し、隠し層ノードの数は 5 で、隠し層はシグモイド活性化関数を使用します。 - # シグモイド活性化関数を使用する
- NN = NNClassifier(n = [np.nan, 5 , 1 ], アルファ = 0.02 ,
- ITERNUM = 200000 、gfunc = 'シグモイド' )
- NN.fit(X_train,y_train)
- # 目的関数の反復曲線を描く
- %matplotlib インライン
- NN.dfJ.plot(図のサイズ = ( 12 , 8 ))
- # 検証セットでAUCスコアをテストする
- sklearn.metricsからroc_auc_scoreをインポートします
- Y_確率 = NN.予測確率(X_テスト)
- roc_auc_score(リスト(y_test),リスト(Y_prob))
隠れ層は Tanh 活性化関数を使用します。 - # Tanh活性化関数の使用
- NN = NNClassifier(n = [np.nan, 5 , 1 ], アルファ = 0.02 ,
- ITERNUM = 200000 、 gfunc = 'Tanh' )
- NN.fit(X_train,y_train)
- # 目的関数の反復曲線を描く
- %matplotlib インライン
- NN.dfJ.plot(図のサイズ = ( 12 , 8 ))
- # 検証セットでAUCスコアをテストする
- sklearn.metricsからroc_auc_scoreをインポートします
- Y_確率 = NN.予測確率(X_テスト)
- roc_auc_score(リスト(y_test),リスト(Y_prob))
隠し層は ReLu 活性化関数を使用します。 - # ReLu活性化関数を使用する
- NN = NNClassifier(n = [np.nan, 5 , 1 ], アルファ = 0.02 ,
- ITERNUM = 200000 、gfunc = 'ReLu' )
- NN.fit(X_train,y_train)
- # 目的関数の反復曲線を描く
- %matplotlib インライン
- NN.dfJ.plot(図のサイズ = ( 12 , 8 ))
- # 検証セットでAUCスコアをテストする
- sklearn.metricsからroc_auc_scoreをインポートします
- Y_確率 = NN.予測確率(X_テスト)
- roc_auc_score(リスト(y_test),リスト(Y_prob))
隠し層は LeakyReLu 活性化関数を使用します。 - # LeakyReLu活性化関数を使用する
- NN = NNClassifier(n = [np.nan, 5 , 1 ], アルファ = 0.02 ,
- ITERNUM = 200000 、gfunc = 'LeakyReLu' )
- NN.fit(X_train,y_train)
- # 目的関数の反復曲線を描く
- %matplotlib インライン
- NN.dfJ.plot(図のサイズ = ( 12 , 8 ))
- # 検証セットでAUCスコアをテストする
- sklearn.metricsからroc_auc_scoreをインポートします
- Y_確率 = NN.予測確率(X_テスト)
- roc_auc_score(リスト(y_test),リスト(Y_prob))
上記の実験は、現在のデータセットでは、隠し層に ReLu 活性化関数を使用するのが最良の選択であり、最高の AUC スコアが 0.99958 であることを示しているようです。 06 二重隠れ層ニューラルネットワーク 隠し層を 2 つ設定し、隠し層ノードの数は 5 で、隠し層は ReLu 活性化関数を使用します。 - # 2つの隠し層を設定し、ReLu活性化関数を使用する
- NN = NNClassifier(n = [np.nan, 5 , 5 , 1 ],アルファ = 0.02 ,
- ITERNUM = 200000 、gfunc = 'ReLu' )
- NN.fit(X_train,y_train)
- # 目的関数の反復曲線を描く
- %matplotlib インライン
- NN.dfJ.plot(図のサイズ = ( 12 , 8 ))
- # 検証セットでAUCスコアをテストする
- sklearn.metricsからroc_auc_scoreをインポートします
- Y_確率 = NN.予測確率(X_テスト)
- roc_auc_score(リスト(y_test),リスト(Y_prob))
AUC スコア 0.99874 は、単一の隠し層を使用した場合の最適スコア 0.99958 よりも低くなっています。これは、モデルの複雑さが高すぎることが原因である可能性があります。モデルの複雑さを軽減するために、隠し層ノードの数を 3 に減らすことを試みます。 - # 二重隠し層、隠し層ノードの数は3
- NN = NNClassifier(n = [np.nan, 3 , 3 , 1 ],アルファ = 0.02 ,
- ITERNUM = 200000 、gfunc = 'ReLu' )
- NN.fit(X_train,y_train)
- # 目的関数の反復曲線を描く
- %matplotlib インライン
- NN.dfJ.plot(図のサイズ = ( 12 , 8 ))
- # 検証セットでAUCスコアをテストする
- sklearn.metricsからroc_auc_scoreをインポートします
- Y_確率 = NN.予測確率(X_テスト)
- roc_auc_score(リスト(y_test),リスト(Y_prob))
AUC スコアは 0.99979 となり、改善が見られます。 sklearn に付属するニューラル ネットワーク分類器と比較します。 - # sklearnのモデルと比較する
- sklearn.neural_network からMLPClassifierをインポートします
- # 最初の隠れ層のニューロンの数は3で、2 番目の隠れ層のニューロンの数は3です。
- MLPClf = MLPClassifier(隠しレイヤーのサイズ=( 3 , 3 ),max_iter= 200000 ,アクティベーション= 'relu' )
- MLPClf.fit(X_train、y_train) 関数
- # 目的関数の反復曲線を描く
- dfJ = pd.DataFrame(データ = np.array(MLPClf.loss_curve_)、列 = [ 'J' ])
- dfJ.plot(図のサイズ = ( 12 , 8 ))
- # 検証セットでAUCスコアをテストする
- sklearn.metricsからroc_auc_scoreをインポートします
- Y_prob = MLPClf.predict_proba(X_test)[:, 1 ]
- roc_auc_score(リスト(y_test),リスト(Y_prob))
上記の実験から、現在のデータ セットでは、ReLu 活性化関数を選択し、二重の隠し層を使用し、各隠し層のノード数を 3 に設定することが適切な選択であり、AUC スコアは 0.99979 であることが示されています。このスコアは、CV クロス検証を使用してハイパーパラメータを最適化した後のロジスティック回帰モデルの AUC スコア 0.99897 よりも高くなります。 |