处理多维特征的输入
之前我们处理的都是单维度的输入,也就是输入 x x x 是一个实数,那当我们面对多维输入的时候,那么我们怎么预测它对应的分类呢?
在之前的例子中,我们使用了这样的两个数据集。第一个是用来做回归任务的,第二个是用来做分类任务的。这两个数据集的差别主要在于
y
y
y 的输出值。对于回归任务来说,它的输出
y
y
y 是属于实数的;而对于分类任务来说,它的输出
y
y
y 是一个离散的集合。
下面我们再来看这样一个数据集,该数据集是关于糖尿病的。每一行是一个 Sample(样本),每一列是一个 Feature(特征)。
在 sklearn 中也提供了相应的数据:
现在我们数据的特征从 1 维变化到 8 维,所以模型也就相应的变化。
如果我们将
x
x
x 看作一个向量,可以将上面的式子写成如下形式:
我们的输出也就相应的写成(
σ
σ
σ 是 Sigmoid 函数):
接下来我们来看看 mini-batch 的情况,对于上面的输出 z^(1) 到 z^(n),都要去计算相应的
σ
σ
σ, 实际上,在 Pytorch 中,所提供的函数都是遵从向量化函数。
比如,举个栗子。
输出 z^(1) 到 z^(n) 的表达式如下:
所以 z^(1) 到 z^(n),唯一不同的就是样本不同,也就是
x
x
x 不同。如果我们将 z^(1) 到 z^(N) 看成一个 N 行 1 列的矩阵,那么相应的表达式就可以修改为:
这样我们就将一组的方程运算转换成了矩阵运算,矩阵运算好处就是可以利用并行计算的能力来提高整个运算的速度。
那么我们的代码在模型设计那一块只需要做一处修改即可。
我们之前说的逻辑回归一直都只有一层,现在我们想把它扩展为多层,意思就是将多个逻辑回归这种线性变换首尾相连,就可以构造一个多层的神经网络。下面来看一下构造的方式。
现在我们的输入
x
x
x 是 8 维,输出是 1 维,那么根据
y
=
w
x
+
b
y = wx + b
y=wx+b,可以得出
W
W
W 是一个 8x1 的矩阵。
那么:
如果我们的输入变成了 2 维,而不再是一维:
那么,有些小伙伴肯定觉得不行呀,我们的输出是一个概率,应该是只有一个维度的。我们只需要再在后面接一个 2 个维度的输入和 1 个维度的输出即可,那么这样就可以从 2 维降到 1 维。所以我们就会发现线性变换层实际就是线性代数中的矩阵,矩阵其实就是空间变换的函数。比如常见的线性方程
y
=
A
x
y = Ax
y=Ax,
x
x
x 属于 N 维的向量,
y
y
y 属于 M 维的向量,所以
A
A
A 就是一个 MxN 的矩阵。
上面这个式子实际上就揭示了空间的转换,我们要把所有的
x
x
x 从 N 维空间映射到 M 维的空间中。所以我们要把矩阵看做是一种空间变换的函数。
那我们再来看这个式子:
它的意思就是把一个8维空间的向量映射到一个维空间中,做这样一个线性的映射。但是我们所做的空间变换不一定是这种线性的,可能是一种复杂的非线性的映射。所以我们就想用多个线性变换层通过找到最优的权重把它们组合起来来模拟出这种非线性的变换。所以神经网络的本质就是寻找一种非线性的空间变换函数。
那么对于神经网络来说,假设我们输入的
X
X
X 是一个 8 维的,我们通过一个非线性的变换转换为
O
1
O_1
O1,它是一个6维的,然后我们再通过一个非线性的变换将
O
1
O_1
O1 降成一个2维的,以此类推,直到降到 1 维。
当然我们也可以将升维,再降维,但是变换的层数决定了神经网络的复杂程度。但是这里降到哪一个维度最好,这就是关于超参数的搜索的问题。
下面举一个小例子,比如说我们要构造这样一个神经网络。
那么我们就用这个模型来处理糖尿病这个分类,数据中的
X
1
X1
X1 到
X
8
X8
X8 是病人的各项指标,
Y
Y
Y 表示一年后病情是否会加重。
我们使用神经网络来处理这个多维特征的输入,那是那四步。
先来看一下第一步数据的读取:
下面我们看一下模型上的改变,由一个线性模型增加到了三个线性模型:
关于损失函数的构造和优化器,没有变化。
最后关于 Training Cycle,虽然之前说的是 mini-batch 的风格,但是我们还是把所有的输入都放入模型中,所以下面这个不是 mini-batch。
所以整体的代码就是这么一个形式。