PaddlePaddle / Paddle

PArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice (『飞桨』核心框架,深度学习&机器学习高性能单机、分布式训练和跨平台部署)
http://www.paddlepaddle.org/
Apache License 2.0
22.07k stars 5.55k forks source link

关于卷积网络的问题 #5774

Closed sandycs closed 6 years ago

sandycs commented 6 years ago

问题1: 看到卷积网络的公式里有这几个参数,不知道他们分别代表什么呢?

filter_size=5,
num_filters=50,
num_channel=20,
pool_size=2,
pool_stride=2,

问题2: 今天在分类测试中。发现结果是这样的:

label=0, predict=0:53.99% | 1:46.01% |
label=1, predict=0:54.19% | 1:45.81% |
label=0, predict=0:53.79% | 1:46.21% |
label=0, predict=0:53.65% | 1:46.35% |
label=1, predict=0:53.66% | 1:46.34% |
label=1, predict=0:53.79% | 1:46.21% |
label=1, predict=0:53.74% | 1:46.26% |
label=0, predict=0:53.4% | 1:46.6% |
label=0, predict=0:53.29% | 1:46.71% |
label=0, predict=0:53.46% | 1:46.54% |
label=0, predict=0:53.37% | 1:46.63% |
label=0, predict=0:53.22% | 1:46.78% |
label=1, predict=0:53.03% | 1:46.97% |
label=0, predict=0:53.23% | 1:46.77% |
label=0, predict=0:53.25% | 1:46.75% |
label=0, predict=0:53.32% | 1:46.68% |
label=0, predict=0:53.11% | 1:46.89% |
label=0, predict=0:53.2% | 1:46.8% |
label=0, predict=0:53.08% | 1:46.92% |
label=1, predict=0:52.97% | 1:47.03% |

这个结果能否理解为:没有得到良好的收敛效果?

sandycs commented 6 years ago

我用的x是240维的一组数据。该240维数据以4个为一组,一共60组 我希望通过该60组数据。推出一个0或1 的结论

x = paddle.layer.data(name='x', type=paddle.data_type.dense_vector(240)) label = paddle.layer.data(name='label', type=paddle.data_type.integer_value(2))

目前的训练数据一共是4000多笔(即有4000多笔240维的数据) 由于这些数据都比较接近,归一化以后区别都在小数点后第二位小数。所以我把步长设短了点:

optimizer = paddle.optimizer.Momentum( learning_rate=0.1 / 10240.0, momentum=0.9, regularization=paddle.optimizer.L2Regularization(rate=0.0005 * 10240))

训练语句如下:

trainer.train( reader=paddle.batch( paddle.reader.shuffle(traindata(), buf_size=1000), batch_size=2), event_handler=event_handler, num_passes=30)

sandycs commented 6 years ago

我后来琢磨,是不是步长设的太短了。反而影响收敛。 于是我重新把leaning_rate改为0.1/128 然后我又琢磨。样本数据过少,也会影响规律掌握 所以我提供了100倍于刚才数据量的数据。即40万笔数据 重新进行了一次学习。这次的buf_size改为8192,batch_size改为128(于第二章教程类似)

然后学习过程中的cost变化如下:

Test with Pass 0, Cost 0.898307, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 1, Cost 0.728773, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 2, Cost 1.098430, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 3, Cost 1.044206, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 4, Cost 1.074964, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 5, Cost 0.895754, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 6, Cost 0.884701, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 7, Cost 0.754446, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 8, Cost 1.327887, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 9, Cost 1.016371, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 10, Cost 1.251134, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 11, Cost 1.053356, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 12, Cost 0.780456, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 13, Cost 0.989510, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 14, Cost 0.765060, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 15, Cost 0.693722, {'classification_error_evaluator': 0.4650000035762787}

Test with Pass 16, Cost 0.755487, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 17, Cost 0.921464, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 18, Cost 1.180495, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 19, Cost 0.831349, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 20, Cost 1.250572, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 21, Cost 0.809136, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 22, Cost 1.201214, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 23, Cost 1.123674, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 24, Cost 0.730279, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 25, Cost 1.139530, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 26, Cost 1.093548, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 27, Cost 0.950384, {'classification_error_evaluator': 0.5350000262260437}

Test with Pass 28, Cost 1.057719, {'classification_error_evaluator': 0.5350000262260437}

最后“考试”结果如下:(非常令人纳闷的是,考试数据是随机抽取的,考试结果却以一个顺序来排序

label=0, predict=0:59.41% | 1:40.59% | label=1, predict=0:59.49% | 1:40.51% | label=0, predict=0:59.57% | 1:40.43% | label=0, predict=0:59.62% | 1:40.38% | label=1, predict=0:59.65% | 1:40.35% | label=1, predict=0:59.68% | 1:40.32% | label=1, predict=0:59.71% | 1:40.29% | label=0, predict=0:59.77% | 1:40.23% | label=0, predict=0:59.82% | 1:40.18% | label=0, predict=0:59.91% | 1:40.09% | label=0, predict=0:60.01% | 1:39.99% | label=0, predict=0:60.08% | 1:39.92% | label=1, predict=0:60.16% | 1:39.84% | label=0, predict=0:60.24% | 1:39.76% | label=0, predict=0:60.31% | 1:39.69% | label=0, predict=0:60.39% | 1:39.61% | label=0, predict=0:60.45% | 1:39.55% | label=0, predict=0:60.52% | 1:39.48% | label=0, predict=0:60.6% | 1:39.4% | label=1, predict=0:60.67% | 1:39.33% |

will-am commented 6 years ago

filter_size就是卷积中filter(也可以叫kernel)的大小,filter_size=5就是用5*5的矩阵作为kernel,num_filters就是用多少个这样的kernel,num_channel是输入有多少个通道,比如彩色图片通常有r, g, b三个通道,所以对于输入时彩色图片的话一般是num_channel=3, pool_size是pooling时窗口的大小,pool_stride是做pooling时挪动的步长。

从测试结果看确实训练的结果不太好。不过模型的预测效果受到模型结构、模型参数以及数据本身等多种因素的影响。

sandycs commented 6 years ago

我的打印语句是:(是不是打印语句出了问题。总感觉打印结果怪怪的)

  probs = paddle.infer(
         output_layer=predict, parameters=parameters, input=test_data)
  for i in xrange(len(probs)):
         strprob = "label=" + str(test_label[i]) + ", predict="
         for j in range(0,len(probs[i])):
                 strprob = strprob + str(j) + ":"+ str(round(100*probs[i][j],2)) + "% | "
         print strprob
will-am commented 6 years ago

strprob = strprob + str(j) 这个是有点问题

sandycs commented 6 years ago

@will-am 愿闻其详?这个j是否代表着label?怎么能打印不同label和不同的预测比率呢?

will-am commented 6 years ago

请查看你的网络输出层是什么,要是输出层size是2,act是Softmax,那现在的代码就没有问题

sandycs commented 6 years ago

@will-am 但是我并没有做排序,为什么结果却按着顺序排下来了呢?

will-am commented 6 years ago

因为输出的顺序和label顺序是对应的,prob中的第0位置就对应label为0,第1位置就对应lable为1

sandycs commented 6 years ago

谢谢你! 虽然我还是有大量疑问。。。 这个没收敛的问题。我有点奇怪,因为规则来说应该是可以收敛的。

sandycs commented 6 years ago

@lcy-seso 大哥帮我看看?

lcy-seso commented 6 years ago

同学,先纠正一下,我不是“大哥”(也别叫大姐,太奇怪了 -_____- )。


明天再细看一下这个 issue,先解释一点点。

Test with Pass 28, Cost 1.057719, {'classification_error_evaluator': 0.5350000262260437}

从上面这两点看,模型应该啥都没有拟合到。

optimizer = paddle.optimizer.Momentum(
    learning_rate=0.1 / 10240.0,
    momentum=0.9,
    regularization=paddle.optimizer.L2Regularization(rate=0.0005 * 10240))

image

lcy-seso commented 6 years ago

shuffle的粒度是基于buf_size个样本,只要有足够的内存,你可以试试改大一些。

sandycs commented 6 years ago

谢谢 @lcy-seso 女神。 女神大半夜的还来帮俺回答问题。眼泪湿润了眼眶。

在没有看到你回答的时候,我也怀疑到了leaningrate 女神提供的论文我有点看不太懂,我在看PADDLEPADDLE帮助的时候,也一直在想为什么这个知识不能用更通俗的语言讲述清楚。

后来我发现真的很难。

但是我尝试讲讲。我觉得机器学习的拟合可以看做一个过程。 我告诉计算机,我心里想了个数字(可以理解为机器学习中的参数),你来猜猜吧。 比如我想的数字是89 计算机说,是50吗?我说不对,小了。计算机说100,我又说不对,大了。 如果计算机的leaningrate是25,他下一步可能会猜75。如果learnignrate是1,它可能会慢慢加上去直到找到89。 是这概念吧?

我昨天调节了learningrate,仍然坚持使用softmax算法。(主要是我这类问题和图像识别好像有点区别。所以不知道怎么应用卷积神经网络)

然后我又注意到。我归一后的数据,都在0.20附近打转(因为数据源的缘故,本来就差别不大)。所以我想。是不是这个数据的归一也出了问题。我重新调整了归一的策略。

其实在我心里的本意,是希望把我给计算机的240维数据,在一个横纵坐标轴上画出来,画出来的图形呈现了一个曲线形态。我想让计算机把这种曲线形态学起来。所以。既然只要拟合形态,横纵坐标的单位好像没有那么重要。所以我把归一策略调整为每次只在240维数据里打转。

总结起来。改动1:

optimizer = paddle.optimizer.Momentum(
        learning_rate=0.1 / 32.0,
        momentum=0.9,
        regularization=paddle.optimizer.L2Regularization(rate=0.0005 * 32))

learningrate被我改成了0.1/32,我觉得步长也够短了。 为了让训练足够充分,训练设置为1000次。 这里的buf_size和batch_size有点搞不懂是啥意思。反正只影响速度吧,我有的是时间。

trainer.train(
        reader=paddle.batch(
            paddle.reader.shuffle(traindata(), buf_size=3000),
            batch_size=2),
        event_handler=event_handler,
        num_passes=1000)

这是昨晚跑完的结果:(我仍然非常纳闷。为什么计算机这么偏爱0呢?)

label=0, predict=0:76.99% | 1:23.01% |  Bingo
label=1, predict=0:79.95% | 1:20.05% |
label=0, predict=0:81.89% | 1:18.11% |  Bingo
label=0, predict=0:81.53% | 1:18.47% |  Bingo
label=1, predict=0:78.63% | 1:21.37% |
label=1, predict=0:78.04% | 1:21.96% |
label=1, predict=0:78.06% | 1:21.94% |
label=0, predict=0:79.11% | 1:20.89% |  Bingo
label=0, predict=0:80.54% | 1:19.46% |  Bingo
label=0, predict=0:82.94% | 1:17.06% |  Bingo
label=0, predict=0:84.69% | 1:15.31% |  Bingo
label=0, predict=0:84.24% | 1:15.76% |  Bingo
label=1, predict=0:83.67% | 1:16.33% |
label=0, predict=0:83.74% | 1:16.26% |  Bingo
label=0, predict=0:83.32% | 1:16.68% |  Bingo
label=0, predict=0:81.17% | 1:18.83% |  Bingo
label=0, predict=0:80.75% | 1:19.25% |  Bingo
label=0, predict=0:80.6% | 1:19.4% |  Bingo
label=0, predict=0:81.42% | 1:18.58% |  Bingo
label=1, predict=0:78.58% | 1:21.42% |

正确率到达了14/20=70%?小弟在澳门赌场玩筛子的时候也达到过这个胜率。 但是我不放心。早上又跑了一次。跑的真心慢啊。。 总数据大概30多万笔(文件400多M...)花了大概30分钟。结果如下:

label=1, predict=0:55.79% | 1:44.21% |
label=0, predict=0:60.47% | 1:39.53% |  Bingo
label=0, predict=0:75.96% | 1:24.04% |  Bingo
label=1, predict=0:47.28% | 1:52.72% |  Bingo
label=1, predict=0:51.26% | 1:48.74% |
label=1, predict=0:52.79% | 1:47.21% |
label=0, predict=0:53.73% | 1:46.27% |  Bingo
label=0, predict=0:53.28% | 1:46.72% |  Bingo
label=0, predict=0:61.39% | 1:38.61% |  Bingo
label=0, predict=0:72.7% | 1:27.3% |  Bingo
label=0, predict=0:49.3% | 1:50.7% |
label=1, predict=0:50.0% | 1:50.0% |
label=0, predict=0:44.8% | 1:55.2% |
label=0, predict=0:65.64% | 1:34.36% |  Bingo
label=0, predict=0:29.33% | 1:70.67% |
label=0, predict=0:26.93% | 1:73.07% |
label=0, predict=0:39.62% | 1:60.38% |
label=0, predict=0:53.81% | 1:46.19% |  Bingo
label=1, predict=0:49.19% | 1:50.81% |  Bingo

只剩下50%了。。。 拟合肯定是出现问题了。但是排查问题的思路我有点不明白。 比如我应该排查哪些东西。 还请指点一下

luotao1 commented 6 years ago

@sandycs 非常感谢您对PaddlePaddle的支持,我们想给您发个纪念品。请问您可以把收件地址发到:tianye12@baidu.com 么?

sandycs commented 6 years ago

@luotao1 好哒!!

sandycs commented 6 years ago

@lcy-seso 纠正一下上面的一个回答。 我那两次测试的原数据可能确实存在问题。归一化不小心做了两次。 也慢慢得出结论。原数据分布越均匀,拟合概率越大。 我原来的原数据变动范围太小了,可能是这个原因。

当然。数据纠正以后,我又满怀欣喜的执行了一次。仍然没能拟合了。 我也公布下。我选取的数据是上证指数从2000年开始到今天的日线数据。 每一日选择4组数据:最低价、最高价、开盘价、收盘价。 选择60天。一共240笔数据

我希望通过60天的数据。对未来十天的数据做个预测。 由于2000年到现在全部都已经是过去式了。所以完全可以进行监督学习。

这其实就是把以前一本日本蜡烛图理论,用人工智能搞定了。 以上

lcy-seso commented 6 years ago

同学,我大致概括一下上面一段issue中涉及的问题:




一般情况下,先保证对训练集的拟合正常且监控,在学习的前期学习曲线呈明显的下降。”先无脑地“拟合住训练样本集。不知道现在对训练样本集拟合如何。

sandycs commented 6 years ago

@lcy-seso 女神这次的内容有点多。我消化了很久。 我这么理解不知道对不对。 我用的这种softmax方法,特别适用于,当信息足够充分时的情况。 也就是说,仅凭借现有信息,已经可以做出判断,且是可以判断的。对吗?

从60天的最低价、最高价。开盘价、收盘价来预测。是可以实现的

我在看alphago zero论文的时候,他们有提到。 他们把当前的棋盘信息作为输入,用蒙特卡洛树的走法作为预测结果来监督学习。

我觉得我现在想研究的这个和他们这个有点类似。是不是应该用SOFTMAX方法?

为了进一步证实这件事。我做了一个动作。 我把最后一个预测值的规则改成,如果240维数字中的第一个大于第二个,就为1,否则为0 也就是说,其实只用到了前2维。拟合马上就正常了 300次训练下来。准确率85%。

是不是我的数据不够大。对于这么高维的数据来说,我的数据量太小了?

lcy-hugepanda commented 6 years ago

@sandycs 路过一下,关于paddle本身的问题有paddle的同学解决,我想对你选取的特征和想要拟合的数据,给一点个人的建议:

  1. 如果我理解的没错,你想做的是通过大盘一段时间的最低价、最高价、开盘价、收盘价,预测未来一段时间的走势。
  2. 在具体尝试选择模型去解决问题之前,首先需要仔细考虑一个问题,即这个问题(1)是否是“可学习”的。举个栗子,我如果用每天的最高气温、最低气温、早8点的气温、晚8点的气温来拟合股票大盘的数据,你觉得可以拟合成功吗?
  3. 对于 2 的例子,你肯定会觉得不能拟合,因为气温和股票没有决定性的因果关系。于是,单纯“最低价、最高价、开盘价、收盘价”是否能对“未来的走势”有决定性的刻画,也是值得商榷的。

具体到股票这件事情,如果你想做对于走势的预测,建议从量化投资的角度调研,还有哪些值得作为特征的数据可用。最基本的,作为“量价关系”的基本技术面指标之一,除了你已经使用的几个价格变化,还需要观察成交量的变化。另外一个小建议是,你可以研究一下6124和5178这两个牛市最高点在点位前后有哪些技术指标在显著变化,就可能得到对走势有更好刻画的特征。

如果跳出股票这个具体的问题,在利用机器学习工具拟合一组数据的时候,有一个比较简单的验证方法值得尝试(前面的comments里面也有提到):

  1. 首先尽量让模型能“过拟合”到样本上,即在训练集上效果很好,确保基本的可学习性
  2. 然后通过调整模型或参数,把模型从过拟合中解放出来,获取我们想要的模型泛化能力

以上。

sandycs commented 6 years ago

先保证对训练集的拟合正常且监控,在学习的前期学习曲线呈明显的下降。”先无脑地“拟合住训练样本集

这个对我来说还是有点抽象,是不是说先让样本集做点简单的预测工作,再慢慢复杂起来。 比如我刚才尝试的那种

sandycs commented 6 years ago

@lcy-hugepanda 这个就是我来这儿的目的。 可以向这么多像您这样的高手学习,真的受益良多。 你的例子举得非常好。我本身对金融小有研究,在指数预测上是比较准确的。 其实我就是纯蜡烛图分析,没有参考成交量,所以我以为计算机也能做到。或者说做到超过50%,因此才做了这样的一个实验。 目前我先按您的思路来。先过拟合,然后泛化。

sandycs commented 6 years ago

@lcy-seso @lcy-hugepanda 问个关于过拟合的问题。 如果我现在有240维的一组数据。 我给定的学习结果规则是这样的。这240维数据中,第一维大于第二维,则结果为1,反之为0 然后开始学习。

为什么不管怎么学习。最高也只能到85左右的准确率? 我的trainging数据是这么设置的:(buf-size和batch-size设置过各种组合。但于结果变化并不显著)

trainer.train(
        reader=paddle.batch(
            paddle.reader.shuffle(traindata(), buf_size=32768),
            batch_size=64),
        event_handler=event_handler,
        num_passes=1000)
optimizer = paddle.optimizer.Momentum(
        learning_rate=0.1/64 ,
        momentum=0.9,
        regularization=paddle.optimizer.L2Regularization(rate=0.0005*64 ))

上述参数中的momentum不知道是什么意思。。我基本都是0.9没有动

这样可以吗?

sandycs commented 6 years ago

@lcy-seso 女神好。 虽然您没继续回答我问题。我还是自己研究了一下 目前有了一些新的进展。 提个问题: 如果把深度学习网络应用于对弈(类似于alpha go那样) 对弈中,举个例子比如五子棋吧 五子棋中,我们把整个棋盘当做一个输入,下一步当做一个输出。 随着行棋的深入,输出的label是变化的。已经走过的地方,是不能落子的。 在深度学习进行中的时候,机器会自己把这种情况学习起来吗?这时候label应该是如何设置的呢?

sandycs commented 6 years ago

对不起我换个问法。 比如数字识别问题。如果已知出来的数字就是10-20之间的数字. 用一个已经学过0-100的参数来识别 能不能把输出就定义在10-20之间呢?

sandycs commented 6 years ago

因为当时学习0-100的时候,肯定是把0-100的整数给进去了 这时候如果改成0-10.计算机铁定懵逼

sandycs commented 6 years ago

额。貌似这个问题没有被人看到了

yeyupiaoling commented 6 years ago

你这说得有点多了,我不禁要进来看看发生什么情况了

chengduoZH commented 6 years ago

Closed due to low activity, please feel free to reopen it.