2023年7月17日发(作者:)
cs231n学习有疑惑?看这⼀篇或许能搞定cs231n assignments学习⼼得cs231n是斯坦福的⼀门以计算机视觉为载体的深度学习课程,由李飞飞和她的⼏个博⼠⽣上课。这门课亲测好评。下⾯是我完成这些assignment的⼀些疑问点和解决办法。Assignment1:KNN,SVM,Softmax,Neuron Network总体来说,这个assignment难度适中,但是对于numpy的要求还挺⾼的,要⽐较纯熟的使⽤才能完成⼀些诸如⽮量化⼀样的操作。⽐较困难的地⽅在于梯度的计算。作为初学者的我⼀开始是⾮常懵逼的,(现在好⼀点了也还有点懵逼)。看了官⽅给出的⼀些说明,还有慕课学院讲解课以后才理解了⼀些。现在尝试对于⼀些问题给出⾃⼰的理解。图⽚部分出⾃上⾯内容主要的考察点就是两重循环,⼀重循环和全向量化。先介绍⼀下背景,给出n维的测试点和训练点,要求出它们之间的距离。使⽤两重循环的话就是通过索引到这两个数据再处理。 for i in xrange(num_test): for j in xrange(num_train): distances = (((self.X_train[j] - X[i]))) dists[i,j]=distances使⽤⼀重循环是借助了numpy ndarry之间的相减功能,单独的算出所有训练点到⼀个测试点的距离,再⼀次便利即可。for i in xrange(num_test): distances = (((self.X_train - X[i]),axis = 1)) dists[i, :] = distances使⽤全向量化就⽐较有技术了,这⾥通过(X-Y)2=X2-2XY+Y^2来计算。 num_test = [0] num_train = self.X_[0] dists = ((num_test, num_train))
a = -2 * (X, self.X_train.T) b = ((self.X_train), axis = 1) c = ose([((X), axis=1)]) dists = (a + b + c)这⾥我想介绍⼀下背景知识。⾸先介绍⼀下SVM的loss计算。2018-04-18-07-32-19这⾥的1是margin。SVM使⽤的是hinge loss。hinge loss图形如下:2018-04-18-07-37-27我们之前学习到SVM的代价函数是这个样⼦2018-04-18-07-38-14调转⼀下约束项的位置,就成了e >= 1 - ywx了。可以看出来SVM损失函数可以看作是L2-norm和Hinge Loss之和。在这⾥我们只需要计算hinge loss就⾏了。 num_train = [0] num_classes = [1] scores = (W) correct_class_scores = scores[range(num_train), list(y)].reshape(-1,1) #(N, 1) margins = m(0, scores - correct_class_scores + 1) margins[range(num_train), list(y)] = 0 loss = (margins) / num_train + 0.5 * reg * (W * W)⾄于gradient,我们需要对这个loss进⾏w求导:2018-04-18-07-45-53注意上⾯的计算l(*)只有在符合相应条件的时候才进⾏。 for i in xrange(num_train): scores = X[i].dot(W) correct_class_score = scores[y[i]] for j in xrange(num_classes): if j == y[i]: continue margin = scores[j] - correct_class_score + 1 # note delta = 1 if margin > 0: loss += margin dW[:,j] += X[i].T dW[:,y[i]] += -X[i].T loss /= num_train dW /= num_train # vectorized操作 coeff_mat = ((num_train, num_classes)) coeff_mat[margins > 0] = 1 coeff_mat[range(num_train), list(y)] = 0 coeff_mat[range(num_train), list(y)] = -(coeff_mat, axis=1) dW = (X.T).dot(coeff_mat) dW = dW/num_train + reg*xSoftmax也是常见的non-linearity函数。下⾯是Softmax的定义2018-04-18-07-57-33单个测试数据的损失就是这样计算,最后求总和要加起来所有的才⾏。 num_classes = [1] num_train = [0] scores = (W) softmax_output = (scores)/((scores), axis = 1).reshape(-1,1) loss = -((softmax_output[range(num_train), list(y)])) loss /= num_train
loss += 0.5* reg * (W * W)再求gradient。求导很重要的⼀点就是要分清求导对象2018-04-18-08-01-49 dS = softmax_() dS[range(num_train), list(y)] += -1 dW = (X.T).dot(dS) dW = dW/num_train + reg* W
-layer NN从题⽬可以知道这⾥的结构是Input--FC--ReLU--FC--Softmax+loss的结构。由于我们引⼊了ReLU层,将输⼊中所有⼩于0的项都给去掉了。所以反向将gradient传回来的时候,这些⼩于0的位是没有贡献的。下⾯是残差分布,这⾥对于后向传播的gradient计算做了⼀些解释。梯度计算与反向传播对梯度计算给出了⼀个很好的实例。2018-04-18-08-06-36 dscores = softmax_() # how this come from please see /neural-networks-case-study/
dscores[range(N), list(y)] -= 1 dscores /= N grads['W2'] = h_(dscores) + reg * W2 # 以上通过Softmax章节的w求导就可以得到 grads['b2'] = (dscores, axis = 0)
dh = (W2.T) dh_ReLu = (h_output > 0) * dh grads['W1'] = (dh_ReLu) + reg * W1 grads['b1'] = (dh_ReLu, axis = 0)e这个涉及到图⽚的直⽅图之类的,感觉⽤处不⼤,懒得看了Assignment2: FC-NN, BatchNormalization, Dropout, cnn,PytorchAssignment2相对Assignment1来说知识程度更深了,但是因为有了Assignment1中对梯度和backpropagate的学习,所以相对来说都能触类旁通。唯⼀⽐较复杂的就只有卷积层梯度的求解了。所以这部分我先总结⼀下⾃⼰所学到的东西,然后针对题⽬中的相关问题给出⼀些讲解。-connected Neural Network这⼀部分介绍了⼏种常见的层的forward/backward,并对这些⾏为的实现加以封装。 Layer仿射层。其实也就是fully-connected layer. Affine Layer其实就是y=wx+b的实现。这⼀层的backward梯度也⽐较好求层。这⼀层运⽤了ReLU函数,对于前⾯传来的⼩于0的输⼊都置零,⼤于0的输⼊照常输出。引⼊这种⾮线性激励函数的作⽤是避免线性情况下输出永远都是输⼊的线性组合,从⽽与没有隐藏层效果相当。在求backward梯度时要注意,只有输出为正数的才有梯度,输出的梯度应该等于dout*x。除了讲解上⾯的层级,还引⼊了模块化编程的概念,使⽤Solver来控制整个训练过程,将模型常⽤的参数都传给Solver,然后Solver内部进⾏训练。斯坦福⼤学学⽣编程能⼒真的强。然后给出了⼏种更新规则的区别,SGD+momentum,RMSProp,Adam等,这些算法只要知道个原理,都不是很难。ormalization这⼀部分难点主要在于模式下BN的操作:由于我们在训练时候已经得到了running_mean和running_var,这两个值将⽤在test模式下替换原有的sample_mean和sample_var。再带⼊公式即可。rd梯度的计算:这⾥有⼀篇⾮常好的⽂章Understanding the backward pass through Batch Normalization Layer。简单来说就是当我们没办法⼀下⼦看出梯度来时,画出计算图,逐层递推。这和cs231n课程讲到的也是⼀个意思。最后得到梯度后直接计算,可以⽐逐层递推有更⾼的效率。具体怎么搞就去看代码吧。tDropout相对⽐较简单,但是要注意训练模式和测试模式下的不同。测试模式下我们可以使⽤Dropout,但是测试模式下为了避免随机性不能使⽤Dropout。为了实现⾼效率,我们直接对训练时除以p即可。具体的原因请看上⾯的参考⽂章:深度学习笔记⼆。在这⾥,我们并不是简单的去除以p,⽽是除以1-p。因为这样可以避免后续的normalize操作。并且这⾥要把Dropout的mask记住,然后在backward的时候需要。这是和BN⼀样的原理。utional Network最难的应该是这部分了。⾸先,第⼀个难点就是backward梯度的推导。这⾥我推导了⼀次。好难过啊,不知道怎么显⽰latex。这⾥的推导⼤家如果看不懂就去慕课学院讲解课这⾥看吧。假设我们有⼀个原来的图⽚。⽤3*3的简化$$ begin{Bmatrix} a_{11} & a_{12} & a_{12} a_{21} & a_{22} & a_{23} a_{31} & a_{32} & a_{33} end{Bmatrix} $$我们的filter是这样的:$$ begin{Bmatrix}w_{11} & w_{12}w_{21} & w_{22}end{Bmatrix} $$最后的结果是:$$ begin{Bmatrix}z_{11} & z_{12}z_{21} & z_{22}end{Bmatrix} $$容易得到:$ z_{11}=a_{11}w_{11}+a_{12}w_{12}+a_{21}w_{21}+a_{22}w_{22} $$ z_{12}=a_{12}w_{11}+a_{13}w_{12}+a_{22}w_{21}+a_{23}w_{22} $$ z_{21}=a_{21}w_{11}+a_{22}w_{12}+a_{31}w_{21}+a_{32}w_{22} $$ z_{22}=a_{22}w_{11}+a_{23}w_{12}+a_{32}w_{21}+a_{33}w_{22} $⼜因为我们可以计算出{z}的gradient。也就是backpropagate时候从后⾯传来的上游gradient。$$ begin{Bmatrix}delta_{11} & delta_{12}delta_{21} & delta_{22}end{Bmatrix} $$这样当我们对$ a_{ij} $求导的时候,由于同⼀个$ a_{ij} $可能参与了多个$ z_{ij} $的计算,所以求导的时候要加起来。例如:$ triangledown a_{11} = delta_{11}w_{11} $$ triangledown a_{12} = delta_{11}w_{12} + delta_{12}w_{11} $...$ triangledown a_{33} = delta_{22}w_{22} $然后我们进⾏⼀下排列组合。2018-04-27-12-26-59第⼆个难点是在fast_layer的时候,会出现col2im_6d_cython isn't defined的问题,这时候需要删除cs231n⽂件夹下⾯除im2col_以外所有以im2col_cython开头的⽂件,然后重新编译。第三个难点是在Spatial Batch Normalization处理图⽚时,这⾥的输⼊是(N,C,H,W),我们需要先转换为(N,H,W,C)再reshape成(N*H*W, C),最后再转换回来,这样才能保留住channel进⾏Spatial BN操作。然后我们就可以愉快的组装layer成⼀个完整的convolutional network了。h和TensorFlow这⾥就没啥好讲的了。Assignment3: RNN, Network visualization, style transfer, 是种⼗分强⼤的⽹络,尤其是改进版LSTM,更是让⼈叹为观⽌。这个作业写了⼀个⽂本标注的例⼦,只要注意到了rnn的模型架构,⼀般不会有问题。我放在这⾥来。2018-04-26-23-45-12特别注意LSTM的模型中,$c_t$的梯度来源有两个,dc_t和tanh。所以要把两个相加。Network visualizationStyle transferGAN这⼏个专题感觉都是偏应⽤型的,代码没什么难度,⽽且我的代码注释⽐较详细。直接跟着代码看就⾏了。
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1689561831a266345.html
评论列表(0条)