bluejad / deeplearning

deep learing note
1 stars 0 forks source link

CS231n: Convolutional Neural Networks for Visual Recognition #2

Open bluejad opened 7 years ago

bluejad commented 7 years ago

斯坦福CS231n:面向视觉识别的卷积神经网络

CS231n课程翻译系列

课程教师Andrej Karpathy

bluejad commented 7 years ago

将原始的数据集的大小由[N x D]降到了[N x 100],留下了数据中包含最大方差的100个维度

bluejad commented 7 years ago

通常使用PCA降维过的数据训练线性分类器和神经网络会达到非常好的性能效果,同时还能节省时间和存储器空间

bluejad commented 7 years ago

白化操作的输入是特征基准上的数据,然后对每个维度除以其特征值来对数值范围进行归一化

bluejad commented 7 years ago

该变换的几何解释是:如果数据服从多变量的高斯分布,那么经过白化后,数据的分布将会是一个均值为零,且协方差相等的矩阵。该操作的代码如下:

Xwhite = Xrot/np.sqrt(S + 1e - 5)

bluejad commented 7 years ago

特征基准

Xrot

bluejad commented 7 years ago

分母中添加了1e-5(或一个更小的常量)来防止分母为0

bluejad commented 7 years ago

该变换的一个缺陷是在变换的过程中可能会夸大数据中的噪声,这是因为它将所有维度都拉伸到相同的数值范围,这些维度中也包含了那些只有极少差异性(方差小)而大多是噪声的维度

bluejad commented 7 years ago

夸大的噪声可以用更强的平滑来解决(例如:采用比1e-5更大的值)

bluejad commented 7 years ago
pca
bluejad commented 7 years ago
bluejad commented 7 years ago

应该先分成训练/验证/测试集,只是从训练集中求图片平均值,然后各个集(训练/验证/测试集)中的图像再减去这个平均值

译者注:此处确为初学者常见错误,请务必注意!

bluejad commented 7 years ago

权重初始化

bluejad commented 7 years ago
bluejad commented 7 years ago

小随机数权重初始化的实现方法是:

W = 0.01 * np.random.randn(D, H)

bluejad commented 7 years ago

randn函数是基于零均值和标准差的一个高斯分布来生成随机数的

bluejad commented 7 years ago

警告。并不是小数值一定会得到好的结果。例如,一个神经网络的层中的权重值很小,那么在反向传播的时候就会计算出非常小的梯度(因为梯度与权重值是成比例的)

bluejad commented 7 years ago

使用1/sqrt(n)校准方差

建议将神经元的权重向量初始化为:w = np.random.randn(n) / sqrt(n)

其中n是输入数据的数量

这样就保证了网络中所有神经元起始时有近似同样的输出分布。实践经验证明,这样做可以提高收敛的速度

bluejad commented 7 years ago

给出了一种针对ReLU神经元的特殊初始化,并给出结论:网络中神经元的方差应该是2.0/n

代码为w = np.random.randn(n) * sqrt(2.0/n)

这个形式是神经网络算法使用ReLU神经元时的当前最佳推荐

bluejad commented 7 years ago

给出了一种针对ReLU神经元的特殊初始化,并给出结论:网络中神经元的方差应该是2.0/n

代码为w = np.random.randn(n) * sqrt(2.0/n)

这个形式是神经网络算法使用ReLU神经元时的当前最佳推荐

bluejad commented 7 years ago

稀疏初始化(Sparse initialization)

另一个处理非标定方差的方法是将所有权重矩阵设为0,但是为了打破对称性,每个神经元都同下一层固定数目的神经元随机连接(其权重数值由一个小的高斯分布生成)

一个比较典型的连接数目是10个

bluejad commented 7 years ago

偏置的初始化

通常将偏置初始化为0,这是因为随机小数值权重矩阵已经打破了对称性

bluejad commented 7 years ago

当前的推荐是使用ReLU激活函数,并且使用w = np.random.randn(n) * sqrt(2.0/n)来进行权重初始化

bluejad commented 7 years ago

批量归一化

bluejad commented 7 years ago

在实践中,使用了批量归一化的网络对于不好的初始值有更强的鲁棒性

bluejad commented 7 years ago

正则化

bluejad commented 7 years ago

有不少方法是通过控制神经网络的容量来防止其过拟合的

bluejad commented 7 years ago

L2正则化可以直观理解为它对于大数值的权重向量进行严厉惩罚,倾向于更加分散的权重向量

bluejad commented 7 years ago

使用L2正则化意味着所有的权重都以w += -lambda * W向着0线性下降

bluejad commented 7 years ago

L2正则化可能是最常用的正则化方法了。可以通过惩罚目标函数中所有参数的平方将其实现。即对于网络中的每个权重w,向目标函数中增加一个1/2λ w^2,其中λ是正则化强度

bluejad commented 7 years ago

L1正则化是另一个相对常用的正则化方法。对于每个w我们都向目标函数增加一个λ|w|

bluejad commented 7 years ago

L1和L2正则化也可以进行组合:λ|w| + λw^2

bluejad commented 7 years ago

L1正则化有一个有趣的性质,它会让权重向量在最优化的过程中变得稀疏(即非常接近0)

也就是说,使用L1正则化的神经元最后使用的是它们最重要的输入数据的稀疏子集,同时对于噪音输入则几乎是不变的了

bluejad commented 7 years ago

一般说来L2正则化都会比L1正则化效果好

bluejad commented 7 years ago

最大范式约化

另一种形式的正则化是给每个神经元中权重向量的量级设定上限,并使用投影梯度下降来确保这一约束

bluejad commented 7 years ago

在实践中,与之对应的是参数更新方式不变,然后要求神经元中的权重向量必须满足这一条件||w|| < c,一般值为3或者4。有研究者发文称在使用这种正则化方法时效果更好

这种正则化还有一个良好的性质,即使在学习率设置过高的时候,网络中也不会出现数值“爆炸”,这是因为它的参数更新始终是被限制着的

bluejad commented 7 years ago

随机失活的实现方法是让神经元以超参数p的概率被激活或者被设置为0

bluejad commented 7 years ago
dropout

在训练过程中,随机失活可以被认为是对完整的神经网络抽样出一些子集,每次基于输入数据只更新子网络的参数

bluejad commented 7 years ago

一个3层神经网络的普通版随机失活可以用下面代码实现:

普通版随机失活: 不推荐实现

3层neural network的前向传播

p = 0.5
def train_step(X):

前向传播

H1 = np.maximum(0, np.dot(W1, X) + b1)   
U1 = np.random.randn(*H1.shape) < p   第一个随机失活遮罩
H1 *= U1  drop!
H2 = maximum(0, np.dot(W2, H1) + b2)
U2 = np.random.randn(*H2.shape) < p 第一个随机失活遮罩
H2 *= U2   drop!
out = np.dot(W3, H2) + b3

def predict(X):

前向传播时模型集成

H1 = np.maximum(0, np.dot(W1, X) + b1)
H2 = np.maximum(0, np.dot(W2, H1) + b2) * p
out = np.dot(W3, H2) + b3
bluejad commented 7 years ago
bluejad commented 7 years ago

反向随机失活: 推荐实现方式 在训练的时候drop和调整数值范围,测试时不做任何事

3层neural network的前向传播

p = 0.5
def train_step(X):

前向传播

H1 = np.maximum(0, np.dot(W1, X) + b1)   
U1 = np.random.randn((*H1.shape) < p)/p   第一个随机失活遮罩
H1 *= U1  drop!
H2 = maximum(0, np.dot(W2, H1) + b2)
U2 = np.random.randn((*H2.shape) < p)/p 第一个随机失活遮罩
H2 *= U2   drop!
out = np.dot(W3, H2) + b3

def predict(X):

前向传播时模型集成

H1 = np.maximum(0, np.dot(W1, X) + b1)
H2 = np.maximum(0, np.dot(W2, H1) + b2) * p
out = np.dot(W3, H2) + b3
bluejad commented 7 years ago

在随机失活发布后,很快有大量研究为什么它的实践效果如此之好

bluejad commented 7 years ago

在使用费希尔信息矩阵(fisher information matrix)的对角逆矩阵的期望对特征进行数值范围调整后,再进行L2正则化这一操作,与随机失活正则化是一阶相等的

bluejad commented 7 years ago

前向传播中的噪音

bluejad commented 7 years ago

偏置正则化

bluejad commented 7 years ago

每层正则化:对于不同的层进行不同强度的正则化很少见(可能除了输出层以外)

bluejad commented 7 years ago

实践:通过交叉验证获得一个全局使用的L2正则化强度是比较常见的。在使用L2正则化的同时在所有层后面使用随机失活也很常见。p值一般默认设为0.5,也可能在验证集上调参

bluejad commented 7 years ago

正则化

bluejad commented 7 years ago

损失函数:可以看做是对模型复杂程度的某种惩罚

bluejad commented 7 years ago

损失函数的第二个部分是数据损失,它是一个有监督学习问题,用于衡量分类算法的预测结果(即分类评分)和真实标签结果之间的一致性

bluejad commented 7 years ago

数据损失是对所有样本的数据损失求平均

default