笔记:CS231n+assignment2(作业二)(三)

终于来到了最终的大BOSS,卷积神经网络~

这里我想还是主要关注代码的实现,具体的CNN的知识点想以后在好好写一写,CNN的代码关键就是要加上卷积层和池话层.

一、卷积层

  卷积层的前向传播还是比较容易的,我们主要关注的是反向传播,看下图就知道了:

  

def conv_forward_naive(x, w, b, conv_param):
    stride, pad = conv_param[‘stride‘], conv_param[‘pad‘]
    N, C, H, W = x.shape
    F, C, HH, WW = w.shape
    x_padded = np.pad(x, ((0, 0), (0, 0), (pad, pad), (pad, pad)), mode=‘constant‘) #补零
    H_new = 1 + (H + 2 * pad - HH) / stride
    W_new = 1 + (W + 2 * pad - WW) / stride
    s = stride
    out = np.zeros((N, F, H_new, W_new))

    for i in xrange(N):       # ith image
        for f in xrange(F):   # fth filter
            for j in xrange(H_new):
                for k in xrange(W_new):
                    out[i, f, j, k] = np.sum(x_padded[i, :, j*s:HH+j*s, k*s:WW+k*s] * w[f]) + b[f]#对应位相乘

    cache = (x, w, b, conv_param)

    return out, cache

def conv_backward_naive(dout, cache):
    x, w, b, conv_param = cache
    pad = conv_param[‘pad‘]
    stride = conv_param[‘stride‘]
    F, C, HH, WW = w.shape
    N, C, H, W = x.shape
    H_new = 1 + (H + 2 * pad - HH) / stride
    W_new = 1 + (W + 2 * pad - WW) / stride

    dx = np.zeros_like(x)
    dw = np.zeros_like(w)
    db = np.zeros_like(b)

    s = stride
    x_padded = np.pad(x, ((0, 0), (0, 0), (pad, pad), (pad, pad)), ‘constant‘)
    dx_padded = np.pad(dx, ((0, 0), (0, 0), (pad, pad), (pad, pad)), ‘constant‘)

    for i in xrange(N):       # ith image
        for f in xrange(F):   # fth filter
            for j in xrange(H_new):
                for k in xrange(W_new):
                    window = x_padded[i, :, j*s:HH+j*s, k*s:WW+k*s]
                    db[f] += dout[i, f, j, k]
                    dw[f] += window * dout[i, f, j, k]
                    dx_padded[i, :, j*s:HH+j*s, k*s:WW+k*s] += w[f] * dout[i, f, j, k]#上面的式子,关键就在于+号

    # Unpad
    dx = dx_padded[:, :, pad:pad+H, pad:pad+W]

    return dx, dw, db

  和http://www.cnblogs.com/tornadomeet/p/3468450.html中提到的一样,卷积层的BP算法就是这么计算的,也就是一个正统的卷积操作

二、pooling层

  

def max_pool_forward_naive(x, pool_param):
    HH, WW = pool_param[‘pool_height‘], pool_param[‘pool_width‘]
    s = pool_param[‘stride‘]
    N, C, H, W = x.shape
    H_new = 1 + (H - HH) / s
    W_new = 1 + (W - WW) / s
    out = np.zeros((N, C, H_new, W_new))
    for i in xrange(N):
        for j in xrange(C):
            for k in xrange(H_new):
                for l in xrange(W_new):
                    window = x[i, j, k*s:HH+k*s, l*s:WW+l*s]
                    out[i, j, k, l] = np.max(window)

    cache = (x, pool_param)

    return out, cache

def max_pool_backward_naive(dout, cache):
    x, pool_param = cache
    HH, WW = pool_param[‘pool_height‘], pool_param[‘pool_width‘]
    s = pool_param[‘stride‘]
    N, C, H, W = x.shape
    H_new = 1 + (H - HH) / s
    W_new = 1 + (W - WW) / s
    dx = np.zeros_like(x)
    for i in xrange(N):
        for j in xrange(C):
            for k in xrange(H_new):
                for l in xrange(W_new):
                    window = x[i, j, k*s:HH+k*s, l*s:WW+l*s]
                    m = np.max(window)               #获得之前的那个值,这样下面只要windows==m就能得到相应的位置
                    dx[i, j, k*s:HH+k*s, l*s:WW+l*s] = (window == m) * dout[i, j, k, l]

    return dx

三、与之前的区别

  这里BN算法与之前是不太一样的,因为网络的输入变成了saptail的

  

def spatial_batchnorm_forward(x, gamma, beta, bn_param):
    N, C, H, W = x.shape
    x_new = x.transpose(0, 2, 3, 1).reshape(N*H*W, C)#分成不同的channel来算,所以可以直接用之前的代码
    out, cache = batchnorm_forward(x_new, gamma, beta, bn_param)
    out = out.reshape(N, H, W, C).transpose(0, 3, 1, 2)

    return out, cache

def spatial_batchnorm_backward(dout, cache):
    N, C, H, W = dout.shape
    dout_new = dout.transpose(0, 2, 3, 1).reshape(N*H*W, C)
    dx, dgamma, dbeta = batchnorm_backward(dout_new, cache)
    dx = dx.reshape(N, H, W, C).transpose(0, 3, 1, 2)

    return dx, dgamma, dbeta

四、总结

  assignment2终于弄完了,总的来说..numpy还是要多熟悉,具体的操作也要熟悉。卷积层的前向传播很好理解,反向传播和之前的区别不大,只不过需要做一个卷积的操作。

时间: 2024-11-11 15:32:42

笔记:CS231n+assignment2(作业二)(三)的相关文章

ufldl学习笔记与编程作业:Logistic Regression(逻辑回归)

ufldl出了新教程,感觉比之前的好,从基础讲起,系统清晰,又有编程实践. 在deep learning高质量群里面听一些前辈说,不必深究其他机器学习的算法,可以直接来学dl. 于是最近就开始搞这个了,教程加上matlab编程,就是完美啊. 新教程的地址是:http://ufldl.stanford.edu/tutorial/ 本节学习链接:http://ufldl.stanford.edu/tutorial/supervised/LogisticRegression/ 有了线性回归的基础再来学

ufldl学习笔记与编程作业:Debugging: Gradient Checking(梯度检测)

ufldl出了新教程,感觉比之前的好,从基础讲起,系统清晰,又有编程实践. 在deep learning高质量群里面听一些前辈说,不必深究其他机器学习的算法,可以直接来学dl. 于是最近就开始搞这个了,教程加上matlab编程,就是完美啊. 新教程的地址是:http://ufldl.stanford.edu/tutorial/ 本节学习链接:http://ufldl.stanford.edu/tutorial/supervised/DebuggingGradientChecking/ 所谓梯度,

读书笔记-HBase in Action-第二部分Advanced concepts-(2)Coprocessor

Coprocessor是HBase 0.92.0引入的特性.使用Coprocessor,可以将一些计算逻辑下推到HBase节点,HBase由一个单纯的存储系统升级为分布式数据处理平台. Coprocessor分为两种:Observer和Endpoint.Observer能修改扩展已有的客户端操作功能,而Endpoint能引入新的客户端操作. Observer Observer的作用类似于数据库的触发器或者AOP中的advice.下图为Put操作增加Observer,其中1-2-4-6是一次正常的

Object C学习笔记26-文件管理(二)

上一篇简单的介绍了如何获取文件属性,删除,拷贝文件等,本文继续记录Object C中文件IO操作. 一. 获取文件的执行主目录 在Object C中提供了一个方法 NSHomeDirectory() 用于获得执行执行的主目录,使用如下代码测试: NSString *homePath=NSHomeDirectory(); NSLog(@"执行文件的主目录:%@",homePath); 通过以上代码可以正确的输出应用程序的执行目录,上一张也提到了文件的目录问题,这个和Windows系统的有

机器学习 1 linear regression 作业(二)

机器学习 1 linear regression 作业(二) 这个线性回归的作业需要上传到https://inclass.kaggle.com/c/ml2016-pm2-5-prediction 上面,这是一个kaggle比赛的网站.第一次接触听说这个东西,恰好在京东上有一本刚出来的关于这个的书<Python机器学习及实践:从零开始通往Kaggle竞赛之路>.把我自己写的代码运行保存的结果提交上去后发现,损失函数值很大,baseline是6,而我的却是8,于是很不心甘,尝试了其他方法无果后,准

马程序员学习笔记——红黑树解析二

---------------------- ASP.Net+Unity开发..Net培训.期待与您交流! ---------------------- 四.树中删除元素 1.先找到需要删除的元素. 2. 2.1如果被删元素没有子元素,那么直接用NIL节点代替他: 2.2如果被删元素只有一个子元素,那么直接用这个子元素代替他: 2.3如果被删元素有两个子元素,那么就用左子元素中的最大元素或者右子元素的最小元素代替他. 比如说原来要删除的元素是N,N有两个分支,其中P是N左分支中的最大元素,那么就

機器學習基石(Machine Learning Foundations) 机器学习基石 作业二 课后习题解答

大家好,我是Mac Jiang,首先祝贺大家清明节快乐!作为一名苦逼的程序员,博主只能窝在实验室玩玩游戏,顺便趁着大早上没人发一篇微博.不过还是祝各位出行的兄弟玩的开心! 今天和大家分享coursera-NTU-機器學習基石(Machine Learning Foundations)-作业二的习题解答.笔者在做这些题目时遇到很多困难,当我在网上寻找答案时却找不到,而林老师又不提供答案,所以我就想把自己做题时对题目如何思考的写下来,为大家提供一些思路.当然,我对题目的理解不一定是正确的,如果各位博

capwap学习笔记&mdash;&mdash;初识capwap(二)

2.5.1 AC发现机制 WTP使用AC发现机制来得知哪些AC是可用的,决定最佳的AC来建立CAPWAP连接. WTP的发现过程是可选的.如果在WTP上静态配置了AC,那么WTP并不需要完成AC的发现过程. WTP首先发送一个 Discovery Request message给受限的广播地址,或者CAPWAP的多播地址(224.0.1.140),或者是预配置的AC的单播地址.在IPV6网络中,由于广播并不存在,因此使用"All ACs multicast address" (FF0X

作业二:操作系统是如何工作的进行

作业二:操作系统是如何工作的进行 mykernel实验指导(操作系统是如何工作的) 运行并分析一个精简的操作系统内核,理解操作系统是如何工作的 打开shell cd LinuxKernel/linux-3.9.4 qemu -kernel arch/x86/boot/bzImage 然后cd mykernel 您可以看到qemu窗口输出的内容的代码mymain.c和myinterrupt.c 一.实验截图 二.分析进程的启动和进程的切换机制 一个小的内核源代码 mypcb.h: 1.#defin

团队作业(三):确定分工

团队作业(三):确定分工 一.修改完善上周提交的需求规格说明书 修改之后的需求规格说明书请详见团队作业(二):团队选题 二.阅读<构建之法>第四章并总结代码规范和编码原则 良好的编码习惯 Java注释尽可能全面:对于方法的注释应该包含详细的入参和结果说明,有异常抛出的情况也要详细叙述:类的注释应该包含类的功能说明.作者和修改者. 多次使用的相同变量最好归纳成常量:多处使用的相同值的变量应该尽量归纳为一个常量,方便日后的维护. 尽量少的在循环中执行方法调用:尽量在循环中少做一些可避免的方法调用,