Backpropagation
学习笔记
这部分主要是比较详细的介绍使用计算树进行反向传播的计算方法。
首先举了一个很简单的例子,例子中详细的介绍了前向传播和反向传播的计算方式,其实就是链式法则。每个节点的导数都是用后一个部位的导数乘以当前节点的导数。
然后总结了一个节点导数的求法,就是上一个节点的导数乘以当前节点的local gradient。
然后举了一个相对复杂的例子,也是一步一步进行了正向和反向传播。
这个例子的公式其实可以看成一个sigmoid函数和一个wx的向量相乘。
最后将链式求导扩展到矩阵的计算
矩阵求导的计算方式也是一样的,需要注意的一个细节是如果,计算
需要对
进行转置,计算
需要对
进行转置,并且因为
与
维度相同,
与
维度相同,所以我们在计算导数的时候关注一下矩阵维度,这样可以减少错误的概率。
推荐一个补充学习的文章,写的很好CS231n课程笔记翻译:反向传播笔记
几点思考:
- 神经网络中会用到很多
的矩阵相乘,而
的值与
的值相关,如果
的值统一扩大1000倍,那么
会变大很多,这样我们就必须用更小的learning_rate,否则收敛效果不好。这就是为什么一般我们都希望
的值在一个相对小范围内。
- 以前我一直不知道tensorflow中是如何进行链式求导的,如果用
进行求导,这样需要进行两次前向计算才能求出导数,所以每次参数更新需要大量的计算。学习了这一课后我知道了框架也是进行的链式求导。比如tensorflow有graph的概念,就是计算图,会将每一个算子也就是op的连接过程记录下来,导数就可以根据计算图和每个op的local gradient公式进行链式求导。op就是一些我们常用的计算,比如加减乘除,relu,softmax,sigmoid,dropout等都是op,他们都有对应的导函数用来求local gradient。
@ops.RegisterGradient("Relu") def _ReluGrad(op, grad): return gen_nn_ops.relu_grad(grad, op.outputs[0])
作业softmax
作业主要是用循环的方式和向量化的方式实现loss softmax正向和反向传播
1.循环的方式
前向传播很简单,就是套用softmax的公式
代码实现如下:
num_train = X.shape[0]
num_cls = W.shape[1]
for i in range(num_train):
scores = np.dot(X[i, :], W)
softmax = np.exp(scores[y[i]]) / np.sum(np.exp(scores))
loss_log = - np.log(softmax)
loss += lo