接 神经网络笔记Ⅰ
从CNN到RNN再到LSTM,深入了解三种神经网络。其中,CNN主要用于图像识别与处理,RNN处理具有动态时序行为的任务,而LSTM则在此基础上添加了记忆单元,更适合处理时间序列中间隔和延迟非常长的事件。仅靠前向传播已不满足要求,反向传播也变得重要。
CNN(卷积神经网络)
零基础入门深度学习(4)
- 卷积神经网络
CNN(Convolutional Neural
Netword,卷积神经网络)是一种前馈神经网络,人工神经元可以响应周围单元,可以大型图像处理。卷积神经网络包括卷积层和池化层。
基础结构
特征提取层,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征。一旦该局部特征被提取后,它与其他特征间的位置关系也随之确定下来
特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有的神经元的权值相等。采用影响函数较小的\(sigmoid\) 函数作为卷积网络的激活函数,使得特征映射具有位移不变性
CNN主要用来识别位移、缩放以及其他形式扭曲不变性的二维图形。由于CNN的特征检测层通过训练数据进行学习,所以在使用CNN时,避免了显示的特征抽取,从而隐式地从训练数据中进行学习。由于同一特征映射面上的神经元权值相同,所以网络可以并行学习。
对于图像识别任务
全连接网络
参数数量过多
像素间的位置信息
网络层数限制
解决方案:
局部连接——不是全连接,减少参数数量
权值共享——一组连接可以共享共一个权重,再一次减少参数数量
下采样——使用池化(Pooling)来减少每层的样本数,进一步减少参数数量,提供鲁棒性
P.S.
鲁棒是Robust的音译,也就是健壮和强壮的意思。它是在异常和危险情况下系统生存的关键。比如说,计算机软件在输入错误、磁盘故障、网络过载或有意攻击情况下,能否不死机、不崩溃,就是该软件的鲁棒性。所谓“鲁棒性”,是指控制系统在一定(结构,大小)的参数摄动下,维持其它某些性能的特性。根据对性能的不同定义,可分为稳定鲁棒性和性能鲁棒性。以闭环系统的鲁棒性作为目标设计得到的固定控制器称为鲁棒控制器。
卷积神经网络:卷积层、Pooling层(池化层)、全连接层
INPUT -> [[CONV]*N -> POOL]*M -> [FC]*K
N个卷积层叠加再加上一个池化层,重复M次,加上K个全连接层。
概念介绍和计算方式请看下面这篇博客
【深度学习系列】卷积神经网络CNN原理详解(一)——基本原理
总结:
池化方式:
MaxPooling:取滑动窗口里最大的值
AveragePooling:取滑动窗口内所有值的平均值
StochasticPooling,介于两者之间,通过对像素点按照数值大小赋予概率,再按照概率进行亚采样;
Zero Padding(补零):保留原始图片的尺寸
卷积
对于一个\(l_1*l_2\) 的图像,使用\(f_1*f_2\) 的filter进行卷积(后者小于前者),得到一个\(f_3*f_4\) 的feature map。
\[
a_{ij}=f(\sum\limits_{m=0}^{f_1-1}\sum\limits_{n=0}^{f_2-1}w_{mn}x_{(m+i)(n+j)}+w_b)
\]
\(a_{ij}\) 表示的是feature
map的元素,\(w_{mn}\) 表示对应元素,\(f\) 函数表示激活函数,\(x_{(m+i)(n+j)}\) 表示图像的元素,\(w_b\) 表示偏置项,这里从0开始计数,所以需要-1。
这里简单起见,步幅设置为1。
图像大小、步幅和卷积后的Feature Map大小是有关系的。
\(W_2=(W_1-F+2P)/S+1\)
\(H_2=(H_1-F+2P)/S+1\)
\(W_2\) 是卷积后Feature
Map的宽度;\(W_1\) 是卷积前图像的宽度;\(F\) 是filter的宽度;\(P\) 是Zero
Padding 数量,Zero
Padding 是指在原始图像周围补几圈0,如果的值是1,那么就补1圈0;\(S\) 是步幅 ;\(H_2\) 是卷积后Feature Map的高度;\(H_1\) 是卷积前图像的宽度。
二维卷积公式,已知矩阵\(A\) 、\(B\) ,行列数分别用\(m\) 和\(n\) 表示。卷积公式如下
\(C_{st}=\sum\limits_0^{m_A-1}\sum\limits_0^{n_A-1}A_{mn}B_{(s-m)(t-n)}\)
\(0\le s<m_A+m_B-1\)
\(0\le t<n_A+n_B-1\)
也可以写成\(C=A*B\)
数学中的卷积与卷积神经网络中的卷积是一定区别的。可以把神经网络中的卷积称为互相关(cross-correlation) 。这两种操作转换方式,可以通过把矩阵\(A\) 翻转180度,再交换\(A\) 、\(B\) 运算位置,即可以将卷积变为互相关。
RNN(循环神经网络)
RNN(Recurrent neural
Network,循环神经网络/多层反馈网络)是一种节点定向连接成环的人工神经网络。这种网络的内部状态可以展示动态时序行为。不同于前馈神经网络的是,RNN可以利用它内部的记忆来处理任意时序的输入序列,这让它可以更容易处理,如不分段的手写识别、语音识别等。
RNN网络的本质特征是处理单元之间既有内部的反馈连接又有前馈连接。从系统的观点看,它是一个反馈动力系统,在计算过程中体现过程动态特性,比前馈神经网络具有更强的动态行为和计算能力。
参考文章
Talk is cheap. Show me
the code .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 import numpy as npimport copydef sigmoid (x, deriv=False ): if (deriv == True ): return x * (1 - x) return 1 / (1 + np.exp(-x)) int2binary = {} binary_dim = 8 larget_number = 2 ** binary_dim binary = np.unpackbits( np.array([range (larget_number)], dtype=np.uint8).T, axis=1 ) for i in range (larget_number): int2binary[i] = binary[i] alpha = 0.1 input_dim = 2 hidden_dim = 16 output_dim = 1 syn_0 = 2 * np.random.random((input_dim, hidden_dim)) - 1 syn_1 = 2 * np.random.random((hidden_dim, output_dim)) - 1 syn_h = 2 * np.random.random((hidden_dim, hidden_dim)) - 1 syn_0_update = np.zeros_like(syn_0) syn_1_update = np.zeros_like(syn_1) syn_h_update = np.zeros_like(syn_h) for _ in range (10000 ): a_int = np.random.randint(larget_number / 2 ) a = int2binary[a_int] b_int = np.random.randint(larget_number / 2 ) b = int2binary[b_int] c_int = a_int + b_int c = int2binary[c_int] d = np.zeros_like(c) overallError = 0 layer_2_deltas = [] layer_1_values = [] layer_1_values.append(np.zeros(hidden_dim)) for position in range (binary_dim): X = np.array( [[a[binary_dim - position - 1 ], b[binary_dim - position - 1 ]]]) y = np.array([[c[binary_dim - position - 1 ]]]).T layer_1 = sigmoid(np.dot(X, syn_0) + np.dot(layer_1_values[-1 ], syn_h)) layer_2 = sigmoid(np.dot(layer_1, syn_1)) layer_2_error = y - layer_2 layer_2_deltas.append(layer_2_error * sigmoid(layer_2, deriv=True )) overallError += np.abs (layer_2_error[0 ]) d[binary_dim - position - 1 ] = np.round (layer_2[0 ][0 ]) layer_1_values.append(layer_1.copy()) futuer_layer_1_delta = np.zeros(hidden_dim) for position in range (binary_dim): X = np.array([[a[position], b[position]]]) layer_1 = layer_1_values[-position - 1 ] prev_layer_1 = layer_1_values[-position - 2 ] layer_2_delta = layer_2_deltas[-position - 1 ] layer_1_delta = (np.dot(futuer_layer_1_delta, syn_h.T) + layer_2_delta.dot(syn_1.T)) * sigmoid(layer_1, deriv=True ) syn_1_update += np.atleast_2d(layer_1).T.dot(layer_2_delta) syn_h_update += np.atleast_2d(prev_layer_1).T.dot(layer_1_delta) syn_0_update += X.T.dot(layer_1_delta) futuer_layer_1_delta = layer_1_delta syn_0 += syn_0_update * alpha syn_1 += syn_1_update * alpha syn_h += syn_h_update * alpha syn_0_update *= 0 syn_1_update *= 0 syn_h_update *= 0 if (_ % 1000 == 0 ): print ("Error: " + str (overallError)) print ("Pred: " + str (d)) print ("True: " + str (c)) out = 0 for index, x in enumerate (reversed (d)): out += x * (2 **index) print (str (a_int) + " + " + str (b_int) + "=" + str (out)) print ("-------------" )
将前向传播比喻为字母表顺序读出,反向传播就是字母表反序读出。
LSTM(时间递归神经网络)
长短期记忆(英语:Long Short-Term
Memory,LSTM)是一种时间递归神经网络(RNN),论文首次发表于1997年。由于独特的设计结构,LSTM适合于处理和预测时间序列中间隔和延迟非常长的重要事件。
LSTM的表现通常比时间递归神经网络及隐马尔科夫模型(HMM)更好,比如用在不分段连续手写识别上。作为非线性模型,LSTM可作为复杂的非线性单元用于构造更大型深度神经网络。