深度学习:不调TensorFlow,自己写神经网络学习MNIST数据集(1)—基础版(正确率96%~97%)

本篇文章是基础版,而实际上对于MNIST数据集的利用程度还没达到极限,对该模型还可进一步探究(反向查询),有兴趣可以看我另一篇文章

https://blog.csdn.net/CxsGhost/article/details/104829332
——————————————————————————————————————————————————

1. MNIST介绍:


2. 搭建前馈神经网络(全连接):

主要思路:

  • 784个输入层节点,500个隐藏层节点(可以按照自己的意愿设置,500个时我得到的准确率最高)
  • 10个输出层节点:比如对于数字2的一条训练数据,我们可以把target转化成
    2: [0.0, 0.0, 0.99, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    这样做的意思就是,指导神经网络在第2个输出节点输出尽可能大的数字,因为sigmoid函数不能输出1,所以就0.99
    所以最终输出的10个数据中,最大数所在的位置,就是神经网络给出的判断

(1)需要具备的属性:

  • 输入节点数量,隐藏节点数量,输出节点数量。(隐藏层只一层就可以
  • 学习率
  • 节点上采用的激活函数(这里我选择sigmoid)
  • 输入层和隐藏层间的权重矩阵,隐藏层和输出层之间的权重矩阵

用numpy中normal函数从正态分布中选取初始权重

  • 均值:0.0

  • 标准差:前一层的节点数量平方根的倒数(比较科学的选法,自行百度详解)

  • 矩阵大小:
    输入层与隐藏层(self.wih):输入层节点数为列数,隐藏层节点数为行数
    隐藏层与输出层(self.who):隐藏层节点数为列数,输出层节点数为行数

    计算方法如下图(以一个输入中有两个数据为例), W1,1代表第一个节点与下一层的第一个节点间的权重链接
    在这里插入图片描述

class NeuralNetwork:

    def __init__(self, inputnodes, outputnodes,
                 hiddennodes, learningrate):
        # 设置节点数量属性
        self.innodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes

        self.lr = learningrate

        # 按照正态分布设置初始权重矩阵
        self.wih = np.random.normal(loc=0.0,
                                    scale=1 / np.sqrt(self.innodes),
                                    size=(self.hnodes, self.innodes))
        self.who = np.random.normal(loc=0.0,
                                    scale=1 / np.sqrt(self.hnodes),
                                    size=(self.onodes, self.hnodes))

        # 这里scipy.special.expit(),是sigmoid函数,用于正向激活
        self.activation_function = lambda x: scipy.special.expit(x)

——————————————————————————————————————————————————

(2)接收数据,更新权重

  • 主要方法:梯度下降
  • 损失函数:平方损失函数

先把输入数据由行向量转置为列向量,同时把target也转置为列,因为最终输出的是列向量
然后计算输出,结合target更新权重,下面的代码也有注释。
数据是采用一条一条输入进行训练的,矩阵运算的速度非常快

权重更新:

以更新隐藏层和输出层之间的某个权重为例,损失函数是:
在这里插入图片描述
对某一个权重求偏导后(把2省略了):
在这里插入图片描述
红色的output是这个权重连接的隐藏层的节点的输出,不是输出节点的输出(上面的式子可以自己推一下)

根据以上公式更新权重即可,代码如下:

    def train(self, input_list_1, target_list):
        # 转置输入数据,以及目标数据
        input_1 = np.array(input_list_1, ndmin=2)
        input_1 = np.transpose(input_1, axes=(1, 0)
  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值