如何在 Matlab 中为多 class 数据集创建多层感知器
How to create a multi-layer perceptron in Matlab for a multi-class dataset
我想为作业创建一个双层感知器。
它将充当 Fisher 鸢尾花数据集的 class 转换器。
我在创建网络时遇到了以下问题:
- 对于像上面这样的数据集,我可以用一个单一的设置网络吗?
输入并传递 n 行和 4 个特征的整个训练矩阵作为
输入值?或者,我是否需要调整网络以使用 4 个输入
节点,每个特征1个,并将训练矩阵作为输入
值?
- 此外,如何正确连接各层?
例如,当我使用 4 个输入创建一个感知器时
network 命令,我真的不明白 biasConnect、inputConnect 和 layerConnect 到底做了什么。
- 最后,我需要多少个输出才能正确 classify 一个元素?
我遇到的每个例子都使用一个输出,但是,只会一个
够了吗?或者,每个 class 都需要一个吗?
用于创建第二点提到的网络的命令:
net = network(4, 2, [1; 0], [1 1 1 1;0 0 0 0], [0 0; 1 0], [0 1]);
让我们从网络连接开始。 network
函数的工作方式不是很直观。为了控制输入向量是否正确描述结构,您可以使用 view(net)
:
现在让我们简单地讨论一下每个参数:
numInputs
- 如果你的网络只会得到一个输入数据集,你需要把 1
放在这里。
numLayers
- 对于 iris 数据集,这里使用 2
是可以的。
biasConnect
- 偏置单元用于 "increase" 输入和输出之间的非线性。我们希望网络能够逼近复杂的非线性函数,这就是为什么在两层都添加偏置单元是个好主意。所以放在这里 [1, 1]
.
inputConnect
- 向量的维度为 numLayers-by-numInputs
。它显示哪些输入连接到哪些层。你只有一个输入连接到第一层,所以把 [1;0]
放在这里。
layerConnect
- 向量的维度为 numLayers-by-numLayers
。你有两层。第一层连接到第二层,但不连接到自身。从第二层到第一层没有连接,第二层也不自己供电。将 [0 0; 1 0]
放在这里。
outputConnect
- 向量的维度为 1-by-numLayers
并显示哪个层连接到输出。将 [0 1]
放在这里。
这是我们的命令和对应的图表:
net = network(1, 2, [1; 1], [1;0], [0 0; 1 0], [0 1]);
您可以对参数进行试验,得到的结构可能非常复杂。
网络配置
现在您需要配置网络。您可以在文档中找到所有参数,我将在这里描述最重要的参数:
为层设置正确的激活函数很重要。默认情况下,函数设置为 purelin
。您可能想在这里使用 tansig
或 logsig
.
您需要设置每一层的大小。在你的情况下,我会在第一层使用 5 或 7 个单元。第二层的大小应该等于输出的数量 类: 3
在你的情况下。
还应为每一层设置权重和偏置单元的初始化函数。
生成的网络如下所示:
代码如下:
net = network(1, 2, [1; 1], [1;0], [0 0; 1 0], [0 1]);
net.adaptFcn = 'adaptwb';
net.divideFcn = 'dividerand'; %Set the divide function to dividerand (divide training data randomly).
net.performFcn = 'mse';
net.trainFcn = 'trainlm'; % set training function to trainlm (Levenberg-Marquardt backpropagation)
net.plotFcns = {'plotperform', 'plottrainstate', 'ploterrhist', 'plotconfusion', 'plotroc'};
%set Layer1
net.layers{1}.name = 'Layer 1';
net.layers{1}.dimensions = 7;
net.layers{1}.initFcn = 'initnw';
net.layers{1}.transferFcn = 'tansig';
%set Layer2
net.layers{2}.name = 'Layer 2';
net.layers{2}.dimensions = 3;
net.layers{2}.initFcn = 'initnw';
net.layers{2}.transferFcn = 'tansig';
[x,t] = iris_dataset; %load of the iris data set
net = train(net,x, t); %training
y = net(x); %prediction
view(net);
混淆矩阵看起来不错。所以网络很好!
有点射手的方式
如果你想使用已经预装的网络,你可以使用这个代码:
[x,t] = iris_dataset;
net = patternnet;
net = configure(net,x,t);
net = train(net,x,t); %training
view(net);
y = net(x); %predict
我想为作业创建一个双层感知器。
它将充当 Fisher 鸢尾花数据集的 class 转换器。
我在创建网络时遇到了以下问题:
- 对于像上面这样的数据集,我可以用一个单一的设置网络吗? 输入并传递 n 行和 4 个特征的整个训练矩阵作为 输入值?或者,我是否需要调整网络以使用 4 个输入 节点,每个特征1个,并将训练矩阵作为输入 值?
- 此外,如何正确连接各层?
例如,当我使用 4 个输入创建一个感知器时 network 命令,我真的不明白 biasConnect、inputConnect 和 layerConnect 到底做了什么。 - 最后,我需要多少个输出才能正确 classify 一个元素? 我遇到的每个例子都使用一个输出,但是,只会一个 够了吗?或者,每个 class 都需要一个吗?
用于创建第二点提到的网络的命令:
net = network(4, 2, [1; 0], [1 1 1 1;0 0 0 0], [0 0; 1 0], [0 1]);
让我们从网络连接开始。 network
函数的工作方式不是很直观。为了控制输入向量是否正确描述结构,您可以使用 view(net)
:
现在让我们简单地讨论一下每个参数:
numInputs
- 如果你的网络只会得到一个输入数据集,你需要把 1
放在这里。
numLayers
- 对于 iris 数据集,这里使用 2
是可以的。
biasConnect
- 偏置单元用于 "increase" 输入和输出之间的非线性。我们希望网络能够逼近复杂的非线性函数,这就是为什么在两层都添加偏置单元是个好主意。所以放在这里 [1, 1]
.
inputConnect
- 向量的维度为 numLayers-by-numInputs
。它显示哪些输入连接到哪些层。你只有一个输入连接到第一层,所以把 [1;0]
放在这里。
layerConnect
- 向量的维度为 numLayers-by-numLayers
。你有两层。第一层连接到第二层,但不连接到自身。从第二层到第一层没有连接,第二层也不自己供电。将 [0 0; 1 0]
放在这里。
outputConnect
- 向量的维度为 1-by-numLayers
并显示哪个层连接到输出。将 [0 1]
放在这里。
这是我们的命令和对应的图表:
net = network(1, 2, [1; 1], [1;0], [0 0; 1 0], [0 1]);
您可以对参数进行试验,得到的结构可能非常复杂。
网络配置
现在您需要配置网络。您可以在文档中找到所有参数,我将在这里描述最重要的参数:
为层设置正确的激活函数很重要。默认情况下,函数设置为
purelin
。您可能想在这里使用tansig
或logsig
.您需要设置每一层的大小。在你的情况下,我会在第一层使用 5 或 7 个单元。第二层的大小应该等于输出的数量 类:
3
在你的情况下。还应为每一层设置权重和偏置单元的初始化函数。
生成的网络如下所示:
代码如下:
net = network(1, 2, [1; 1], [1;0], [0 0; 1 0], [0 1]);
net.adaptFcn = 'adaptwb';
net.divideFcn = 'dividerand'; %Set the divide function to dividerand (divide training data randomly).
net.performFcn = 'mse';
net.trainFcn = 'trainlm'; % set training function to trainlm (Levenberg-Marquardt backpropagation)
net.plotFcns = {'plotperform', 'plottrainstate', 'ploterrhist', 'plotconfusion', 'plotroc'};
%set Layer1
net.layers{1}.name = 'Layer 1';
net.layers{1}.dimensions = 7;
net.layers{1}.initFcn = 'initnw';
net.layers{1}.transferFcn = 'tansig';
%set Layer2
net.layers{2}.name = 'Layer 2';
net.layers{2}.dimensions = 3;
net.layers{2}.initFcn = 'initnw';
net.layers{2}.transferFcn = 'tansig';
[x,t] = iris_dataset; %load of the iris data set
net = train(net,x, t); %training
y = net(x); %prediction
view(net);
混淆矩阵看起来不错。所以网络很好!
有点射手的方式
如果你想使用已经预装的网络,你可以使用这个代码:
[x,t] = iris_dataset;
net = patternnet;
net = configure(net,x,t);
net = train(net,x,t); %training
view(net);
y = net(x); %predict