【TensorFlow篇】--Tensorflow框架初始,實現機器學習中多元線性迴歸

1、前述node

TensorFlow是谷歌基於DistBelief進行研發的第二代人工智能學習系統,其命名來源於自己的運行原理。Tensor(張量)意味着N維數組,Flow(流)意味着基於數據流圖的計算,TensorFlow爲張量從流圖的一端流動到另外一端計算過程。TensorFlow是將複雜的數據結構傳輸至人工智能神經網中進行分析和處理過程的系統。python

2、相關概念和安裝git

TensorFlow中的計算能夠表示爲一個有向圖(DirectedGraph)
或者稱計算圖(ComputationGraph)
其中每個運算操做(operation)將做爲一個節點(node)
計算圖描述了數據的計算流程,也負責維護和更新狀態
用戶經過python,C++,go,Java語言設計這個這個數據計算的有向圖
計算圖中每個節點能夠有任意多個輸入和任意多個輸出
每個節點描述了一種運算操做,節點能夠算是運算操做的實例化(instance)
計算圖中的邊裏面流動(flow)的數據被稱爲張量(tensor),故得名TensorFlowgithub

安裝流程:數組

pip install tensorflow==1.1.0緩存

3、代碼規範網絡

詳細源碼在本人github上https://github.com/LhWorld/AI_Project.gitsession

代碼一:tensorflow 基本語法數據結構

 

import tensorflow as tf

x = tf.Variable(3, name='x') #Variable建立一個變量
y = tf.Variable(4, name='y')
f = x*x*y + y + 2

# 能夠不分別對每一個變量去進行初始化
# 並不當即初始化,在run運行的時候才初始化
init = tf.global_variables_initializer()

with tf.Session() as sess:
    init.run()
    result = f.eval()
    print(result)

 

代碼二:Variable的聲明週期框架

 

import tensorflow as tf

# 當去計算一個節點的時候,TensorFlow自動計算它依賴的一組節點,而且首先計算依賴的節點
w = tf.constant(3)
x = w + 2
y = x + 5
z = x * 3

with tf.Session() as sess:
    print(y.eval())
    # 這裏爲了去計算z,又從新計算了x和w,除了Variable值,tf是不會緩存其餘好比contant等的值的
    # 一個Variable的生命週期是當它的initializer運行的時候開始,到會話session close的時候結束
    print(z.eval())

# 若是咱們想要有效的計算y和z,而且又不重複計算w和x兩次,咱們必需要求TensorFlow計算y和z在一個圖裏
with tf.Session() as sess:
    y_val, z_val = sess.run([y, z])
    print(y_val)
    print(z_val)

 代碼三:Tensorflow手動實現多元線性迴歸中解析解求解過程

import tensorflow as tf
import numpy as np
from sklearn.datasets import fetch_california_housing

# 馬上下載數據集
housing = fetch_california_housing()
print(housing)
# 得到X數據行數和列數
m, n = housing.data.shape
# 這裏添加一個額外的bias輸入特徵(x0=1)到全部的訓練數據上面,由於使用的numpy全部會當即執行
housing_data_plus_bias = np.c_[np.ones((m, 1)), housing.data]#np.c_整合combine np.ones((m, 1)是x0=1這一列
#以上代碼會當即執行 由於不是tf的函數
# 建立兩個TensorFlow常量節點X和y,去持有數據和標籤
X = tf.constant(housing_data_plus_bias, dtype=tf.float32, name='X')#延遲執行,只是作了一下標記
y = tf.constant(housing.target.reshape(-1, 1), dtype=tf.float32, name='y')#reshape(-1,1)把行向量轉變成列向量  -1表明隨便行 不限制行數 最終m行一列
#以上y是真實的數據
# 使用一些TensorFlow框架提供的矩陣操做去求theta
XT = tf.transpose(X)
# 解析解一步計算出最優解
theta = tf.matmul(tf.matmul(tf.matrix_inverse(tf.matmul(XT, X)), XT), y)#解析解公式
with tf.Session() as sess:
    theta_value = theta.eval()  # 與sess.run(theta)等價 theta至關於一個圖經過DAG構建
    print(theta_value)

 

代碼四:Tensorflow手動實現多元線性迴歸中梯度降低求解過程

 

import tensorflow as tf
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import StandardScaler

#多元線性迴歸是一個凸函數 ,因此能找到全局最優解
#神經網絡只有局部最優解
n_epochs = 1000#把樣本集數據學習1000次
learning_rate = 0.01 #步長 學習率 不能太大 太大容易來回震盪 過小 耗時間,跳不出局部最優解
#能夠寫learn_rate動態變化,隨着迭代次數愈來愈大 ,學習率愈來愈小 learning_rate/n_epoches
housing = fetch_california_housing()
m, n = housing.data.shape
housing_data_plus_bias = np.c_[np.ones((m, 1)), housing.data]
# 可使用TensorFlow或者Numpy或者sklearn的StandardScaler去進行歸一化
#歸一化能夠最快的找到最優解
#經常使用的歸一化方式:
# 最大最小值歸一化 (x-min)/(max-min)
# 方差歸一化 x/方差
# 均值歸一化 x-均值 結果有正有負 可使調整時的速度愈來愈快。
scaler = StandardScaler().fit(housing_data_plus_bias) #建立一個歸一化對象
scaled_housing_data_plus_bias = scaler.transform(housing_data_plus_bias) #真正執行 由於來源於sklearn因此會直接執行,不會延遲。


X = tf.constant(scaled_housing_data_plus_bias, dtype=tf.float32, name='X')
y = tf.constant(housing.target.reshape(-1, 1), dtype=tf.float32, name='y')

# random_uniform函數建立圖裏一個節點包含隨機數值,給定它的形狀和取值範圍,就像numpy裏面rand()函數
theta = tf.Variable(tf.random_uniform([n + 1, 1], -1.0, 1.0), name='theta') #theta是參數 W0-Wn 一列 按照-1.0到1.0隨機給
y_pred = tf.matmul(X, theta, name="predictions")#相乘 m行一列
error = y_pred - y #列向量和列向量相減 是一組數
mse = tf.reduce_mean(tf.square(error), name="mse")#偏差平方加和,最小二乘 平方均值損失函數 手動實現
# 梯度的公式:(y_pred - y) * xj  i表明行 j表明列
gradients = 2/m * tf.matmul(tf.transpose(X), error)#矩陣和向量相乘會獲得新的向量 一組梯度
# 賦值函數對於BGD來講就是 theta_new = theta - (learning_rate * gradients)
training_op = tf.assign(theta, theta - learning_rate * gradients)#assigin賦值 算一組w
# training_op實際上就是須要迭代的公式

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init) #初始化

    for epoch in range(n_epochs):#迭代1000次
        if epoch % 100 == 0:
            print("Epoch", epoch, "MSE = ", mse.eval())#每運行100次的時候輸出
        sess.run(training_op)

    best_theta = theta.eval()#最後的w參數值
    print(best_theta)

 

經過Tensorflow運行機器學習能夠實現分佈式運算,提升速度。

代碼五:使用tensorflow自己API實現

 

import tensorflow as tf
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import StandardScaler


# TensorFlow爲咱們去計算梯度,可是同時也給了咱們更方便的求解方式
# 它提供給咱們不同凡響的,有創意的一些優化器,包括梯度降低優化器
# 替換前面代碼相應的行,而且一切工做正常


n_epochs = 1000
learning_rate = 0.01

housing = fetch_california_housing()
m, n = housing.data.shape
housing_data_plus_bias = np.c_[np.ones((m, 1)), housing.data]
# 可使用TensorFlow或者Numpy或者sklearn的StandardScaler去進行歸一化
scaler = StandardScaler().fit(housing_data_plus_bias)
scaled_housing_data_plus_bias = scaler.transform(housing_data_plus_bias)

X = tf.constant(scaled_housing_data_plus_bias, dtype=tf.float32, name='X')
y = tf.constant(housing.target.reshape(-1, 1), dtype=tf.float32, name='y')

# random_uniform函數建立圖裏一個節點包含隨機數值,給定它的形狀和取值範圍,就像numpy裏面rand()函數
theta = tf.Variable(tf.random_uniform([n + 1, 1], -1.0, 1.0), name='theta')
y_pred = tf.matmul(X, theta, name="predictions")
error = y_pred - y
mse = tf.reduce_mean(tf.square(error), name="mse")
# 梯度的公式:(y_pred - y) * xj
# gradients = 2/m * tf.matmul(tf.transpose(X), error)
# gradients = tf.gradients(mse, [theta])[0]
# 賦值函數對於BGD來講就是 theta_new = theta - (learning_rate * gradients)
# training_op = tf.assign(theta, theta - learning_rate * gradients)
 optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
# MomentumOptimizer收斂會比梯度降低更快
# optimizer = tf.train.MomentumOptimizer(learning_rate=learning_rate, momentum=0.9)
training_op = optimizer.minimize(mse)#去減少偏差

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)

    for epoch in range(n_epochs):
        if epoch % 100 == 0:
            print("Epoch", epoch, "MSE = ", mse.eval())
        sess.run(training_op)

    best_theta = theta.eval()
    print(best_theta)

 代碼六:placeholder的使用

 

import tensorflow as tf

# 讓咱們修改前面的代碼去實現Mini-Batch梯度降低
# 爲了去實現這個,咱們須要一種方式去取代X和y在每一次迭代中,使用一小批數據
# 最簡單的方式去作到這個是去使用placeholder節點
# 這些節點特色是它們不真正的計算,它們只是在執行過程當中你要它們輸出數據的時候去輸出數據
# 它們會傳輸訓練數據給TensorFlow在訓練的時候
# 若是在運行過程當中你不給它們指定數據,你會獲得一個異常

# 須要作的是使用placeholder()而且給輸出的tensor指定數據類型,也能夠選擇指定形狀
# 若是你指定None對於某一個維度,它的意思表明任意大小
A = tf.placeholder(tf.float32, shape=(None, 3))
B = A + 5

with tf.Session() as sess:
    B_val_1 = B.eval(feed_dict={A: [[1, 2, 3]]})#等價於session.run(B)一行數據三個維度
    B_val_2 = B.eval(feed_dict={A: [[4, 5, 6], [7, 8, 9]]})#兩行數據,三個維度

print(B_val_1)
print(B_val_2)
相關文章
相關標籤/搜索