【深度学习】Numpy实现简单神经网络

原文地址:点击访问

许久未更,是因为开学之后学习任务太充实了。每天都有做不完的事情,每件事情都又想把它做好。

我航中秋国庆假期长达8天,真应了那句话:该放的假一天不少,该补的课一次没有。期间,有多门作业要完成。今天,为大家推送简单神经网络的实现,是我的《人工智能加速器》的作业。

实验内容

搭建基本的多层神经网络,并在给定测试集上进行精度测试。

  • 注1:不使用深度学习框架完成网络搭建。

  • 注2:不限制编程语言,推荐使用python进行神经网络搭建,允许使用numpy等工具包。

  • 注3:使用给定的训练集和测试集,可使用提供的代码模板(bp_template.py)并在其基础上进行修改,也可以重新进行编写。

实验要求

  • 网络输入:784 个输入节点(每个节点对应图片的一个像素)
  • 网络输出:10 个输出节点(分别代表0~9 这10 个数字)
  • 网络深度建议为3 至5 层即可,如果太深则需要太长运行时间。
  • 使用给定训练集(mnist_train.csv)进行权重训练,使用测试集(mnist_test.csv)测试并给出测试精度。(不对精度做特别的要求,只需在合理范围内即可)

网络架构

本文参考tutorial学习了后向传播的原理, 参考tutorial学习了后向传播的设计, 从而设计出了两个隐含层的简单神经网络. 具体网络架构见图1所示.

主要代码实现

完整代码点击阅读原文跳转到我的Github,后向与前向传播代码如下:

# neural network class definition
class neuralNetwork:
    param = {}

    # initialise the neural network
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        '''
        The network consists of three types of layers: input layer(784 nodes), hidden layers and output layer(10 nodes).
        You can define the number of hidden nodes and layers you want.
        '''

        self.hiddennodes_1 = hiddennodes[0]
        self.hiddennodes_2 = hiddennodes[1]

        self.param['W1'] = np.random.randn(hiddennodes[0], inputnodes) * np.sqrt(1 / hiddennodes[0])
        self.param['b1'] = np.random.randn(hiddennodes[0], 1) * np.sqrt(1 / hiddennodes[0])
        self.param['W2'] = np.random.randn(hiddennodes[1], hiddennodes[0]) * np.sqrt(1 / outputnodes)
        self.param['b2'] = np.random.randn(hiddennodes[1], 1) * np.sqrt(1 / hiddennodes[1])
        self.param['W3'] = np.random.randn(outputnodes, hiddennodes[1]) * np.sqrt(1 / outputnodes)
        self.param['b3'] = np.random.randn(outputnodes, 1) * np.sqrt(1 / outputnodes)

        self.learningrate = learningrate
        self.inputnodes = inputnodes
        self.hiddennodes = hiddennodes
        self.outputnodes = outputnodes

    def forward(self, inputs_list):
        '''
        forward the neural network
        '''

        inputs_list = inputs_list.reshape(-1, 1)
        self.inputs_list = inputs_list

        z1 = np.dot(self.param['W1'], inputs_list) + self.param['b1']
        h1 = sigmoid(z1)

        z2 = np.dot(self.param['W2'], h1) + self.param['b2']
        h2 = sigmoid(z2)

        z3 = np.dot(self.param['W3'], h2) + self.param['b3']
        h3 = sigmoid(z3)

        self.final_outputs = h3
        self.z1 = z1
        self.h1 = h1
        self.z2 = z2
        self.h2 = h2
        self.z3 = z3
        self.h3 = h3

    def Backpropagation(self, targets_list):
        '''
        propagate backword
        '''
        change = {}

        targets_list = targets_list.reshape(-1, 1)
        loss_val = mse_loss(targets_list, self.final_outputs)

        # calculate W3 update
        error = -2 * (targets_list - self.final_outputs)
        error = np.multiply(error, sigmoid(self.z3, derivative=True))
        change['W3'] = np.dot(error, self.h2.T)
        change['b3'] = error

        # calculate W2 update
        error = np.multiply(np.dot(self.param['W3'].T, error), sigmoid(self.z2, derivative=True))
        change['W2'] = np.dot(error, self.h1.T)
        change['b2'] = error

        # calculate W1 update
        error = np.multiply(np.dot(self.param['W2'].T, error), sigmoid(self.z1, derivative=True))
        change['W1'] = np.dot(error, self.inputs_list.T)
        change['b1'] = error

        self.param['W1'] -= self.learningrate * change['W1']
        self.param['b1'] -= self.learningrate * change['b1']
        self.param['W2'] -= self.learningrate * change['W2']
        self.param['b2'] -= self.learningrate * change['b2']
        self.param['W3'] -= self.learningrate * change['W3']
        self.param['b3'] -= self.learningrate * change['b3']

        return loss_val

精度与损失

本实验中, 训练了20代, 共耗时3590.8710s. 在训练集上的损失和验证精度如下图, 可以看到, 随着训练代数增多, l o s s loss loss值逐渐减低, 精度逐渐升高, 最高可以达到100%.

最终, 在测试集上的精度达到了98%. 图3展示了测试集中前10个测试样本的预测结果, 期预测结果与其真实标签基本吻合. 但是, 对于图3(i)这样人为都难以辨别出来的测试样本, 神经网络就更加难以预测准确. 现实中, 这种脏数据往往是无意义的.

训练时间

整个实验运行时间如下表所示, 其中训练时间最长, 平均每一代的训练时间为179.5436s, 相当耗时.

图4显示了各个时间的占比, 平均每代训练时间占比高达93.6%.

实验环境

本文使用Python 3.6, 在配置为Intel® Xeon® Gold 5120T CPU @2.20GHz 2.19 GHz (2 processors)的PC机上进行实验,

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值