用TensorFlow進行邏輯回歸(二)

邏輯回歸的例子

邏輯回歸是經典的分類算法。為了簡單,我們考慮二分類。這意味著,我們要處理識別二個分類的問題,我們的標簽為 0 1 我們要一個與線性回歸不同的激活函數,不同的損失函數,神經元的輸出略有不同。我們的目的是能構建模型能預測一個新的觀察屬于兩個分類中的哪一個。 對于輸入 x神經元應輸出概率P(y = 1| x) 作為分類1.我們分類觀察作為分類1,如果 P(y = 1| x) > 0.5, 或者分類 0,如果P(y = 1| x) < 0.5.

損失函數

作為損失函數,我們使用交叉熵. 對于一個觀察函數為

對于多于一個觀察 失函數是求和所有的觀察

后面我們可以從頭書寫完整的邏輯回歸,但是現在,tensorflow會為我們處理細節--微分,梯度下降,等的實現。我們只需要構建對的神經元。

激活函數

記住:我們想要神經元輸出觀察是分類 0或分類 1的概率。因些,我們想要激活函數輸出0 1的值。否則我們不能把它作為概率。對于邏輯回歸,我們使用 sigmoid函數作為激活函數.

數據集

要構建一個有趣的模型,我們要使用修改版的 MNIST數據集。你可以在 http://yann.lecun.com/exdb/ mnist/找到相關信息。

?MNIST數據集是大的手寫字數據集可以用來訓練我們的模型。 MNIST數據集包含70,000張圖像。 原始的黑白圖像 (bilevel)來自NIST的大小被歸一化以適合 20×20像素盒子而保留它們的比例.結果圖像包含灰度水平作為歸一化算法使用的 ?anti-aliasing技術的結果。圖像集中于 28×28圖像,通過計算像素質心,我后轉換圖像使中心在28×28 區域內” (來源: http://yann. lecun.com/exdb/mnist/).

我們的特征是每個像素的灰度值,所以我們有28 × 28 = 784個特征取值為0255 (灰度值).數據集包含10個數字,從09. 用下面的代碼,你可以準備數據以供下一節使用。通常,我們先導入必要的庫.

?#List3-46

from ?sklearn.datasets ?import ?fetch_mldata

然后加載數據.

mnist = fetch_mldata('MNIST original') X,y ?= ?mnist["data"], ?mnist["target"]

現在X包含輸入圖像且y是目標標簽 (記住在機器學習里我們想要預測的值稱為目標). 只要輸入 X.shape就會得到 X的形狀: (70000, 784). 注意 X 70,000 (每行是一張圖像) 784 (每列是一個特征,或像素灰度值,本例中).我們檢查一下數據集里有多少個數字.

?#List3-47

for i in range(10):

print ("digit", i, "appears", np.count_nonzero(y == i), "times")

結果如下:

digit

0

appears

6903

times

digit

1

appears

7877

times

digit

2

appears

6990

times

digit

3

appears

7141

times

digit

4

appears

6824

times

digit

5

appears

6313

times

digit

6

appears

6876

times

digit

7

appears

7293

times

digit

8

appears

6825

times

digit

9

appears

6958

times

定義一個函數來可視化數字是有用的.

?#List3-48

def ?plot_digit(some_digit):

some_digit_image?? ?=?? ?some_digit.reshape(28,28)? plt.imshow(some_digit_image,?? ?cmap?? ?=?? ?matplotlib.cm.binary,?? ?interpolation

= "nearest") plt.axis("off") plt.show()

例如, 我們隨機的作圖 (見圖 3-46).

plot_digit(X[36003])

3-46. 數據集里第 36,003個數字,它很容易的識別為 5

我們這里要實現的模型是二分類的簡單的邏輯回歸。所以數據集必須減少為兩個分類,這種情況,兩個數字。我們選擇12.我們提取數據集,只呈現 1 2. 我們的神經元會試圖識別給定的圖像是分類 0 (數字 1)還是分類 1 (數字 2).

X_train = X[np.any([y == 1,y == 2], axis = 0)] y_train ?= ?y[np.any([y ?== ?1,y ?== ?2], ?axis ?= ?0)]

接下來,輸入觀察必須歸一化. (注意,當你使用 sigmoid 激活函數時你不想讓你的輸入數據過大,因為有784個值.)

X_train_normalised? ?=? ?X_train/255.0

我們選擇 255,因為特征是像素灰度值,取值為 0255.后面我們討論為什么要歸一化輸入特征。現在相信我這是必要的步驟。 每一列,我們想要一個輸入觀察,每一行表示特征,所以我們要改變張量的形狀

X_train_tr ?= ?X_train_normalised.transpose() y_train_tr?? ?=?? ?y_train.reshape(1,y_train.shape[0])

我們可以定義變量n_dim 包含特征數

n_dim?? ?=?? ?X_train_tr.shape[0]

現在時重點。數據集的標簽為 1 2 (它們只告訴你圖像表示哪個數字). 然而,我們要構建我們的損失函數使用分類標簽為01, 所以我們要改變 y_train_tr數組的尺度。

注意??? 當處理二分類時,記得檢查標簽的值。有時候,使用錯誤的標簽 (不是 0 1)會浪費很多時間來理解模型為什么不工作。

y_train_shifted = y_train_tr - 1

現在所有表示 1的圖像來標簽 0, 所有表示2的圖像有標簽 1.最后,我們給變理合適的名稱.

Xtrain = X_train_tr ytrain ?= ?y_train_shifted

3-47展示了我們處理的數字.

3-47. 從數據集隨機選取的6個數字。相對的標簽在括號里 (記住現在標簽為0 1).

tensorflow實現

?tensorflow實現并不難,與線性回歸幾乎相同。首先定義placeholdersvariables.

tf.reset_default_graph()

X ?= ?tf.placeholder(tf.float32, ?[n_dim, ?None]) Y? ?=? ?tf.placeholder(tf.float32, ?[1, ?None])

learning_rate ?= ?tf.placeholder(tf.float32, ?shape=())

W? ?=? ?tf.Variable(tf.zeros([1, ?n_dim])) b??? ?=??? ?tf.Variable(tf.zeros(1))

init? ?=? ?tf.global_variables_initializer()

注意代碼與上面的線性回歸相同。但是我們必須定義不同的損失函數和不神經元輸出 (sigmoid函數).

y_? ?=? ?tf.sigmoid(tf.matmul(W,X)+b)

cost ?= ?- ?tf.reduce_mean(Y ?* ?tf.log(y_)+(1-Y) ?* ?tf.log(1-y_))

training_step?? ?=?? ?tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

我們用sigmoid函數作為神經元的輸出,使用 tf.sigmoid(). 運行模型的代碼與線性回歸相同.我們只改變函數名稱.

def? ?run_logistic_model(learning_r,? ?training_epochs,? ?train_obs, train_labels, ?debug ?= ?False):

sess ?= ?tf.Session() sess.run(init)

cost_history ?= ?np.empty(shape=[0], ?dtype ?= ?float)

for epoch in range(training_epochs+1):

sess.run(training_step, ?feed_dict ?= ?{X: ?train_obs, ?Y: ?train_labels, learning_rate:?? ?learning_r})

cost_ = sess.run(cost, feed_dict={ X:train_obs, Y: train_labels, learning_rate: ?learning_r})

cost_history ?= ?np.append(cost_history, ?cost_)

if (epoch % ?500 == 0) & ?debug:

print("Reached epoch",epoch,"cost J =", str.format('{0:.6f}', cost_))

return sess, cost_history

我們運行模型并看一下結果.我們從學習速率0.01開始.

sess, ?cost_history ?= ?run_logistic_model(learning_r ?= ?0.01,

training_epochs = 5000, train_obs ?= ?Xtrain, train_labels? ?=? ?ytrain, debug = True)

代碼的輸出如下 ( 3000 epochs后停止):

Reached epoch 0 cost J = 0.678598 Reached epoch 500 cost J = 0.108655 Reached epoch 1000 cost J = 0.078912 Reached epoch 1500 cost J = 0.066786 Reached epoch 2000 cost J = 0.059914 Reached epoch 2500 cost J = 0.055372 Reached epoch 3000 cost J = nan

發生什么了? 突然,某些點,我們的損失函數取nan (不是數字).看來模型在某個點工作得不好。如果學習速率太大,或初始化權重錯誤,你的值

y?(i )? = P (y(i )? = 1|x(i ) ) 或能接按于零或1?( sigmoid函數取值接近 0 1 以于非常大的正或負的z值).記住,在損失函數里,你有兩個項tf.log(y_) tf.log(1-y_), 因為 log函數對于值零沒有定義,如果 y_ 0 1, 你會得到 nan, 因為代碼試圖評估tf.log(0).例如,我們可以運行模型使用學習速率 2.0.只要一個 epoch, 你的損失函數就得到nan值。很容易理解原因,如果你打印b在第一個訓練步前后。簡單的修改你的模型代碼,使用下面的版本 :

def? ?run_logistic_model(learning_r,? ?training_epochs,? ?train_obs,? ?train_ labels, ?debug ?= ?False):

sess ?= ?tf.Session() sess.run(init)

cost_history = np.empty(shape=[0], dtype = float) for epoch in range(training_epochs+1):

print ('epoch: ', epoch)

print(sess.run(b, ?feed_dict={X:train_obs, ?Y: ?train_labels, learning_rate:? ?learning_r}))

sess.run(training_step, ?feed_dict ?= ?{X: ?train_obs, ?Y: ?train_labels, learning_rate:?? ?learning_r})

print(sess.run(b, ?feed_dict={X:train_obs, ?Y: ?train_labels, learning_rate:? ?learning_r}))

cost_ = sess.run(cost, feed_dict={ X:train_obs, Y: train_labels, learning_rate: ?learning_r})

cost_history ?= ?np.append(cost_history, ?cost_)

if (epoch % ?500 == 0) & ?debug:

print("Reached epoch",epoch,"cost J =", str.format('{0:.6f}', cost_))

return sess, cost_history

你得到下面的結果 (訓練一個epoch):

epoch:??? 0

[ 0.]

[-0.05966223]

Reached epoch 0 cost J = nan epoch:????? 1

[-0.05966223]

[ nan]

你看到b0變到 -0.05966223然后再到 nan? 因此, z = wTX + b 這為 nan, 然后y = σ(z) 也變為 nan, 最后損失函數是 y的函數,結果為nan. 這是因為學習速率過大。解決方案呢? 你應該試試不同的學習速率 (更少的值).

我們試試并得到更穩定的結果,在 2500 epochs之后.我們運行模型:

sess,? ?cost_history? ?=? ?run_logistic_model(learning_r? ?=? ?0.005,

training_epochs = 5000, train_obs ?= ?Xtrain, train_labels? ?=? ?ytrain, debug = True)

輸出如下

Reached epoch 0 cost J = 0.685799 Reached epoch 500 cost J = 0.154386 Reached epoch 1000 cost J = 0.108590 Reached epoch 1500 cost J = 0.089566 Reached epoch 2000 cost J = 0.078767 Reached epoch 2500 cost J = 0.071669 Reached epoch 3000 cost J = 0.066580 Reached epoch 3500 cost J = 0.062715 Reached epoch 4000 cost J = 0.059656 Reached epoch 4500 cost J = 0.057158 Reached epoch 5000 cost J = 0.055069

再也沒有nan輸出了。你可以在圖 3-48看損失數.要評估我們的模型,我們必須選擇優化量度 (如前所述).對于二分類問題,分類量度是準確率 ?(記為 a) 可以理解為結果與真實值的差的量度.數學上,它這樣計算

要得到準確率,我們運行下面的代碼. (記住 我們分類觀察i為分類 0 如果 P(y(i) = 1| x(i)) < 0.5, 或者分類 1如果 P(y(i) = 1| x(i)) > 0.5.)

correct_prediction1? ?=? ?tf.equal(tf.greater(y_,? ?0.5),? ?tf.equal(Y,1)) accuracy ?= ?tf.reduce_mean(tf.cast(correct_prediction1, ?tf.float32)) print(sess.run(accuracy, ?feed_dict={X:Xtrain, ?Y: ?ytrain, ?learning_rate: 0.05}))

使用這個模型,我們得到準確率為 98.6%. 這對于一個神經元的網絡不差。

3-48. 損失函數與 epochs,學習速率為0.005

你可以運行前面的模型更多的epochs (使用學習速度為 0.005) 。你會發現,在7000 epochs,又出現 nan 。解決方案是減少學習速率增加 epochs數。簡單的解決方案是,每 500 減半學習速率,就會消除 nans.后面詳細討論相似的方法.

你可以運行前面的模型更多的epochs (使用學習速度為 0.005) 。你會發現,在7000 epochs,又出現 nan 。解決方案是減少學習速率增加 epochs數。簡單的解決方案是,每 500 減半學習速率,就會消除 nans.后面詳細討論相似的方法.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914409.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914409.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914409.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java設計模式之行為型模式(命令模式)介紹與說明

一、核心定義與目標 命令模式通過對象化請求&#xff0c;將操作的具體實現細節隱藏在命令對象中&#xff0c;使得調用者&#xff08;Invoker&#xff09;無需直接與接收者&#xff08;Receiver&#xff09;交互&#xff0c;僅需通過命令對象間接調用。這種解耦設計支持以下功能…

【深度學習新浪潮】xAI新發布的Grok4有什么看點?

Grok4作為馬斯克旗下xAI公司最新發布的旗艦AI模型,其核心看點和評測要點可總結如下: 一、Grok4的核心看點 學術推理能力全面超越人類博士水平 在「人類終極考試」(HLE)中,Grok4基礎版正確率達25.4%,啟用工具后飆升至44.4%,遠超Gemini 2.5 Pro(21.6%)和OpenAI o3(20.…

觀成科技:基于自監督學習技術的惡意加密流量檢測方案

1.前言當前&#xff0c;隨著加密協議技術的廣泛應用&#xff0c;互聯網用戶的個人流量隱私得到了有效保護&#xff0c;但與此同時也衍生出一系列安全問題。由于加密流量在傳輸過程中無法被解密&#xff0c;導致傳輸信息呈現“黑盒化”特征&#xff0c;這為惡意攻擊者利用加密流…

通用定時器GPT

目錄 GPT核心特性 GPT 計數器操作模式 重啟模式 自由運行模式 GPT時鐘源 GPT框圖 輸入捕獲&#xff1a;測量外部信號的高電平脈沖寬度 輸出比較&#xff1a;生成 1kHz PWM 波 GPT模塊外部引腳復用與功能映射表 GPT使用注意事項 GPT Memory Map GPT寄存器 GPTx_CR寄存…

#oda0095. 字符串通配符【B卷 100分】-字符串

題目描述問題描述&#xff1a;在計算機中&#xff0c;通配符一種特殊語法&#xff0c;廣泛應用于文件搜索、數據庫、正則表達式等領域。現要求各位實現字符串通配符的算法。要求&#xff1a;實現如下2個通配符&#xff1a;* &#xff1a;匹配0個或以上的字符&#xff08;注&…

面向對象設計原則

面向對象&#xff1a;是一種編程思想&#xff0c;面向過程是關注實現的步驟&#xff0c;每個步驟定義一個函數&#xff0c;調用函數執行即可。面向對象關注的是誰來執行&#xff0c;把具有相同屬性和行為的一類事物進行抽象成類&#xff0c;然后再通過實例化出一個個具體的對象…

Hyperledger Fabric深入解讀:企業級區塊鏈的架構、應用與未來

一、引言&#xff1a;企業級區塊鏈的標桿Hyperledger Fabric是Linux基金會主導的開源項目&#xff0c;專為企業級應用設計&#xff0c;以模塊化架構、許可鏈機制和隱私保護為核心&#xff0c;廣泛應用于金融、供應鏈、醫療等領域。相較于公有鏈&#xff08;如以太坊&#xff09…

從0開始學習R語言--Day45--Hausman檢驗

當我們在探究數據本身是否和變量相關時&#xff0c;往往都會對這兩者進行回歸分析&#xff0c;控制一下變量來看看趨勢走向。但其實在分析前&#xff0c;我們可以先嘗試做Hausman檢驗&#xff0c;這可以幫助我們判斷數據的變化到底是因為變量不一樣了還是因為自己的個體效應所以…

閑庭信步使用圖像驗證平臺加速FPGA的開發:第九課——圖像插值的FPGA實現

&#xff08;本系列只需要modelsim即可完成數字圖像的處理&#xff0c;每個工程都搭建了全自動化的仿真環境&#xff0c;只需要雙擊top_tb.bat文件就可以完成整個的仿真&#xff0c;大大降低了初學者的門檻&#xff01;&#xff01;&#xff01;&#xff01;如需要該系列的工程…

Android事件分發機制完整總結

一、核心概念事件分發的本質Android事件分發采用責任鏈模式&#xff0c;事件從Activity開始&#xff0c;依次經過ViewGroup和View。整個機制只有一個入口&#xff1a;dispatchTouchEvent方法。onInterceptTouchEvent和onTouchEvent都不是獨立的事件入口&#xff0c;而是被dispa…

【論文閱讀】AdaReasoner: Adaptive Reasoning Enables More Flexible Thinking

AdaReasoner: Adaptive Reasoning Enables More Flexible Thinking3. AdaReasoner3.1 動機3.2 問題定義3.3 動作選擇過程3.3.1 動作空間定義3.3.2 動作選擇3.4 探索策略3.5 強化學習訓練3.5.1 訓練算法3.5.2 目標函數3.5.3 損失函數AdaReasoner: Adaptive Reasoning Enables Mo…

深入了解Modbus TCP:工業通信的“通用語言”

目錄 簡介一、Modbus TCP的“前世今生”二、Modbus TCP的核心特點三、Modbus TCP的工作原理1. 報文結構2. 功能碼四、Modbus TCP的應用場景五、使用Modbus TCP的注意事項六、總結簡介 在工業自動化的世界里,不同設備之間的“對話”至關重要。從PLC(可編程邏輯控制器)到傳感…

基于Selenium和FFmpeg的全平臺短視頻自動化發布系統

一、項目背景與概述在當今短視頻營銷盛行的時代&#xff0c;許多企業和個人需要同時管理多個短視頻平臺賬號。手動上傳視頻到抖音、快手、小紅書等平臺不僅效率低下&#xff0c;而且容易出錯。本文將介紹一個基于Python的自動化短視頻處理與發布系統&#xff0c;它能夠&#xf…

技術演進中的開發沉思-31 MFC系列:類層次結構

提及MFC&#xff0c;不得不說他的類層次。如果把 MFC 框架比作是座精密的鐘表&#xff0c;那類層次結構便是其內部咬合的齒輪組。每個類都有明確的 “家族地位”&#xff0c;既繼承著先輩的本領&#xff0c;又發展出獨特的專長。這種層級分明的設計&#xff0c;讓 Windows 編程…

2023.05.06 更新前端面試問題總結(12道題)

2023.05.04 - 2023.05.06 更新前端面試問題總結&#xff08;12道題&#xff09; 獲取更多面試相關問題可以訪問 github 地址: https://github.com/pro-collection/interview-question/issues gitee 地址: https://gitee.com/yanleweb/interview-question/issues 目錄&#xff1…

【網絡】Linux 內核優化實戰 - net.ipv4.tcp_keepalive_intvl

目錄1. TCP Keep-Alive 機制回顧2. 參數作用3. 參數取值與影響4. 使用場景與建議5. 相關參數6. 如何配置該參數臨時生效&#xff08;重啟后失效&#xff09;&#xff1a;永久生效&#xff08;需重啟或重載配置&#xff09;&#xff1a;7. 性能優化建議8. 監控與故障排查net.ipv…

20250710解決KickPi的K7的SDK編譯異常:rk3576-android14.0-25250704.tar.gz【降低BUILD_JOBS】

20250710解決KickPi的K7的SDK編譯異常&#xff1a;rk3576-android14.0-25250704.tar.gz【降低BUILD_JOBS】 2025/7/10 20:59緣起&#xff1a;KickPi的K7的SDK編譯異常&#xff1a;rk3576-android14.0-25250704.tar.gzZ:\14TB\SDK\rk3576_data\1-SDK軟件源碼\Android14\20250704…

《Java EE與中間件》實驗一 基于MyBatis的留言本

目 錄 一、實驗目的和要求 1、實驗目的 2、實驗要求 二、實驗實現思路及步驟 1、實驗思路 2、實驗步驟 3、實驗方案 三、主要開發工具 四、實驗效果及實現代碼 1、留言本數據庫構建實現 &#xff08;1&#xff09;建立javaee-project數據庫 &#xff08;2&#xf…

ARM匯編編程(AArch64架構) - 第14課:安全擴展(ARM TrustZone)

目錄1. TrustZone基礎概念1.1 安全擴展架構1.2 關鍵組件2. 世界切換機制2.1 狀態切換流程2.2 關鍵寄存器配置3. SMC調用實現3.1 調用規范3.2 完整調用流程4. 實戰練習4.1 實驗&#xff1a;實現雙世界通信4.2 調試技巧1. TrustZone基礎概念 1.1 安全擴展架構 startuml rectang…

OpenCV哈希算法------Marr-Hildreth 邊緣檢測哈希算法

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 該類實現了 Marr-Hildreth 邊緣檢測哈希算法&#xff08;Marr-Hildreth Hash&#xff09;&#xff0c;用于圖像相似性比較。它基于 Marr-Hildreth …