深度学习系列之cs231n assignment1 two_layer_net(五)

写在开头:这次是完成assignmengt1的第四个作业浅层神经网络,通过这样的浅层神经网络来感受神经网络向前计算得分与向后计算梯度更新的过程。

内容安排

今天的任务主要是搭建两层全连接层,并在中间加入Relu的操作处理,最后使用softmax的损失函数进行梯度的更新,并进行预测。在本次的任务中与上一节softmax的区别在于搭建网络和全连接层的传递,任务的loss是softmax是一样的,同样会在需要公示或者讲解的地方进行讲解。

开始完成任务

1.构建网路并加载测试数据
首先是加载一些调用的包,还有我们用于计算误差的函数,

# A bit of setup

import numpy as np
import matplotlib.pyplot as plt

from cs231n.classifiers.neural_net import TwoLayerNet


%matplotlib inline
plt.rcParams['figure.figsize'] = (10.0, 8.0) # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'

# for auto-reloading external modules
# see http://stackoverflow.com/questions/1907993/autoreload-of-modules-in-ipython
%load_ext autoreload
%autoreload 2

def rel_error(x, y):
    """ returns relative error """
    return np.max(np.abs(x - y) / (np.maximum(1e-8, np.abs(x) + np.abs(y))))

然后为了方便我们测试代码是否运行正常,我们在这里应当使用小样本数据来进行测试,并且我们要初始化网络的输入,隐藏层数量,还有输出类别的数量,

# Create a small net and some toy data to check your implementations.
# Note that we set the random seed for repeatable experiments.

input_size = 4
hidden_size = 10
num_classes = 3
num_inputs = 5

def init_toy_model():
    np.random.seed(0)
    return TwoLayerNet(input_size, hidden_size, num_classes, std=1e-1)

def init_toy_data():
    np.random.seed(1)
    X = 10 * np.random.randn(num_inputs, input_size)
    y = np.array([0, 1, 2, 2, 1])
    return X, y

net = init_toy_model()
X, y = init_toy_data()

2.编写得分、损失、梯度函数
老样子这时我们需打开neural_net.py并对其中的任务进行编辑,在前面我们可以一起编辑得分、损失和梯度的计算,但是这里我们需要通过分块并采用讲解加编程的结合进行。
浅层神经网络
首先我们讲解一下今天的关键的两层神经网络是个啥。首先上一张图,
在这里插入图片描述这个图就是我们今天要研究的两层浅层神经网络,首先我们来说一下第一个问题,他们是如何进行传递的?
Q1:神经网络是怎么进行传递的?
我们这里的数据从输入层到隐藏层1是怎么进行的呢?利用的就是一个全连接层,跟我们在前文计算svm和softmax一样,通过像素与权重相乘得到每个类别的得分,在这里插入图片描述
这里展示的s231n课程文件中对于一张猫猫图片的预测流程,这与前几节是一样的,先将图片像素向量化乘以权重矩阵子再加上常数调整项,得到每个类别的得分。如果还有更多层,那么就将计算得到的结果再与下一个权重矩阵相乘得到类的得分。
Q2:ReLU是什么?
根据题目要求,我们需要在第一层与第二层之间加入一个ReLU函数进行处理,那么ReLU函数是什么呢?我们将其函数图像放出来,
在这里插入图片描述
ReLU函数的形式是,
f = m a x ( 0 , x ) f=max(0,x) f=max(0,x)
通过这样的处理,在第一层计算得到数据后,需要对其进行ReLU处理,让小于0的数变为0,也就是不去考虑得分小于0的值,那么有的朋友会问了,为什么需要这样一个ReLU处理呢?不处理不行吗?其他的处理方法不行吗?这个主要还是因为ReLU首先符合一种生物学的激活特性,其次能够引入稀疏增快计算效率,可以参考一下这篇博客,点击这里进行查看。笔者会在后期看了论文后进行分析和讨论。
任务1:得分函数代码编写
所以再将ReLU后的结果放入下一层中就可以输出我们的得分了。我们直接在这里展示一下我们第一个需要编辑的代码,就是求每个样本在全部类别的得分,我们在编写代码时需要注意一下矩阵维度的对应,

"""
X: (N, D). X[i]就是一个训练样本,共有N个训练样本.
W1:第一层权重;(D, H)
b1: 第一层偏移项;(H,)
W2: 第二层权重;(H, C)
b2: 第二层偏移项;(C,)
"""
layer1 = np.dot(X, W1) + b1  #输出(N,H)
reluLayer = np.maximum(0, layer1) #输出(N,H)
scores = np.dot(reluLayer, W2) + b2 #输出(N,C)

第一个任务就完成了,在作业里有对应的验证程序我们后再后面调用时说明。那么求解完了得分,我们就需要就算损失函数,这里我们仍使用上一节的softmax损失函数,具体函数形式见上一节,可以点击这里进行查看。
任务2:sotfmax损失函数代码编写
损失函数是通过计算得分函数的变形得到,于是代码如下,

scores = scores - np.max(scores, axis=1).reshape(-1,1)
softmaxFucntion = np.exp(scores)/np.sum(np.exp(scores), axis=1).reshape(-1,1)
loss = np.sum(-np.log(softmaxFucntion[range(N), list(y)]))
loss /= N
loss += 0.5*reg*np.sum(W1*W1) + 0.5*reg*np.sum(W2*W2)

这里我们需要注意两点,第一点就是需要对得分函数进行处理,减去其最大值为了使得结果更加稳定;第二个点就是在正则化的时候需要对两个权重都进行正则化,并且各占一半的比例,对于正则化的使用我还不是很熟练后面会集中学习一下再更新。同样针对损失函数也有对应的测试代码,后面再进行展示。
任务3:浅层神经网络梯度代码编写
计算完得分函数、损失函数后就是需要计算梯度来对参数进行更新,这里我们将整个的一个推导过程进行展示,主要使用的是求偏导的链式法则进行倒推。
首先我们计算得分函数的流程为,
l a y e r 1 = X × W 1 + b 1 layer1 = X\times W_1+b_1 layer1=X×W1+b1 r e l u L a y e r = m a x ( 0 , l a y e r 1 ) reluLayer = max(0,layer1) reluLayer=max(0,layer1) s c o r e s = l a y e r 2 = r e l u L a y e r × W 2 + b 2 scores = layer2 = reluLayer\times W_2+b_2 scores=layer2=reluLayer×W2+b2 l o s s = s o f t m a x ( l a y e r 2 ) loss=softmax(layer2) loss=softmax(layer2)
然后我们计算倒推梯度计算

∂ l o s s ∂ W 2 = ∂ l o s s ∂ l a y e r 2 × ∂ l a y e r 2 ∂ W 2 = ∂ l o s s ∂ s c o r e s × ∂ s c o r e s ∂ W 2 = ∂ l o s s ∂ s c o r e s × r e l u L a y e r \frac{\partial loss}{\partial W_2}=\frac{\partial loss}{\partial layer2}\times\frac{\partial layer2}{\partial W_2}=\frac{\partial loss}{\partial scores}\times\frac{\partial scores}{\partial W_2}=\frac{\partial loss}{\partial scores}\times reluLayer W2loss=layer2loss×W2

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值