Anna-Lena Popkes,德國波恩大學計算機科學專業的研究生,主要關注機器學習和神經網絡。
編譯 | 林椿眄
出品 | 人工智慧頭條
導讀:Python 被稱為是最接近 AI 的語言。最近一位名叫Anna-Lena Popkes的小姐姐在GitHub上分享了自己如何使用Python(3.6及以上版本)實現7種機器學習算法的筆記,並附有完整代碼。所有這些算法的實現都沒有使用其他機器學習庫。這份筆記可以幫大家對算法以及其底層結構有個基本的了解,但並不是提供最有效的實現。
Softmax 回歸算法,又稱為多項式或多類別的 Logistic 回歸算法。
給定:
數據集
Softmax 回歸模型有以下幾個特點:
訓練 Softmax 回歸模型有不同步驟。首先(在步驟0中),模型的參數將被初始化。在達到指定訓練次數或參數收斂前,重複以下其他步驟。
第 0 步:用 0 (或小的隨機值)來初始化權重向量和偏置值
第 1 步:對於每個類別k,計算其輸入的特徵與權重值的線性組合,也就是說為每個類別的訓練樣本計算一個得分值。對於類別k,輸入向量為,則得分值的計算如下:
其中表示類別k的權重矩陣,·表示點積。
我們可以通過矢量化和矢量傳播法則計算所有類別及其訓練樣本的得分值:
其中 X 是所有訓練樣本的維度矩陣,W 表示每個類別的權重矩陣維度,其形式為;
第 2 步:用 softmax 函數作為激活函數,將得分值轉化為概率值形式。屬於類別 k 的輸入向量的概率值為:
同樣地,我們可以通過矢量化來對所有類別同時處理,得到其概率輸出。模型預測出的表示的是該類別的最高概率。
第 3 步:計算整個訓練集的損失值。
我們希望模型預測出的高概率值是目標類別,而低概率值表示其他類別。這可以通過以下的交叉熵損失函數來實現:
在上面公式中,目標類別標籤表示成獨熱編碼形式( one-hot )。因此為1時表示的目標類別是 k,反之則為 0。
第 4 步:對權重向量和偏置量,計算其對損失函數的梯度。
關於這個導數實現的詳細解釋,可以參見這裡(http://ufldl.stanford.edu/tutorial/supervised/SoftmaxRegression/)。
一般形式如下:
對於偏置量的導數計算,此時為1。
第 5 步:對每個類別k,更新其權重和偏置值。
其中,表示學習率。
In [1]:
from sklearn.datasets import load_iris
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
np.random.seed(13)
數據集
In [2]:
X, y_true = make_blobs(centers=4, n_samples = 5000)
fig = plt.figure(figsize=(8,6))
plt.scatter(X[:,0], X[:,1], c=y_true)
plt.title("Dataset")
plt.xlabel("First feature")
plt.ylabel("Second feature")
plt.show()
In [3]:
# reshape targets to get column vector with shape (n_samples, 1)
y_true = y_true[:, np.newaxis]
# Split the data into a training and test set
X_train, X_test, y_train, y_test = train_test_split(X, y_true)
print(f'Shape X_train: {X_train.shape}')
print(f'Shape y_train: {y_train.shape}')
print(f'Shape X_test: {X_test.shape}')
print(f'Shape y_test: {y_test.shape}')
Shape X_train: (3750, 2)
Shape y_train: (3750, 1)
Shape X_test: (1250, 2)
Shape y_test: (1250, 1)
Softmax回歸分類
class SoftmaxRegressor:
def __init__(self):
pass
def train(self, X, y_true, n_classes, n_iters=10, learning_rate=0.1):
"""
Trains a multinomial logistic regression model on given set of training data
"""
self.n_samples, n_features = X.shape
self.n_classes = n_classes
self.weights = np.random.rand(self.n_classes, n_features)
self.bias = np.zeros((1, self.n_classes))
all_losses = []
for i in range(n_iters):
scores = self.compute_scores(X)
probs = self.softmax(scores)
y_predict = np.argmax(probs, axis=1)[:, np.newaxis]
y_one_hot = self.one_hot(y_true)
loss = self.cross_entropy(y_one_hot, probs)
all_losses.append(loss)
dw = (1 / self.n_samples) * np.dot(X.T, (probs - y_one_hot))
db = (1 / self.n_samples) * np.sum(probs - y_one_hot, axis=0)
self.weights = self.weights - learning_rate * dw.T
self.bias = self.bias - learning_rate * db
if i % 100 == 0:
print(f'Iteration number: {i}, loss: {np.round(loss, 4)}')
return self.weights, self.bias, all_losses
def predict(self, X):
"""
Predict class labels for samples in X.
Args:
X: numpy array of shape (n_samples, n_features)
Returns:
numpy array of shape (n_samples, 1) with predicted classes
"""
scores = self.compute_scores(X)
probs = self.softmax(scores)
return np.argmax(probs, axis=1)[:, np.newaxis]
def softmax(self, scores):
"""
Tranforms matrix of predicted scores to matrix of probabilities
Args:
scores: numpy array of shape (n_samples, n_classes)
with unnormalized scores
Returns:
softmax: numpy array of shape (n_samples, n_classes)
with probabilities
"""
exp = np.exp(scores)
sum_exp = np.sum(np.exp(scores), axis=1, keepdims=True)
softmax = exp / sum_exp
return softmax
def compute_scores(self, X):
"""
Computes class-scores for samples in X
Args:
X: numpy array of shape (n_samples, n_features)
Returns:
scores: numpy array of shape (n_samples, n_classes)
"""
return np.dot(X, self.weights.T) + self.bias
def cross_entropy(self, y_true, scores):
loss = - (1 / self.n_samples) * np.sum(y_true * np.log(scores))
return loss
def one_hot(self, y):
"""
Tranforms vector y of labels to one-hot encoded matrix
"""
one_hot = np.zeros((self.n_samples, self.n_classes))
one_hot[np.arange(self.n_samples), y.T] = 1
return one_hot
初始化並訓練模型
regressor = SoftmaxRegressor()
w_trained, b_trained, loss = regressor.train(X_train, y_train, learning_rate=0.1, n_iters=800, n_classes=4)
fig = plt.figure(figsize=(8,6))
plt.plot(np.arange(800), loss)
plt.title("Development of loss during training")
plt.xlabel("Number of iterations")
plt.ylabel("Loss")
plt.show()Iteration number: 0, loss: 1.393
Iteration number: 100, loss: 0.2051
Iteration number: 200, loss: 0.1605
Iteration number: 300, loss: 0.1371
Iteration number: 400, loss: 0.121
Iteration number: 500, loss: 0.1087
Iteration number: 600, loss: 0.0989
Iteration number: 700, loss: 0.0909
測試模型
n_test_samples, _ = X_test.shape
y_predict = regressor.predict(X_test)
print(f"Classification accuracy on test set: {(np.sum(y_predict == y_test)/n_test_samples) * 100}%")
測試集分類準確率:99.03999999999999%
原文連結:
https://github.com/zotroneneis/machine_learning_basics
往期精彩文章(單擊就可查看):
美國科學院院士、圖靈獎得主:約翰•愛德華•霍普克羅夫特——深度學習
南京大學教授:周志華——深度森林:探索深度神經網絡以外的方法
史丹福大學人工智慧實驗室主任:李飛飛——ImageNet之後,計算機視覺研究最新進展
海軍工程大學教授:賁可榮——人工智慧技術及其應用進展
清華大學:劉洋——基於深度學習的機器翻譯
國防科技大學教授:殷建平——計算機科學理論的過去、現在與未來
清華大學軟體學院院長——劉雲浩:與高中生對話人工智慧
【原創】|日本理化學研究所先進智能研究中心主任——Masashi Sugiyama:弱監督機器學習研究新進展
「人物特寫」清華大學鄧志東:「特徵提取+推理」的小數據學習才是AI崛起的關鍵
明略講堂 | 清華馬少平教授詳解「人工智慧能做什麼?」
【原創】|西安電子科大——焦李成:人工智慧時代後深度學習的挑戰與思考
Michael I. Jordan——計算思維、推斷思維與數據科學
【原創】王飛躍:生成式對抗網絡的機會與挑戰
【原創】|微軟亞洲研究院——劉鐵巖:深度學習前沿
清華大學教授:孫富春——認知時代人工智慧與機器人
清華大學:朱軍博士——When Bayes meets Big Data
加州大學伯克利分校:馬毅——低維結構和高維深模型(視覺)數據
加州大學伯克利分校計算機系教授:Dawn SONG——AI如何建立一個更強的防禦系統
清華大學:劉知遠——知識表示學習及其應用
李飛飛和ImageNet的洪荒之力
清華大學教授:孫富春——教育機器人核心技術展望
從高端人才配置看全國第四輪計算機科學與技術專業一級學科評估結果
長江學者、北京大學教授:黃鐵軍——人工智慧的過去、現在和未來