Sklearn官方文档中文整理10——等式回归和神经网络模型(有监督)篇
1. 监督学习
1.15. 等式回归【isotonic.IsotonicRegression】
IsotonicRegression
类对数据进行非降函数拟合. 它解决了如下的问题:
最小化 ∑ i w i ( y i − y ^ i ) 2 \sum_i w_i (y_i - \hat{y}_i)^2 ∑iwi(yi−y^i)2
服从于 y ^ m i n = y ^ 1 ≤ y ^ 2 . . . ≤ y ^ n = y ^ m a x \hat{y}_{min} = \hat{y}_1 \le \hat{y}_2 ... \le \hat{y}_n = \hat{y}_{max} y^min=y^1≤y^2...≤y^n=y^max
其中每一个 w i w_i wi 是 strictly 正数而且每个 y i y_i yi 是任意实 数. 它生成一个由平方误差接近的不减元素组成的向量.实际上这一些元素形成 一个分段线性的函数.
sklearn.isotonic.IsotonicRegression
参数 | 解释 |
---|---|
y_min:float, default=None | 最低预测值的下限(最小值可能更高)。如果未设置,则默认为-inf。 |
y_max:float, default=None | 最高预测值的上限(最大值可能仍然较低)。如果未设置,则默认为+inf。 |
increasing:bool or ‘auto’, default=True | 确定预测是否应限制为随X增加或减少。“auto”将根据Spearman相关估计的符号来决定。 |
out_of_bounds:{‘nan’, ‘clip’, ‘raise’}, default=’nan’ | 处理在预测期间如何处理训练域之外的X值。 |
属性 | 解释 |
---|---|
X_min_:float | 左边界输入数组X的最小值。 |
X_max_:float | 右边界的输入数组X的最大值。 |
X_thresholds_:ndarray of shape (n_thresholds,) | 用于插值y=f(X)单调函数的唯一升序X值。 |
y_thresholds_:ndarray of shape (n_thresholds,) | 适用于插值y=f(X)单调函数的消除重复的y值。 |
f_:function | 覆盖输入域X的逐步插值函数。 |
increasing_:bool | 增加的推断值。 |
方法 | 解释 |
---|---|
fit(X, y[, sample_weight]) | 对训练集拟合模型 |
fit_transform(X[, y]) | 拟合数据,然后转换它。 |
get_params([deep]) | 获取此估计器的参数。 |
set_params(**params) | 设置此估计器的参数。 |
predict(T) | 预测 |
score(X, y[, sample_weight]) | 返回预测的 R 2 R^2 R2确定系数。 |
transform(T) | 用线性插值变换新数据 |
例:
>>> from sklearn.datasets import make_regression
>>> from sklearn.isotonic import IsotonicRegression
>>> X, y = make_regression(n_samples=10, n_features=1, random_state=41)
>>> iso_reg = IsotonicRegression().fit(X, y)
>>> iso_reg.predict([.1, .2])
array([1.8628..., 3.7256...])
1.17. 神经网络模型(有监督)
警告 此实现不适用于大规模数据应用。 特别是 scikit-learn 不支持 GPU。
1.17.1. 多层感知器
多层感知器(MLP)
是一种监督学习算法,通过在数据集上训练来学习函数 f ( ⋅ ) : R m → R o f(\cdot): R^m \rightarrow R^o f(⋅):Rm→Ro,其中 m m m 是输入的维数, o o o 是输出的维数。 给定一组特征 X = x 1 , x 2 , . . . , x m X = {x_1, x_2, ..., x_m} X=x1,x2,...,xm 和标签 y y y ,它可以学习用于分类或回归的非线性函数。 与逻辑回归不同的是,在输入层和输出层之间,可以有一个或多个非线性层,称为隐藏层。 图1 展示了一个具有标量输出的单隐藏层 MLP。
最左层的输入层由一组代表输入特征的神经元 x i ∣ x 1 , x 2 , . . . , x m {x_i | x_1, x_2, ..., x_m} xi∣x1,x2,...,xm 组成。 每个隐藏层中的神经元将前一层的值进行加权线性求和转换 w 1 x 1 + w 2 x 2 + . . . + w m x m w_1x_1 + w_2x_2 + ... + w_mx_m w1x1+w2x2+...+wmxm ,再通过非线性激活函数 g ( ⋅ ) : R → R g(\cdot):R \rightarrow R g(⋅):R→R - 比如双曲正切函数 t a n h tanh tanh 。 输出层接收到的值是最后一个隐藏层的输出经过变换而来的。
该模块包含公共属性 coefs_
和intercepts_
。 coefs_
是一系列权重矩阵,其中下标为 i 的权重矩阵表示第 i 层和第 i+1 层之间的权重。 intercepts_
是一系列偏置向量,其中的下标为 i 的向量表示添加到第 i+1 层的偏置值。
多层感知器的优点:
- 可以学习得到非线性模型。
- 使用partial_fit 可以学习得到实时模型(在线学习)。
多层感知器(MLP)的缺点:
- 具有隐藏层的 MLP 具有非凸的损失函数,它有不止一个的局部最小值。 因此不同的随机权重初始化会导致不同的验证集准确率。
- MLP 需要调试一些超参数,例如隐藏层神经元的数量、层数和迭代轮数。
- MLP 对特征归一化很敏感.
1.17.2. 分类【neural_network.MLPClassifier】
MLPClassifier
类实现了通过 Backpropagation 进行训练的多层感知器(MLP)算法。
MLP 在两个 array 上进行训练:大小为 (n_samples, n_features) 的 array X 储存表示训练样本的浮点型特征向量; 大小为 (n_samples,) 的 array y 储存训练样本的目标值(类别标签):
>>> from sklearn.neural_network import MLPClassifier
>>> X = [[0., 0.], [1., 1.]]
>>> y = [0, 1]
>>> clf = MLPClassifier(solver='lbfgs', alpha=1e-5,
... hidden_layer_sizes=(5, 2), random_state=1)
...
>>> clf.fit(X, y)
MLPClassifier(activation='relu', alpha=1e-05, batch_size='auto',
beta_1=0.9, beta_2=0.999, early_stopping=False,
epsilon=1e-08, hidden_layer_sizes=(5, 2),
learning_rate='constant', learning_rate_init=0.001,
max_iter=200, momentum=0.9, n_iter_no_change=10,
nesterovs_momentum=True, power_t=0.5, random_state=1,
shuffle=True, solver='lbfgs', tol=0.0001,
validation_fraction=0.1, verbose=False, warm_start=False)
拟合(训练)后,该模型可以预测新样本的标签:
>>> clf.predict([[2., 2.], [-1., -2.]])
array([1, 0])
MLP 可以为训练数据拟合一个非线性模型。 clf.coefs_
包含了构建模型的权值矩阵:
>>> [coef.shape for coef in clf.coefs_]
[(2, 5), (5, 2), (2, 1)]
目前, MLPClassifier
只支持交叉熵损失函数,通过运行 predict_proba
方法进行概率估计。
MLP 算法使用的是反向传播的方式。 更准确地说,它使用了通过反向传播计算得到的梯度和某种形式的梯度下降来进行训练。 对于分类来说,它最小化交叉熵损失函数,为每个样本 x 给出一个向量形式的概率估计 P(y|x)
>>> clf.predict_proba([[2., 2.], [1., 2.]])
array([[ 1.967...e-04, 9.998...-01],
[ 1.967...e-04, 9.998...-01]])
MLPClassifier
通过应用 Softmax 作为输出函数来支持多分类。
此外,该模型支持 多标签分类 ,一个样本可能属于多个类别。 对于每个类,原始输出经过 logistic 函数变换后,大于或等于 0.5 的值将进为 1,否则为 0。 对于样本的预测输出,值为 1 的索引位置表示该样本的分类类别:
>>> X = [[0., 0.], [1., 1.]]
>>> y = [[0, 1], [1, 1]]
>>> clf = MLPClassifier(solver='lbfgs', alpha=1e-5,
... hidden_layer_sizes=(15,), random_state=1)
...
>>> clf.fit(X, y)
MLPClassifier(activation='relu', alpha=1e-05, batch_size='auto',
beta_1=0.9, beta_2=0.999, early_stopping=False,
epsilon=1e-08, hidden_layer_sizes=(15,),
learning_rate='constant', learning_rate_init=0.001,
max_iter=200, momentum=0.9, n_iter_no_change=10,
nesterovs_momentum=True, power_t=0.5, random_state=1,
shuffle=True, solver='lbfgs', tol=0.0001,
validation_fraction=0.1, verbose=False, warm_start=False)
>>> clf.predict([[1., 2.]])
array([[1, 1]])
>>> clf.predict([[0., 0.]])
array([[0, 1]])
sklearn.neural_network.MLPClassifier
参数 | 解释 |
---|---|
hidden_layer_sizes:tuple, length = n_layers - 2, default=(100,) | 第i个元素表示第i个隐藏层中的神经元数量。 |
activation:{‘identity’, ‘logistic’, ‘tanh’, ‘relu’}, default=’relu’ | 隐藏层的激活功能。 |
solver:{‘lbfgs’, ‘sgd’, ‘adam’}, default=’adam’ | 权重优化的求解器。“lbfgs” 是拟牛顿法族中的一个优化器。“sgd” 是指随机梯度下降。“adam” 是指由Kingma、Diederik和jimmyba提出的基于随机梯度的优化器。注意:默认的解算器’adam’在相对较大的数据集(具有数千个或更多的训练样本)上的训练时间和验证分数都非常好。不过,对于小型数据集,“lbfgs”可以更快地收敛,性能更好。 |
alpha:float, default=0.0001 | L2惩罚(正则化项)参数。 |
batch_size:int, default=’auto’ | 随机优化器的minibatches大小。如果解算器是“lbfgs”,分类器将不使用minibatch。当设置为“auto”时,batch_size=min(200, n_samples) |
learning_rate:{‘constant’, ‘invscaling’, ‘adaptive’}, default=’constant’ | 权重更新的学习率计划,仅当solver='sgd’时使用。。“constant” 是由“learning_rate_init”给出的恒定学习速率。“invscaling” 使用“power_t”的逆缩放指数在每个时间步“t”逐渐降低学习速率。effective_learning_rate = learning_rate_init / pow(t, power_t)。“adaptive” 保持学习速率恒定为“learning_rate_init”,只要训练损失不断减少。每次连续两个阶段未能将训练损失至少减少tol,或者如果启用“early_stopping”,则验证分数至少增加tol,则当前学习率除以5。 |
learning_rate_init:double, default=0.001 | 使用的初始学习速率。它控制更新权重的步长。仅当solver='sgd’或’adam’时使用。 |
power_t:double, default=0.5 | 逆比例学习率的指数。当learning_rate设置为“invscaling”时,用于更新有效学习速率。仅当solver='sgd’时使用。 |
max_iter:int, default=200 | 最大迭代次数。解算器迭代直到收敛(由“tol”确定)或此迭代次数。对于随机解算器(‘sgd’,‘adam’),请注意,这决定了epoch数(每个数据点将使用多少次),而不是梯度步数。 |
shuffle:bool, default=True | 是否在每次迭代中洗牌样本。仅当solver='sgd’或’adam’时使用。 |
random_state:int, RandomState instance, default=None | 确定权重和偏差初始化的随机数生成,如果使用提前停止,则进行train-test拆分,以及在solver='sgd’或’adam’时进行批采样。 |
tol:float, default=1e-4 | 优化公差。当损失或分数在连续迭代中没有至少tol的改善时,除非学习率设置为“自适应”,否则认为达到收敛并停止训练。 |
verbose:bool, default=False | 是否将进度消息打印到标准输出。 |
warm_start:bool, default=False | 当设置为True时,重用上一个调用的解决方案以适应初始化,否则,只需擦除上一个解决方案。 |
momentum:float, default=0.9 | 梯度下降更新的动量。应介于0和1之间。仅当solver='sgd’时使用。 |
nesterovs_momentum:bool, default=True | 是否使用Nesterov’s动力。仅在动力。仅在动力。仅在solver=’sgd’ 和momentum > 0时使用。 |
early_stopping:bool, default=False | 验证分数未提高时是否提前停止终止训练。如果设置为true,则会自动留出10%的训练数据作为验证,当验证分数在n_iter_no_change个连续epoch中没有改善时,终止训练。分割是分层的,但在多标签设置中除外。仅当solver='sgd’或’adam’时有效 |
validation_fraction:float, default=0.1 | 为提前停止而设置的作为验证集的训练数据的比例。必须介于0和1之间。仅在“early_stopping”为True时使用 |
beta_1:float, default=0.9 | adam中一阶矩向量估计的指数衰减率,应在[0,1]中。仅在solver=’adam’时使用 |
beta_2:float, default=0.999 | adam中二阶矩向量估计的指数衰减率,应在[0,1]中。仅在solver=’adam’时使用 |
epsilon:float, default=1e-8 | adam中的数值稳定性值。仅在solver=’adam’时使用 |
n_iter_no_change:int, default=10 | 无法满足的最大epoch数。仅当solver='sgd’或’adam’时有效 |
max_fun:int, default=15000 | 仅在solver='lbfgs’时使用。损失函数调用的最大数目。 |
属性 | 解释 |
---|---|
classes_:ndarray or list of ndarray of shape (n_classes,) | 每个输出的类标签。 |
loss_:float | 用损失函数计算的损失 |
best_loss_:float | 求解器在整个拟合过程中达到的最小损失。 |
loss_curve_:list of shape (n_iter_,) | 列表中的第i个元素表示第i次迭代的损失。 |
t_:int | 拟合期间解算器的训练样本数。 |
coefs_:list of shape (n_layers - 1,) | 列表中的第i个元素表示与第i层对应的权重矩阵。 |
intercepts_:list of shape (n_layers - 1,) | 列表中的第i个元素表示对应于层i+1的偏置向量。 |
n_iter_:int | 解算器已运行的迭代次数。 |
n_layers_:int | 层数。 |
n_outputs_:int | 输出数量。 |
out_activation_:str | 输出激活函数的名称。 |
方法 | 解释 |
---|---|
fit(X, y) | 对训练集拟合模型 |
get_params([deep]) | 获取此估计器的参数。 |
set_params(**params) | 设置此估计器的参数。 |
predict(X) | 利用多层感知器分类器进行预测 |
predict_log_proba(X) | 返回概率估计的对数 |
predict_proba(X) | 概率估计。 |
score(X, y[, sample_weight]) | 返回给定测试数据和标签的平均精度。 |
例:
>>> from sklearn.neural_network import MLPClassifier
>>> from sklearn.datasets import make_classification
>>> from sklearn.model_selection import train_test_split
>>> X, y = make_classification(n_samples=100, random_state=1)
>>> X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y,
... random_state=1)
>>> clf = MLPClassifier(random_state=1, max_iter=300).fit(X_train, y_train)
>>> clf.predict_proba(X_test[:1])
array([[0.038..., 0.961...]])
>>> clf.predict(X_test[:5, :])
array([1, 0, 1, 0, 1])
>>> clf.score(X_test, y_test)
0.8...
1.17.3. 回归【neural_network.MLPRegressor】
MLPRegressor
类多层感知器(MLP)的实现,在使用反向传播进行训练时的输出层没有使用激活函数,也可以看作是使用恒等函数(identity function)作为激活函数。 因此,它使用平方误差作为损失函数,输出是一组连续值。
MLPRegressor
还支持多输出回归,其中一个样本可以有多个目标值。
sklearn.neural_network.MLPRegressor
参数 | 解释 |
---|---|
hidden_layer_sizes:tuple, length = n_layers - 2, default=(100,) | 第i个元素表示第i个隐藏层中的神经元数量。 |
activation:{‘identity’, ‘logistic’, ‘tanh’, ‘relu’}, default=’relu’ | 隐藏层的激活功能。 |
solver:{‘lbfgs’, ‘sgd’, ‘adam’}, default=’adam’ | 权重优化的求解器。“lbfgs” 是拟牛顿法族中的一个优化器。“sgd” 是指随机梯度下降。“adam” 是指由Kingma、Diederik和jimmyba提出的基于随机梯度的优化器。注意:默认的解算器’adam’在相对较大的数据集(具有数千个或更多的训练样本)上的训练时间和验证分数都非常好。不过,对于小型数据集,“lbfgs”可以更快地收敛,性能更好。 |
alpha:float, default=0.0001 | L2惩罚(正则化项)参数。 |
batch_size:int, default=’auto’ | 随机优化器的minibatches大小。如果解算器是“lbfgs”,分类器将不使用minibatch。当设置为“auto”时,batch_size=min(200, n_samples) |
learning_rate:{‘constant’, ‘invscaling’, ‘adaptive’}, default=’constant’ | 权重更新的学习率计划,仅当solver='sgd’时使用。。“constant” 是由“learning_rate_init”给出的恒定学习速率。“invscaling” 使用“power_t”的逆缩放指数在每个时间步“t”逐渐降低学习速率。effective_learning_rate = learning_rate_init / pow(t, power_t)。“adaptive” 保持学习速率恒定为“learning_rate_init”,只要训练损失不断减少。每次连续两个阶段未能将训练损失至少减少tol,或者如果启用“early_stopping”,则验证分数至少增加tol,则当前学习率除以5。 |
learning_rate_init:double, default=0.001 | 使用的初始学习速率。它控制更新权重的步长。仅当solver='sgd’或’adam’时使用。 |
power_t:double, default=0.5 | 逆比例学习率的指数。当learning_rate设置为“invscaling”时,用于更新有效学习速率。仅当solver='sgd’时使用。 |
max_iter:int, default=200 | 最大迭代次数。解算器迭代直到收敛(由“tol”确定)或此迭代次数。对于随机解算器(‘sgd’,‘adam’),请注意,这决定了epoch数(每个数据点将使用多少次),而不是梯度步数。 |
shuffle:bool, default=True | 是否在每次迭代中洗牌样本。仅当solver='sgd’或’adam’时使用。 |
random_state:int, RandomState instance, default=None | 确定权重和偏差初始化的随机数生成,如果使用提前停止,则进行train-test拆分,以及在solver='sgd’或’adam’时进行批采样。 |
tol:float, default=1e-4 | 优化公差。当损失或分数在连续迭代中没有至少tol的改善时,除非学习率设置为“自适应”,否则认为达到收敛并停止训练。 |
verbose:bool, default=False | 是否将进度消息打印到标准输出。 |
warm_start:bool, default=False | 当设置为True时,重用上一个调用的解决方案以适应初始化,否则,只需擦除上一个解决方案。 |
momentum:float, default=0.9 | 梯度下降更新的动量。应介于0和1之间。仅当solver='sgd’时使用。 |
nesterovs_momentum:bool, default=True | 是否使用Nesterov’s动力。仅在动力。仅在动力。仅在solver=’sgd’ 和momentum > 0时使用。 |
early_stopping:bool, default=False | 验证分数未提高时是否提前停止终止训练。如果设置为true,则会自动留出10%的训练数据作为验证,当验证分数在n_iter_no_change个连续epoch中没有改善时,终止训练。分割是分层的,但在多标签设置中除外。仅当solver='sgd’或’adam’时有效 |
validation_fraction:float, default=0.1 | 为提前停止而设置的作为验证集的训练数据的比例。必须介于0和1之间。仅在“early_stopping”为True时使用 |
beta_1:float, default=0.9 | adam中一阶矩向量估计的指数衰减率,应在[0,1]中。仅在solver=’adam’时使用 |
beta_2:float, default=0.999 | adam中二阶矩向量估计的指数衰减率,应在[0,1]中。仅在solver=’adam’时使用 |
epsilon:float, default=1e-8 | adam中的数值稳定性值。仅在solver=’adam’时使用 |
n_iter_no_change:int, default=10 | 无法满足的最大epoch数。仅当solver='sgd’或’adam’时有效 |
max_fun:int, default=15000 | 仅在solver='lbfgs’时使用。损失函数调用的最大数目。 |
属性 | 解释 |
---|---|
loss_:float | 用损失函数计算的损失 |
best_loss_:float | 求解器在整个拟合过程中达到的最小损失。 |
loss_curve_:list of shape (n_iter_,) | 列表中的第i个元素表示第i次迭代的损失。 |
t_:int | 拟合期间解算器的训练样本数。 |
coefs_:list of shape (n_layers - 1,) | 列表中的第i个元素表示与第i层对应的权重矩阵。 |
intercepts_:list of shape (n_layers - 1,) | 列表中的第i个元素表示对应于层i+1的偏置向量。 |
n_iter_:int | 解算器已运行的迭代次数。 |
n_layers_:int | 层数。 |
n_outputs_:int | 输出数量。 |
out_activation_:str | 输出激活函数的名称。 |
方法 | 解释 |
---|---|
fit(X, y) | 对训练集拟合模型 |
get_params([deep]) | 获取此估计器的参数。 |
set_params(**params) | 设置此估计器的参数。 |
predict(X) | 利用多层感知器分类器进行预测 |
score(X, y[, sample_weight]) | 返回给定测试数据和标签的平均精度。 |
例:
>>> from sklearn.neural_network import MLPRegressor
>>> from sklearn.datasets import make_regression
>>> from sklearn.model_selection import train_test_split
>>> X, y = make_regression(n_samples=200, random_state=1)
>>> X_train, X_test, y_train, y_test = train_test_split(X, y,
... random_state=1)
>>> regr = MLPRegressor(random_state=1, max_iter=500).fit(X_train, y_train)
>>> regr.predict(X_test[:2])
array([-0.9..., -7.1...])
>>> regr.score(X_test, y_test)
0.4...
1.17.4. 正则化
MLPRegressor
类和 MLPClassifier
类都使用参数 alpha
作为正则化( L2 正则化)系数,正则化通过惩罚大数量级的权重值以避免过拟合问题。 下面的图表展示了不同的 alpha
值下的决策函数的变化。
1.17.5. 算法
MLP
使用 Stochastic Gradient Descent
(随机梯度下降)(SGD
), Adam
, 或者 L-BFGS
进行训练。 随机梯度下降(SGD
) 使用关于需要适应的一个参数的损失函数的梯度来更新参数,即
w ← w − η ( α ∂ R ( w ) ∂ w + ∂ L o s s ∂ w ) w \leftarrow w - \eta (\alpha \frac{\partial R(w)}{\partial w}+ \frac{\partial Loss}{\partial w}) w←w−η(α∂w∂R(w)+∂w∂Loss)
其中 η \eta η 是控制训练过程参数更新步长的学习率(learning rate)。 L o s s Loss Loss 是损失函数(loss function)。
Adam
类似于 SGD
,因为它是 stochastic optimizer
(随机优化器),但它可以根据低阶矩的自适应估计自动调整参数更新的量。
使用SGD
或Adam
,训练过程支持在线模式和小批量学习模式。
L-BFGS
是利用 Hessian 矩阵
来近似函数的二阶偏导数的求解器,它使用Hessian
的逆矩阵来近似进行参数更新。 该实现使用 Scipy 版本的 L-BFGS。
如果所选择的方法是 ‘L-BFGS’
,训练过程不支持在线学习模式和小批量学习模式。
1.17.6. 复杂度
假设有 n n n 个训练样本, m m m 个特征, k k k 个隐藏层,每个包含 h h h 个神经元 - 为简单起见, o o o 个输出神经元。 反向传播的时间复杂度是 O ( n ⋅ m ⋅ h k ⋅ o ⋅ i ) O(n\cdot m \cdot h^k \cdot o \cdot i) O(n⋅m⋅hk⋅o⋅i) ,其中 i i i 是迭代次数。 由于反向传播具有高时间复杂性,最好以较少数量的隐藏层神经元和较少的隐藏层个数开始训练。
1.17.7. 数学公式
给出一组训练样本 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1, y_1), (x_2, y_2) (x1,y1),(x2,y2), … \ldots …, ( x n , y n ) (x_n, y_n) (xn,yn) 其中 x i ∈ R n , y i ∈ 0 , 1 x_i \in \mathbf{R}^n , y_i \in {0, 1} xi∈Rn,yi∈0,1 ,一个单隐藏层单神经元 MLP 学习到的函数是 f ( x ) = W 2 g ( W 1 T x + b 1 ) + b 2 f(x) = W_2 g(W_1^T x + b_1) + b_2 f(x)=W2g(W1Tx+b1)+b2 ,其中 W 1 ∈ R m W_1 \in \mathbf{R}^m W1∈Rm 和 W 2 , b 1 , b 2 ∈ R W_2, b_1, b_2 \in \mathbf{R} W2,b1,b2∈R 是模型参数. W 1 W_1 W1, W 2 W_2 W2 分别是输入层与隐藏层之间和隐藏层与输出层之间的权重, b 1 b_1 b1, b 2 b_2 b2 分别是隐藏层和输出层的偏置值. g ( ⋅ ) : R → R g(\cdot) : R \rightarrow R g(⋅):R→R 是激活函数,默认为双曲正切函数。 具体形式如下,
g ( z ) = e z − e − z e z + e − z g(z)= \frac{e^z-e^{-z}}{e^z+e^{-z}} g(z)=ez+e−zez−e−z
对于二分类, f ( x ) f(x) f(x) 经过 l o g i s t i c logistic logistic 函数 g ( z ) = 1 / ( 1 + e − z ) g(z)=1/(1+e^{-z}) g(z)=1/(1+e−z) 得到 0 到 1 之间的输出值。 阈值设置为 0.5 ,输出大于等于 0.5 的样本分到 positive class (正类),其他的分为 negative class (负类)。
如果多于两类,则 f ( x ) f(x) f(x) 本身将是一个大小为 (n_classes,) 的向量。 它需要经过 softmax 函数而不是 logistic 函数进行变换,具体形式如下,
softmax ( z ) i = exp ( z i ) ∑ l = 1 k exp ( z l ) \text{softmax}(z)_i = \frac{\exp(z_i)}{\sum_{l=1}^k\exp(z_l)} softmax(z)i=∑l=1kexp(zl)exp(zi)
其中 z i z_i zi 表示 softmax 函数的第 i i i 个输入的元素,它对应于第 i i i 类, K K K 是类别的数量。 计算结果是样本 x x x 属于每个类别的概率的向量。 最终输出的分类结果是具有最高概率的类别。
在回归问题中,输出依然是 f ( x ) f(x) f(x) ;因此,输出激活函数就是恒等函数。
MLP 根据特定问题使用不同的损失函数。 二分类问题的损失函数的是交叉熵,具体形式如下,
L o s s ( y ^ , y , W ) = − y ln y ^ − ( 1 − y ) ln ( 1 − y ^ ) + α ∣ ∣ W ∣ ∣ 2 2 Loss(\hat{y},y,W) = -y \ln {\hat{y}} - (1-y) \ln{(1-\hat{y})} + \alpha ||W||_2^2 Loss(y^,y,W)=−ylny^−(1−y)ln(1−y^)+α∣∣W∣∣22
其中 α ∣ ∣ W ∣ ∣ 2 2 \alpha ||W||_2^2 α∣∣W∣∣22 是 L2 正则化的模型复杂度惩罚项; α > 0 \alpha > 0 α>0 这个非负的超参数控制惩罚的程度。
对于回归问题,MLP 使用平方误差损失函数,具体形式如下,
L o s s ( y ^ , y , W ) = 1 2 ∣ ∣ y ^ − y ∣ ∣ 2 2 + α 2 ∣ ∣ W ∣ ∣ 2 2 Loss(\hat{y},y,W) = \frac{1}{2}||\hat{y} - y ||_2^2 + \frac{\alpha}{2} ||W||_2^2 Loss(y^,y,W)=21∣∣y^−y∣∣22+2α∣∣W∣∣22
从随机初始化权重开始,多层感知器(MLP)不断更新这些权重值来最小化损失函数。计算完损失之后,从输出层到前面各层进行反向传播,更新权重参数的值,旨在减小损失函数。
在梯度下降中,计算得到损失函数关于每个权重的梯度 ∇ L o s s W \nabla Loss_{W} ∇LossW 并从权重 W 中减掉。用公式表示为,
W i + 1 = W i − ϵ ∇ L o s s W i W^{i+1} = W^i - \epsilon \nabla {Loss}_{W}^{i} Wi+1=Wi−ϵ∇LossWi
其中 i i i 是当前迭代步数, ϵ \epsilon ϵ 是大于 0 学习率。
算法停止的条件或者是达到预设的最大迭代次数,或者是损失函数低于某个特定值。
1.17.8. 实用技巧
多层感知器对特征的缩放是敏感的,所以它强烈建议您归一化你的数据。 例如,将输入向量 X 的每个属性放缩到到 [0, 1] 或 [-1,+1] ,或者将其标准化使它具有 0 均值和方差 1。注意,为了得到有意义的结果,您必须对测试集也应用 相同的 尺度缩放。 您可以使用 StandardScaler
进行标准化。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
# Don't cheat - fit only on training data
scaler.fit(X_train)
X_train = scaler.transform(X_train)
# apply same transformation to test data
X_test = scaler.transform(X_test)
另一个推荐的方法是在 Pipeline
中使用的 StandardScaler
。
- 最好使用
GridSearchCV
找到一个合理的正则化参数 α \alpha α ,通常范围是在 10.0 ∗ ∗ − n p . a r a n g e ( 1 , 7 ) 10.0 ** -np.arange(1, 7) 10.0∗∗−np.arange(1,7) 。 - 据经验可知,我们观察到
L-BFGS
收敛速度是更快的并且是小数据集上更好的解决方案。对于规模相对比较大的数据集,Adam
是非常鲁棒的。 它通常会迅速收敛,并得到相当不错的表现。另一方面,如果学习率调整得正确, 使用momentum
或 nesterov’s momentum 的 SGD 可以比这两种算法更好。
1.17.9. 使用 warm_start 的更多控制
如果您希望更多地控制 SGD
中的停止标准或学习率,或者想要进行额外的监视,使用 warm_start=True
和 max_iter=1
并且自身迭代可能会有所帮助:
>>> X = [[0., 0.], [1., 1.]]
>>> y = [0, 1]
>>> clf = MLPClassifier(hidden_layer_sizes=(15,), random_state=1, max_iter=1, warm_start=True)
>>> for i in range(10):
... clf.fit(X, y)
... # additional monitoring / inspection
MLPClassifier(...