《第三章》
最后更新于
这有帮助吗?
最后更新于
这有帮助吗?
《第三章》
线性回归模型的房屋价格预测表达式为:
假设我们采集的样本数为n,索引为i的样本的特征为x(i)1 和x(i)2 ,标签为y(i) 。对于索引为i的房屋,w指权重(weight),b是偏差(bias),y帽是预估。
平方损失函数(损失函数,衡量价格预测值与真实值之间的误差。):
目标函数:是找到使损失最小的权重w和偏差b:
迭代方式(通过迭代始得参数回归真实的值):
小技巧:向量化的运算速度远快于for循环。
全连接层是指每一个结点都与上一层的所有结点相连。
为什么squared_loss
函数中需要使用reshape
函数?
答:因为y_hat的shape为(10,1)而y为(1,10)
尝试使用不同的学习率,观察损失函数值的下降快慢。
答:数值小下降越快,但损失较大,即比较不准确
如果样本个数不能被批量大小整除,data_iter
函数的行为会有什么变化?
答:因为有min函数,末尾剩下的会作为一批返回。(但是最后一次返回,data_iter没有改变batch_size的值,会导致sgd梯度下降函数的超参数偏低)
如果将l = loss(net(X), y)
替换成l = loss(net(X), y).mean()
,我们需要将trainer.step(batch_size)
相应地改成trainer.step(1)
。这是为什么呢?
答:因为原始l所计算的损失是小批量地计算的,需要除以批量数才能获得平均损失,通过trainer.step告诉批量的大小。所以如果预先计算了评均损失,则trainer.step(1)
即可。
查阅MXNet文档,看看gluon.loss
和init
模块里提供了哪些损失函数和初始化方法。
损失函数
定义
Base class for loss.
Calculates the mean squared error(均方误差) between label and pred.
Calculates the mean absolute error(平均绝对误差) between label and pred.
The cross-entropy(交叉熵) loss for binary classification.jun
The cross-entropy(交叉熵) loss for binary classification.
Computes the softmax cross entropy(交叉熵) loss.
Computes the softmax cross entropy(交叉熵) loss.
The Kullback-Leibler divergence loss.(发散损失)
Connectionist Temporal Classification Loss.
Calculates smoothed L1 loss that is equal to L1 loss if absolute error exceeds rho but is equal to L2 loss otherwise.
Calculates the hinge loss function often used in SVMs:
Calculates the soft-margin loss function used in SVMs:
Calculates the logistic loss(逻辑损失) (for binary losses only):
Calculates triplet loss given three input tensors and a positive margin.
For a target (Random Variable) in a Poisson distribution, the function calculates the Negative Log likelihood loss.
For a target label 1 or -1, vectors input1 and input2, the function computes the cosine distance between the vectors.(向量的余弦距离)
Calculates Batchwise Smoothed Deep Metric Learning (SDML) Loss given two input tensors and a smoothing weight SDM Loss learns similarity between paired samples by using unpaired samples in the minibatch as potential negative examples.
初始化函数
定义
Initialize weight for upsampling layers.
Initializes the weights to a given value.(给定值)
Descriptor for the initialization pattern.
The base class of an initializer.(初始化基类)
Initialize all biases of an LSTMCell to 0.0 except for the forget gate whose bias is set to custom value.
Initializes variables by loading data from file or dict.(用文件或字典来初始化)
Initialize the weight according to a MSRA paper.
Initialize parameters using multiple initializers.
Initializes weights with random values sampled from a normal distribution with a mean of zero and standard deviation of sigma.(正态分布初始化)
Initializes weights to one.
Initialize weight as orthogonal matrix.(正交矩阵初始化)
Initializes weights with random values uniformly sampled from a given range.(给定范围初始化)
Returns an initializer performing “Xavier” initialization for weights.
Initializes weights to zero.
如何访问dense.weight
的梯度?
答:dense.weight.grad()获得梯度,通过help(dense.weigth)获得帮助
适用场景:分类问题
一共有4种特征和3种输出动物类别,所以权重包含12个标量(带下标的w)、偏差包含3个标量(带下标的b),且对每个输入计算o1,o2,o3这3个输出:
softmax公式:
损失函数(交叉熵)公式:
带下标的y(i)j是向量y(i)中非0即1的元素,需要注意将它与样本i类别的离散数值,即不带下标的y(i)区分。
小技巧:最小化交叉熵损失函数等价于最大化训练数据集所有标签类别的联合预测概率。
查阅资料,了解最大似然估计。它与最小化交叉熵损失函数有哪些异曲同工之妙?
答:Softmax函数一个重要的性质就是把输出归一化转换到每一个对应分类的概率。一旦转换为概率之后,我们就可以用到最大似然估计(交叉熵)的方式来求得最大似然或者最小交叉熵。
其他知识
相对熵,又称KL Divergence (KL散度):是用来判断两个概率分布的距离,DKL的值越小,表示q分布(pred)和p分布(label)越接近。
交叉熵:刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近,即拟合的更好。上述等式的前一部分就是p的熵,后一部分,就是交叉熵:
softmax回归模型中实际上是使用相对熵来评估pred和label的差距,因为label的熵不变,所以损失函数使用交叉熵来计算。
减小batch_size
(如到1)会影响读取性能吗?
会,从256->1,时间从2.7s到7.8s。
查阅MXNet文档,mxnet.gluon.data.vision
里还提供了哪些别的数据集?
CIFAR-10数据集:包含10个类别的60000个32x32彩色图像,每个类别6000个图像。有50000张训练图像和10000张测试图像。
CIFAR-100数据集:类似于CIFAR-10,不同之处在于它有100个类别,每个类别包含600张图像。每个课程有500张训练图像和100张测试图像。CIFAR-100中的100个类别分为20个超类。每个图像都带有一个“精细”标签(它所属的类)和一个“粗糙”标签(它所属的超类)。
MNIST手写数字数据集
gluon.data.vision的方法
描述
A dataset wrapping over a RecordIO file containing images.
A dataset for loading image files stored in a folder structure.
A dataset for loading image files specified by a list of entries.
查阅MXNet文档,mxnet.gluon.data.vision.transforms
还提供了哪些别的变换方法?
gluon.data.vision.transforms
描述
Sequentially composes multiple transforms.
Cast inputs to a specific data type(改变数据类型)
transforms.ToTensor
Converts an image NDArray or batch of image NDArray to a tensor NDArray.
transforms.Normalize
Normalize an tensor of shape (C x H x W) or (N x C x H x W) with mean and standard deviation.
transforms.RandomResizedCrop
Crop the input image with random scale and aspect ratio.
transforms.CenterCrop
Crops the image src to the given size by trimming on all four sides and preserving the center of the image.
transforms.Resize
Resize an image or a batch of image NDArray to the given size.(调整大小)
ToTensor
实例将图像数据从uint8格式变换成32位浮点数格式,并除以255使得所有像素的数值均在0到1之间。
nd.pick(x, y)
以y为索引,从x中取得y对应的值。
y_hat.argmax(axis=1)
返回矩阵y_hat
每行中最大元素的索引
X.sum(axis=0, keepdims=True)
保持第0轴,取总和,保持维度。
在 Python 3.x 中为了减少内存,zip([iterable,...])
返回的是一个对象。如需展示列表,需手动 list() 转换。相当于range,但是针对自定义的迭代器。
如果keepdims=False,结果为一维向量。
在本节中,我们直接按照softmax运算的数学定义来实现softmax函数。这可能会造成什么问题?(提示:试一试计算exp(50)exp(50)的大小。)
答:数据过大,内存存储耗费大,计算复杂。
本节中的cross_entropy
函数是按照“softmax回归”一节中的交叉熵损失函数的数学定义实现的。这样的实现方式可能有什么问题?(提示:思考一下对数函数的定义域。)
答:所获得的损失函数都是负的。
你能想到哪些办法来解决上面的两个问题?
答:1.将exp换成log;2.向下平移一格softmax函数
尝试调一调超参数,如批量大小、迭代周期和学习率,看看结果会怎样。
答:缩小batch_size能提高精确度,缩小到64的效果比较好;
提高num_epochs能提高精确度,提高到8左右即可;(可能缩小batch_size需要配合提高num_epochs)
learning_rate从0.3到0.1有助于提高精确率,再低反而降低。
多层感知机在输出层与输入层之间加入了一个或多个全连接隐藏层,并通过激活函数对隐藏层输出进行变换。
常用的激活函数包括ReLU函数、sigmoid函数和tanh函数。
sigmoid函数:1.值域在0和1之间;2.函数具有非常好的对称性;3.函数对输入超过一定范围就会不敏感.
tanh函数:Tanh函数是0均值的更加有利于提高训练效率,由于Sigmoid输出是在0-1之间,总是正数,在训练过程中参数的梯度值为同一符号,这样更新的时候容易出现zigzag现象,不容易到达最优值。
ReLU函数:1.更加有效率的梯度下降以及反向传播;2.仿生物学原理,少数神经元活跃;3.简化计算过程。
512:
256:
128:
改变超参数num_hiddens
的值,看看对实验结果有什么影响。
答:num_hiddens越高越耗时间,精确率有一定提高,但是超过512之后的不太显眼了,没必要。性价比高的数值大概在256-512之间。
试着加入一个新的隐藏层,看看对实验结果有什么影响。
答:第一次的精确率较低,但是梯度下降的速度更快了,后面的几次精确率显著提高。
尝试多加入几个隐藏层,对比上一节中从零开始的实现。
加入3个隐藏层。
使用其他的激活函数,看看对结果的影响。
答:使用tanh和sigmoid的效果均没有relu的好。
训练误差(training error)指模型在训练数据集上表现出的误差
泛化误差(generalization error):模型在任意一个测试数据样本上表现出的误差的期望,通过测试数据集上的误差来近似
k 折交叉验证:在k折交叉验证中,我们把原始训练数据集分割成k个不重合的子数据集,然后我们做k次模型训练和验证。每一次,我们使用一个子数据集验证模型,并使用其他k−1个子数据集来训练模型。在这k次训练和验证中,每次用来验证模型的子数据集都不同。最后,我们对这k次训练误差和验证误差分别求平均。
欠拟合(underfitting):模型无法得到较低的训练误差
过拟合(overfitting):模型的训练误差远小于它在测试数据集上的误差
如果用一个三阶多项式模型来拟合一个线性模型生成的数据,可能会有什么问题?为什么?
答:可能会发生过拟合。但是要看线性模型生成多少个点,如果点非常少,例如小于等于4,那么3次模型会有可能严重过拟合,在训练集上loss可以降为0,但是在测试集上表现很差。但是如果数据点非常多的话,例如1000个点,3次模型来你和还是不错的,因为高阶项的系数基本都是趋近于0的。因此在测试集上表现也不会很差的。(借鉴)
在本节提到的三阶多项式拟合问题里,有没有可能把100个样本的训练误差的期望降到0,为什么?(提示:考虑噪声项的存在。)
答:没有可能。除非这1000个样本中只有小于等于4个点不共线,这种情况才会使得loss为0,因为3次多项式最多可以完全拟合4个不共线的点。(借鉴)
带有L2范数惩罚项的新损失函数为
权重w1和w2的迭代方式更改为
可见,L2范数正则化令权重w1和w2先自乘小于1的数,再减去不含惩罚项的梯度。因此,L2范数正则化又叫权重衰减。权重衰减通过惩罚绝对值较大的模型参数为需要学习的模型增加了限制,这可能对过拟合有效。实际场景中,我们有时也在惩罚项中添加偏差元素的平方和。
对比线性回归迭代方式:
回顾一下训练误差和泛化误差的关系。除了权重衰减、增大训练量以及使用复杂度合适的模型,你还能想到哪些办法来应对过拟合?
dropout:dropout细节可以参考【深度学习中Dropout原理解析】 什么是dropout: 在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作。 原因: 整个dropout过程就相当于对很多个不同的神经网络取平均,是一种bagging机制。
Batch NomalizationBN的分析 BN真的是一大利器,有一定的正则效果。对于BN为什么这么牛的研究很多,现在还处于讨论阶段,我们只要知道BN是真的叼,搭网络必备网络层。
如果你了解贝叶斯统计,你觉得权重衰减对应贝叶斯统计里的哪个重要概念?
调节实验中的权重衰减超参数,观察并分析实验结果。
答:权重衰减超参数越大,test的loss下降的越快,train越拟合,但是test上的最终loss不会改变。
fit_and_plot_gluon(3)
L2 norm of w: 0.039488398
fit_and_plot_gluon(10)
L2 norm of w: 0.028417032
梯度消失:在神经网络中,当前面隐藏层的学习速率低于后面隐藏层的学习速率,即随着隐藏层数目的增加,分类准确率反而下降了。这种现象叫做消失的梯度问题。
丢弃法:按照一定的概率丢弃隐藏层。设丢弃概率为p, 那么有p的概率hi会被清零,有1−p的概率hi会除以1−p做拉伸。
丢弃法不改变输入的期望值。
我们可以通过使用丢弃法应对过拟合。
丢弃法只在训练模型时使用。
如果把本节中的两个丢弃概率超参数对调,会有什么结果?
答:结果接近,无显著差别。
增大迭代周期数,比较使用丢弃法与不使用丢弃法的结果。
答:1.不使用丢弃的话会过拟合,loss一直降低,train acc一直提高。
2.使用丢弃法的话,loss也会降低,train acc也会一直提高,但速度较慢。
如果将模型改得更加复杂,如增加隐藏层单元,使用丢弃法应对过拟合的效果是否更加明显?
答:会。下列为两隐藏层神经网络和四隐藏层神经网络的有无使用丢弃法的对比。
以本节中的模型为例,比较使用丢弃法与权重衰减的效果。如果同时使用丢弃法和权重衰减,效果会如何?
答:写不出来。等待后续复习时候再写。
正向传播沿着从输入层到输出层的顺序,依次计算并存储神经网络的中间变量。
反向传播沿着从输出层到输入层的顺序,依次计算并存储神经网络的中间变量和参数的梯度。
在训练深度学习模型时,正向传播和反向传播相互依赖。
这些中间变量的个数大体上与网络层数线性相关,每个变量的大小与批量大小和输入个数也是线性相关的,它们是导致较深的神经网络使用较大批量训练时更容易超内存的主要原因。
衰减和爆炸:指数的次方导致的数值衰减或者爆炸。
我们通常对神经网络的模型参数,特别是权重参数,进行随机初始化。
net.initialize(init.Normal(sigma=0.01))
使模型net
的权重参数采用正态分布的随机初始化方式。
如果不指定初始化方法,如net.initialize()
,MXNet将使用默认的随机初始化方法:权重参数每个元素随机采样于-0.07到0.07之间的均匀分布,偏差参数全部清零。
Xavier随机初始化 [1]。 假设某全连接层的输入个数为a,输出个数为b,Xavier随机初始化将使该层中权重参数的每个元素都随机采样于均匀分布
ps:它的设计是为了,模型参数初始化后,每层输出的方差不该受该层输入个数影响,且每层梯度的方差也不该受该层输出个数影响。
有人说随机初始化模型参数是为了“打破对称性”。这里的“对称”应如何理解?
答:当我们把所有的参数都设成0的话,那么每一条边上的权重就都是0,那么神经网络就还是对称的,对于同一层的每个神经元,它们就一模一样了。 这样的后果是什么呢?我们知道,不管是哪个神经元,它的前向传播和反向传播的算法都是一样的,如果初始值也一样的话,不管训练多久,它们最终都一样,都无法打破对称(fail to break the symmetry),那每一层就相当于只有一个神经元,最终L层神经网络就相当于一个线性的网络,如Logistic regression,线性分类器对我们上面的非线性数据集是“无力”的,所以最终训练的结果就瞎猜一样。
因此,我们决不能把所有参数初始化为0,同样也不能初始化为任何相同的值,因为我们必须“打破对称性”!(借鉴)
是否可以将线性回归或softmax回归中所有的权重参数都初始化为相同值?
答:线性回归设相同值对结果影响不大。softmax设相同值,分类准确率一直是0.1.感觉是因为有无激活函数的原因。
NA代表缺失值,NaN代表不可能值
https://blog.csdn.net/maymay_/article/details/80198468
pd.get_dummies:将非数字的特征转化成0或1的数字特征(有无这个非数字特征)
https://blog.csdn.net/W_weiying/article/details/81411257
pd.iloc:根据索引取数据
对数均方根误差RMSE:
(weight, batch_axis, **kwargs)
([weight, batch_axis])
([weight, batch_axis])
([…])
([axis, …])
([from_logits, axis, weight, …])
([layout, label_layout, weight])
([rho, weight, batch_axis])
([margin, weight, batch_axis])
([margin, weight, batch_axis])
([weight, batch_axis, label_format])
([margin, weight, batch_axis])
([weight, from_logits, …])
([weight, batch_axis, margin])
([smoothing_parameter, weight, …])
()
(value)
(**kwargs)
([forget_bias])
(param[, default_init, verbose])
([factor_type, slope])
(patterns, initializers)
([sigma])
()
([scale, rand_type])
([scale])
([rnd_type, factor_type, magnitude])
()
(filename[, flag, transform])
(root[, flag, transform])
([root, imglist, flag])