8/12训练日记

今天开始了新的篇章——数论!

数论一直都是代码的重点呢!无论是从数字方面,还是从几何方面,都不算是什么容易的东西……

所以数论一定要——好好背模板……

今天开到了最大公约数!

最开始讲的还是我们的老朋友素数和约数,无论是以前做题、网上找题解,都能发现n种求解素数、约数的代码,而且一个比一个省时间!

判断素数,老方法,1~sqrt(n)试试能不能整除。

求素数,老方法+1,循环1~n,不是素数的倍数也不是素数,用一个visit[]数组标记一下,防止超时。

线性筛法暂时背不熟,这里……默写不过,看倒是看得懂,实际上想法跟上面那个有点相似,也要标记,而且要用一个数组存储所有的质数,总之这个方法没有上面的那个好用好背,我觉得现在这个水平还是看上面那俩老方法就挺好。

质因数分解,很久以前做题的时候,求质因数个数的时候,见到过类似的代码,因为看不懂而印象深刻(是记不住的那种印象深刻……),现在再看,可以理解了,比较明了,很好的方法,一看就知道不会超时,因为n本身就在随着i(因子)的变化而变化,i越大,n就会变得越小。

中心思想:2~sqrt(n)遍历,遇到是因数并且是质数的,就放在数组里面,并且从n里面除去所有的i。最后判断你、本身是不是质数(最后的结果留下大于1说明除不尽,是质数,要加到质数的数组里面,否则不加)。

约数也是比较常考,但是最开始的那些东西啊,真的很不好背唉,那都是一些什么东西啊!混蛋,看不懂,以前也没有考过,所以就不想看……然后导致后面有个例题看不懂……呜呜呜,好难背啊这里。

求n的约数很简单,就是一个个的遍历,并且约数都是成对出现的,i是,那么n/i也是,放到数组里面就好了。

1~n的稍微有点难,因为n本身的话时间复杂度为根号n,这样字就变成了n倍的根号N,最一般的情况下都会超时,所以要用一个新的办法:二维的动态数组。

每次找到一个i,它的倍数i*j的因子就一定有i,这时候把i放进下标为i*j的第二维数组里面就好。

其实也很简单啦~

最大公约数那个辗转相除法、辗转相加法什么的,应该都很熟悉,就是时间久了有点容易忘事!还要再去网上找一找模板在背背。

今晚上!练习打字的时候,到了第三个复习的关卡!超开心!可惜的是打着打着就烦了,就打不下去了……呜,没耐心!

但是啊!今晚的博客,可是我努力不看键盘,放好手指,尽力一个字一个字打出来的!而且我发现,果然专门去背过按键的位置是十分的不靠谱的!完全没有我不看键盘随便打来的准、来的快!

好开心!这是实实在在的进步啊!下次继续努力!

<think>嗯,用户现在让我解释一下他们提供的PyTorch训练代码部分。我之前已经帮他们理解了线性回归模型的类定义,现在他们想了解超参数设置、损失函数、优化器和训练循环的部分。用户可能刚开始学习深度学习,所以需要通俗易懂的解释,避免使用太多术语,同时确保他们理解每个步骤的作用。 首先,我需要拆分这段代码的结构,看看每个部分的作用。超参数设置包括学习率和周期数,这部分需要解释它们对训练的影响。损失函数是MSE,优化器是SGD,这些可能需要用类比来帮助理解。训练循环部分比较复杂,包含前向传播、反向传播、梯度清除和参数更新,这些步骤需要逐步讲解。 用户可能不太明白为什么需要设置学习率,或者epochs是什么,所以得用生活中的例子,比如学自行车时的调整幅度和练习次数。损失函数的作用是衡量预测和实际的差距,而优化器则是根据差距调整模型参数,这里可以用修正自行车方向的例子。 在训练循环中,dataloader分批数据,需要解释分批的好处,比如内存效率和训练稳定性。前向传播就是模型做预测,反向传播是计算梯度,优化器更新参数。梯度清零是为了防止累积,这点很重要,可能用户会忘记为什么每次都要清零。 另外,用户可能对loss_history的作用有疑问,记录损失是为了监控训练过程,判断模型是否在改进。每隔20轮打印一次损失,这样用户可以看到训练进度,调整超参数或提前停止。 还要注意常见误区,比如学习率过大或过小的影响,epochs设置过多导致过拟合,或者忘记清零梯度导致计算错误。这些都是用户在实际操作中可能会遇到的问题,需要提前提醒。 最后,确保整个解释结构清晰,步骤分明,用生活中的比喻帮助用户理解,同时保持专业性,指出每个部分在训练中的作用和重要性。可能需要检查是否有遗漏的细节,比如优化器的选择,SGD和其他优化器的区别,但根据用户提供的代码,暂时不需要展开,专注于解释现有代码即可。</think>### **一句话总结** 这是「AI厨师」的烹饪指南——通过不断试吃调整配方,最终做出完美预测的料理流程! --- ### **分步骤动画演示** ![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5a9a8aef73f445d4a0d31e7f4b2e4c7c~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=400&h=300&s=1000323&e=gif&f=25&b=f6f6f6) --- ### **核心组件解析** #### **1. 超参数设置:烹饪火候控制** ```python learning_rate = 0.01 # 学习步幅(每次调整配方的幅度) epochs = 200 # 训练轮次(试吃调整配方的次数) ``` - **类比**:学骑自行车时 - `learning_rate`太大 → 左右猛晃容易摔倒(震荡不收敛) - `learning_rate`太小 → 半天学不会(收敛速度慢) - `epochs`不足 → 刚能骑2米就停止练习(欠拟合) - `epochs`过多 → 反复练习导致只会骑特定路线(过拟合) --- #### **2. 损失函数:口味评测器** ```python criterion = nn.MSELoss() # 均方误差 ``` - **计算公式**: $$ \text{Loss} = \frac{1}{N}\sum_{i=1}^{N}(y_{\text{预测}}^{(i)} - y_{\text{真实}}^{(i)})^2 $$ - **作用**:量化预测值与真实值的差距(类似尝菜后打分:1分难吃,10分完美) --- #### **3. 优化器:配方调整师** ```python optimizer = optim.SGD(model.parameters(), lr=learning_rate) ``` - **SGD工作原理**: $$ w_{新} = w_{旧} - \text{learning\_rate} \times \frac{\partial \text{Loss}}{\partial w} $$ (根据误差的导数方向调整参数,类似根据「太咸」的反馈减少盐量) --- ### **训练循环详解:厨房实操** #### **步骤1:准备食材(数据加载)** ```python for batch_X, batch_y in dataloader: # 自动分批 ``` - **分批的好处**: - 内存友好(一次处理100个样本 vs 处理10000个) - 增加参数更新频率(类似尝一小口就调整,比整锅尝完再调整更灵敏) --- #### **步骤2:试做菜品(前向传播)** ```python pred = model(batch_X) # 用当前配方做预测 loss = criterion(pred, batch_y) # 对比真实值计算误差 ``` - **可视化**: ``` 预测值: [152.3, 165.8, 130.1] 真实值: [160.0, 170.0, 135.0] 误差: 7.7² + 4.2² + 4.9² = 121.54 ``` --- #### **步骤3:分析问题(反向传播)** ```python optimizer.zero_grad() # 清空之前的调料残留(梯度清零) loss.backward() # 自动计算每个参数该调整的方向和幅度 ``` - **梯度示例**: ```python print(model.linear.weight.grad) # 输出:tensor([[-0.34, 1.21, -0.89]]) → w1需要增加,w2需要减少... ``` --- #### **步骤4:改进配方(参数更新)** ```python optimizer.step() # 根据分析结果调整参数 ``` - **更新过程**(假设当前权重为[0.3, 0.5, 0.2]): $$ w_{新} = 0.3 - 0.01 \times (-0.34) = 0.3034 $$ (类似发现盐少了,下次多放0.0034克) --- ### **训练日志:成长日记** ```python loss_history = [] # 记录每次的误差 if (epoch+1) % 20 == 0: # 每20轮打印进度 ``` - **理想曲线**: ``` Epoch [20/200], Loss: 25.6342 Epoch [40/200], Loss: 12.7851 ... Epoch [200/200], Loss: 0.8923 ``` (损失逐渐下降,类似厨艺评分从60分提升到95分) --- ### **关键点记忆口诀** ``` 梯度清零要记牢, ← optimizer.zero_grad() 前向传播算味道, ← pred = model(x) 反向传播找问题, ← loss.backward() 优化步骤调调料。 ← optimizer.step() ``` --- ### **常见错误示例** ❌ **错误1:忘记梯度清零** ```python # 错误代码 loss.backward() optimizer.step() ``` → **后果**:梯度会累积,导致参数更新幅度异常(类似把十次调料调整量一次性倒入) ❌ **错误2:错误的数据维度** ```python # 输入形状应为 (batch_size, input_dim) inputs = torch.tensor([1, 2, 3]) # 错误!应该是[[1,2,3]] ``` → **修正**:`inputs = torch.tensor([[1,2,3]])` --- ### **参数更新可视化** ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/33d4c0b7d6d3493a8e2f42a3e6a1c8e1~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=600&h=400&s=1234567&e=png&b=fefefe) (随着训练轮数增加,参数逐渐向最优解靠近) --- ### **扩展知识:优化器对比** | 优化器类型 | 适用场景 | 特点 | |----------------|---------------------|-----------------------------| | SGD | 简单模型 | 基础款,容易震荡 | | Adam | 大多数深度学习模型 | 自适应学习率,收敛快 | | RMSprop | RNN网络 | 处理非平稳目标效果佳 | --- ### **完整训练流程类比** **目标**:做出完美红烧肉 | 步骤 | 对应代码 | 现实映射 | |--------------------|---------------------|--------------------------| | 设定练习次数 | `epochs=200` | 决定练习200次 | | 准备小份试做 | `batch_X` | 每次用500克肉试验 | | 尝汤评价咸淡 | `loss.backward()` | 发现「有点淡」 | | 调整酱油用量 | `optimizer.step()` | 下次多放3毫升酱油 | | 记录每次失败经验 | `loss_history` | 厨房笔记第58页:火候不足 | --- ### **下一步学习建议** 1. 尝试修改`learning_rate`观察训练曲线变化(建议尝试0.1, 0.01, 0.001) 2. 用Matplotlib绘制`loss_history`的下降曲线 3. 添加验证集监控模型是否过拟合 4. 探索学习率衰减策略(如`lr_scheduler.StepLR`)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值