caffe中solver相关代码有:
几种优化方法的源文件如上:
例如随机梯度下降:(关于梯度与梯度下降会介绍)
SGD源码中:
在:
void Solver<Dtype>::Step(int iters){
while(iter_<stop_iter){
net_->ClearParamDiffs(); //初始化参数 for diff
for (int i=0;i<callbacks_.size;++i)
{
callbacks_[i]->on_start(); //以指针的方式访问使用多卡训练相关参数
}
Dtype loss=0;
for (int i=0;i<param_.iter_size();++i)
{
loss+=net_->ForwardBackward(); // 调用net中的代码,引出前向传播与反响传播,前向用一计算模型的最终输出与loss,后向用于计算每一层网络的参数和梯度
}
loss /=param_.iter_size();
UpadeSmoothedLoss(loss,start_iter,average_loss); //
此函数用于平滑模型产出的loss值(caffe训练方式是批量数据的优化方法)
for (int i=o;i<callbacks_size();++i){
callbacks_[i]->on_gradients_ready();
}
ApplyUpate(); /此函数用于参数的更新任务。下面看相关代码以随机梯度下降SGD为例
++iter_;
}
}
---------------------------------------------------------------------------------------------------------------------------
void SGDSolver<Dtype>::ApplyUpdate() {
CHECK(Caffe::root_solver());
Dtype rate =
GetLearningRate();
if (this->param_.display() && this->iter_ % this->param_.display() == 0) {
LOG(INFO) << "Iteration " << this->iter_ << ", lr = " << rate; //log记录的 this指针访问的是iter每一轮跌打的学习lr
}
ClipGradients(); //梯度值大小修剪的函数,主要是防止参数过大的情况。
for (int param_id = 0; param_id < this->net_->learnable_params().size();
++param_id) {
Normalize(param_id);
Regularize(param_id);
ComputeUpdateValue(param_id, rate);
}
this->net_->Update();
}
Dtype rate =
GetLearningRate(); 学习率的选择方式; caffe对于学习率的选择主要有(相关介绍后补):
fixed: lr 不变
step:
exp;
inv;
multistep;
ploy
sigmoid;