循环神经网络用于预测序列中的下一个值的示例请求

29

谁能给我一个实际的例子,使用(pybrain)python中的递归神经网络,以预测序列的下一个值?(我已经阅读了pybrain文档,但没有清晰的例子。) 我也发现了这个问题但我不明白它在更一般的情况下如何工作。因此,我想问这里是否有人能够提供一个清晰的例子来预测pybrain中序列的下一个值,使用递归神经网络

举个例子。

比如说,我们有一个数字范围为[1,7]的序列。

First run (So first example): 1 2 4 6 2 3 4 5 1 3 5 6 7 1 4 7 1 2 3 5 6

Second run (So second example): 1 2 5 6 2 4 4 5 1 2 5 6 7 1 4 6 1 2 3 3 6

Third run (So third example): 1 3 5 7 2 4 6 7 1 3 5 6 7 1 4 6 1 2 2 3 7

and so on.

现在给出一个新序列的开始:1 3 5 7 2 4 6 7 1 3

下一个值是什么/下一组值是什么?

这个问题看起来有些懒惰,但我认为缺乏如何用pybrain解决这个问题的好的、体面的例子。


另外:如果存在多个特征,怎么做呢:

例如:

假设我们有几个序列(每个序列都有两个特征),范围在[1,7]之间。

First run (So first example): feature1: 1 2 4 6 2 3 4 5 1 3 5 6 7 1 4 7 1 2 3 5 6
                              feature2: 1 3 5 7 2 4 6 7 1 3 5 6 7 1 4 6 1 2 2 3 7


Second run (So second example): feature1: 1 2 5 6 2 4 4 5 1 2 5 6 7 1 4 6 1 2 3 3 6
                                feature2: 1 2 3 7 2 3 4 6 2 3 5 6 7 2 4 7 1 3 3 5 6    

Third run (So third example): feature1: 1 3 5 7 2 4 6 7 1 3 5 6 7 1 4 6 1 2 2 3 7
                              feature2: 1 2 4 6 2 3 4 5 1 3 5 6 7 1 4 7 1 2 3 5 6

and so on.

现在举个例子,开始一个新的序列:

                                            feature 1: 1 3 5 7 2 4 6 7 1 3

                                            feature 2: 1 2 3 7 2 3 4 6 2 4

下一个值(或值)是什么?


请随意使用自己的示例,只要它与这些示例相似并且有一些深入的解释。

2个回答

10

Issam Laradji曾为我工作,帮助我预测序列的序列,但我的pybrain版本需要一个元组来创建UnserpervisedDataSet对象:

from pybrain.tools.shortcuts import buildNetwork
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.datasets import SupervisedDataSet,UnsupervisedDataSet
from pybrain.structure import LinearLayer
ds = SupervisedDataSet(21, 21)
ds.addSample(map(int,'1 2 4 6 2 3 4 5 1 3 5 6 7 1 4 7 1 2 3 5 6'.split()),map(int,'1 2 5 6 2 4 4 5 1 2 5 6 7 1 4 6 1 2 3 3 6'.split()))
ds.addSample(map(int,'1 2 5 6 2 4 4 5 1 2 5 6 7 1 4 6 1 2 3 3 6'.split()),map(int,'1 3 5 7 2 4 6 7 1 3 5 6 7 1 4 6 1 2 2 3 7'.split()))
net = buildNetwork(21, 20, 21, outclass=LinearLayer,bias=True, recurrent=True)
trainer = BackpropTrainer(net, ds)
trainer.trainEpochs(100)
ts = UnsupervisedDataSet(21,)
ts.addSample(map(int,'1 3 5 7 2 4 6 7 1 3 5 6 7 1 4 6 1 2 2 3 7'.split()))
[ int(round(i)) for i in net.activateOnDataset(ts)[0]]

给出:

=> [1, 2, 5, 6, 2, 4, 5, 6, 1, 2, 5, 6, 7, 1, 4, 6, 1, 2, 2, 3, 6]

要预测较小的序列,只需按此进行训练,可以作为子序列或重叠序列(此处显示重叠):

from pybrain.tools.shortcuts import buildNetwork
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.datasets import SupervisedDataSet,UnsupervisedDataSet
from pybrain.structure import LinearLayer
ds = SupervisedDataSet(10, 11)
z = map(int,'1 2 4 6 2 3 4 5 1 3 5 6 7 1 4 7 1 2 3 5 6 1 2 5 6 2 4 4 5 1 2 5 6 7 1 4 6 1 2 3 3 6 1 3 5 7 2 4 6 7 1 3 5 6 7 1 4 6 1 2 2 3 7'.split())
obsLen = 10
predLen = 11
for i in xrange(len(z)):
  if i+(obsLen-1)+predLen < len(z):
    ds.addSample([z[d] for d in range(i,i+obsLen)],[z[d] for d in range(i+1,i+1+predLen)])

net = buildNetwork(10, 20, 11, outclass=LinearLayer,bias=True, recurrent=True)
trainer = BackpropTrainer(net, ds)
trainer.trainEpochs(100)
ts = UnsupervisedDataSet(10,)
ts.addSample(map(int,'1 3 5 7 2 4 6 7 1 3'.split()))
[ int(round(i)) for i in net.activateOnDataset(ts)[0]]

给出:

=> [3, 5, 6, 2, 4, 5, 6, 1, 2, 5, 6]

不太好...


你的第二个例子看起来是一个可行的答案。 - Olivier_s_j
你能详细说明“可行”的答案吗?你如何判断输出是否“好”?是基于原始示例吗?但是给出的示例太少了。 - Peter Teoh

4
这些步骤旨在完成你在问题第一部分中所要求的内容。
1)创建一个监督式数据集,该数据集的参数包括样本和目标。
 ds = SupervisedDataSet(21, 21)
 #add samples (this can be done automatically)
 ds.addSample(map(int,'1 2 4 6 2 3 4 5 1 3 5 6 7 1 4 7 1 2 3 5 6'.split()),map(int,'1 2 5 6 2 4 4 5 1 2 5 6 7 1 4 6 1 2 3 3 6'.split()))
 ds.addSample(map(int,'1 2 5 6 2 4 4 5 1 2 5 6 7 1 4 6 1 2 3 3 6'.split()),map(int,'1 3 5 7 2 4 6 7 1 3 5 6 7 1 4 6 1 2 2 3 7'.split()))

一个后继样本是其前一个样本的目标或标签y。我们之所以用数字21,是因为每个样本都有21个数字或特征。

请注意,在您问题的后半部分中,对于标准符号,最好将feature1和feature2称为sample1和sample2,对于序列,让features表示样本中的数字。

2)创建网络,初始化trainer并运行100个epochs。

net = buildNetwork(21, 20, 21, outclass=LinearLayer,bias=True, recurrent=True)
trainer = BackpropTrainer(net, ds)
trainer.trainEpochs(100)

请确保将recurrent参数设置为True 3) 创建测试数据
ts = UnsupervisedDataSet(21, 21)
#add the sample to be predicted
ts.addSample(map(int,'1 3 5 7 2 4 6 7 1 3 5 6 7 1 4 6 1 2 2 3 7'.split()))

我们创建了一个无监督的数据集,因为我们假设没有标签或目标值。
4) 使用已训练的网络预测测试样本。
net.activateOnDataset(ts)

这应该显示预期的第四次运行的值。

对于第二种情况,当一个序列可以拥有多个样本时,不要创建一个监督式数据集,而是创建一个序列数据集ds = SequentialDataSet(21,21)。然后,每次你获得一个新的序列,调用ds.newSequence()并使用ds.addSample()将特征添加到该序列中。

希望这很清楚明了 :)

如果您希望获得完整的代码以免导入库的麻烦,请告诉我。


哦,您似乎没有回答问题...“现在假设有一个新序列的开头:1 3 5 7 2 4 6 7 1 3接下来是什么值?”那么,在序列中最后一个 3 之后是什么? - Olivier_s_j
回答你的具体问题,仅凭如此少的示例是没有意义的——任何事情都有可能发生。但是@Curious所提供的是执行此操作的算法,如果您将其输入大量序列中——我们不确定您如何获取这些序列——输出的准确度将更高。我们不感兴趣的是具体答案。 - Peter Teoh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接