泥土巢 - 机器学习之优化方法 https://www.nituchao.com/category/optimize/ zh-CN Sun, 07 Apr 2024 10:57:33 +0800 Sun, 07 Apr 2024 10:57:33 +0800 交叉熵方法(CEM)优化 https://www.nituchao.com/optimize/92.html https://www.nituchao.com/optimize/92.html Sun, 07 Apr 2024 10:57:33 +0800 liang CEM(Cross-Entropy Method)是一种优化算法,通常用于解决连续优化问题。它的基本思想是通过迭代地生成随机样本,并根据样本在目标函数上的表现来更新参数,以找到最优解。下面是一个具体的例子,展示如何使用CEM算法来解决一个简单的连续优化问题。

实例

假设我们要最小化函数 f(x) = x^2 + 2x + 1,其中 x 是实数。我们想找到使函数 f(x) 取得最小值的 x 值。

import numpy as np

# 定义目标函数
def f(x):
    return x**2 + 2*x + 1

# 定义CEM算法的参数
num_samples = 100   # 每次迭代生成的样本数量
elite_frac = 0.2    # 每次迭代保留下来的精英个数的比例前20%
learning_rate = 0.1 # 每次迭代的学习率

# 定义初始解集
mean = 0.0
std = 1.0
solutions = np.random.normal(mean, std, num_samples)

# 接下来,我们执行CEM算法的迭代过程。在每次迭代中,我们生成样本,
# 计算他们在目标函数上的表现,选择表现最好的一部分样本,并使用他
# 们来更新解集的均值和标准差
num_iterations = 10 # 迭代次数

for i in range(num_iterations):
    # 生成样本
    samples = np.random.normal(mean, std, num_samples)
    
    # 计算样本在目标函数上的表现
    scores = f(samples)

    # 选择表现最好的一部分样本
    elite_size = int(num_samples * elite_frac)
    elite_indices = np.argsort(scores)[:elite_size]
    elite_samples = samples[elite_indices]

    # 更新解集的均值和标准差
    mean = np.mean(elite_samples)
    std = np.std(elite_samples)

    # 打印当前的均值和标准差
    print(f"Iteration {i+1}: Mean = {mean:.4f}, Std = {std:.4f}")

    # 输出迭代结果
    best_sample = elite_samples[0]
    best_score = f(best_sample)

    print(f"Best sample after iteration {i+1}: x = {best_sample:.4f}, f(x) = {best_score:.4f}")

    # print(elite_samples)

运行结果:

Iteration 1: Mean = -1.0185, Std = 0.1761
Best sample after iteration 1: x = -1.0124, f(x) = 0.0002
Iteration 2: Mean = -0.9993, Std = 0.0225
Best sample after iteration 2: x = -1.0004, f(x) = 0.0000
Iteration 3: Mean = -0.9999, Std = 0.0044
Best sample after iteration 3: x = -0.9999, f(x) = 0.0000
Iteration 4: Mean = -1.0000, Std = 0.0011
Best sample after iteration 4: x = -1.0000, f(x) = 0.0000
Iteration 5: Mean = -1.0000, Std = 0.0001
Best sample after iteration 5: x = -1.0000, f(x) = 0.0000
Iteration 6: Mean = -1.0000, Std = 0.0000
Best sample after iteration 6: x = -1.0000, f(x) = 0.0000
Iteration 7: Mean = -1.0000, Std = 0.0000
Best sample after iteration 7: x = -1.0000, f(x) = 0.0000
Iteration 8: Mean = -1.0000, Std = 0.0000
Best sample after iteration 8: x = -1.0000, f(x) = 0.0000
Iteration 9: Mean = -1.0000, Std = 0.0000
Best sample after iteration 9: x = -1.0000, f(x) = 0.0000
Iteration 10: Mean = -1.0000, Std = 0.0000
Best sample after iteration 10: x = -1.0000, f(x) = 0.0000

即:当取x=-1.0000时,f(x) = x^2 + 2x + 1有最小值0.0000

]]>
0 https://www.nituchao.com/optimize/92.html#comments https://www.nituchao.com/feed/optimize/92.html
随机坐标梯度下降法 https://www.nituchao.com/optimize/91.html https://www.nituchao.com/optimize/91.html Sun, 07 Apr 2024 10:49:00 +0800 liang 坐标随机梯度下降法(Coordinate Stochastic Gradient Descent,简称CSGD)是一种优化算法,用于求解目标函数的最小化问题。与传统的梯度下降法不同,CSGD每次迭代仅更新一个坐标(参数),而不是同时更新所有参数。

CSGD的基本思想是,在每次迭代中,选择一个随机的坐标(参数),然后计算该坐标上的梯度,并更新该坐标的取值。这样,通过在不同的坐标上进行迭代更新,最终可以达到目标函数的最小值。

下面是CSGD的基本步骤:

  1. 初始化参数:给定一个初始的参数向量。
  2. 随机选择一个坐标:从参数向量中随机选择一个坐标。
  3. 计算梯度:计算选择的坐标上的梯度。
  4. 更新坐标:使用梯度信息更新选择的坐标的取值。
  5. 重复步骤2-4,直到满足停止条件(例如达到最大迭代次数或梯度的变化很小)。

CSGD的优点是每次迭代的计算成本相对较低,因为只需计算一个坐标上的梯度。这在处理大规模数据集或高维参数空间时特别有用。然而,CSGD也存在一些挑战,例如可能收敛速度较慢,因为每次迭代只更新一个坐标。

需要注意的是,CSGD是一种随机算法,每次迭代选择的坐标都是随机的。因此,它不能保证在每次迭代中都朝着全局最小值的方向前进。然而,通过合理的学习率调度和随机坐标选择策略,可以使CSGD在实践中表现良好。

实例

假设我们有一个简单的线性回归问题,目标是通过最小化均方误差来拟合一个线性模型。
我们的模型参数是一个二维向量 (w0, w1),其中 w0 是截距,w1 是斜率。

我们的训练数据集包含多个样本点 (x, y),其中 x 是输入特征,y 是对应的目标值。
我们使用坐标随机梯度下降法来优化模型参数。

下面是一个简化的示例代码,演示如何使用坐标随机梯度下降法来拟合线性回归模型:

import numpy as np

# 训练数据集
X = np.array([1, 2, 3, 4, 5])   # 输入特征
y = np.array([2, 3, 4, 5, 6])   # 目标值

# 初始化参数
w0 = 0.0    # 初始截距
w1 = 0.0    # 初始斜率

# 定义学习率和迭代次数
learning_rate = 0.01
num_iterations = 100

# 坐标随机梯度下降法
for _ in range(num_iterations):
    # 随机选择一个坐标
    index = np.random.randint(len(X))

    # 计算选择坐标的梯度
    gradient_w0 = -2 * (y[index] - w0 - w1 * X[index])
    gradient_w1 = -2 * X[index] * (y[index] - w0 - w1 * X[index])

    # 更新选择坐标的参数
    w0 -= learning_rate * gradient_w0
    w1 -= learning_rate * gradient_w1

# 打印最终的模型参数
print("w0: ", w0)
print("w1: ", w1)

在上述代码中,我们使用 NumPy 库来进行向量化计算。每次迭代时,随机选择一个训练样本,
计算选择坐标的梯度,并更新对应的参数。重复这个过程一定次数后,得到最终的模型参数 w0 和 w1。

需要注意的是,这只是一个简化的示例,实际应用中可能需要进行更多的数据预处理、参数调优等步骤。

希望这个示例能帮助你理解坐标随机梯度下降法在线性回归问题中的应用。如有任何进一步的问题,请随时提问。

]]>
0 https://www.nituchao.com/optimize/91.html#comments https://www.nituchao.com/feed/optimize/91.html