1. 程式人生 > >全連線神經網路

全連線神經網路

 

#演算法原理
在生物神經網路中,每個神經元與其他神經元相連,當它興奮時,就會向相連的神經元傳送化學物質,從而改變這些神經元內的電位。如果某神經元的電位超過了一個閾值,那麼它就會被啟用,從而興奮起來,繼續向其他神經元傳送化學物質,從而將訊號逐層傳遞下去。
 

如上所示,神經元接收到來自n個其他神經元傳遞過來的輸入訊號,並且每個輸入訊號帶有一定的權重,神經元接收到的總輸入值將與神經元的閾值比較,然後通過啟用函式處理以產生神經元的輸出(決定是否被啟用)。

把許多個這樣的神經元按照一定的層次結構連線起來,就得到了神經網路。
之所以又把DNN叫多層感知機Multi-Layer Perceptron,是因為我們的邏輯迴歸實際上就是一個一層的神經網路,只有輸入層和輸出層,沒有隱藏層,這就是一個感知機,所以感知機本質上還是一個對數線性模型,無法處理非線性問題,但是多層感知機(含有1到多個隱藏層的神經網路)可以,可以證明,只需一個包含足夠多神經元的隱層,MLP就能以任意精度逼近任意複雜度的連續函式。
 

神經網路(DNN、CNN、RNN等)的訓練都是通過反向傳播(backpropagation)完成的,反向傳播是梯度下降演算法的一種特殊實現,是神經網路專用的引數更新演算法,引數的更新過程也是通過梯度下降的公式推到計算而來的。(推導過程詳見:《機器學習》周志華第5.3節):

反向傳播最終是根據偏誤差反向傳遞。假設我們取啟用函式為Sigmoid,Oj代表每一個神經元(隱藏層和輸出層)的輸出值,Oi為每個神經元的實際值,那麼我們可以計算每個神經元的偏誤差:
對於輸出層:


對於隱藏層:
 


權重更新:


偏向更新:

下面通過一個實際例子來說明反向傳播的具體過程,假設下面的兩層神經網路最終的輸出T = 1:
 

以上就是通過backpropagation進行第一輪神經網路訓練的全部過程,引數更新完成後,再帶入下一個樣本點,繼續按照一模一樣的方式進行後面一輪的迭代更新。
上面的更新過程叫做標準BP演算法,即每次傳入單個樣本進行引數更新,如果每次傳入mini-batch資料,就是累積BP演算法,這時每個神經元Err的計算就是所有樣本Err的平均值。
#模型訓練



#sklearn版



程式碼地址 https://github.com/qianshuang/ml-exp


def train():
   print("start training...")
   # 處理訓練資料
   train_feature, train_target =process_file(train_dir, word_to_id, cat_to_id) 
# 詞頻特徵
   # train_feature, train_target = process_tfidf_file(train_dir, word_to_id, cat_to_id)  # TF-IDF特徵
   # 模型訓練
   model.fit(train_feature,train_target)


def test():
   print("start testing...")
   # 處理測試資料
   test_feature, test_target =process_file(test_dir, word_to_id, cat_to_id)
   # test_feature, test_target =process_tfidf_file(test_dir, word_to_id, cat_to_id)  # 不能直接這樣處理,應該取訓練集的IDF值
   test_predict = model.predict(test_feature)  # 返回預測類別
   # test_predict_proba = model.predict_proba(test_feature)    # 返回屬於各個類別的概率
   # test_predict =np.argmax(test_predict_proba, 1)  # 返回概率最大的類別標籤

   # accuracy
   true_false = (test_predict == test_target)
   accuracy = np.count_nonzero(true_false) /
float(len(test_target))
   print()
   print("accuracy is %f" % accuracy)

   # precision    recall  f1-score
   print()
  
print(metrics.classification_report(test_target, test_predict,target_names=categories))

   # 混淆矩陣
   print("Confusion Matrix...")
   print(metrics.confusion_matrix(test_target,test_predict))


if not os.path.exists(vocab_dir):
   # 構建詞典表
   build_vocab(train_dir, vocab_dir)

categories, cat_to_id = read_category(test_dir)
words,word_to_id = read_vocab(vocab_dir)

# kNN
# model= neighbors.KNeighborsClassifier()
#
decision tree
# model= tree.DecisionTreeClassifier()
# random
forest
# model= ensemble.RandomForestClassifier(n_estimators=10)  # n_estimators為基決策樹的數量,一般越大效果越好直至趨於收斂
#
AdaBoost
# model= ensemble.AdaBoostClassifier(learning_rate=1.0)  # learning_rate的作用是收縮基學習器的權重貢獻值
#
GBDT
# model= ensemble.GradientBoostingClassifier(n_estimators=10)
#
xgboost
# model= xgboost.XGBClassifier(n_estimators=10)
#
Naive Bayes
# model= naive_bayes.MultinomialNB()
#
logistic regression
# model= linear_model.LogisticRegression()   #
ovr
# model= linear_model.LogisticRegression(multi_class="multinomial",
solver="lbfgs")  # softmax迴歸
# SVM
# model= svm.LinearSVC()  # 線性,無概率結果
# model= svm.SVC()  # 核函式,訓練慢
# MLP
model =neural_network.MLPClassifier(max_iter=200,
verbose=True,
early_stopping=True)  # 注意max_iter是epoch數

train()
test()



執行結果:



building vacab...
read_category...
read_vocab...
start training...
Iteration 1, loss = 0.72800690
Validation score: 0.961111

Iteration 2, loss = 0.12962878
Validation score: 0.967778
Iteration 3, loss = 0.06385715
Validation score: 0.973333
Iteration 4, loss = 0.03742299
Validation score: 0.975556
Iteration 5, loss = 0.02495986
Validation score: 0.974444
Iteration 6, loss = 0.01741929
Validation score: 0.974444
Iteration 7, loss = 0.01319729
Validation score: 0.972222
Validation score did not improve more than tol=0.000100 for two consecutive epochs.
Stopping.
start testing...

accuracy is 0.971000

            precision    recall  f1-score   support

        科技       0.98     0.99      0.98        94
        家居       0.93      0.94     0.94        89
        財經       0.99     0.98      0.99       115
        房產       0.94     0.93      0.94       104
        教育       0.97     0.96      0.97       104
        遊戲       0.99     0.98      0.99       104
        時政       0.95     0.96      0.95        94
        時尚       0.96     0.98      0.97        91
        體育       1.00     0.98      0.99       116
        娛樂       0.99     1.00      0.99        89

avg /total       0.97      0.97     0.97      1000

Confusion Matrix...
[[93   1  0   0   0  0   0   0  0   0]
[  0  84   0  1   2   1  0   1   0   0]
[ 0   0 113   1  0   0   1  0   0   0]
[ 0   3   0  97  0   0  3   1   0   0]
[ 0   1   0  1 100   0  0   2   0   0]
[  1   0  0   0   1 102  0   0   0   0]
[ 0   0   1  3   0   0 90   0   0   0]
[ 0   1   0  0   0   0  0  89   0   1]
[ 1   0   0  0   0   0  1   0 114   0]
[ 0   0   0  0   0   0  0   0   0 89]]

#tensorflow版
程式碼地址 https://github.com/qianshuang/dl-exp

class
TextCNN(object):
   """文字分類,MLP模型"""
   def __init__(self, config):
       self.config = config

       # 三個待輸入的資料
       self.input_x =
tf.placeholder(tf.float32, [None, self.config.vocab_size], name='input_x')
       self.input_y =
tf.placeholder(tf.float32, [None, self.config.num_classes], name='input_y')
       self.keep_prob =
tf.placeholder_with_default(1.0, shape=())
       self.log()

   def log(self):
       with tf.name_scope("score"):
           # hidden layer
           # 使用truncated_normal(高斯)初始化權重,可以避免大的權重值減慢訓練,切記不可用全0初始化,回憶BP原理
           W1 =
tf.Variable(tf.truncated_normal([self.config.vocab_size, 1024],
stddev=0.1))  # 隱藏層1024個神經元
           b1 = tf.Variable(tf.constant(0.1,
shape=[1024]))
           y_conv_1 = tf.matmul(self.input_x,
W1) + b1
           layer_1 = tf.nn.relu(y_conv_1)  # 啟用函式

           # 以上程式碼還可以通過下面的方式簡化實現:
           # y_conv_1 =
tf.layers.dense(self.input_x, 1024)
           # y_conv_1 =
tf.contrib.layers.fully_connected(self.input_x, 1024,
weights_regularizer=tf.contrib.layers.l2_regularizer(scale=0.001))

           # output layer
           W2 =
tf.Variable(tf.truncated_normal([1024, self.config.num_classes], stddev=0.1))
           b2 = tf.Variable(tf.constant(0.1,
shape=[self.config.num_classes]))
           y_conv = tf.matmul(layer_1, W2) +b2

           self.y_pred_cls = tf.argmax(y_conv,1)  # 預測類別

       with tf.name_scope("optimize"):
           self.loss =tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=self.input_y,
logits=y_conv))
           # 優化器
           self.optim =
tf.train.AdamOptimizer(learning_rate=self.config.learning_rate).minimize(self.loss)

       with tf.name_scope("accuracy"):
           # 準確率
           correct_pred =tf.equal(tf.argmax(self.input_y, 1), self.y_pred_cls)
           self.acc =tf.reduce_mean(tf.cast(correct_pred, tf.float32))

執行結果:

Configuringb model...
Loading training data...
Training and evaluating...
Epoch:
1
Iter:      0, Train Loss:    5.4, Train Acc:   8.59%, Val Loss:    5.2, Val Acc:  10.40%, Time: 0:00:02 *
Iter:     10, Train Loss:   0.81, Train Acc:  72.66%, Val Loss:   0.92, Val Acc:  71.60%, Time: 0:00:05 *
Iter:     20, Train Loss:   0.61, Train Acc:  85.16%, Val Loss:   0.42, Val Acc:  87.90%, Time: 0:00:08 *
Iter:     30, Train Loss:   0.48, Train Acc:  85.16%, Val Loss:   0.37, Val Acc:  89.80%, Time: 0:00:12 *
Iter:     40, Train Loss:   0.37, Train Acc:  92.97%, Val Loss:   0.32, Val Acc:  91.60%, Time: 0:00:16 *
Iter:     50, Train Loss:   0.18, Train Acc:  94.53%, Val Loss:   0.23, Val Acc:  94.00%, Time: 0:00:18 *
Iter:     60, Train Loss:   0.17, Train Acc:  96.09%, Val Loss:   0.21, Val Acc:  94.10%, Time: 0:00:23 *
Iter:     70, Train Loss:    0.4, Train Acc:  92.50%, Val Loss:   0.18, Val Acc:  95.60%, Time: 0:00:26 *
Epoch: 2
Iter:     80, Train Loss:  0.026, Train Acc:  99.22%, Val Loss:   0.22, Val Acc:  93.90%, Time: 0:00:29 
Iter:     90, Train Loss:   0.02, Train Acc: 100.00%, Val Loss:   0.18, Val Acc:  95.20%, Time: 0:00:31 
Iter:    100, Train Loss:   0.02, Train Acc:  99.22%, Val Loss:   0.16, Val Acc:  95.80%, Time: 0:00:35 *
......
Epoch: 6
Iter:    360, Train Loss: 0.0017, Train Acc: 100.00%, Val Loss:   0.14, Val Acc:  96.20%, Time: 0:01:57 
Iter:    370, Train Loss: 0.0016, Train Acc: 100.00%, Val Loss:   0.14, Val Acc:  96.10%, Time: 0:01:59 
Iter:    380, Train Loss: 0.0016, Train Acc: 100.00%, Val Loss:   0.14, Val Acc:  96.10%, Time: 0:02:02 
No optimization for a long time, auto-stopping...
Loading test data...
Testing...
Test Loss:   0.14, Test Acc:  96.30%
Precision,Recall and F1-Score...
            precision    recall  f1-score   support

        財經       0.98     0.97      0.98       115
        娛樂       1.00     0.98      0.99        89
        時政       0.93     0.96      0.94        94
        家居       0.90     0.93      0.92        89
        遊戲       1.00     0.97      0.99       104
        教育       0.97     0.92      0.95       104
        時尚       0.95     0.99      0.97        91
        科技       0.99     0.99      0.99        94
        房產       0.91     0.92      0.91       104
        體育       1.00     0.99      1.00       116

avg /total       0.96      0.96     0.96      1000

Confusion
Matrix...
[[112   0   1   1    0   0  0   0   1   0]
[    0  87   1   0    0   0  1   0   0   0]
[    1   0  90   0    0   0  0   0   3   0]
[    1   0   0  83    0   1  0   0   4   0]
[    0   0   0   0  101   1  1   1   0   0]
[    0   0   1   3   0   96  2   0   2   0]
[    0   0   0   0   0   1  90   0   0   0]
[    0   0   0   1   0   0   0  93   0   0]
[    0   0   3   4   0   0   1   0  96   0]
[    0   0   1   0   0   0   0   0   0 115]]

#社群




QQ交流群


微信公眾號