普通神经网络和RNN简单demo (一)

2017-08-04

花了两天时间看了下神经网络的一点基础知识,包括单层的感知机模型,普通的没有记忆功能的多层神经网咯,还有递归神经网络RNN。这里主要是参考了一个博客,实现了几个简单的代码,这里把源地址给出来,还有几个我觉的不错的神经网络的入门资源:

 

https://iamtrask.github.io/2015/11/15/anyone-can-code-lstm/ 这个是我的代码参考连接

https://github.com/kjw0612/awesome-rnn 这个是github上被人整理的RNN资源汇总,相当的丰富

http://cs231n.stanford.edu/2016/syllabus.html 这是李菲菲教授的课程讲授 CNN,有很多的资料,视频在youtube上有,暂时没有2017的

 

1.简单神经网络实现(没有隐层hidden layer)

 模型: 输出有第一列决定(也可以改为由第二列或者其他的决定,修改相应的y就行)

 1 # -*- coding: utf-8 -*-
 2 
 3 '''
 4 function: 
 5 note: 1.系统只有输入层和输出层,没有隐层;
 6       2.这里神经网络要训练的模型是:有几个输入特征,但是输出只和第二个特征有关(也可以改成之和第一个
 7           有关系试试~);
 8       3.
 9 date: 2017.8.5 
10 '''
11 
12 import numpy as np
13 
14 #sigmoid functoin: map the output to probability
15 def sigmoid(x):
16     output = 1 / (1 + np.exp(-x))
17     return output
18 
19 #derivation of sigmoid function
20 def sigmoid_Derivation(x):
21     output = sigmoid(x) * (1 - sigmoid(x))
22     #output = x * (1-x)
23     return output 
24 
25 # initialize the matrix randomly,syn0 between the input and output layer
26 np.random.seed(1)
27 syn0 = 2*np.random.random((3,1)) - 1 # 3*1 vector 神经网络的核心,连接输入层和输出层,完成反馈
28 
29 x = np.array([[0,0,1],     #x 4*3 matrix 一行代表一次输入数据,所以是三个特征输入
30                 [0,1,1],
31                 [1,0,1],
32                 [1,1,1]])
33 
34 # y = np.array([[0],         # y 4*1 vector 每行代表一次输入的输出
35 #                 [0],
36 #                 [1],
37 #                 [1]])
38 
39 y = np.array([[0,1,0,1]]).T
40 
41 #设置迭代次数#如果是python 2 可以用xrange(100000)
42 for iter in range(1000):
43 
44     #input layer, output layer
45     l0 = x #数组可以直接复制,和list不一样
46     l1 = sigmoid(np.dot(l0,syn0)) #点积 4*1 vector 输出层,用sigmoid函数将y转化为0~1之间,否则可能大于1
47 
48     #calculate the error
49     l1_error = y - l1 # 4*1 vector
50 
51     #reduce the error of high confidence
52     l1_delta = l1_error * sigmoid_Derivation(l1) #接近0或者1的sigmoid导数很小,所以就降低了对应的差错 
53     
54     #update the matrix
55     syn0 += np.dot(l0.T, l1_delta)
56 
57 #print some info
58 print('correct output:')
59 print(y)
60 
61 print('output after training: ')
62 print(l1)
63 
64 print('error: ')
65 print(l1_error)

 

2.有一个隐层的神经网络

 模型:输出由前两个特征决定:

 1 # -*- coding: utf-8 -*-
 2 
 3 '''
 4 note : 1.系统含有一个隐层,采用后向传播训练(应该是的吧..);
 5        2.神经网络训练的模型是:输出 = 前两个特征的和
 6 
 7 date: 2017.8.5
 8 '''
 9 
10 import numpy as np
11 #sigmoid function,map output to (0~1)
12 def sigmoid(x):
13     output = 1 / (1 + np.exp(-x))
14     return output
15 
16 #derivation of sigmoid function
17 def sigmoid_derivation(x):
18     output = sigmoid(x) * (1 - sigmoid(x))
19     return output
20 
21 #input x,
22 x = np.array([[0,0,1],
23                 [0,1,1],
24                 [1,0,1],
25                 [1,1,1]])
26 
27 y = np.array([[0,1,1,0]]).T  #correct output 4*1
28 
29 #initialize the neaurla network matrix syn0,syn1
30 np.random.seed(1)
31 syn0 = 2*np.random.random((3,4))-1 #连接input layer ,hidden layer,输入层三个单元隐层四个单元,所以3*4
32 
33 syn1 = 2*np.random.random((4,1))-1 #连接hidden layer and output layer,隐层四个输出层一个单元
34 
35 #times we train the network
36 for iter in range(60000):
37 
38     #input layer,hidden layer,output layer
39     l0 = x
40     l1 = sigmoid(np.dot(l0,syn0)) #4*4 hidden layer
41     l2 = sigmoid(np.dot(l1,syn1)) #4*1 output layer
42 
43     #how big the error is
44     l2_error = y - l2 #输出层错误 计算错误需要从后向前
45     l2_delta = l2_error * sigmoid_derivation(l2) #减小偏差小的错误,相应参数更新会比较小
46 
47 
48     #l1_error = np.dot(syn1.T,l2_delta) #4*1 隐层的偏差从输出层传递过来
49     l1_error = l2_delta.dot(syn1.T) #4 * 4
50     l1_delta = l1_error * sigmoid_derivation(l1)
51 
52     #update the matrix syn0,syn1
53     syn0 += np.dot(l0.T,l1_delta)
54     syn1 += np.dot(l1.T,l2_delta)
55 
56 #print some info
57 print('output after training')
58 print(l2)
59 
60 print('correct answer')
61 print(y)

 

 

 迭代次数对结果的影响很大,直观的感受就是下面这个图。分别是迭代次数为  1000, 10000, 60000

刚刚开始i还以为哪里的参数有问题,改了迭代次数明显就效果更好了,也就是对结果的预测更加准确了。

 

3.RNN(隐层的数据来源包括上个时间戳的隐层和当前的输入)

注意:

1).这里和前面有一个隐层的区别在于,这里隐层的输出不仅是input layer,还有上一个时间戳的隐层输出,也是作为这个隐层的输入。

2).这里说的上个时间戳隐层的输出layer_1作为这个时刻隐层的输入,不是指output layer 的输出,因为layer_1 =sigmoid( np.dot(layer_0,syn0) + np.dot(layer_1_values[-1], syn_h))

但是 output layer 的输出为: 

layer_2 = sigmoid(np.dot(layer_1, syn1))所以不能混淆;

3)这里采用模型是计算二进制加法 a + b = c;训练模型,让它找到这个加法的规律,从而给定两个数就可以计算二进制的和。

因为RNN是对时间序列有一定的记忆能力,所以在不同次的训练的时候,就是不同的时间戳。

这里截图表示是否把上个时间戳的隐层输出作为此刻隐层输入的区别:

 

从图中可以看出,如果仅仅考虑输入层作为当前隐层输入,那么前面的信息就全部丢失了,考虑到以前的信息可能对以后的决策有帮助,采用RNN是一个比较好的策略。

 

代码下次补上

posted on 2017-08-05 16:39  洛珈山下  阅读(1071)  评论(0编辑  收藏  举报

导航