最近在上【開課吧人工智能學院】,第六期【計算機視覺】的課程。講師上課講了線性迴歸與邏輯迴歸。我來簡單總結一下線性迴歸~
那就從我有一個房子開始吧~ 最近想去大城市闖蕩,需要錢,想賣掉老家的房子。我知道自己的房子150平米,我想預估這個房子的價格。我就去賣房子的網站去看別人的房子都是什麼樣的價格。剛開始我很單純,只關注了一個點,就是房子的面積和價格。
我收集了以下數據:(100平米,350萬)(200平米,650萬),就想自己的房子應該介於350萬到650萬之間。
我是學習過數學嘛,想到 ,根據兩個數據的規律得到以下經驗:
房子價格 = 3 ✖️房子的面積 + 50。
那我把自己房子的面積帶入,那價格應該是500萬。
以上過程,進一步理解。
- 關於收集來的簡單數據可看作數據集,簡單記爲( ,)。
- 房子的面積可看作特徵。
- 線性方程中的 、 可看作參數,根據數據求得 、,可看作求參數的過程,也可稱作訓練過程。訓練所用的數據又是訓練集。
- 房子的價格能影響參數的值,這樣的影響,可看作有監督的過程,房子的價格監督 、 求解的過程。
- 函數【房子價格 = 3 ✖️房子的面積 + 50】 可看作一個模型,帶入新的數據【房子的面積】可知道該房子的價格。
那我繼續收集數據~
現在繼續使用一條直線去靠近這些點,便以下的圖示過程,可稱作擬合的過程。
用紅色的線記錄同一個橫軸下直線與點的差異。
可以看到,當所有紅色的線累計到最短的時候,便是擬合效果最好的時候。
我們將綠色直線的值記爲 。那 表示擬合直線與真實值的誤差(Error),即是紅色的線。則所有數據的平均絕對誤差(Mean Absolute Error,MAE),若有個數據,第個數據下的真實值表示爲,擬合曲線在第個值下的值爲 , MAE表示爲:
同樣,考慮到擬合直線與真實值的面積誤差,稱之爲 Mean Squared Error(MSE),表達式如下:
這樣,我們的目標是希望擬合直線與真實值的誤差最小,可以選擇MSE或者MAE,監督參數的求解,這樣的MSE/MAE的函數,又稱爲損失函數/期望函數/目標函數(cost/loss/target function)。
== 那如何求解參數呢?==
選擇MSE作爲監督的函數 ,cost function = MSE 。
目標是希望 MSE 越小越好,如何讓MSE越來越小呢?也就是隨機調整參數 、。通過觀察 cost function的值,監督參數 、 的調整。
隨機調整參數有點佛系,比較耗時。
有沒有誰能指點方向,讓參數求解faster呢?
梯度的方向是函數變化最快的方向。梯度便可用於參數求解。CV講師給出瞭如何求參數的過程。
那我照葫蘆畫瓢~
-
Hypothesis (擬合的直線) :
-
Parameters (參數) :
-
Cost Func (損失函數) :
-
Goal :
梯度下降
- 首先對 、 賦值,這個值可以是隨機的,也可以是一個零向量;
- 改變 、 的值,使得 按梯度下降的方向進行減少;
- 當 下降到無法下降時爲止,這時 對 的導數爲0.
以上的參數是怎麼改變的呢?
是步長,也被成爲學習率,憑經驗值。
, 是多少呢?
參數求解之後,帶入擬合的直線,擬合的直線可以對新的數據進行預測。現在進入代碼實踐的過程~
# inference 擬合的直線 y_hat
def inference(a,b,x):
y_hat = a * x + b
return y_hat
# cost function
def eval_loss(a,b,x_list,gt_y_list):
avg_loss = 0
for i in range(len(x_list)):
avg_loss += 0.5 * (a * x_list[i] + b - gt_y_list[i]) ** 2
avg_loss /= len(gt_y_list)
return avg_loss
# 一個數據的梯度
def gradient(y_hat, gt_y, x):
diff = y_hat - gt_y
da = diff * x
db = diff
return da,db
def cal_step_gradient(x_list, gt_y_list, a, b ,lr):
avg_da, avg_db = 0, 0
x_number = len(x_list)
for i in range( len(x_list)):
y_hat = inference(a, b, x_list[i])
da, db = gradient(y_hat, gt_y_list[i], x_list[i])
avg_da += da
avg_db += db
avg_da /= x_number
avg_db /= x_number
a -= lr * avg_da
b -= lr * avg_db
return a,b
def train(x_list, gt_y_list, lr, max_iter):
a = 0
b = 0
num_samples = len(x_list)
for i in range(max_iter):
a, b = cal_step_gradient(x_list, gt_y_list, a, b, lr)
print('a:{0},b:{1}'.format(a,b))
print('loss is {}'.format(eval_loss(a,b,x_list,gt_y_list)))
time.sleep(0.1)
return a,b
import time
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
data = pd.DataFrame({'size': [50, 80, 100, 120, 160, 180, 200, 250],
'price': [150, 200, 350, 400, 500, 600, 650, 700]})
train(data['size'], data['price'],0.1, 4)
我做的這份筆記只是課堂內容的冰山一角,我要繼續啃冰山了。。。