把隐藏层数量当做参数
在搭建深度网络时,不一定非要使用很多隐藏层,在刚开始解决一个新问题时,通常可以从
logistic回归开始,再试试一到两个隐层,把隐藏层数量当做参数、超参数一样去调试,这样
去找比较合适的深度。
在训练神经网络时,权重随机初始化是很重要的。
对于逻辑回归,把权重初始化为0当然也是可以的。但是对于一个神经网络,如果你把权重
或者参数都初始化为 0,那么梯度下降将不会起作用。
如果你把权重都初始化为 0,那么由于隐含单元开始计算同一个函数,所有的隐含单元就会对输出单元有同样的影响。
一次迭代后同样的表达式结果仍然是相同的,即隐含单元仍是对称的。通过推导,两次、三次、无论多少次迭代,不管你训练网络多长时间,
隐含单元仍然计算的是同样的函数。因此这种情况下超过 1 个隐含单元也没什么意义,因为他们计算同样的东西。如果你要初始化成 0,
由于所有的隐含单元都是对称的,无论你运行梯度下降多久,他们一直计算同样的函数。这没有任何帮助,因为你想要两个不同
的隐含单元计算不同的函数,这个问题的解决方法就是随机初始化参数。
使用一个神经网络时,需要决定使用哪种激活函数用隐藏层上,哪种用在输出节点上。
在不同的神经网络层中,激活函数可以不同
几种常用的激活函数:
note:
1.tanh函数总体上优于sigmoid函数(因为tanh函数值值域在-1,1之间,其均值更接近0)
2.例外:在二分类的问题中,对于输出层,因为𝑦的值是 0 或 1,所以想让𝑦^的数
值介于 0 和 1 之间,而不是在-1 和+1 之间。所以需要使用 sigmoid 激活函数。
如果输出是 0、1 值(二分类问题),则输出层选择 sigmoid 函数,然后其它的所有单
元都选择 Relu 函数。
3.sigmoid 函数和 tanh 函数两者共同的缺点是,在𝑧特别大或者特别小的情况下,导数的
梯度或者函数的斜率会变得特别小,最后就会接近于 0,导致降低梯度下降的速度。
总结:
sigmoid 激活函数:除了输出层是一个二分类问题基本不会用它。
tanh 激活函数:tanh 是非常优秀的,几乎适合所有场合。
ReLu 激活函数:最常用的默认函数,,如果不确定用哪个激活函数,就使用 ReLu 或者
Leaky Relu
在编写神经网络时:
1.不要使用秩为1的一维数组
2.总是使用n x 1维矩阵(列向量-column vector)或者1 X n维矩阵(行向量-row vector)
3.敢于使用reshape()来确保你的矩阵或向量所需要的维数
4.在不完全确定一个向量的维维度时使用assert()语句
(Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况。)
demo:
a = np.random.randn(5) # Don't use
# a.shape = (5,) # rank 1 array
a = np.random.randn(5,1) # a.shape=(5,1) column vector
a = np.random.randn(1,5) # a.shape=(1,5) row vector
assert(a.shape == (5,1))
a = a.reshape((5,1))
"""
Calories from Carbs,Proteins,Fats in 100g of different foods:
Apples Beef Eggs Potatoes
Carb [94.91525424 0. 2.83140283 88.42652796]
Protein [ 2.03389831 43.51464435 33.46203346 10.40312094]
Fat [ 3.05084746 56.48535565 63.70656371 1.17035111]
Q:Calculate % of calories from Carbs,Proteins,Fats.Can you do this without
explicit for-loop?
"""
import numpy as np
A = np.array([[56.0,0.0,4.4,68.0],
[1.2,104.0,52.0,8.0],
[1.8,135.0,99.0,0.9]])
print(A)
cal = A.sum(axis=0)
print(cal)
percentage = 100*A/cal.reshape(1,4)
print(percentage)