一、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、挑選資料

 # 為了使得程式碼在 python2 或者3下都執行,加的 __future__包。如果是python3,下面的包可以不加。
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function import itertools import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import rcParams
import matplotlib from sklearn.model_selection import train_test_split # scaler, put the value range from min to max
from sklearn.preprocessing import MinMaxScaler import tensorflow as tf # 定義多少條記錄會被當作log。
tf.logging.set_verbosity(tf.logging.INFO) # InteractiveSession 與 Session的區別是不用每一次執行命令時,前面都加一個session。可以自己查一下
sess = tf.InteractiveSession() # 檔案目錄
path_train = '/Users/adrian.wu/Desktop/learn/kaggle/price/data/all/train.csv' '''
首先只用數字特徵進行預測,去除掉其它特徵,比如類別等
'''
train = pd.read_csv(path_train) print('所有特徵下,矩陣緯度:', train.shape) # 挑選出只是數字型別的特徵
train = train.select_dtypes(exclude=['object'])
print('數字型別特徵矩陣的緯度:', train.shape) # 去掉沒用的特徵Id
train.drop('Id', axis=1, inplace=True) # 處理缺失值,簡單的填充0
train.fillna(0, inplace=True) print("\n特徵:", list(train.columns)) '''
用Isolation Forest去掉異常值
'''
from sklearn.ensemble import IsolationForest clf = IsolationForest(max_samples=100, random_state=42)
clf.fit(train) y_noano = clf.predict(train)
print(y_noano)
y_noano = pd.DataFrame(y_noano, columns=['Top'])
# y_noano[y_noano['Top'] == 1].index.values, 等於1的不是異常值,-1為異常值 train = train.iloc[y_noano[y_noano['Top'] == 1].index.values]
train.reset_index(drop=True, inplace=True) print("異常值數量:", y_noano[y_noano['Top'] == -1].shape[0])
print("正常資料數量:", train.shape[0])

3、特徵預處理

 '''
特徵預處理
'''
import warnings warnings.filterwarnings('ignore') # 得到特徵名字,並存為list型別
col_train = list(train.columns)
col_train_bis = list(train.columns) # 去除要預測的值,SalePrice
col_train_bis.remove('SalePrice') # 用numpy轉為可操作的矩陣
mat_train = np.mat(train) mat_y = np.array(train.SalePrice).reshape((1314, 1)) # 歸一化方法,把所有特徵歸一化到0~1之間
prepro_y = MinMaxScaler()
prepro_y.fit(mat_y) prepro = MinMaxScaler()
prepro.fit(mat_train) # 將處理過後的資料轉為DataFrame
train = pd.DataFrame(prepro.transform(mat_train), columns=col_train)

4、train test資料集合處理

 '''
train test集合資料處理
''' # 把列都列出來
COLUMNS = col_train
FEATURES = col_train_bis
LABEL = "SalePrice" # 暫且理解將DataFrame的資料轉為對應的輸入值,因此要指定一列列的值。
feature_cols = [tf.contrib.layers.real_valued_column(k) for k in FEATURES] # 得到Feature 和 預測值
training_set = train[COLUMNS]
prediction_set = train.SalePrice # 將Train test 分為2:1分
x_train, x_test, y_train, y_test = train_test_split(training_set[FEATURES], prediction_set, test_size=0.33,
random_state=42)
# 整合特徵和預測值,對train集
y_train = pd.DataFrame(y_train, columns=[LABEL])
training_set = pd.DataFrame(x_train, columns=FEATURES).merge(y_train, left_index=True, right_index=True) # 整合特徵和預測值,對test集
y_test = pd.DataFrame(y_test, columns=[LABEL])
testing_set = pd.DataFrame(x_test, columns=FEATURES).merge(y_test, left_index=True, right_index=True) # 打log的,可以忽略
tf.logging.set_verbosity(tf.logging.ERROR)

5、DNN網路

 '''
快速建立一個DNN網路,
optimizer = tf.train.GradientDescentOptimizer( learning_rate= 0.1 )) 可以自己選優化方式
啟用函式為relu
都有哪些feature
隱藏層的神經元個數,遞減,200,100,50,25,12個
''' regressor = tf.contrib.learn.DNNRegressor(feature_columns=feature_cols,
activation_fn=tf.nn.relu,
hidden_units=[200, 100, 50, 25, 12]) training_set.reset_index(drop=True, inplace=True) # 定義一個函式用來train網路
def input_fn(data_set, pred=False):
if pred == False:
feature_cols = {k: tf.constant(data_set[k].values) for k in FEATURES}
labels = tf.constant(data_set[LABEL].values) return feature_cols, labels if pred == True:
feature_cols = {k: tf.constant(data_set[k].values) for k in FEATURES} return feature_cols # trainDNN網路
regressor.fit(input_fn=lambda: input_fn(training_set), steps=2000) # 估計測試集
ev = regressor.evaluate(input_fn=lambda: input_fn(testing_set), steps=1)
loss_score = ev["loss"]
print("test集的損失為: {0:f}".format(loss_score))

6、Adagrad優化器

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

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

1、迭代公式

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

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

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

1、建立網路

 import tensorflow as tf
from numpy.random import RandomState
from sklearn.model_selection import train_test_split batch_size = 8 # 定義網路
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
b1 = tf.Variable(tf.zeros([1, 3], name="bias1"))
b2 = tf.Variable(tf.zeros([1], name="bias2"))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1)) x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')
a = tf.matmul(x, w1) + b1 # 這裡一定不要寫成 tf.sigmoid
y_last = tf.nn.sigmoid(tf.matmul(a, w2) + b2)

2、定義損失函式

 # 損失與準確率
loss = tf.losses.sigmoid_cross_entropy(y_, y_last)
train_step = tf.train.AdamOptimizer(0.07).minimize(loss) correct_prediction = tf.equal(tf.round(y_last), y_)
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