在Caffe的Solver的逻辑,需要计算一个平滑后的平均值,它的计算逻辑如下:
void Solver<Dtype>::UpdateSmoothedLoss(Dtype loss, int start_iter,
int average_loss) {
if (losses_.size() < average_loss) {
losses_.push_back(loss);
int size = losses_.size();
smoothed_loss_ = (smoothed_loss_ * (size - 1) + loss) / size;
} else {
int idx = (iter_ - start_iter) % average_loss;
smoothed_loss_ += (loss - losses_[idx]) / average_loss;
losses_[idx] = loss;
}
}
基本思路:
- 在losses_容器大小小于average_loss阈值的时候,通过
(smoothed_loss_ * (size - 1) + loss) / size;
方式进行计算,这个比较好理解。其中average_loss相当于losses_最大容量。 - 如果容器已经满了,再来一个新的loss数据,由于不能再往容器里面放了,需要通过滚动的方式替换原有值。此时计算新的smoothed_loss_也可以采用
(smoothed_loss_ * (size - 1) + loss) / size;
来计算,只是size不是容器大小,而是历史数据条目数目。但是Caffe没有采用这个方案,而是采用smoothed_loss_ += (loss - losses_[idx]) / average_loss;
,大概含义就是这次新增的数据的增量((loss - losses_[idx])),均衡到容器中每一个方格中。
网友评论