学习笔记: 源码 solver.cpp 初访

本文详细解析了深度学习训练流程中的关键步骤,包括Solver的初始化、网络的前向及反向传播、权重更新以及模型快照保存等。通过具体函数如Solver::step的介绍,深入理解如何计算损失和梯度,并最终实现模型训练。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. solver.cpp中,主要是Solver的初始化函数Solver::Init(const SolverParameter& param),以及训练网络net_的初始化InitTrainNets() ,和测试网络test_nets_初始化InitTestNets() 。还有就是关于手动中断训练的相关函数GetRequestedAction()等。最最重要的,应该是Solver::solve(),而Solver::solve()中最主要的是step()函数。

2. void Solver<Dtype>::step(int iters)
这一部分主要包括:
(1)
TestAll(); //通过前向传播计算测试的loss,和想要的accuracy。
(2)
for (int i = 0; i < param_.iter_size(); ++i) {
loss += net_->ForwardBackward(); //通过前向后向传播,计算loss 和 梯度.
}
loss /= param_.iter_size();
(3)
ApplyUpdate(); //根据之前的计算,更新weights.
(4)
Snapshot(); //序列化model参数并存储

3. 接下来,就是了解net 是如何进行ForwardBackward() 了。
<think>嗯,用户遇到了一个AttributeError,错误信息是'Solver' object没有'value'属性。我需要仔细看看他们的代码哪里出错了。首先,用户在使用solver.value(c_max),但是根据错误提示,Solver实例确实没有value方法。 让我回忆一下OR-Tools的API。通常,在OR-Tools的线性求解器中,变量的值是通过调用Variable的SolutionValue()方法获取的,或者使用solver库中的某些函数。例如,solver.Objective().Value()是正确的,而用户可能在其他地方正确使用了solver.Value(),比如solver.Value(e_lom[task]),这里没有问题,但为什么在c_max的时候用了solver.value呢? 注意到用户代码中有两处处理c_max的地方。第一处是print(f"最小化最大完工时间: {solver.value(c_max)}"),这里应该是solver.Value(c_max),因为Python对大小写敏感,value和Value是不同的。用户可能在第二处写错了方法名,应该是Value而不是value。 此外,用户可能在定义c_max变量时是否正确?假设c_max是一个普通的变量,那么应该使用solver.Value(c_max)来获取它的解值。或者,如果c_max是一个表达式或者目标值,可能需要不同的处理方式。不过根据错误信息,问题更可能出在方法名的大小写上。 再看用户的代码,他们在前面正确使用了solver.Objective().Value(),而后面却用了solver.value,这显然是一个拼写错误。所以解决方法就是将solver.value改为solver.Value,或者如果是变量的话,可能直接调用变量的SolutionValue()方法,比如c_max.SolutionValue()。 另外,用户可能在循环外部打印c_max时,重复了同样的错误。需要检查所有出现solver.value的地方,确保正确使用大写V的Value方法。 总结一下,错误原因是方法名的大小写不正确,应该将solver.value(c_max)改为solver.Value(c_max)。同时,还要确认其他类似的地方是否也有同样的错误,比如在循环内的solver.Value(s_lom[task])是正确的,但循环外的solver.value(c_max)是错误的,需要修正。</think>该错误是由于`Solver`对象没有`value()`方法导致的。在OR-Tools中,正确的用法是调用`Value()`方法(注意大写字母V),或直接通过变量本身的`solution_value()`方法获取值。 以下是修正后的代码: ```python if status == pywraplp.Solver.OPTIMAL: solution = solver print('最优解找到!') print(f'目标函数值: {solver.Objective().Value(): .2f}') # 正确调用 lots_dispatch_result = {} if status == pywraplp.Solver.OPTIMAL or status == pywraplp.Solver.FEASIBLE: print("Solution:") for lot_id, step_info in LotFlowInfo.items(): for step_id, machine_info in Machine_of_operation.items(): for machine_id in machine_info: if x_lom[lot_id, step_id, machine_id].solution_value() == 1: # 另一种正确写法 lots_dispatch_result.setdefault(machine_id, []).append((lot_id, step_id)) for machine_id in lots_dispatch_result: print(f"机台 {machine_id} 的加工任务:") for task in lots_dispatch_result[machine_id]: print( f"lot:{task[0]} 的step:{task[1]} 的加工时间 {solver.Value(s_lom[task])} -> {solver.Value(e_lom[task])}") # 正确调用 # 完工时间 print(f"最小化最大完工时间: {c_max.solution_value()}") # 直接调用变量的方法 else: print("未找到可行解.") print(f"最小化最大完工时间: {solver.Value(c_max)}") # 统一修改为正确方法 ``` --- **错误原因分析:** 1. **方法名大小写错误**:Python区分大小写,`solver.value()`是错误写法,正确方法名为`Value()`。 2. **变量值获取方式**:OR-Tools提供两种获取变量值的方式: - 通过求解器调用:`solver.Value(variable)` - 直接通过变量调用:`variable.solution_value()` --- **修改说明:** 1. 将最后一行代码中的`solver.value(c_max)`改为`c_max.solution_value()`或`solver.Value(c_max)` 2. 补充了`lots_dispatch_result.setdefault(machine_id, [])`避免KeyError 3. 统一所有变量值获取方式(推荐使用同一种风格) --- **代码改进建议:** 1. **状态判断优化**:外层`if status == OPTIMAL`和内层`if status == OPTIMAL or FEASIBLE`存在冗余,可合并判断 2. **数据结构初始化**:使用`defaultdict`更安全: ```python from collections import defaultdict lots_dispatch_result = defaultdict(list) ``` 希望这能解决您的问题!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值