实现神经网络模型的前向传播、反向传播和训练

标题第1关:实现神经网络模型的前向传播

任务描述
本关任务:实现神经网络模型的前向传播。

相关知识
为了完成本关任务,你需要掌握:

神经网络前向传播的原理;
计算图;
神经网络前向传播的实现。
本实训内容可参考《深度学习入门——基于 Python 的理论与实现》一书中第 5.1 章节的内容。

神经网络的前向传播
在之前的实训中,我们简单学习了神经网络的前向传播。神经网络网络是由多个神经网络层堆叠而成的模型。神经网络的前向传播就是按照神经网络层的堆叠顺序,将前驱网络层的输出作为后继网络层的输入,通过网络层的运算规则计算对应的输出。在之前实训中,我们曾以一个简单的三层神经网络为例,这里我们简单做一个回顾。

图1
图1 简单三层神经网络
假设这个神经网络的三层分别为f
1

(x;W
1

), f
2

(x;W
2

), f
3

(x;W
3

),每层之后的激活函数为g
1

(x), g
2

(x), g
3

(x)。网络训练使用的损失函数为L(x,t),其中x表示网络的输出,t表示目标。那么这个网络的计算过程可以表示为:

y
1

z
1

y
2

z
2

y
3

z
3

=f
1

(x;W
1

)
=g
1

(y
1

)
=f
2

(z
1

;W
2

)
=g
2

(y
2

)
=f
3

(z
2

;W
3

)
=g
3

(y
3

)

这里z
3

就是神经网络模型的输出。结合损失函数,可以得到网络模型的损失值:

l=L(z
3

,t)

计算图
这里我们希望进一步引入计算图的概念。到目前为止,我们一直讲神经网络是网络层的堆叠。但是,这里希望强调的是,这种堆叠结构并不一定是线性堆叠的结构,对于一些复杂的神经网络模型,通常有多个输入和多个输出,网络模型的中间结果也会互相调用。但是,网络层的计算一定是有序的,不能有环状依赖的存在。这样,就形成了一个 DAG(有向无环图)的结构。这样的图结构就叫做神经网络的计算图。

计算图中的节点包含两种,一种是数据节点,一种是计算节点。顾名思义,数据节点的作用是存储数据,网络的输入、网络层的参数、网络层的中间计算结果、网络层的计算结果等都存储在数据节点中。而计算节点,就是把若干个数据节点作为输入,进行某种运算,再将结果输出到另一个数据节点中。也就是说,数据节点和计算节点是间隔分布的。在构造计算节点时,通常会使用一些非常基础的计算作为一个节点,如矩阵乘法、加法、卷积等,例如全连接层会被拆分成矩阵乘法和加法两个操作。下图展示了一个使用 sigmoid 激活函数的全连接层对应的计算图。

图1
图2 使用sigmoid激活函数的全连接层对应的计算图
神经网络前向传播的实现
在本实训中,基于之前我们一步一步实现的网络层,需要你自己定义一个小型的卷积神经网络,并实现其前向传播。这里要求实现一个名为 TinyNet 的小型卷积神经网络模型。TinyNet 包含 7 层,输入是一个形状为(B,3,8,8)的numpy.array;第一层是一个输出通道为 6、卷积核大小为 3、步长为 1、填充为 1 的卷积层;第二层是 ReLU 激活;第三层是一个池化核大小为 2、步长为 2、填充为 0 的最大值池化层,该池化层将特征图大小变为4×4;第四层是一个输出通道为 12、卷积核大小为 3、步长为 1、填充为 1 的卷积层;第五层是 ReLU 激活;第六层是一个池化核大小为 2、步长为 1、填充为 0 的最大值池化层,该池化层将特征图大小变为2×2;第 7 层是一个全连接层,有 10 个输出神经元。最后,网络使用SoftmaxWithLoss作为损失函数。整个网络的结构如下表所示:

序号 类型 参数 输出特征图大小
0 输入 (B, 3, 8, 8) -
1 卷积层 输出通道6,卷积核大小3x3,步长1,填充0 (B, 6, 8, 8)
2 激活函数 ReLU (B, 6, 8, 8)
3 池化层 池化窗口2x2,步长2,填充0 (B, 6, 4, 4)
4 卷积层 输出通道12,卷积核大小3x3,步长1,填充0 (B, 12, 4, 4)
5 激活函数 ReLU (B, 12, 4, 4)
6 池化层 池化窗口2x2,步长2,填充0 (B, 12, 2, 2)
7 全连接层 输出神经元10 (B, 10)
8 损失函数 SoftmaxWithLoss -
实训已经预先定义了一个TinyNet类。该类的构造函数接受 6 个参数:W_conv1和b_conv1对应第一个卷积层的权重和偏置,W_conv2和b_conv2对应第二个卷积层的权重和偏置,W_fc和b_fc对应全连接层的权重和偏置。你需要在该类的构造函数中,定义网络中的各个层。实训已经提供了各个网络层的定义与实现,与之前实训中的定义完全相同,你可以直接使用。之后,你需要在前向传播函数forward(x, t)中实现TinyNet的前向传播,并返回全连接层的输出以及 loss 函数的值(按照此顺序)。

编程要求
根据提示,在右侧编辑器中 Begin 和 End 之间补充代码,实现上述 TinyNet 的定义和前向传播。

测试说明
平台会对你编写的代码进行测试,测试方法为:
平台会随机产生输入x、目标t以及三组权重和偏置,然后根据你的实现代码,创建一个TinyNet类的实例,然后利用该实例进行前向传播计算。你的答案将与标准答案进行比较。因为浮点数的计算可能会有误差,因此只要你的答案与标准答案之间的误差不超过 1e-5 即可。

开始你的任务吧,祝你成功!

import numpy
from layers import Convolution, Relu, FullyConnected, MaxPool, SoftmaxWithLoss

class TinyNet:
    def __init__(self, W_conv1, b_conv1, W_conv2, b_conv2, W_fc, b_fc):
        ########## Begin ##########
        self.conv1 = Convolution(W_conv1, b_conv1, stride=1, pad=1)  
        self.relu1 = Relu()  
        self.pool1 = MaxPool(2, 2, stride=2, pad=0)  
        self.conv2 = Convolution(W_conv2, b_conv2, stride=1, pad=1)  
        self.relu2 = Relu()  
        self.pool2 = MaxPool(2, 2, stride=2, pad=0)  
        self.fc = FullyConnected(W_fc, b_fc)  
        self
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值