Softmax迴歸簡介
softmax迴歸簡介
Softmax迴歸也稱多項或多類的Logistic迴歸,是Logistic迴歸在多分類問題上的推廣。
對於這樣的一個資料分佈,我們希望有一種方法能夠將這組資料分成四類。
很顯然,我們用四根直線就可以將這組資料劃分開。
softmax迴歸與Logistic迴歸的不同之處就是softmax迴歸要面對的是兩類以上的分類問題,一般的認為,要進行的分類問題有幾種型別,就需要繪製幾條直線,每條直線的作用是“將某一類與其他所有類區分開①”。
①所描述的正是一種一對多餘的思想。
如何設計一個多分類的線性判別函式?
- 一對其餘
- 一對一
- argmax
一對其餘
把多分類問題轉換為C個“一對其餘”的二分類問題。這樣的方式需要C個判別函式,C指需要區分的類別的個數。其中第c個判別函式fc是將類別c的資料樣本和其他所有不屬於c的資料樣本分開。
一對一
把多分類問題轉換為C(C-1)/2個“一對一”的二分類問題。這種方式需要C(C-1)/2個判別函式,其中第(i,j)個判別函式是把類別i和類別j的資料樣本分開。
argmax
argmax是一種改進的“一對其餘”方式,同樣需要C個判別函式。
這C個判別函式的通式是:
f
c
(
x
:
w
c
)
=
w
c
T
x
+
b
c
,
c
∈
{
1
,
⋯
,
C
}
f_c(x:w_c) = w^T_cx+b_c , c∈\lbrace1,\cdots,C\rbrace
fc(x:wc)=wcTx+bc,c∈{1,⋯,C}
對於一個樣本x,如果存在一個類別c,相對於其他所有類別
c
~
\tilde{c}
c~(
c
~
\tilde{c}
c~≠c)有
f
c
(
x
;
w
c
)
f_c(x;w_c)
fc(x;wc)>KaTeX parse error: Got function '\tilde' with no arguments as subscript at position 3: f_\̲t̲i̲l̲d̲e̲{c}(x;w\tilde{c… ,那麼x就是屬於類別c的。
對於函式 f c ( x ; w c ) f_c(x;w_c) fc(x;wc),我們可以理解為它表示樣本點 x i x_i xi關於這C條直線(C個判別函式)的距離判別。
我們先看一下三種判別方式能得到的區分效果。
可以看到,無論是“一對其餘”還是“一對一”方式,都會有盲區。而且“argmax”方式對前面兩種方式做了改進,使得這些盲區內的資料也可以被區分。
我們可以將argmax方式的判別函式看成是歐式距離的計算,顯然,即使是“盲區”內的資料點,這些資料點關於直線的歐式距離是一定存在的,所以它一定是可以被劃分的,所以在一定程度上解決了這個問題。
one-hot編碼
Logistic迴歸輸出的是一個範圍為[0,1]的概率值,是因為Logistic迴歸面對的二分類問題,一個範圍在[0,1]內的概率值可以明確的區分輸出的結果是0類還是1類。
然而在softmax迴歸中,多類問題使分類結果的表示變得困難起來。
所以會對輸出結果y進行one-hot編碼,進行編碼後使得這個結果y_hot可以清晰的表示結果所屬的類別。
那麼什麼是one-hot編碼呢?
我們直觀的拿一個例子:
假設四分類問題中分類為1,2,3,4四類,分類y=1經過one-hot編碼後,得到的結果是[1,0,0,0]。
是的,它是一個陣列,或者說是一個向量。
那麼同樣的,分類y=2經過one-hot編碼後得到的結果是[0,1,0,0],以此類推。
當然,在實際進行引數訓練後得到的結果不可能是這麼精確的值,我們知道分類問題得到的都是一些概率值。
所以我們得到的值可能是y1 = [0.1,0.2,0.5,0.2],y2 = [0.7,0.1,0.1,0.1]…
不過結果依然很顯然了,y1表示這個資料更趨向於3類,y2表示的資料更趨向於1類。
softmax用到的函式
- softmax啟用函式
- one-hot編碼
- 交叉熵損失函式
- 梯度下降法
與Logistic迴歸不同的是啟用函式,softmax迴歸用到的啟用函式是softmax。
softmax和sigmoid函式的目的都是將 w 1 ∗ x 1 + w 2 ∗ x 2 + b w_1*x_1+w_2*x_2+b w1∗x1+w2∗x2+b得到的值進行一個歸一化,將值壓縮到區間(0,1)內,這樣便於所有的值進行比較。
程式碼實現
-
引入所需庫
import numpy as np import matplotlib.pyplot as plt
-
隨機生成資料集
np.random.seed(0) Num=100 #0類別 x1 = np.random.normal(-3,1,size=(Num)) x2 = np.random.normal(-3,1,size=(Num)) y= np.zeros(Num) data0 = np.array([x_1,x_2,y]) #1類別 x1 = np.random.normal(3,1,size=(Num)) x2 = np.random.normal(-3,1,size=(Num)) y= np.ones(Num) data1 = np.array([x_1,x_2,y]) #2類別 x1 = np.random.normal(-3,1,size=(Num)) x2 = np.random.normal(3,1,size=(Num)) y= np.ones(Num)*2 data2 = np.array([x_1,x_2,y]) #3類別 x1 = np.random.normal(3,1,size=(Num)) x2 = np.random.normal(3,1,size=(Num)) y= np.ones(Num)*3 data3 = np.array([x_1,x_2,y]) data0 = data0.T data1 = data1.T data2 = data2.T data3 = data3.T
-
檢視資料分佈
plt.scatter(data0[:,0],data0[:,1],marker="o") plt.scatter(data1[:,0],data1[:,1],marker="+") plt.scatter(data2[:,0],data2[:,1],marker="v") plt.scatter(data3[:,0],data3[:,1],marker="s")
-
隨機初始化權值與偏置
W = np.random.rand(4,2) b = np.random.rand(4,1)
-
打亂資料集
All_data=np.concatenate((data0,data1,data2,data3)) np.random.shuffle(All_data)
-
檢視初始化後判別函式的情況
x=np.arange(-5,5) y1=(-W[0,0]*x-b[0])/W[0,1] y2=(-W[1,0]*x-b[1])/W[1,1] y3=(-W[2,0]*x-b[2])/W[2,1] y4=(-W[3,0]*x-b[3])/W[3,1] plt.scatter(data0[:,0],data0[:,1],marker="o") plt.scatter(data1[:,0],data1[:,1],marker="+") plt.scatter(data2[:,0],data2[:,1],marker="v") plt.scatter(data0[:,0],data3[:,1],marker="s") plt.plot(x,y1) plt.plot(x,y2) plt.plot(x,y3) plt.plot(x,y4)
-
定義函式
#softmax(x)=e^x/sum(e^x) def softmax_matrix(z):#當z不是一維時 exp = np.exp(z) sum_exp = np.sum(np.exp(z),axis=1,keepdims=True) return exp/sum_exp def softmax_vector(z):#當z是一維時 return np.exp(z)/np.sum(np.exp(z)) #對Y進行one-hot編碼 #temp = {0,1,2,3} def one_hot(temp): one_hot = np.zeros((len(temp),len(np.unique(temp)))) one_hot[np.arange(len(temp)),temp.astype(np.int).T]=1 return one_hot # 計算 y_hat def compute_y_hat(W,X,b): return np.dot(X,W.T)+b.T #計算交叉熵 def cross_entropy(y,y_hat): loss = -(1/len(y))*np.sum(y*np.log(y_hat)) return loss
-
進行訓練
#w = w + lr*grad lr = 0.01 loss_list=[] for i in range(1000): #計算loss y_hat = softmax_matrix(compute_y_hat(W,train_data_X,b)) y = one_hot(train_data_Y) loss = cross_entropy(y,y_hat) loss_list.append(loss) #計算梯度 grad_w = (1/len(train_data_X))*(np.dot(train_data_X.T,(y-y_hat)).T) grad_b = (1/len(train_data_X))*np.sum(y-y_hat) #更新引數 W = W + lr*grad_w b = b + lr*grad_b # 輸出 if i%100==1 : print("i:%d , loss:%f"%(i,loss))
-
繪製訓練後的分類情況
x=np.arange(-5,5) y1=(-W[0,0]*x-b[0])/W[0,1] y2=(-W[1,0]*x-b[1])/W[1,1] y3=(-W[2,0]*x-b[2])/W[2,1] y4=(-W[3,0]*x-b[3])/W[3,1] plt.scatter(data0[:,0],data0[:,1],marker="o") plt.scatter(data1[:,0],data1[:,1],marker="+") plt.scatter(data2[:,0],data2[:,1],marker="v") plt.scatter(data3[:,0],data3[:,1],marker="s") plt.plot(x,y1) plt.plot(x,y2) plt.plot(x,y3) plt.plot(x,y4)
-
檢視loss值下降曲線
plt.plot(loss_list)
相關文章
- Keras上實現Softmax迴歸模型Keras模型
- Logistic迴歸、softmax迴歸以及tensorflow實現MNIST識別
- 貝葉斯迴歸簡介
- ML-邏輯迴歸-Softmax-交叉熵(小航)邏輯迴歸熵
- Spark LogisticRegression 邏輯迴歸之簡介Spark邏輯迴歸
- 機器學習中的邏輯迴歸模型簡介機器學習邏輯迴歸模型
- tf.keras實現邏輯迴歸和softmax多分類Keras邏輯迴歸
- 數值解和解析解/softmax迴歸/泰勒展開/牛頓法
- 機器學習簡介之基礎理論- 線性迴歸、邏輯迴歸、神經網路機器學習邏輯迴歸神經網路
- 【動手學深度學習】第三章筆記:線性迴歸、SoftMax 迴歸、交叉熵損失深度學習筆記熵
- 線性迴歸—求解介紹及迴歸擴充套件套件
- 貝葉斯線性迴歸簡介(附完整程式碼)
- python實現線性迴歸之簡單迴歸Python
- 歸一化(softmax)、資訊熵、交叉熵熵
- softmax迴歸——原理、one-hot編碼、結構和運算、交叉熵損失熵
- 【機器學習】線性迴歸原理介紹機器學習
- 簡單介紹pytorch中log_softmax的實現PyTorch
- EVIEWS 簡單線性迴歸 02View
- 機器學習——簡單線性迴歸(上)機器學習
- 機器學習——簡單線性迴歸(下)機器學習
- 【機器學習】多項式迴歸原理介紹機器學習
- 閃迴歸檔的簡單測試
- 簡明線性迴歸演算法演算法
- 迴歸
- Pytorch 實現簡單線性迴歸PyTorch
- 機器學習演算法--邏輯迴歸原理介紹機器學習演算法邏輯迴歸
- 機器學習 | 線性迴歸與邏輯迴歸機器學習邏輯迴歸
- javascript遞迴概念簡單介紹JavaScript遞迴
- 邏輯迴歸:使用Python的簡化方法邏輯迴歸Python
- 李巨集毅機器學習課程筆記-4.1分類簡介及其與迴歸的區別機器學習筆記
- nodejs事件和事件迴圈簡介NodeJS事件
- 線性迴歸模型公式推導完整簡潔版模型公式
- 機器學習-樹迴歸機器學習
- 線性迴歸
- 線性迴歸-如何對資料進行迴歸分析
- 迴歸初心:極簡 Android 元件化方案 — AppJointAndroid元件化APP
- 【深度學習基礎-10】簡單線性迴歸(上)深度學習
- 機器學習程式碼筆記-2-簡單線性迴歸機器學習筆記