矩阵乘法
www.mathsisfun.com/algebra/mat…
multiply a matrix by a single number:
multiply a matrix by another matrix
When we do multiplication:
- The number of columns of the 1st matrix must equal the number of rows of the 2nd matrix.
- And the result will have the same number of rows as the 1st matrix, and the same number of columns as the 2nd matrix.
反向传播
zhuanlan.zhihu.com/p/261710847
BP算法的学习过程由正向传播过程和反向传播过程组成。在正向传播过程中,输入信息通过逐层处理并传向输出层。如果在输出层得不到期望的输出值,则通过构造输出值与真实值的损失函数作为目标函数,转入反向传播,逐层求出目标函数对各神经元权值的偏导数,构成目标函数对权值向量的梯度,作为修改权值的依据,网络的学习在权值修改过程中完成。输出值与真实值的误差达到所期望值时,网络学习结束。
计算图
zhuanlan.zhihu.com/p/191648279 计算图是用来描述运算的有向无环图,有两个主要元素:节点 (Node) 和边 (Edge)。节点表示数据,如向量、矩阵、张量。边表示运算,如加减乘除卷积等。
用计算图表示:𝑦=(𝑥+𝑤)∗(𝑤+1)
计算图与梯度求导
这里求 𝑦 对 𝑤 的导数。根复合函数的求导法则,可以得到如下过程。
体现到计算图中,就是根节点 𝑦 到叶子节点 𝑤 有两条路径 y -> a -> w和y ->b -> w。根节点依次对每条路径的孩子节点求导,一直到叶子节点w,最后把每条路径的导数相加即可。
import torch
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
# y=(x+w)*(w+1)
a = torch.add(w, x) # retain_grad()
b = torch.add(w, 1)
y = torch.mul(a, b)
# y 求导
y.backward()
# 打印 w 的梯度,就是 y 对 w 的导数
print(w.grad)
结果为tensor([5.])。
我们回顾前面说过的 Tensor 中有一个属性is_leaf标记是否为叶子节点。
在上面的例子中,𝑥 和 𝑤 是叶子节点,其他所有节点都依赖于叶子节点。叶子节点的概念主要是为了节省内存,在计算图中的一轮反向传播结束之后,非叶子节点的梯度是会被释放的。
动态计算图(Dynamic Computation Graph)
PyTorch 采用的是动态图机制 (Dynamic Computational Graph),而 Tensorflow 采用的是静态图机制 (Static Computational Graph)。
动态图是运算和搭建同时进行,也就是可以先计算前面的节点的值,再根据这些值搭建后面的计算图。优点是灵活,易调节,易调试。
静态图是先搭建图,然后再输入数据进行运算。优点是高效,因为静态计算是通过先定义后运行的方式,之后再次运行的时候就不再需要重新构建计算图,所以速度会比动态图更快。但是不灵活。
step
- load data
- build model
- train
- test
Tensor操作
Tensor操作
PyTorch tensor和NumPy array非常相似,但是tensor还可以在GPU上运算,而NumPy array则只能在CPU上运算。
在PyTorch中,我们可以使用.backward()方法来计算梯度。例如:
如果out.backward()中的out是一个向量(或者理解成1xN的矩阵)的话,其参数要传入和out维度一样的矩阵 out.backward(torch.FloatTensor([[1.,1.]]))
传入的参数 (看成一个行向量),是对原来模型正常求导出来的雅克比矩阵进行线性操作