Matlab - 神经网络训练

时间:2009-08-17 23:27:03

标签: matlab machine-learning neural-network

我正在创建一个带有反向传播的2层神经网络。 NN应该从20001x17向量中获取其数据,该向量在每行中保存以下信息:

- 前16个单元格保存0到15之间的整数,它们作为变量来帮助我们确定在看到这些变量时我们要表达的26个字母中的哪一个。例如,如下所示的一系列16个值表示字母A:[2 8 4 5 2 7 5 3 1 6 0 8 2 7 2 7]。

- 第17个单元格保存1到26之间的数字,表示我们想要的字母。 1代表A,2代表B等。

NN的输出层由26个输出组成。每当NN被输入如上所述的输入时,它应该输出包含零的1x26向量,除了与输入值要表示的字母对应的一个单元。例如,输出[1 0 0 ... 0]将为字母A,而[0 0 0 ... 1]将为字母Z.

在我呈现代码之前一些重要的事情:我需要使用traingdm函数,隐藏的图层编号在21处是固定的(现在)。

尝试创建上述概念我编写了以下matlab代码:

%%%%%%%%
%Start of code%
%%%%%%%%

%
%Initialize the input and target vectors
%
p = zeros(16,20001);
t = zeros(26,20001);

%
%Fill the input and training vectors from the dataset provided
%
for i=2:20001
    for k=1:16
        p(k,i-1) = data(i,k);
    end
    t(data(i,17),i-1) = 1;
end

net = newff(minmax(p),[21 26],{'logsig' 'logsig'},'traingdm');

y1 = sim(net,p);

net.trainParam.epochs = 200;
net.trainParam.show = 1;
net.trainParam.goal = 0.1;
net.trainParam.lr = 0.8;
net.trainParam.mc = 0.2;
net.divideFcn = 'dividerand';
net.divideParam.trainRatio = 0.7;
net.divideParam.testRatio = 0.2;
net.divideParam.valRatio = 0.1;

%[pn,ps] = mapminmax(p);
%[tn,ts] = mapminmax(t);

net = init(net);
[net,tr] = train(net,p,t);

y2 = sim(net,pn);

%%%%%%%%
%End of code%
%%%%%%%%

现在我的问题:我希望我的输出如上所述,例如y2向量的每一列应该是一个字母的表示。我的代码不会这样做。相反,它产生的结果在0和1之间变化很大,值从0.1到0.9。

我的问题是:我需要做一些转换吗?我不是吗?这意味着,我是否必须将输入和/或输出数据转换为一种形式,通过该形式我可以实际看到我的NN是否正确学习?

任何意见都会受到赞赏。

4 个答案:

答案 0 :(得分:2)

这很正常。你的输出层使用了一个log-sigmoid传递函数,它总会给你一些介于0和1之间的中间输出。

您通常会查找具有最大值的输出 - 换句话说,最有可能的字符。

这意味着,对于y2中的每一列,您都在寻找包含该行中最大值的行的索引。您可以按如下方式计算:

[dummy, I]=max(y2);

I是一个包含每行中最大值索引的向量。

答案 1 :(得分:1)

您可以将 y2 视为每个输入为26个字母字符之一的输出概率分布,例如,如果一列 y2 表示:

.2
.5
.15
.15

那么这个字符为B的概率为50%(如果我们假设只有4个可能的输出)。



== REMARK ==

  

NN的输出层由   26项产出。每次NN喂食   像上述那样的输入   它应该输出1x26矢量   除了一个之外的所有内容都包含零   对应于字母的单元格   输入值的意思是   代表。例如输出[1 0   0 ... 0]将是字母A,而[0   0 0 ... 1]将是字母Z。

最好避免使用0,1的目标值来编码网络的输出 避免目标值0和1的原因是'logsig' sigmoid传递函数在给定有限权重的情况下不能产生这些输出值。如果您尝试训练网络以适应0和1的目标值,则梯度下降将迫使权重无限制地增长。
因此,请尝试使用0.04和0.9的值代替0和1值,以便[0.9,0.04,...,0.04]是字母 A 的目标输出向量。


参考:
Thomas M. Mitchell,机器学习,McGraw-Hill高等教育,1997年,第114-115页

答案 2 :(得分:1)

  1. 在输出图层中使用hardlin fcn
    1. 使用trainlmtrainrp来培训网络。
    2. 要了解您的网络,请使用for循环和比较输出和目标的条件。当它是最佳使用时,请从学习循环中退出。
    3. 使用其他方式代替mapminmax预处理数据集。

答案 3 :(得分:0)

我不知道这是否构成了实际答案:但这里有一些评论。

  • 我不明白你的编码方案。 “A”如何表示为那组数字?看起来你正陷入使用任意数字来编码分类值的相当普遍的陷阱。不要这样做:例如,如果'a'是1,'b'是2而'c'是3,那么你的编码暗示'a'更像'b'而不是'c'(因为网络具有实数值输入,序数属性很重要)。正确地做到这一点的方法是将每个字母表示为26个二进制值输入,其中只有一个是活动的,代表字母。
  • 您的输出是正确的,输出层的激活不会 永远不是0或1,而是实数。你可以把最大值作为 你的活动功能,但这是有问题的,因为它不是 可区分,所以你不能使用back-prop。你应该做的是 将输出与softmax function耦合,以便它们的总和 是一个。然后,您可以将输出视为条件概率 如果您愿意的话,给予投入。虽然网络不是 明确的概率,具有正确的活动和激活 函数的结构与对数线性模型相同 (可能有潜在变量对应隐藏层), 人们一直这样做。

请参阅David Mackay's textbook了解神经网络的一个很好的介绍,它将明确概率连接。查看this paper from Geoff Hinton's group,其中描述了在给定上下文的情况下预测下一个字符的任务,以获取有关正确表示和激活/活动功能的详细信息(尽管要注意他们的方法非常重要并且使用具有不同培训的经常性网络法)。