-
Notifications
You must be signed in to change notification settings - Fork 3
/
深度学习笔记.py
214 lines (179 loc) · 17.2 KB
/
深度学习笔记.py
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# deeplearning
=============================================================================================================
# 1.在卷积神经网络中,经过卷积层或池化层后还剩多少像素:
这里不考虑边缘填充的问题,只讲方法帮助理解以便笔试中快速计算。
【图片尺寸-卷积核尺寸(或者池化尺寸)】/步长+1=卷积或者池化
后的尺寸....最后加1是因为比如1,2有两个数,2-1+1=2。。。
例如:图片尺寸100*100,卷积核尺寸5*5,【按照卷积核窗口的最后一个像素为标准移动,一直
移动到图片的最后一个像素】
【步长为1时】,经过卷积层后的像素大小计算过程为,由于卷积核为5*5,那么图片的
前5*5个像素是第1个点,然后向右移动一步则第2个到第6个像素的5*5个像素变成第2个点,
以此类推,从第5个像素移动到第100个像素共有100-5+1=96个,即卷积层后图片变为了96*96,这是步长为1的情况。
【步长为2时】:是第5,7,9,11,...,99。总共移动了(99-5)/2+1=48次,即图片由100*100变为了48*48了。
这里没考虑第100个像素,因为步长为2,最后只剩一列了,组合不了5*5,只有4*5.填充什么的我不考虑。
【步长为3时】,按照上面的方法就行了。5,8,11,...,98。。。核窗口的最后一个像素总共移
动了(98-5)/3+1=32次,卷积或者池化后的尺寸为32*32
对于书中讲的【池化层】,比如2*2的池化窗口并没有重叠的,那是因为池化的步长为2.
如果池化窗口为3*3,步长为3,那也是没有重叠的.
==============================================================================================================
# 2.关于权重初始化是否可为0的问题
【1.神经网络】:隐藏层的每个神经元分别学习到不同的特征,如果权重全部初始化为0,那么各层的每个神经元在做相同
的运算,其激活值都一样,即都学习相同的特征,就相当于每层神经元都只有一个神经元,因此神经网络不能权重初始化为0.
【2.单层感知机】只有一个神经元,他的权重可初始化为0。感知机是误分类驱动。吴恩达根本不讲感知机。所以咱们先不管感
知机,值学习logistic回归就行了。
【3.线性回归模型】相当于单层感知机,其权重也可以初始化为0
【4.logistic回归】其结构相当于感知机,就是单层神经网络,只有一个神经元,权重可初始化为0。
【5.初始化】神经网络权重不能初始化为0,偏置可以初始化为0,因为权重更新只和成本函数对权重的偏导有关,和偏置无关
只需要记住,对神经网络初始化权重选择随机数(np.random.randn((_,_))*0.01),偏置初始化为0就行了。
我们通常喜欢把权重矩阵初始化成很小很小的随机值,因为如果你用的是tanh或者sigmoid激活函数或者你在输出层有一
个sigmoid函数,如果权重w太大,当你计算激活函数值时,z=wx+b就会很大或者很小,所以这种情况下,激活值可能落在tanh
和sigmoid函数的平缓部分,梯度的斜率非常小,意味着梯度下降法会非常慢,所以一开始学习就会很慢,。
如果神经网络中没有任何sigmoid或者tanh激活函数,问题可能就没那么大了。但如果你在做二元分类,你的输出单元是sigmoid函数,
那么你就不希望初始参数太大。所以np.random.randn((_,_))再乘以0.01或者更小的其他数字,浅层神经网络选择乘以0.01可以,
但是在深层神经网络的时候,就得试试乘以0.01以外的其他常数了。初始化每层的权重都一样的方式。
==============================================================================================================
# 3.关于梯度下降法
【1】比如[x1 x2] = meshgrid(-5:5, -5:5);y=x1.^2+x2.^2 surf(x1,x2,y); 可把该代码在matlab中运行看图形是什么样。
这个表达式的图形就是一个把四个角吊起来的网。梯度为(2*x1,2*x2),该图的负梯度方向是平行于x1 x2平面
并指向里面的方向,并不是该点的切线方向,也不是某个指向地面的容易让人混淆的切线.
【2】但是对于只有一个变量的比如 y=x.^2,其梯度为2*x,即其负梯度方向为-2*x,即是其导数。
对于线性函数比如y=x,其梯度就是其斜率。
【3】#只需要记住,负梯度方向是使函数值减少最快的方向,但是是供变量迭代相加减的,并不是供函数值相加减的。
只需要用变量加上负梯度方向就是变量的下一个迭代值:w1=w0-α*dy/dw0,α是步长,dy/dw0是在w0处的梯度方向。
【4】在多变量时候还容易想通,对于一元二次函数,对变量迭代时,由于根据图像来推导,总是觉得梯度方向是跟
变量迭代的加减扯不上关系的,不知道为什么要用变量加上步长乘以负梯度。似懂非懂,那就不管了吧,记住多变量的就好
【5】梯度下降法可以运用在很多算法中,比如logistic回归;即并不是只要有梯度下降就要想到反向传播,
而是只要有反向传播,就会有梯度下降法,并不是充要条件
【6】梯度下降算法除了不一定能达到全局最优外,即可能达到局部最优,另一个问题就是计算时间太长。
【6.1】因为要在全部训练数据上最小化损失,所以成本函数是在所有训练数据上的损失和。这样每一轮迭代都需要计
算在全部训练数据上的成本函数。在海量训练数据下非常耗时间。为了加速训练过程,可以使用随机梯度下降算法。
【6.2】随机梯度下降算法优化的并不是在全部训练数据上的损失函数,而是在每一轮迭代中,随机优化某一条训练数据上
的损失函数。这样每一轮参数更新的速度就大大加快了。因为随机梯度下降算法每次优化的只是某一条数据上的损
失函数,所以问题也非常明显:在某一条数据上损失函数更小并不代表在全部数据上损失函数更小,于是使用随
机梯度下降优化得到的神经网络甚至可能无法达到局部最优。
【6.3】综合梯度下降和随机梯度下降算法的优缺点,采用每次计算一小部分训练数据的损失函数,这一小部分数据被称之
为一个batch。通过矩阵运算,每次在一个batch上优化神经网络参数并不会比单个数据慢太多。另一方面,每次使用一
个batch可以大大减小收敛所需要的迭代次数,同时可以使收敛到的结果更加接近梯度下降的效果。
==============================================================================================================
# 4.激活函数---------【摘自吴恩达深度学习视频】
【0】使用非线性激活函数的原因:
如果使用线性激活函数或者不使用激活函数,那么无论你的神经网络有多少层,你一直在做的只是计算线性激活
函数,倒不如直接去掉全部隐藏层。
即线性激活函数用在隐藏层一点用也没有,因为两个线性函数的组合本身就是线性函数。
所以如果不引入非线性激活函数,你无法计算更有趣的函数,网络层数再多也不行。
只有一个地方可以使用线性激活函数,就是你要机器学习的是回归问题:目标值y是一个实数,不只是0和1,比如你想预测房地产价格。
可能偶尔会在神经网络的输出层使用线性激活函数,以及一些与压缩有关的一些特殊情况
【1】ReLU:修正线性单元:a= max(0,z)
【2】带泄露ReLU:即当z<0时,不再为0,而是有一个平缓的斜率,接近平行于横轴。公式可能是 a= max(0.01z,z)
因为当z为负数时,ReLU的导数为0,所以才有了带泄露ReLU。他通常比ReLU激活函数更好,但实际中使用频率没那么高
【3】sigmoid: a= σ(z) = 1/(1+ e^-z) 范围0~1。他有性质:σ’(z)=σ(z)*(1-σ(z)),也即a’=a*(1-a)
【4】tanh双曲正切函数: a= tanh(z) = (e^z - e^-z)/(e^z + e^-z),可看做是sigmoid函数的平移得到,范围-1~1
他有性质:tanh'(z)= 1-(tanh(z))^2 , 也即a’=1-a^2
【5】选择激活函数的时候有一些经验法则:
如果你的输出值是0和1,即二分类,那么sigmoid函数很适合作为输出层的激活函数,然后其他层都用ReLU
sigmoid除非用在【二元分类】的【输出层】,不然绝对不要用,或者几乎从来不用。
吴恩达几乎从来不用sigmoid,因为tanh几乎在所有场合都更优越
如果你不确定用哪个激活函数,那么就用ReLU作为激活函数
使用ReLU,神经网络的学习上速度通常会快的多。
'''我自己写的:因为sigmoid和tanh函数在z很大或者很小时,导数几近为0,速度就慢的不行了,即梯度弥散问题.
尤其是在反向传播时,靠近输出层的那几层权重变化很快,但是传播到最初几层权重变化就非常缓慢了,也就学不到特征了。'''
===========================================================================================================
# 5.神经网络与logistic回归对比
下面的^[n]表示第n层
只考虑向量化的,不考虑单个样本输入输出,即输入是矩阵,不是单个样本
------------------------------------------------------------------------------------------
# logistic回归
# 相当于只有一个输入层,和一个单神经元的输出层
输入x是由所有样本横向排列的的矩阵,即每列是一个样本
W是一个列向量
z= W.T *x +b ,所以W需要加上转置
logistic的输出是一个行向量,每个元素对应每个样本的预测值(激活值)
------------------------------------------------------------------------------------------
# 神经网络
记住每层比如第i层的W是n[i]*n[i-1]矩阵,即(后一层的神经元个数行)*(前一层神经元个数列)的矩阵
变量z与dz的维度是一致的,w和dw也是相同的维度
# 以只有两层(输入层不算在内)的单神经元输出神经网络为例
# 输入层
a^[0]=[x(1),x(2),...,x(m)] ,a^[0]是矩阵,即所有样本的输入特征组成的矩阵
# 第一层,即隐藏层
W^[1]是一个n[1]*n[0]的矩阵
z^[1]=W^[1] *a^[0] +b^[1] ,z^[1]是矩阵,每列是一个样本的第一层各个神经元的z值组成的列向量
a^[1]=[a^[1](1),a^[1](2),...,a^[1](m)] ,a^[1]是矩阵,每列是一个样本的第一层各个神经元的激活值组成的列向量
# 第二层,即输出层
W^[2]是一个1*n[1]行向量
z^[2]=W^[2] *a^[1] +b^[2] ,z^[2]是行向量,每个元素对应一个样本
a^[2]=[a^[2](1),a^[2](2),...,a^[2](m)] ,a^[2]是行向量,每个元素对应一个样本
Y=[y(1),y(2),...,y(m)], ,Y 是行向量,每个元素对应各个样本的目标值
单神经元输出的神经网络的输出是一个行向量,每个元素对应每个样本的预测值(激活值)
-----------------------------------------------------------------------------------------------
这里我很懵逼,没搞懂:
所以讲logistic回归的时候:dW = dz * x, x没有转置。
z一个行向量1*m,输入x是由所有样本横向排列的的矩阵n*m,即每列是一个样本.什么乱七八糟的,z= W.T *x +b的W有转置,dW没转置吗?很懵逼啊。
而讲神经网络的时候, dW^[2]= dz^[2] * a^[1].T ,比logistic回归多了一个转置符号
dW^[1]= dz^[1] * a^[0].T ,这里a^[0]就是所有样本的输入特征x矩阵
变量z与dz的维度是一致的,w和dw也是相同的维度,z^[1]是n[1]*m矩阵,a^[0]是n[0]*m矩阵,所以需要加上转置符号才能相乘。
-----------------------------------------------------------------------------------------------
np.sum(x,axis=1,keepdims=True)
axis=0,对每列求和
axis=1,对每行求和
keepdims=True,保持维度,使其不会变成秩为1的数组
------------------------------------------------------------------------------------------------
# 6.反向传播
按照吴恩达的视频,反向传播算法不需要那么复杂的公式,只需要将成本函数J对w,b求偏导。
J对w求偏导可变为J对z求偏导,J再对w求偏导,就求出了最后一层的权重更新梯度;
最后一层的梯度变化: dJ/dW^[2]= (dJ/da^[2])*(da^[2]/dz^[2]) * (dz^[2]/dW^[2])
第一层的权重梯度变化:dJ/dW^[1]= (dJ/dz^[1]) * a^[0].T,
而 dJ/dz^[1]=(dJ/da^[2]) * (da^[2]/dz^[2]) * (dz^[2]/da^[1]) * (da^[1]/dz^[1])
代入得 dJ/dW^[1]= (dJ/da^[2]) * (da^[2]/dz^[2]) * (dz^[2]/da^[1]) * (da^[1]/dz^[1])* a^[0].T
即每一层的梯度变化都是由后面的向前求偏导。
总结:某一层的权重梯度变化为 最终的成本函数J对该层的激活值a^[i]求导 * 该层激活值a^[i]对该层的z求导 * z再对w求导,
而成本函数J对该层的激活值a^[i]求导又可以分解为 成本函数J对后一层的激活值a^[i+1]求导,后一层的激活值a^[i+1]
再对后一层的z求导,后一层的z再对该层的激活值a^[i]求导(【因为后一层的z等于前一层的激活值作为输入的】)。
求出了每层的权重梯度变化就可以使用梯度下降法来更新每层的权重了。对于偏置也是同理。
【因为后一层的z等于前一层的激活值作为输入的】这句话是重点,重中之重。
【疑问】
1.在前向传播时,把每层得到的Z,W,b缓存起来,当计算反向传播时会用到它们。
我还没实际操作过,不知道缓存起来怎么用得到,是不是在做更新的时候:
W=W-α*dW,b=b-α*db用到呢?那也没用到z啊?即使用z对w求偏导,那z也是作为函数,而不是数值,但是吴恩达一直强调缓存Z.
2.当学习率(步长)α一定时,每次w迭代的梯度都是一样的,即每次w的变化量都是一样的,对不对?
我的意思是神经网络结构图中的每一条线代表每一个权值,某一条线的权重每次的变化量都是一定的吗?
答:不对。因为每次迭代更新w后w位置变了,成本函数J对w的偏导是一个关于w的函数,因此w在不同位置,dJ/dw的值是不一样的。
举个例子:J=w^2,则dJ/dw=2*w,在某个位置比如w=3时,梯度dJ/dw=6,w=w-α*dJ/dw=3-6;
而在w=8时,梯度dJ/dw=16,w=w-α*dJ/dw=8-16。
即在不同位置的w,dJ/dw不一样。所以在不同位置,w的变化量是不一样的。
3.最后预测值和目标值有误差,计算成本函数之后,成本函数是一个值。就是说只要成本函数值不小于给定误差,
就一直用成本函数对w求偏导(即梯度)来更新权重W,这时候不能把成本函数看做一个值,而应该是一个关于变量a的函数.对不对?
答:对
------------------------------------------------------------------------------------------------------------------
# 7.参数VS超参数
参数parameters指的是w,b等实际参数
超参数hyperparameters指的是能控制实际参数w,b最终结果的一类参数。
hyperparameters如下:
学习率α
迭代次数iterations
隐藏层层数L
隐藏层神经元个数n^[1],n^[2],...,n^[L]
激活函数的选择
minibatch size
momentum
正则化参数 regularization parameters
# 8.logistic回归与softmax的成本函数
【我发现一个问题】:李航的logistic回归对二分类的求法中分母是1+exp(z),其中一个类别分子是1,另一个类别的分子是exp(z)。
而softmax对k个类别的输出单元的求法中,分母是∑exp(zj),分子分别为exp(zj),j为输出神经元个数,即类别个数。
讲解logistic回归时,不需要有两个输出单元,logistic回归可看作是单神经元的神经网络。
讲解softmax时,有几个类别就有几个输出神经单元。样本是什么类型,目标向量的哪个元素位置就是1,其余的元素为0。那么
预测值是什么样的呢?这几个输出神经元的元素到底都是0和1还是所求出的概率呢?
并且logistic回归的成本函数与softmax的成本函数的形式不一样。
logistic成本函数:J(w,b)=-1/m *Σ[y(i)log(a(i))+(1-y(i))log(1-a(i))],即对m个样本求和后再平均,Σ是求和符号
softmax成本函数:J(w,b)=-1/m *ΣΣ1{y^(i)}log exp(z)/Σexp(z),其中第一个求和符是对(i=1~m),第二个求和符是对(j=1~k),
最后一个分母上的求和符是对k输出神经元的exp(z)求和。
解释的不太清楚,很混乱,只需要做这两个相关的程序就会了解了吧!
# 9.epoch、 iteration和batchsize的区别
深度学习中经常看到epoch、 iteration和batchsize,下面按自己的理解说说这三个的区别:
(1)batchsize:批大小。在深度学习中,一般采用SGD训练,即每次训练在训练集中取batchsize个样本训练;
(2)iteration:1个iteration等于使用batchsize个样本训练一次;
(3)epoch:1个epoch等于使用训练集中的全部样本训练一次;
举个例子,训练集有1000个样本,batchsize=10,那么:
训练完整个样本集需要:
100次iteration,1次epoch。
关于batchsize可以看看这里。