如图所示,这是一元线性回归(即假设函数
)中的损失函数图像,一开始我们选定一个起始点(通常是 ),然后沿着这个起始点开始,沿着这一点处损失函数下降最快的方向(即该点的梯度负方向)走一小步,走完一步之后,到达第二个点,然后我们又沿着第二个点的梯度负方向走一小步,到达第三个点,以此类推,直到我们到底局部最低点。为什么是局部最低点呢?因为我们到达的这个点的梯度为 0 向量(通常是和 0 向量相差在某一个可接受的范围内),这说明这个点是损失函数的极小值点,并不一定是最小值点。
从梯度下降法的思想,我们可以看到,最后得到的局部最低点与我们选定的起始点有关。通常情况下,如果起始点不同,最后得到的局部最低点也会不一样。
(4)参数更新每次更新参数的操作:
其中α为学习率(步长),对结果会产生巨大的影响,调节学习率这个超参数是建模中的重要内容。
选择方法:从小的开始,不行再小。
批处理数量:32、64、128比较常用,很多时候还要考虑内存和效率。
因为J(θ)是凸函数,所以GD求出的最优解是全局最优解。批量梯度下降法是求出整个数据集的梯度,再去更新θ,所以每次迭代都是在求全局最优解。
三、单特征回归建模 1、数据预处理写一个prepare_for_training函数,对数据进行函数变换、标准化等操作。最后返回处理过的数据,以及均值和标准差。
import numpy as np from .normalize import normalize from .generate_sinusoids import generate_sinusoids from .generate_polynomials import generate_polynomials """数据预处理""" def prepare_for_training(data, polynomial_degree=0, sinusoid_degree=0, normalize_data=True): # 计算样本总数 num_examples = data.shape[0] data_processed = np.copy(data) # 预处理 features_mean = 0 features_deviation = 0 data_normalized = data_processed if normalize_data: ( data_normalized, features_mean, features_deviation ) = normalize(data_processed) data_processed = data_normalized # 特征变换sinusoid if sinusoid_degree > 0: sinusoids = generate_sinusoids(data_normalized, sinusoid_degree) data_processed = np.concatenate((data_processed, sinusoids), axis=1) # 特征变换polynomial if polynomial_degree > 0: polynomials = generate_polynomials(data_normalized, polynomial_degree) data_processed = np.concatenate((data_processed, polynomials), axis=1) # 加一列1 data_processed = np.hstack((np.ones((num_examples, 1)), data_processed)) return data_processed, features_mean, features_deviation