优化器是模型训练的主要承担者,当模型输出的数据通过损失函数得到梯度后,优化器根据相应的优化算法计算得到新的模型参数,如下图所示:
图 1在BigDL中,可以通过Optimizer对象的apply方法创建优化器:
val optimizer = Optimizer(
model = buildModel(classNum),
sampleRDD = trainingRDD,
criterion = new ClassNLLCriterion[Float](),
batchSize = param.batchSize
)
BigDL中为优化器提供了两个实现,即LocalOptimizer和DistriOptimizer。前者主要用于单进程环境下的测试,后者才是用于Spark环境下的实现,其工作流程主要包含一下几部分:
1. 环境初始化
Spark应用以Executor进程作为调度单元,因而在初始化阶段,DistriOptimizer将模型以Spark broadcast的方式将定义好的模型为每个数据分区clone一个模型副本,供后续训练使用。
2. 梯度计算
对于每一轮迭代,以Spark任务的方式,在每个数据分片上,首先根据当前的梯度得到最新的模型参数,执行前向计算,然而根据前向计算的输出,得到本轮迭代的梯度。最后,将各个分片的梯度通过BlockManager写入。
3. 梯度汇聚
通过另外一个Spark任务,从BlockManager读出各个分片写入的梯度,进行聚合,供下一轮迭代使用。
网友评论