DNN網絡,python下用Tensorflow實現DNN網絡以及Adagrad優化器


一、DNN 簡介

 DNN一共可以分為三層。

  • 輸入層(input layer)
  • 隱藏層(hidden layer)
  • 輸出層(output layer)

 

 

DNN的前向傳播即由輸入經過一些列激活函數得到最終的輸出

在對DNN參數求解的時候,通過反向傳播,以及鏈式法則求得。

 

二、Tensorflow下的DNN實現 

1、實現功能簡介:

本文摘自Kaggle的一篇房價預測題目,找了一篇比較全的,當作自己的Tensorflow入門。鏈接:

https://www.kaggle.com/zoupet/neural-network-model-for-house-prices-tensorflow

數據和題目可以在文章開頭的地址找的。

主要是給定了一個區域的房子價格以及房子特征,要預測一下房價。

 

2、挑選數據

 

 1 # 為了使得代碼在 python2 或者3下都運行,加的 __future__包。如果是python3,下面的包可以不加。
 2 from __future__ import absolute_import
 3 from __future__ import division
 4 from __future__ import print_function
 5 
 6 import itertools
 7 
 8 import pandas as pd
 9 import numpy as np
10 import matplotlib.pyplot as plt
11 from pylab import rcParams
12 import matplotlib
13 
14 from sklearn.model_selection import train_test_split
15 
16 # scaler, put the value range from min to max
17 from sklearn.preprocessing import MinMaxScaler
18 
19 import tensorflow as tf
20 
21 # 定義多少條記錄會被當作log。
22 tf.logging.set_verbosity(tf.logging.INFO)
23 
24 # InteractiveSession 與 Session的區別是不用每一次執行命令時,前面都加一個session。可以自己查一下
25 sess = tf.InteractiveSession()
26 
27 # 文件目錄
28 path_train = '/Users/adrian.wu/Desktop/learn/kaggle/price/data/all/train.csv'
29 
30 '''
31 首先只用數字特征進行預測,去除掉其它特征,比如類別等
32 '''
33 train = pd.read_csv(path_train)
34 
35 print('所有特征下,矩陣緯度:', train.shape)
36 
37 # 挑選出只是數字類型的特征
38 train = train.select_dtypes(exclude=['object'])
39 print('數字類型特征矩陣的緯度:', train.shape)
40 
41 # 去掉沒用的特征Id
42 train.drop('Id', axis=1, inplace=True)
43 
44 # 處理缺失值,簡單的填充0
45 train.fillna(0, inplace=True)
46 
47 print("\n特征:", list(train.columns))
48 
49 '''
50 用Isolation Forest去掉異常值
51 '''
52 from sklearn.ensemble import IsolationForest
53 
54 clf = IsolationForest(max_samples=100, random_state=42)
55 clf.fit(train)
56 
57 y_noano = clf.predict(train)
58 print(y_noano)
59 y_noano = pd.DataFrame(y_noano, columns=['Top'])
60 # y_noano[y_noano['Top'] == 1].index.values, 等於1的不是異常值,-1為異常值
61 
62 train = train.iloc[y_noano[y_noano['Top'] == 1].index.values]
63 train.reset_index(drop=True, inplace=True)
64 
65 print("異常值數量:", y_noano[y_noano['Top'] == -1].shape[0])
66 print("正常數據數量:", train.shape[0])

 

3、特征預處理 

 1 '''
 2 特征預處理
 3 '''
 4 import warnings
 5 
 6 warnings.filterwarnings('ignore')
 7 
 8 # 得到特征名字,並存為list類型
 9 col_train = list(train.columns)
10 col_train_bis = list(train.columns)
11 
12 # 去除要預測的值,SalePrice
13 col_train_bis.remove('SalePrice')
14 
15 # 用numpy轉為可操作的矩陣
16 mat_train = np.mat(train)
17 
18 mat_y = np.array(train.SalePrice).reshape((1314, 1))
19 
20 # 歸一化方法,把所有特征歸一化到0~1之間
21 prepro_y = MinMaxScaler()
22 prepro_y.fit(mat_y)
23 
24 prepro = MinMaxScaler()
25 prepro.fit(mat_train)
26 
27 # 將處理過后的數據轉為DataFrame
28 train = pd.DataFrame(prepro.transform(mat_train), columns=col_train)

 

 

4、train test數據集合處理

 1 '''
 2 train test集合數據處理
 3 '''
 4 
 5 # 把列都列出來
 6 COLUMNS = col_train
 7 FEATURES = col_train_bis
 8 LABEL = "SalePrice"
 9 
10 # 暫且理解將DataFrame的數據轉為對應的輸入值,因此要指定一列列的值。
11 feature_cols = [tf.contrib.layers.real_valued_column(k) for k in FEATURES]
12 
13 # 得到Feature 和 預測值
14 training_set = train[COLUMNS]
15 prediction_set = train.SalePrice
16 
17 # 將Train test 分為2:1分
18 x_train, x_test, y_train, y_test = train_test_split(training_set[FEATURES], prediction_set, test_size=0.33,
19                                                     random_state=42)
20 # 整合特征和預測值,對train集
21 y_train = pd.DataFrame(y_train, columns=[LABEL])
22 training_set = pd.DataFrame(x_train, columns=FEATURES).merge(y_train, left_index=True, right_index=True)
23 
24 # 整合特征和預測值,對test集
25 y_test = pd.DataFrame(y_test, columns=[LABEL])
26 testing_set = pd.DataFrame(x_test, columns=FEATURES).merge(y_test, left_index=True, right_index=True)
27 
28 # 打log的,可以忽略
29 tf.logging.set_verbosity(tf.logging.ERROR)

 

5、DNN網絡 

 1 '''
 2  快速創建一個DNN網絡, 
 3  optimizer = tf.train.GradientDescentOptimizer( learning_rate= 0.1 )) 可以自己選優化方式
 4  激活函數為relu
 5  都有哪些feature
 6  隱藏層的神經元個數,遞減,200,100,50,25,12個
 7 '''
 8 
 9 regressor = tf.contrib.learn.DNNRegressor(feature_columns=feature_cols,
10                                           activation_fn=tf.nn.relu,
11                                           hidden_units=[200, 100, 50, 25, 12])
12 
13 training_set.reset_index(drop=True, inplace=True)
14 
15 
16 # 定義一個函數用來train網絡
17 def input_fn(data_set, pred=False):
18     if pred == False:
19         feature_cols = {k: tf.constant(data_set[k].values) for k in FEATURES}
20         labels = tf.constant(data_set[LABEL].values)
21 
22         return feature_cols, labels
23 
24     if pred == True:
25         feature_cols = {k: tf.constant(data_set[k].values) for k in FEATURES}
26 
27         return feature_cols
28 
29 
30 # trainDNN網絡
31 regressor.fit(input_fn=lambda: input_fn(training_set), steps=2000)
32 
33 # 估計測試集
34 ev = regressor.evaluate(input_fn=lambda: input_fn(testing_set), steps=1)
35 loss_score = ev["loss"]
36 print("test集的損失為: {0:f}".format(loss_score))

 

6、Adagrad優化器

看了下代碼。這里的優化器用的是Adagrad。形式大致和SGD差不多,在其基礎通過對梯度的迭代相加,對學習率進行了更新,從而控制學習率。

學習率隨着梯度的和會逐漸變小。

 

1、迭代公式

eta也就是分子項是初始學習率。G為梯度迭代和,G旁邊長的很像E的那一項是一個小常數,防止分母為0。

由上式可得到,G越大,學習率越小。

 

三、Tensorflow一步一步搭建一個簡單DNN

1、創建網絡

 1 import tensorflow as tf
 2 from numpy.random import RandomState
 3 from sklearn.model_selection import train_test_split
 4 
 5 batch_size = 8
 6 
 7 # 定義網絡
 8 w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
 9 b1 = tf.Variable(tf.zeros([1, 3], name="bias1"))
10 b2 = tf.Variable(tf.zeros([1], name="bias2"))
11 w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
12 
13 x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
14 y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')
15 a = tf.matmul(x, w1) + b1
16 
17 # 這里一定不要寫成 tf.sigmoid
18 y_last = tf.nn.sigmoid(tf.matmul(a, w2) + b2)

 

2、定義損失函數

1 # 損失與准確率
2 loss = tf.losses.sigmoid_cross_entropy(y_, y_last)
3 train_step = tf.train.AdamOptimizer(0.07).minimize(loss)
4 
5 correct_prediction = tf.equal(tf.round(y_last), y_)
6 acc = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

 

3、造數據

# 造數據,X為二維數據例如:[[0.1, 0.8]], 當X的第一項和第二項相加 < 1 時 Y為1, 當X的第一項和第二項相加 >= 1時為 0
rdm = RandomState(1)
data_set_size = 128000
X = rdm.rand(data_set_size, 2)
Y = [[int(x1 + x2 < 1)] for (x1, x2) in X]

X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3)

 

4、訓練與測試

with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    STEPS = 7000
    for i in range(0, 8900 - batch_size, batch_size):
        start = i
        sess.run(train_step, feed_dict={x: X_train[start: start + batch_size], y_: y_train[start: start + batch_size]})

        if i % 800 == 0:
            # 計算所有數據的交叉熵
            total_cross_entropy = sess.run(loss, feed_dict={x: X, y_: Y})
            # 輸出交叉熵之和
            # print("After %d training step(s),cross entropy on all data is %g" % (i, total_cross_entropy))

    acc_ = sess.run(acc, feed_dict={x: X_test, y_: y_test})
    print("accuracy on test data is ", acc_)

    test = sess.run(y_last, feed_dict={x: X_test, y_: y_test})

 

5、結果

accuracy on test data is  0.96091145


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM