Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于 数字识别 章节的问题 #5690

Closed
sandycs opened this issue Nov 16, 2017 · 14 comments
Closed

关于 数字识别 章节的问题 #5690

sandycs opened this issue Nov 16, 2017 · 14 comments
Labels
User 用于标记用户问题

Comments

@sandycs
Copy link

sandycs commented Nov 16, 2017

今天进展到数字识别章节问题
我这么理解。对于softmax回归来说,输入实际上是一个28x28=784的一维矩阵
输出是一个10个元素的一维矩阵。
于是我对程序作了一些变化:
我的输入是随机的:

global dataX
dataX = np.random.rand(1000,3)
我的输出是条件生成的:
(逻辑很简单。就是写一些条件,当X满足某些条件的时候,Y是某个确定的值)
global dataY
dataY = np.zeros((1000,3))
intcount = 0
for e in dataX:
if (e[0]>0.5 and e[1]>0.5 and e[2]>0.5):
dataY[intcount] = [1.0,0,0]
else:
if (e[2] <0.5):
dataY[intcount] = [0,1.0,0]
else:
dataY[intcount] = [0,0,1.0]
intcount = intcount +1

然后我就把这些输入进去进行训练了。

global UCI_TRAIN_DATA 
UCI_TRAIN_DATA = dataFinal[:800]
global UCI_TEST_DATA 
UCI_TEST_DATA= dataFinal[800:]
    
x = paddle.layer.data(name='x', type=paddle.data_type.dense_vector(3))
y = paddle.layer.data(name='y', type=paddle.data_type.dense_vector(3))

predict = softmax_regression(x)

cost = paddle.layer.classification_cost(input=predict, label=y)

# Save the inference topology to protobuf.
inference_topology = paddle.topology.Topology(layers=predict)
with open("inference_topology.pkl", 'wb') as f:
    inference_topology.serialize_for_inference(f)

parameters = paddle.parameters.create(cost)    
# create optimizer
# optimizer = paddle.optimizer.Momentum(momentum=0)
optimizer = paddle.optimizer.Momentum(
    learning_rate=0.1 / 3.0,
    momentum=0.9,
    regularization=paddle.optimizer.L2Regularization(rate=0.0005 * 3))

trainer = paddle.trainer.SGD(
    cost=cost, parameters=parameters, update_equation=optimizer)
# feeding = {'x': 0, 'y': 1}
# event_handler to print training and testing info
def event_handler(event):
    if isinstance(event, paddle.event.EndIteration):
        if event.batch_id % 100 == 0:
            print "Pass %d, Batch %d, Cost %f, %s" % (event.pass_id, event.batch_id, event.cost, event.metrics)
    if isinstance(event, paddle.event.EndPass):
        if event.pass_id % 10 == 0:
            with open('params_pass_%d.tar' % event.pass_id, 'w') as f:
                trainer.save_parameter_to_tar(f)
        result = trainer.test(
            reader=paddle.batch(
            testdata(), batch_size=2)
            )
        print "Test with Pass %d, Cost %f, %s\n" % (event.pass_id, result.cost, result.metrics)

# training
trainer.train(
    reader=paddle.batch(
        paddle.reader.shuffle(traindata(), buf_size=500),
        batch_size=2),
    event_handler=event_handler,
    num_passes=300)

一开始的时候,我忘记修改cost,用的仍然使用线性回归课程中的cost,即

 cost = paddle.layer.square_error_cost(input=y_predict, label=y)

运行是正常的。但结果不收敛
检查发现问题后,我把cost修正为现在的样子,即

cost = paddle.layer.classification_cost(input=predict, label=y)

运行出错了。这个错误信息我有点搞不明白,求教:

F1116 05:56:43.303720    11 Matrix.cpp:3626] Check failed: dynamic_cast<CpuIVector*>(&label)
*** Check failure stack trace: ***
    @     0x7f571ade60ed  google::LogMessage::Fail()
    @     0x7f571ade8438  google::LogMessage::SendToLog()
    @     0x7f571ade5bfb  google::LogMessage::Flush()
    @     0x7f571ade930e  google::LogMessageFatal::~LogMessageFatal()
    @     0x7f571ad08152  paddle::CpuMatrix::oneHotCrossEntropy()
    @     0x7f571aae64cf  paddle::CostLayer::forward()
    @     0x7f571ab547a9  paddle::NeuralNetwork::forward()
    @     0x7f571adb62c0  GradientMachine::forwardBackward()
    @     0x7f571a964424  _wrap_GradientMachine_forwardBackward
    @           0x4cb45e  PyEval_EvalFrameEx
    @           0x4c2765  PyEval_EvalCodeEx
    @           0x4ca8d1  PyEval_EvalFrameEx
    @           0x4c2765  PyEval_EvalCodeEx
    @           0x4ca099  PyEval_EvalFrameEx
    @           0x4c2765  PyEval_EvalCodeEx
    @           0x4ca099  PyEval_EvalFrameEx
    @           0x4c2765  PyEval_EvalCodeEx
    @           0x4ca8d1  PyEval_EvalFrameEx
    @           0x4c2765  PyEval_EvalCodeEx
    @           0x4c2509  PyEval_EvalCode
    @           0x4f1def  (unknown)
    @           0x4ec652  PyRun_FileExFlags
    @           0x4eae31  PyRun_SimpleFileExFlags
    @           0x49e14a  Py_Main
    @     0x7f5734ae1830  __libc_start_main
    @           0x49d9d9  _start
    @              (nil)  (unknown)
Aborted

请问是哪里出了问题
还有,我这个例子用来做回归行不行?

@lcy-seso
Copy link
Contributor

lcy-seso commented Nov 16, 2017

首先祝贺你已经跨域之前的各种问题,进入到数字识别~

这个错误是因为类别标签的输入数据类型有误引起的。

y = paddle.layer.data(name='y', type=paddle.data_type.dense_vector(3))

请把上面的配置改为:

y = paddle.layer.data(name='y', type=paddle.data_type.integer_value(1))

下面这个cost ( paddle.layer.classification_cos)实际上是softmax + cross entropy,来自于极大似然估计,更多被用于分类问题。

cost = paddle.layer.classification_cost(input=predict, label=y)

在分类问题中类别标签是离散值,这与回归问题中拟合连续值不同。在PaddlePaddle中,当使用下面的cost时,label必须指定为 integer_value

祝你好运~ enjoy it.

@sandycs
Copy link
Author

sandycs commented Nov 16, 2017

@lcy-seso
你好
我修改了一下您的代码
type=paddle.data_type.integer_value(1)
改为了
type=paddle.data_type.integer_value(3)
因为我的y值有3种情况,分别是0,1,2

现在问题来了。学习过程里。cost并没有越变越低的情况。
我也不知道我这么设计x与y的关系是否合理。
实际测试的效果并不理想

是不是我对机器学习的整个理解有误?
线性回归我是知道的。线性回归的本质实际上就是拿不同的数字去试验,最后得到参数。

但分类我就有点懵逼,用softmax方法。真的能得到最终结果吗?

@sandycs
Copy link
Author

sandycs commented Nov 16, 2017

@lcy-seso
我修改了这个语句:

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

发现训练结果有比较大的差距,这里的各项参数为什么这么设置。原因是什么呢?
刚才我说,训练结果并不准确,是因为我把上述参数中的learning_rate改为0.1/2,把下面的rate改为0.0005*2。
改为128以后,训练结果开始变得准确了。但是还差点火候
因此我把训练次数提高到300次。训练结束后,在15次的考验中,电脑仅错了1次,已经挺让人满意了

恳请您再多介绍一些

@lcy-seso
Copy link
Contributor

  • 首先您上面的修改是没问题的~
  • 广义地,分类、回归、概率密度估计三大类任务之间往往是可以相互转化。也就是说,同一个问题,是可能同时用回归/分类/概率密度估计不同模型来描述和求解的。您上面的问题用分类模型来解是可以的。分类模型会输出所有类别之上的一个分布,这和回归拟合输出一个拟合值不同。

@lcy-seso
Copy link
Contributor

您修改的这个参数一个是学习率,一个是正则项系数。

  • 学习率是在优化方向上前进的步长,过大会跨过局部最优区域,过小会影响收敛速率(在下降方向上前进很慢);
  • 正则项通常是将可学习参数的范数也加入损失的计算中(避免个别维度的值占压倒性,输出仅仅依赖个别维度特征),而多大程度考虑约束可学习参数的范数可以通过正则项前的系数来控制。

@lcy-seso
Copy link
Contributor

您上面的修改意味着使用了一个较大的学习率和正则惩罚。大的学习率通常有可能引起训练发散,直接跳过了局部最优区域。

@sandycs
Copy link
Author

sandycs commented Nov 16, 2017

谢谢 @lcy-seso
为什么讲的这么清楚?为什么我最近遇到的百度员工都这么好?

@lcy-seso
Copy link
Contributor

不客气不客气~ 希望能踩平所有的坑,最终自由地实现自己想法,喜欢上机器学习 ~
一些用户体验和文档我们也值得持续地完善,大家同努力~

@luotao1
Copy link
Contributor

luotao1 commented Nov 16, 2017

希望您能坚持学习完整个教程,加油!

@sandycs
Copy link
Author

sandycs commented Nov 16, 2017

分类这章对我目前的工作用处最为巨大
后面的图像识别以及词向量。我目前暂无涉及,短期内可能也不会去研究
我想先把卷积神经网络这些了解清楚,其实paddlepaddle平台已经算是傻瓜化平台了。核心算法都被包裹起来,而那个才是人工智能最重要的部分。
我的想法是先从应用层入手,有具体需要了再研究更为细致的部分。

总体来说PADDLEPADDLE给我们很大的帮助,TENSORFLOW我折腾了一礼拜都没把环境跑起来。
感谢百度为全体开发者做出的努力。真的感谢

最后问个问题,docker如果直接运行在linux机器上。是否能做到充分使用本机资源。我感觉运行在WINDOWS时资源利用的不够充分。

@lcy-seso
Copy link
Contributor

docker 的问题其它同学更专业,他们会回答~ 如果是图像分类对您作用巨大,paddle models 下还有一些升级版本的模型,回头如果需要可以同时也试试有没有帮助~ https://github.com/PaddlePaddle/models/tree/develop/image_classification

@Yancey1989
Copy link
Contributor

最后问个问题,docker如果直接运行在linux机器上。是否能做到充分使用本机资源。我感觉运行在WINDOWS时资源利用的不够充分。

可以的,Docker在Linux上运行是直接调用Linux Kernel,而Windows上Docker是跑在一个虚拟机里面的。

@luotao1
Copy link
Contributor

luotao1 commented Nov 16, 2017

Docker运行在linux机器上,我们做过实验:#5148 (comment)
VGG网络,误差最大1.7%,说明在docker内和外基本没啥差别。

此外,不同docker版本的影响也可以忽略不计:#5148 (comment)

@lcy-seso lcy-seso added the User 用于标记用户问题 label Nov 16, 2017
@sandycs
Copy link
Author

sandycs commented Nov 17, 2017

感谢楼上的辛苦帮忙。此问题CLOSE吧。
有问题我再提问哈

@sandycs sandycs closed this as completed Nov 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
User 用于标记用户问题
Projects
None yet
Development

No branches or pull requests

4 participants