Git Operations: Rebase, Squash, and Cherry-Pick
在多分支开发中, 仅仅使用 git merge 是不够的! Hint 把单次提交看做为针对于父提交新增的改动 (delta) 可能会好理解一点: ...
在多分支开发中, 仅仅使用 git merge 是不够的! Hint 把单次提交看做为针对于父提交新增的改动 (delta) 可能会好理解一点: ...
For self reference. Forward Pass “forward pass” (前向传播) 是指神经网络从输入数据开始,逐层计算,直到产生最终输出(预测结果)的过程。可以把它想象成信息在网络中“向前流动”的过程。 与前向传播相对应的,确实还有一个非常关键的步骤叫做 “backward pass” (反向传播),通常更准确地称为 反向传播算法 (Backpropagation) Backward Pass 的作用: 计算损失 (Calculate Loss): 在前向传播得到预测值 a 之后,我们会将它与真实的标签 y (在你的代码中是 torch.tensor([1.0])) 进行比较,计算出一个“损失值” (loss)。 你的代码中 loss = F.binary_cross_entropy(a, y) 做的就是这件事。binary_cross_entropy 是一种常用的损失函数,用于衡量二分类问题中预测值和真实值之间的差异。损失值越小,说明模型的预测越准确。 计算梯度 (Calculate Gradients): 反向传播的核心任务是计算损失函数相对于模型中每个参数(在你的例子中是 w1 和 b)的梯度 (gradient)。 梯度可以告诉我们:为了减小损失,每个参数应该向哪个方向调整,以及调整的幅度有多大。简单来说,梯度指向了损失函数增长最快的方向,所以我们会沿着梯度的反方向去调整参数,以期减小损失。 更新参数 (Update Parameters): 根据计算得到的梯度,使用一种叫做优化器 (optimizer) (例如 SGD, Adam 等) 的算法来更新模型的参数 (w1 和 b)。 目标是让模型在下一次进行前向传播时,能做出更准确的预测,从而得到更小的损失 得到 loss 之后, 可以通过链式法则得到模型中每个参数的梯度, 为了最小化 loss, 最基本的参数更新规则是梯度下降法。对于每个参数,更新规则如下: new_parameter = old_parameter - learning_rate * gradient 虽然基础的梯度下降法很简单,但在实践中,研究人员发现了很多更高级、更有效的优化算法(Optimizer): SGD (Stochastic Gradient Descent) with Momentum: 借用了物理学中“动量”的概念。如果梯度连续指向同一个方向,参数更新的步长会逐渐加速;如果梯度方向改变,动量会帮助减缓更新,有助于跳出局部最小值或平坦区域。 AdaGrad (Adaptive Gradient Algorithm): 为不同的参数自动调整学习率。对于不经常更新的参数,它会使用较大的学习率;对于经常更新的参数,它会使用较小的学习率。 RMSprop (Root Mean Square Propagation): 也是一种自适应学习率的方法,是 AdaGrad 的改进,解决了其学习率可能过早衰减到零的问题。 Adam (Adaptive Moment Estimation): 被广泛使用,它结合了 Momentum 和 RMSprop 的优点,通常能快速收敛且效果良好。 参数更新完成后,一次“前向传播 -> 计算损失 -> 计算梯度 -> 更新参数”的完整迭代就结束了。然后,模型会带着更新后的参数,在下一批数据(或者同样的数据)上重复这个过程。 ...
Shape Manipulating reshape 可以把 NumPy 的 reshape 操作想象成一个先摊平, 再重铺的过程 核心思想: 无论你原来的数组是什么形状,也无论你想要变成什么新形状,reshape 都会(概念上)做两步: 摊平 (Flattening): 一行一行地把整个数组中的元素读出来, 形成一维数组 重铺 (Refilling): 再根据 reshape 后的形状填满一行一行地填满整个数组 import numpy as np a = np.array([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]) # Flatten a_flat = a.reshape(1, 12) print("Flattened array: ", a_flat) # Refill a_refilled = a_flat.reshape(3, 4) print("Refilled array: ", a_refilled) transpose 高维转置的本质是重新安排数组的索引顺序,而不是传统意义上的"矩阵转置" concatenate & stack concatenate: 沿着现有的轨道/维度进行延伸或对接 concatenate 是将多个数组沿着一个已经存在的维度(轴,axis)拼接起来。结果数组的维度数量通常与输入数组的维度数量相同 工作方式: 你需要指定一个 axis 参数,告诉 NumPy 沿着哪个维度进行拼接。 除了要拼接的那个维度之外,其他所有维度的大小必须完全相同。 就像你要把两列火车车厢接起来,它们的高度和宽度得匹配,只有长度可以不同(然后加起来) A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6]]) # 注意:B 也是二维的,才能在 axis=0 上与 A 匹配列数 np.concatenate((A, B), axis=0) # 结果: # [[1, 2], # [3, 4], # [5, 6]] (行数增加了,列数不变) A = np.array([[1, 2], [3, 4]]) C = np.array([[5, 6], [7, 8]]) np.concatenate((A, C), axis=1) # 结果: # [[1, 2, 5, 6], # [3, 4, 7, 8]] (列数增加了,行数不变) stack: 将多个独立的层叠放起来,形成一个新的维度 ...
Summary 记录一些工具性的网站 for references Daily Life Picture Compressor Convert from/to JPG Programming Code Image Generator OpenJDK Docker Proxy
Irregular updates Go Gotcha: math/rand Thread Safety Isn’t Universal Ran into a subtle trap with Go’s math/rand package regarding concurrency. It’s easy to assume all random generation is thread-safe, but that’s not quite right. The Key Difference: rand.Intn() (Package Level): Thread-safe! Uses a global source with an internal mutex. Good for most concurrent uses. myRand.Intn() (Method on *rand.Rand): NOT thread-safe by default! If you create your own *rand.Rand instance (myRand) and share it between goroutines, calling its methods concurrently without your own locking will cause data races. Example I Encountered: ...