這題主要是訓練調參數的技能。其實做模型也是不斷調參換模型的過程。
(i)使用不同的學習速率
嘗試了一下從1到24的迭代次數
隨着學習速率的不斷增加,迭代次數變小,但是當迭代次數大於28的時候,又不收斂了。所以在收斂的情況下,學習速率越大,收斂速度越快。
(ii)隨着迭代次數的增加,降低學習速率
先是使用了e.g中的內容,讓學習速率爲1/迭代次數,a的收斂速度變很慢,又沒法收斂了。
又嘗試了將初始學習速率調爲100/迭代次數,依舊不收斂……
(iii)給損益方程增加一個正則化
本題中本身使用的權益方程如下
增加正則化後
運行程序後發現無法收斂
iv 線性縮小輸入數據的特徵
本題目中一共是100個數據,而我測試了只使用前50個數據,51個數據,52個數據……直到100個數據分別進行了迭代運算,並進行了畫圖
從圖中可以看出,並不是數據量越少,迭代速度越快。
v 增加0均值的高斯分佈
# -*- coding: utf-8 -*-
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
try: #處理異常,若發生NameError則xrange = range
xrange
except NameError:
xrange = range
# def add_intercept(X_): #將X的數據加上一列1
# m, n = X_.shape
# X = np.zeros((m, n + 2))
# X[:, 0] = 1
# mu = 0 # 期望爲1
# sigma = 3 # 標準差爲3
# num = 100 # 個數爲10000
# X[:, 1] = np.random.normal(mu, sigma, num)
# X[:, 2:] = X_
#
# return X
def load_data(filename): #讀取數據,X的數據爲兩列,Y得數據爲1列
D = np.loadtxt(filename)
Y = D[:, 0]
X = D[:, 1:]
# ax = plt.subplot(111, projection='3d')
# ax.scatter(X[:,0], X[:,1], Y, c='y')
# plt.show()
# return add_intercept(X), Y
return X,Y
def calc_grad(X, Y, theta): #計算梯度
m, n = X.shape
grad = np.zeros(theta.shape)
margins = Y * X.dot(theta)
probs = 1. / (1 + np.exp(margins))
grad = -(1./m) * (X.T.dot(probs * Y))
return grad
def logistic_regression(X, Y):
m, n = X.shape
theta = np.zeros(n)
i = 0
error=[]
while True:
i += 1
learning_rate=10
prev_theta = theta
grad = calc_grad(X, Y, theta)
theta = theta - learning_rate * (grad)
error.append(np.linalg.norm(prev_theta - theta))
if i % 10000 == 0:
print('Finished %d iterations' % i)
if np.linalg.norm(prev_theta - theta) < 1e-15 :
print('Converged in %d iterations' % i)
plt.figure(1)
plt.title('data B iteration')
plt.xlabel('iteration')
plt.ylabel('error')
x = len(error) # 設置x軸,以y軸數組長度爲寬度
x = range(x)
plt.scatter(x,error, marker='.', color='g', s=5)
plt.show()
break
return i
def main():
print('\n==== Training model on data set A ====')
Xa, Ya = load_data('data_a.txt')
logistic_regression(Xa, Ya)
n=len(Ya)
iteration_times = []
for i in range(50,n):
Xa1,Ya1=Xa[0:i],Ya[0:i]
iteration_times.append(logistic_regression(Xa1, Ya1))
x = len(iteration_times) # 設置x軸,以y軸數組長度爲寬度
x = range(50,x+50)
fig = plt.figure()
plt.bar(x, iteration_times, 0.4, color="green")
plt.xlabel("data size")
plt.ylabel("iteration")
plt.title("data size and iteration")
plt.show()
print('\n==== Training model on data set B ====')
Xb, Yb = load_data('data_b.txt')
logistic_regression(Xb, Yb)
return
x,y = load_data('data_a.txt')
x1,y1 = load_data('data_b.txt')
def figure(x,y): #畫圖
plt.title('data_b.txt')
plt.xlabel('x1')
plt.ylabel('x2')
m=[]
n=[]
for i in range(len(y)):
if y[i]==1:
m.append(i)
else:
n.append(i)
p1 = plt.scatter(x[n,0], x[n, 1], marker='x', color='m', label='1', s=30)
p2 = plt.scatter(x[m,0], x[m, 1], marker='+', color='c', label='-1', s=50)
plt.legend(loc='upper right')
plt.show()
figure(x, y)
figure(x1, y1)
if __name__ == '__main__':
main()
嘗試了下各種不同的標準差,感覺標準差小一點迭代速度更好一些,當然因爲是隨機生成,每次迭代次數也有所不同……
我覺得是不會,SVM中的hinge loss是挑選少量數據進行擬合,而logistic是用所有數據迭代下降求得參數。