专栏首页AI派TensorFlow什么的都弱爆了,强者只用Numpy搭建神经网络

TensorFlow什么的都弱爆了,强者只用Numpy搭建神经网络

大数据文摘出品

作者:蒋宝尚

很多同学入门机器学习之后,直接用TensorFlow调包实现神经网络,对于神经网络内在机理知之甚少。

编程语言与技术框架变化更新非常之快,理解背后的原理才是王道。下面文摘菌和大家一起用Numpy实现一步一步实现神经网络。

此篇文章旨在帮大家梳理神经网络知识点,且此篇文章是第一部分,只是简单搭一个简单的框架。暂时不涉及梯度下降、学习率调参等知识点。

最简单的神经网络包含三个要素,输入层,隐藏层以及输出层。关于其工作机理其完全可以类比成一个元函数:Y=W*X+b。

一个简单的神经网络可以理解为两次一元函数的输入和输出。

第一次:Y1=A1(W1*X+b1) ,其中X是原始数据的输入,A1代表激活函数。

第二次:Y2=A2(W2*Y1+b2),其中Y1是第一次的输出,A2是激活函数。参数W1、W2、b1、b2原则上各不相同。

本篇文章我们用到的激活函数有两个,一个是tan(x),另一个是softmax。两者的函数曲线如下。

两个函数都有相同的特点,即函数值在零点左右变化较大,当输入值远离零点,其输出较稳定。

首先导入相关的库,需要两个库,一个用于科学计算的Numpy,另一个是math。

import numpy as npimport math

然后定义激活函数,

def tanh(x):    return np.tanh(x)
def softmax(x):   exp=np.exp(x-x.max())   return exp/exp.sum()

这两个激活函数,其中tanh函数,Numpy直接内嵌。softmax根据数学定义进行设置。第二个激活函数因为是指数函数,其值会变化较大,所以我们用x-x.max 缩小其变化范围,这对结果不影响。

我们使用的图片大小是 28*28像素。以后会用手写数字数据集训练网络,所以会有10个数字输入,分别是[1,2,3,4,5,6,7,8,9,10]。所以要先定义三个列表。

dinensions=[28*28,10]
activation=[tanh,softmax]
distribution=[{'b':[0,0]},             {'b':[0,0],'w':[-math.sqrt(6/(dinensions[0]+dinensions[1])),math.sqrt(6/(dinensions[0]+dinensions[1]))]}]

dinensions列表里面包含两个数,第一个是图片的像素大小,第二个是数字的输入变化量。

activation列表包含两个激活函数,分别为tanh,softmax。

distribution 列表里面对应的是字典格式的数据,分别对应神经网络参数取值范围。

其中第一层不包含参数W。

def init_parameters_b(layer):   dist=distribution[layer]['b']   return np.random.rand(dinensions[layer])*(dist[1]-dist[0])+dist[0]  #使得生成的随机数在 b 的区间内
def init_parameters_w(layer):   dist=distribution[layer]['w']   return np.random.rand(dinensions[layer-1],dinensions[layer])*(dist[1]-dist[0])+dist[0]  #使得生成的随机数在 b 的区间内

上面代码是对b和w这两个参数初始化,因为我们输入的是28*28个数字,输出的是10个数字。所以第一层的 b 也有28*28个数字组成。根据矩阵的乘法规则,第二层的时候,w的维度只有是28*28行,10列才能满足输出的10个数字。因此第二层的b是10个数字。

dinensions[X] 意思是取切片,dinensions[1] 取得是10,dinensions[0],取得是28*28。

又因为np.random.rand()这一函数输出值的范围在[0,1],括号里面的参数(即dinensions[layer]只是确保输出的数字个数满足要求),所以为了让输出的值在一开始设置的 b 的区间内,我们设置先乘(dist[1]-dist[0])然后加上dist[0]。dist[1]和dist[0]分别对应参数的上下限。

def init_parameters():   parameters=[]   for i in range(len(distribution)):       layer_parameters={}       for j in distribution[i].keys():           if j=='b':               layer_parameters['b']=init_parameters_b(i)               continue           if j=='w':               layer_parameters['w']=init_parameters_w(i)               continue       parameters.append(layer_parameters)   return parameters

上面代码是将三个参数的初始化集成达到一个函数里面。

先定义一个空列表(不要写错成空字典)是为了将三个参数统一输出。

注:字典类型不能用append,列表可以用,列表.append(字典) 也是可以的。

然后从零开始遍历distribution。用if循环语句,目的是把参数全部包含进来。

第二层for循环和if语句是判断,并正确添加参数。

parameters=init_parameters()   #将参数赋值给新的变量。def predict(img,parameters):    I0_in=img+parameters[0]['b']    I0_out=activation[0](I0_in)    I1_in=np.dot(I0_out,parameters[1]['w']+parameters[1]['b'])    I1_out=activation[1](I1_in)    return I1_out

定义输出函数,思路是这样的:输入数据后,根据函数:y=wx+b,进行变换,第一层w全为1。然后经过激活函数(第一个激活函数是tanh,所以用activation[0]),得出第一层的输入I0_out。 然后进入第二层,第一层的输出作为输入,根据函数:y=wx+b,进行变换,第二层的w为parameters[1]['w'],第二层的b为parameters[1]['b']。然后再经过激活函数softmax,得到输出。

predict(np.random.rand(784),parameters).argmax()

最后,随便输入一个784维数据(像素),都可以输出一个图片标签。

预测图片中的数字

好了,我们第一个简单的神经网络就搭建好了,关于如何使用梯度下降和学习率,如何训练网络以及如何加载图片数据,我们在以后的文章中会介绍。

注:此篇文章受B站up主大野喵渣的启发,并参考了其代码,感兴趣的同学可以去B站观看他关于神经网络的教学视频。

视频地址:

https://www.bilibili.com/video/av51197008

本文分享自微信公众号 - AI派(naodong-open)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 今天免的高速费,以后都会让你交回来

    遵循往年惯例,今年国庆黄金周期间,收费公路对小型客车免费。政策利好刺激下,车流、人流井喷式暴增,高速拥堵与景区爆棚已经可以预见。

    abs_zero
  • 划重点! TensorFlow 2.0 中的符号和命令式 API

    文 / Josh Gordon, Google Developer Advocate

    abs_zero
  • 面对来势汹汹的AI大潮,你该如何应对?

    2018年1月 教育部印发的《普通高中课程方案和语文等学科课程标准》新加入了数据结构、人工智能、开源硬件设计等 AI 相关的课程。

    abs_zero
  • TensorFlow什么的都弱爆了,强者只用Numpy搭建神经网络

    很多同学入门机器学习之后,直接用TensorFlow调包实现神经网络,对于神经网络内在机理知之甚少。

    大数据文摘
  • Go by Example 中文版: 互斥锁

    在前面的例子中,我们看到了如何使用原子操作来管理简单的计数器。 对于更加复杂的情况,我们可以使用一个互斥锁 来在 Go 协程间安全的访问数据。 示例代码如下:

    ccf19881030
  • PyTorch 中Datasets And DataLoaders的使用 | PyTorch系列(十二)

    在这篇文章中,我们将看到如何使用Dataset和DataLoader 的PyTorch类。

    AI算法与图像处理
  • LeetCode: 107_Binary Tree Level Order Traversal II | 二叉树自底向上的层次遍历 | Easy

    本题和上题一样同属于层次遍历,不同的是本题从底层往上遍历,如下: ? ? 代码如下: 1 struct TreeNode { 2 int ...

    CloudDeveloper
  • 后渗透阶段开始

    在后渗透测试阶段我们主要的目标就是上传工具,权限提升,擦除攻击痕迹,安装持久化后门

    意大利的猫
  • 【漏洞通告更新】WebSphere远程代码执行漏洞(CVE-2020-4450、CVE-2020-4449)

    北京时间2020年6月5日,IBM官方发布通告修复了WebSphere Application Server(WAS)中的一个高危远程代码执行漏洞和一个信息泄露...

    绿盟科技安全情报
  • Typecho 支持异步回调版的评论邮件插件 Mailer

    Typecho 的评论邮件通知是个比较麻烦的问题, Handsome 主题使用文档里推荐的是 CommentToMail 插件不知道为啥在明月自己的阿里云ECS...

    明月登楼

扫码关注云+社区

领取腾讯云代金券