使用python去建立一个神经网络(上)———建立一个神经网络

才学习python得小白,可能会觉得在搭建神经网络得时候总是结构混乱,逻辑模糊,这是由于对神经网络整体框架不太清楚导致的,本人在读完关于numpy和《利用python进行数据分析》《python神经网络编程》两本书之后对整体框架有了相对清晰得了解,所以写下这篇博客希望与新人们共享经验。

我们先看numpy: numpy是python中一个高性能和数据分析的基础包,我们通常利用python进行数据分析,特别是针对矩阵运算,numpy有着天然的优势,同时对于神经网络而言,矩阵乘法也有着极大的用途,这就很爽了!也就是说我们是要利用numpy就可以完成很多我们神经网络的运算操作,这是我们求之不得的。好,现在让我们看看numpy中我们的语法。
import numpy as np#首先我们导入numpy这个模块

在这个过程中我们需要了解,numpy这个模块有哪些必备的知识:
1.创建数组
numpy创建数组的方法有很多,我们通常可以自定义数组也可以产生随机数组
(1)自定义数组:我们来看看numpy自定义数组的方法:创建数组最简单的方法就是使用array函数。它接收一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组。

import numpy as np
ndarray1 = np.array([1, 2, 3, 4,5])
ndarray2 = np.array(list('abcdefg'))
ndarray3 = np.array([[11, 22, 33, 44], [10, 20, 30, 40]])

同时我们可以用zeros窗前全零的数组,用ones创建全一的数组,例如

import numpy as np
a=np.zeros([3,2])
b=np.zeros(10)
print(a)
print(b)
[[0. 0.]
 [0. 0.]
 [0. 0.]]#数组a,是二维数组,三行二列
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]#一维数组,十个零

同理,我们来看创建全是一的数组,其方法和上面的相似:

import numpy as np
a=np.ones([3,2])
b=np.ones(10)
print(a)
print(b)
[[1. 1.]
 [1. 1.]
 [1. 1.]]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

(2)自定义数组:创建随机数组,在numpy中存在一个random模块,我们导入后便可以创建随机的数组,其中
numpy.random.randn()的作用如下:
numpy.random.randn(d0,d1,…,dn)

(a)randn函数返回一个或一组样本,具有标准正态分布。
(b)dn表格每个维度
(c)返回值为指定维度的array

import numpy as np
from numpy import 
from numpy.random import randn
data={i:randn() for i in range(7)}
data
out:  {0: -0.7635687937925068,
         1: -0.47305154329288407,
         2: 0.9703604436522195,
         3: 0.814558116785201,
         4: 1.0656944233808374,
         5: 0.07017450765689856,
         6: 2.0996644042878345}
import numpy as np
from numpy.random import randn
a=np.random.randn(5,5)
print(a)
[[-0.3051534  -0.83212356 -1.47102693 -0.29302742  0.42960039]
 [-0.30918142 -0.87603184  0.12840026  0.07128007  1.2898251 ]
 [ 2.32484689  0.60113414 -0.15680769  0.63767889  0.58623097]
 [ 0.55382624  1.1510863  -1.54725901 -0.69722859 -0.02111598]
 [-0.09485041  0.2665025   0.44252223 -0.97124039 -0.84064889]]

好,学到这儿,我们numpy的基本知识算是简单看了一遍,后面我们可以遇到问题在解决问题,一下子记住那么多,太费脑容量,接下来我们来看看神经网络的结构吧,let‘s go!

 

 

 

1.限定大局,谋而后动
我们先看看神经网络的结构吧:这儿我放个图

 

 

 

这是一个最简单的神经网络,input layer(又称输入层) 有一层,hidden layer(又称隐藏层)有一层,output layer(又称输出层)有一层,这样我们有了一个最简单的神经网络结构了,我们在这个基础上看看神经网络上面到底有什么?
 

不言而喻,这里面我们直接看到的便是神经网络的框架!!!这是神经网络的支撑,就像人的骨骼,就像大厦的钢筋结构,我们后面所做的一切都是在这个基础上的修修补补。

 

STOP! STOP!STOP!  让我们停一下,好像有点事情没做,那便是一个python的思想:类!!(学过c++和java的朋友们都知道类是一个很偷懒并且高效的做法,python中也有类的概念)我们先看一段代码:

使用python去建立一个神经网络(上)———建立一个神经网络_第1张图片
 

 

这儿是怎么回事?我们用语言来描述下发生了什么:我们创建了一个叫做sizzeles的狗(Dog),狗是一个类,这儿sieezles可以理解成一个对象,它按照狗的类的形象创建,产生之后,它具备了狗的特征,能够叫(woof!)
使用python去建立一个神经网络(上)———建立一个神经网络_第2张图片
咦?奇了怪了?我们又尝试创建了一个狗的新的对象,它同样可以具备叫的能力。
使用python去建立一个神经网络(上)———建立一个神经网络_第3张图片
类相当于模板,给我们省了很大的体力,我们要记住类的思想,它相当于菜谱书中的蛋糕配方,并没有真的实施,而是给了定义,对象则是我们真的开始按照配方开始做蛋糕了。这是为我们写神经网络提供了省时省力的方法。我们可以不会,但要把这种思想理解透彻,后面会有大用处!
我们接着往你后面看:为了完整,我们看看数据如何添加到类中的使用python去建立一个神经网络(上)———建立一个神经网络_第4张图片
我们在这儿定义了三个函数:__init _,status, setTemperature
在这些括号内的额外的项就是我们要初始化的参数。比如__init _中的petname和temp。其中self是动物本身,我们可以忽略这个参数不看。
现在我们来定义一个类,看看结果如何。

lassie=Dog("Lassie",37)
lassie.status()

结果如下:

dog name is Lassie
dog temperature is 37

 
 

 

 

 

在学完对象相关的知识后,我们开始正式写框架啦!是不是有点激动,现在我们要把前面所学的知识用到我们的框架中去!

还记得我说的那句话吗?先定大局,谋而后动。
 

 

 
从我们创造的函数可以知道,我们至少要做三件事:第一,初始化函数,图中存在输入输出还有隐含节点,我们必须了解它的数量。第二,训练,我们要优化权重,这儿用到了BP算法,第三,查询,给定输入,我们要从输出的地方去看看答案。

我们开始,先仿照前面狗的例子,我们写个基本的框架,这就叫大局!

 

 
 

 

代码如下:

class neuralNetwork:
    def __init__():
        pass      #initialise the neural network
    
    def train():
        pass     #train the neural network
    
    def query():
        pass     #query the neural network

 

 

大局已定,细节先行
框架写好了,我们加入输入节点信息,隐含层节点信息,输出节点信息。我们尝试创建每层三个节点,学习率为0.5的小型网络对象。

使用python去建立一个神经网络(上)———建立一个神经网络_第5张图片

好,接下来我们们看神经网络的筋脉,那便是权重!骨骼有了,筋脉便是权重,他与神经网络共存亡,流动在权重连线下的数值便是血液,血液的好坏决定了人的体质,数值的“好坏“决定了结果的好坏!
 
一般权重是随积产生的,我们前面已经学过numpy的基本知识了,现在我们可以采用一种新的方法产生随机数,代码如下:

self.wih=numpy.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes))
self.who=numpy.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes))

这是用来产生正态分布的,中心值设定为0.0,与下一层中节点相关的标准方差的表达式,就是pow(self.hnodes,-0.5),最后一个参数,就是我们希望numpy数组的形状大小。

python中dot可以用来计算矩阵运算,这个前面未曾说,是因为很简单。

hidden_inputs=numpy.dot(self.wih,inputs)

计算结束!!很简单,但是要注意,上面的不是代码而是示例给你看,同时记住*权重在左边,输入在右边,这是矩阵运算的知识
*。

然后我们既可以引入激活函数,signoid函数,在python他隶属于一个scipy函数库,s函数称为expit(),下面的代码没有什么好说的,理解意思,背下来即可。

import scipy.special
self.activation_function=lambda x:scipy.special.expit(x)#lambda 用来使x输入,sigmoid(x)输出

 

 

 

接下来我们看看目前为止所有的代码

import numpy as np
import scipy.special
from numpy import random
class neuralNetwork:
    def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
        self.inodes=inputnodes
        self.hnodes=hiddennodes
        self.onodes=outputnodes
        self.wih=np.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes))
        self.who=np.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes))
        self.lr=learningrate
        self.activation_function=lambda x:scipy.special.expit(x)
        pass      #initialise the neural network
    
    def train():
        pass     #train the neural network
    
    def query(self,inputs_list):
        inputs=np.array(inputs_list,ndmin=2).T#T的意思是转置的意思
        hidden_inputs=np.dot(self.wih,inputs)
        hidden_outputs=self.activation_function(hidden_inputs)
        final_inputs=np.dot(self.who,hidden_outputs)
        final_outputs=self.activation_function(final_inputs)
        return final_outputs
        pass     #query the neural network
input_nodes=3
hidden_nodes=3
output_nodes=3
learning_rate=0.3
n=neuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)

现在我们用query函数来测试下结果
使用python去建立一个神经网络(上)———建立一个神经网络_第6张图片
以上是我们创建神经网络的过程,希望能帮到大家!!如果想看训练部分,我将会在后面附上接下来的训练步骤!!

你可能感兴趣的:(pyrhon)