摘要:我們使用的損失函數為由于我們的數據集只有兩個特征,因此不用擔心過擬合,所以損失函數里的正規化項就不要了。到此,一個完整的簡單的邏輯回歸模型就實現完畢了,希望通過這篇文章,能讓各位看官對在中機器學習模型的實現有一個初步的了解。
TensorFlow 是一個基于 python 的機器學習框架。在 Coursera 上學習了邏輯回歸的課程內容后,想把在 MATLAB 中實現了的內容用 TensorFlow 重新實現一遍,當做學習 Python 和框架的敲門磚。
目標讀者知道邏輯回歸是什么,懂一點 Python,聽說過 TensorFlow
數據集來自 Coursera 上 Andrew 的機器學習課程中的ex2data1.txt,根據學生的兩次考試成績判斷該學生是否會被錄取。
環境Python 2.7 - 3.x
pandas, matplotlib, numpy
安裝 TensorFlow在自己的電腦上安裝 TensorFlow 框架,安裝方法過程不贅述,CPU 版相對更容易一點,GPU 版需要 CUDA 支持,各位看官看情況安裝就好。
開始創建一個文件夾(比如就叫做tensorflow),在文件夾中創建一個 Python 文件main.py,并將數據集文件放到這個文件夾下:
數據形式:
前兩列分別為兩次考試成績(x1, x2),最后一列為是否被錄取(y),1代表被錄取,0則反之。
在源文件main.py中,我們首先引入需要的包:
import pandas as pd # 用于讀取數據文件 import tensorflow as tf import matplotlib.pyplot as plt # 用于畫圖 import numpy as np # 用于后續計算
pandas是一個數據處理相關的包,可以對數據集進行讀取和其他各種操作;matplotlib可以用來把我們的數據集繪成圖表展示出來。
接著我們將數據集文件讀入程序,用于后面的訓練:
# 讀取數據文件 df = pd.read_csv("ex2data1.txt", header=None) train_data = df.values
pandas函數read_csv可以將 csv(comma-separated values)文件中的數據讀入df變量,通過df.values將 DataFrame 轉化為二維數組:
有了數據之后,我們需要將特征(x1, x2)和標簽(y)分別放到兩個變量中,以便在訓練中代入公式:
# 分離特征和標簽,并獲取數據維數 train_X = train_data[:, :-1] train_y = train_data[:, -1:] feature_num = len(train_X[0]) sample_num = len(train_X) print("Size of train_X: {}x{}".format(sample_num, feature_num)) print("Size of train_y: {}x{}".format(len(train_y), len(train_y[0])))
可以看到,我們的數據集中有100條樣例,每條樣例的特征數量為2。
TensorFlow 模型設計在邏輯回歸中,我們使用的預測函數(Hypothesis)為:
$$
h_θ(x) = sigmoid(XW + b)
$$
其中,sigmoid是一個激活函數,在這里表示學生被錄取的概率:
$$
P(y = 1 | x, heta)
$$
這個函數的形狀請自行百度
W 和 b 是我們接下來的學習目標,W 為權值矩陣(Weights),b 為偏置量(Bias,體現在圖像上又叫截距)。
我們使用的損失函數為:
$$
J(θ) = -frac{1}{m} left[ sum_{i=1}^m y^{(i)}log(h_ heta(x^{(i)})) + (1 - y^{(i)})log(1 - h_ heta(x^{(i)}))
ight]
$$
由于我們的數據集只有兩個特征,因此不用擔心過擬合,所以損失函數里的正規化項就不要了?。
首先我們用 TensorFlow 定義兩個變量用來存放我們的訓練用數據:
# 數據集 X = tf.placeholder(tf.float32) y = tf.placeholder(tf.float32)
這里的X和y不是一般的變量,而是一個 placeholder(占位符),意味著這兩個變量的值是未指定的,直到你開始訓練模型時才需要將給定的數據賦值給變量。
接著我們再定義出我們要訓練的 W 和 b:
# 訓練目標 W = tf.Variable(tf.zeros([feature_num, 1])) b = tf.Variable([-.9])
這里他們的類型為 Variable(變量),意味著這兩個變量將在訓練迭代的過程中不斷地變化,最終取得我們期望的值。可以看到,我們將 W 的初始值設為了 feature_num 維的0向量,將 b 初始值設為了 -0.9(隨便設的,不要介意?)
接下來我們要用 TensorFlow 的方式將損失函數表達出來:
db = tf.matmul(X, tf.reshape(W, [-1, 1])) + b hyp = tf.sigmoid(db) cost0 = y * tf.log(hyp) cost1 = (1 - y) * tf.log(1 - hyp) cost = (cost0 + cost1) / -sample_num loss = tf.reduce_sum(cost)
可以看到,我表達損失函數是分三步進行的:先分別將求和內的兩部分表示出來,再將它們加和并和外面的常數m進行運算,最后對這個向量進行求和,便得到了損失函數的值。
接下來,我們要定義使用的優化方法:
optimizer = tf.train.GradientDescentOptimizer(0.001) train = optimizer.minimize(loss)
其中,第一步是選取優化器,這里我們選擇梯度下降方法;第二步是優化目標,從函數名字顧名思義,我們的優化目標是使得損失函數的值最小化。
注意:此處的學習率(0.001)應當盡可能小,否則可能會出現損失計算中出現 log(0)的問題。
訓練上面的工作做完之后,我們就可以開始訓練我們的模型了。
在 TensorFlow 中,首先要將之前定義的Variable初始化:
init = tf.global_variables_initializer() sess = tf.Session() sess.run(init)
在這里,我們看到出現了一個tf.Session(),顧名思義是會話,即任務執行的主體。我們上面定義了一堆東西,只是一個模型為了得到結果而需要的執行步驟和框架,一個類似流程圖的東西,光有流程圖還不夠,我們需要一個主體來實際地運行它,這就是Session的作用。
----------特別提示----------如果你是使用 GPU 版 TensorFlow 的話,并且你想在顯卡高占用率的情況下(比如玩游戲)訓練模型,那你要注意在初始化 Session 的時候為其分配固定數量的顯存,否則可能會在開始訓練的時候直接報錯退出:
2017-06-27 20:39:21.955486: E c: f_jenkinshomeworkspace elease-winmwindows-gpupy35 ensorflowstream_executorcudacuda_blas.cc:365] failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED Traceback (most recent call last): File "C:UsersDYZAnaconda3envs ensorflowlibsite-packages ensorflowpythonclientsession.py", line 1139, in _do_call return fn(*args) File "C:UsersDYZAnaconda3envs ensorflowlibsite-packages ensorflowpythonclientsession.py", line 1121, in _run_fn status, run_metadata) File "C:UsersDYZAnaconda3envs ensorflowlibcontextlib.py", line 66, in __exit__ next(self.gen) File "C:UsersDYZAnaconda3envs ensorflowlibsite-packages ensorflowpythonframeworkerrors_impl.py", line 466, in raise_exception_on_not_ok_status pywrap_tensorflow.TF_GetCode(status)) tensorflow.python.framework.errors_impl.InternalError: Blas GEMV launch failed: m=2, n=100 [[Node: MatMul = MatMul[T=DT_FLOAT, transpose_a=false, transpose_b=false, _device="/job:localhost/replica:0/task:0/gpu:0"](_arg_Placeholder_0_0/_3, Reshape)]]
這時你需要用下面的方法創建 Session:
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.333) sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
這里的0.333就是占你總顯存的份額。
----------End 特別提示----------下面就是用我們的數據集來對模型進行訓練了:
feed_dict = {X: train_X, y: train_y} for step in range(1000000): sess.run(train, {X: train_X, y: train_y}) if step % 100 == 0: print(step, sess.run(W).flatten(), sess.run(b).flatten())
首先講要傳入的數據存放到一個變量中,在訓練模型時傳入 sess.run();我們進行 10000 次訓練,每隔 100
次輸出一次當前的目標參數 W, b。
到這里,訓練代碼的部分就完成了,你可以使用你自己的 python 命令來運行了。如果你嚴格按照上面的代碼做了,不出現錯誤,你現在應該可以看到控制臺里已經開始不斷輸出訓練狀態了:
圖形化表示結果當訓練結束后,你可以得到一個 W,和一個 b,這樣我們可以將數據集和擬合的結果通過圖表直觀地展現出來。
就在寫作的過程中,我用上面的代碼訓練出了一個結果:
我們將其直接寫入代碼,即:
w = [0.12888144, 0.12310864] b = -15.47322273
下面我們先將數據集表示在圖表上(x1為橫軸,x2為縱軸):
x1 = train_data[:, 0] x2 = train_data[:, 1] y = train_data[:, -1:] for x1p, x2p, yp in zip(x1, x2, y): if yp == 0: plt.scatter(x1p, x2p, marker="x", c="r") else: plt.scatter(x1p, x2p, marker="o", c="g")
其中,我們用 紅色的x 代表 沒有被錄取,用 綠色的o 代表 被錄取。
其次我們將訓練得出的決策邊界 XW + b = 0 表示到圖表上:
# 根據參數得到直線 x = np.linspace(20, 100, 10) y = [] for i in x: y.append((i * -w[1] - b) / w[0]) plt.plot(x, y) plt.show()
此時,如果你的代碼沒錯的話,再次運行,你將得到如下結果:
可以看到,我們通過訓練得出的參數劃出一條直線,非常合適地將兩種不同的數據樣例區分開來。
到此,一個完整的簡單的邏輯回歸模型就實現完畢了,希望通過這篇文章,能讓各位看官對在 TensorFlow 中機器學習模型的實現有一個初步的了解。本人也在初步學習當中,如有不當之處歡迎在評論區拍磚,在實現以上代碼的過程中如果遇到什么問題也請在評論區隨意開火。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38637.html
摘要:目前,是成長最快的一種深度學習框架。這將是對社區發展的一個巨大的推動作用。以下代碼是如何開始導入和構建序列模型。現在,我們來構建一個簡單的線性回歸模型。 作者:chen_h微信號 & QQ:862251340微信公眾號:coderpai簡書地址:https://www.jianshu.com/p/205... Keras 是提供一些高可用的 Python API ,能幫助你快速的構建...
閱讀 3714·2021-11-17 09:33
閱讀 2724·2021-09-22 15:12
閱讀 3344·2021-08-12 13:24
閱讀 2439·2019-08-30 11:14
閱讀 1733·2019-08-29 14:09
閱讀 1325·2019-08-26 14:01
閱讀 3061·2019-08-26 13:49
閱讀 1774·2019-08-26 12:16