李宏毅老师hw1 linear regression模型改进
一.问题回顾
针对hw1中最后出现训练次数越多误差越大的情况,以下的分析。
在学习率Π=1×10^-5时,前30、60、90、120、240、480、1000、1500、2000、2500、3000、3600次的LOSS值
在学习率Π=1×10^-6时,前30、60、90、120、240、480、1000、1500、2000、2500、3000、3600次的LOSS值
结合这张图可以看出当Π=1×10^-5时明显是学习率过大,当Π=1×10^-6时应该是一个比较好的学习率
二.模型改进
1.增加变量的次数(add times of feature)原因:原函数存在欠拟合,增加函数的复杂度
原先的函数y_old=b+Σwixi 更新后的函数y_new=b+Σwixi+Σwj(xi)²
原先的Loss函数loss_old=(y^-(b+Σwixi))²+λΣ(wi)² 更新后的Loss函数loss_new=(y^-(b+Σwixi+Σwj(xi)²))²
更新后函数偏导:δL_new/δb=2(y^-(b+Σwixi+Σwj(xi)²))(-1)
δL_new/δwi=2(y^-(b+Σwixi+Σwj(xi)²))(-xi)
δL_new/δwj=2(y^-(b+Σwixi+Σwj(xi)²))(-(xi)²)
2.自适应梯度 (adagrad)
wt+1=wt-Πtgt/σt Πt=Π/(1+t)½ gt=δL_new/δθ σt=((t+1)-1∑(gi)2)½ 均方根
3.变量归一化(scaling)
将所有的变量都转化在【0,1】之间
Min-Max Normalization
x' = (x - X_min) / (X_max - X_min)
三.实现
Loss函数
''' Loss function ''' def loss_function(y_true,Wi,Wj,b,X,Wi_previous,Wj_previous): ''' Loss function: L=∑(y_ture-(b+∑Wi*Xi+∑Wj*(Xi)^2))^2 gradient descent:∂L/∂Wi=∑2*(y_ture-(b+∑Wi*Xi+∑Wj*(Xi)^2))*(-Xi) ∂L/∂Wj=∑2*(y_ture-(b+∑Wi*Xi+∑Wj*(Xi)^2))*(-Xi^2) ∂L/∂b=∑2*(y_ture-(b+∑Wi*Xi+∑Wj*(Xi)^2))*(-1) :param y_true: :param W: :param b: :param X: :return:更新后的W与b ''' new_Wi=np.empty((1,162)) new_Wj=np.empty((1,162)) new_b=b X_square=X*X Π=0.000000000000000000000000001#学习率 #对每一个Wi参数都进行更新 for index in range(0,len(Wi[0])): #每一个Wi的更新梯度 gradient_descent_Wi=2*(y_true-(b+np.dot(Wi,X)[0][0]+np.dot(Wj,X_square)[0][0]))*(-X[index][0]) #更新参数,原来Wi减去学习率与更新梯之积 σ=root_mean_square_not_contain_N(Wi_previous[index]) new_Wi[0][index]=Wi[0][index]-(Π*gradient_descent_Wi)/σ Wi_previous[index].append(gradient_descent_Wi) #对每一个Wj参数进行更新 for index in range(0,len(Wj[0])): #每一个Wj的更新梯度 gradient_descent_Wj = 2 * (y_true - (b + np.dot(Wi, X)[0][0] + np.dot(Wj, X_square)[0][0])) * (-(X[index][0])**2) # 更新参数,原来Wi减去学习率与更新梯之积 σ = root_mean_square_not_contain_N(Wj_previous[index]) new_Wj[0][index] = Wj[0][index] - (Π * gradient_descent_Wj) / σ Wj_previous[index].append(gradient_descent_Wj) #b的更新梯度 gradient_descent_b=2*(y_true-(b+np.dot(Wi,X)[0][0]+np.dot(Wj,X_square)[0][0]))*(-1) #更新后的b new_b=b-Π*gradient_descent_b #计算误差 Loss=(y_true-(b+np.dot(new_Wi,X)[0][0]+np.dot(new_Wj,X_square)[0][0]))**2 return new_Wi,new_Wj,new_b,Wi_previous,Wj_previous,Loss
linear function
''' linear_function ''' def linear_model(data,Wi,Wj,b,Wi_previous,Wj_previous): ''' :param W: :param b: :param data: :return:返回更新后的W,b,Loss ''' X=np.array(data.iloc[:,0:-1]).astype(np.float64) X=X.reshape(18*9,1) y=data.iloc[:,-1].reset_index(drop=True) try: y_true = float(y[9]) except: print(y) y_model=b+np.dot(Wi,X)+np.dot(Wj,X*X) print('训练前误差为'+str(y_true-y_model[0][0])) Wi,Wj,b,Wi_previous,Wj_previous,Loss=loss_function(y_true,Wi,Wj,b,X,Wi_previous,Wj_previous) y_model=b+np.dot(Wi,X)+np.dot(Wj,X*X) print('训练后误差为' + str(y_true - y_model[0][0])) return Wi,Wj,b,Wi_previous,Wj_previous,Loss