mariolew / Deep-Alignment-Network-tensorflow

A re-implementation of Deep-Alignment-Network using TensorFlow
111 stars 30 forks source link

issues about trainDNA.py #10

Open JWSunny opened 6 years ago

JWSunny commented 6 years ago

您好,我在进行trainDAN训练时,STAGE=2,执行sess.sun();获取数据训练时,运行到models.py中的S2_InputImage = AffineTransformLayer(InputImage, S2_AffineParam)会报错;

错误如下:

Caused by op 'Stage2/MatrixInverse', defined at: File "D:/softmares/Pycharm_workplace/Deep-Alignment-Network-tensorflow-master/DAN-TF/python_test1.py", line 73, in dan = DAN(initLandmarks) File "D:\softmares\Pycharm_workplace\Deep-Alignment-Network-tensorflow-master\DAN-TF\python_test2.py", line 102, in DAN S2_InputImage = AffineTransformLayer(InputImage, S2_AffineParam) ## 通过变换矩阵对原图进行矫正,得到新的图片 File "D:\softmares\Pycharm_workplace\Deep-Alignment-Network-tensorflow-master\DAN-TF\layers.py", line 60, in AffineTransformLayer A = tf.matrix_inverse(A) File "C:\Program Files\Anaconda3\lib\site-packages\tensorflow\python\ops\gen_linalg_ops.py", line 330, in matrix_inverse name=name) File "C:\Program Files\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 768, in apply_op op_def=op_def) File "C:\Program Files\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2336, in create_op original_op=self._default_original_op, op_def=op_def) File "C:\Program Files\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 1228, in init self._traceback = _extract_stack()

InvalidArgumentError (see above for traceback): Input is not invertible. [[Node: Stage2/MatrixInverse = MatrixInverseT=DT_FLOAT, adjoint=false, _device="/job:localhost/replica:0/task:0/cpu:0"]]

请问您遇到过吗?是我开始数据变换出了问题吗?能请教您下吗?

mariolew commented 6 years ago

@JWSunny 还真没遇到过,请问你是用这份代码里的脚本生成的数据吗?

JWSunny commented 6 years ago

是的,我想咨询下您,关于AffineTransformLayer函数中Pama的维度是(N, 6)嘛?还是(1, 6)?目前主要是函数中tf.matrix_inverse(A)报错艾!能提供下脚本产生的数据进行比对下嘛?sunjiawei@focuschina.com?

mariolew commented 6 years ago

@JWSunny 是N 6, 你可以用脚本试试就知道产生的数据是什么样子了的。

JWSunny commented 6 years ago

好的 谢谢,A是所有行的前4列;即N个(2,2)的矩阵;tf_matrix_inverse(A)是同时求N个(2,2)的逆矩阵,是不是不能同时求啊?感觉是因为这个报错!您那边同时求N个2*2矩阵的逆矩阵没问题吗?

JWSunny commented 6 years ago

解决了,是TransformParamsLayer中代码处理有问题,已经重写了!谢谢~

mariolew commented 6 years ago

@JWSunny hi, 请问哪里的处理有问题,也请你说一下,因为我的使用过程中没发现这个问题,有解决方法也请分享一下吧。

JWSunny commented 6 years ago

TransformParamsLayer主要是reshape函数对矩阵转换之后,本人电脑上操作之后Pama的维度并不是(N, 6);于是参考另一位大神的实现https://github.com/zjjMaiMai/Deep-Alignment-Network-A-convolutional-neural-network-for-robust-face-alignment/blob/master/DAN_V2/dan_model.py,觉得可能是因为版本问题!

JWSunny commented 6 years ago

还想咨询您一个问题,NormRmse函数计算的误差属于什么误差,选取[36,42]和[42,48]表示什么意思?

JWSunny commented 6 years ago

您好,方便问下针对一张没有进行68关键点标注的图,如何利用该模型来预测人脸的68关键点?

mariolew commented 6 years ago

@JWSunny 预测的话,首先需要人脸检测,然后需要对图像减去训练集的均值,除以训练集的标准差,然后就直接运行模型得到结果即可,我有看这种结果,也还行,但代码比较乱,目前还不好上传,您可以按照我说的流程自己写一下,有问题可以问我。

JWSunny commented 6 years ago

试了Dlib人脸检测,预测出的68关键点都没Dlib训练的68关键点模型标注的准确,嘴角偏差明显

mariolew commented 6 years ago

@JWSunny 请问你有试过放大一点检测框吗,可以放大一点试试,比如1.3倍?然后,你是用什么数据训的,训到什么程度?

JWSunny commented 6 years ago

检测框设置是哪个?训练集的话就是lfpw、helen的trainset和afw共60960张,迭代了训练500次 image 按照您代码中的BatchErr是0.023746558?是我哪边模型训练时出错了嘛? 方便加个qq聊吗

mariolew commented 6 years ago

@JWSunny 我的意思是,测试的时候,将dlib的人脸框放大一点试试效果。然后你这是stage1还是2啊,如果是2,这个误差有点高了。训stage2的时候,实测应该降学习率才能训得动,我降低了10倍,0.0001,如果不想降学习率,请把原代码里面模型部分的每一层的BN和relu的顺序调换一下,就像这样S1_Conv1a = tf.nn.relu(tf.layers.batch_normalization(tf.layers.conv2d(InputImage,64,3,1, padding='same',activation=None,kernel_initializer=tf.glorot_uniform_initializer()),training=S1_isTrain))

JWSunny commented 6 years ago

stage2,学习速率0.001,误差高了,误差大概多少是合适的?

mariolew commented 6 years ago

@JWSunny BatchErr应该要到0.01左右的。

JWSunny commented 6 years ago

哦哦 感谢感谢,那我试试Dlib人脸检测放大人脸框的方法!

mariolew commented 6 years ago

@JWSunny 哦,对了,我在300-W上训练的模型,在300-W测试集上的结果和他的论文差距不算很大,但是好像测平常的人脸图效果一般。但是用MENPO数据集训练的要好很多。

JWSunny commented 6 years ago

也就是说300-W训练集+MENPO一起训练的模型效果在测试平常人脸效果更好咯,那您针对MENOP的训练集,有像300-W的训练集做镜像、平移之类的操作来扩充训练集训练吗?

mariolew commented 6 years ago

都有的

JWSunny commented 6 years ago

哦哦 好的好的,感谢感谢,我试试~

JWSunny commented 6 years ago

您好,能提供下Menpo的训练数据集嘛,网上的链接貌似失效了!谢谢了!

mariolew commented 6 years ago

@JWSunny https://www.dropbox.com/s/5yw8wb9k278k400/trainset.zip?dl=1 我试了一下,可以下啊,并未失效,你需要去申请一下解压密码,出于这个原因,我也不能把它直接放出来。需要翻墙。

JWSunny commented 6 years ago

哦哦,那可能是因为未翻墙,谢谢!

hengshan123 commented 6 years ago

@mariolew 误差降到0.01 大概训练了多少次啊? 我用gpu训练一次要20分钟 好慢,你训练一次大概多久

mariolew commented 6 years ago

一个epoch20分钟不算慢吧,我好像s1和s2各训练了50个吧,不改代码的话s2得降低学习率,改的话就像这个issue说的那样就OK

JWSunny commented 6 years ago

直接训练S1和S2有什么区别嘛?就层数的不同,之前试了部分数据集S1有时候误差比S2小一些,目前选的是直接训练S2

mariolew commented 6 years ago

@JWSunny 建议你看看论文。是需要先训S1,再训S2的,如果你直接训S2,相当于S1部分是随机初始化的,就没有什么意义了。

hengshan123 commented 6 years ago

训练完,BatchErr 到0.01 那 TestErr 大致降到多少? 我s1 训练了30次,然后没改学习率去训练s2 训练100次和没训练没啥区别,真奇怪 我训练了30次s1, 100次s2, 还可以继续s1吧, 然后再修改学习率 接着训练s2

hengshan123 commented 6 years ago

训练完,BatchErr 到0.01 那 TestErr 大致降到多少? 我s1 训练了30次,然后没改学习率去训练s2 训练100次和没训练没啥区别,真奇怪 我训练了30次s1, 100次s2, 还可以继续s1吧, 然后再修改学习率 接着训练s2

hengshan123 commented 6 years ago

"把原代码里面模型部分的每一层的BN和relu的顺序调换一下” 这个操作为什么和 降低学习率等价呢?

mariolew commented 6 years ago

那个操作并非等价,而是说这样操作以后不降学习率也能训,具体原因我觉得很难解释,但bn一般是放在relu之前的,这样用没什么问题,testerr到4.5几吧。

JWSunny commented 6 years ago

请问您加了Menpo数据集后,训练和交叉验证的数据比例设置多少啊,选了400张交叉验证,然后在模型阶段1训练时,总是报内存溢出,您是选择多少验证集

mariolew commented 6 years ago

我就100张验证集,其实多少无所谓的,你一个batch内存不够就两个batch,三个batch嘛。

JWSunny commented 6 years ago

代码中是利用交叉集来进行阶段1模型训练的,我加了menpo后选的400张,总报内存溢出,所以这边我选小点儿的张数其实也无所谓咯?

mariolew commented 6 years ago

我觉得您可能需要理解一下验证集的作用和意义,以及为何会内存不足,内存不足就是因为一个batch太大了,和其他东西完全没关系。

JWSunny commented 6 years ago

重新训练了stage1和stage2,发现也出现stage2误差几乎不变化的情况,大神之前有遇到吗,还是说需要改了学习速率?stage1学习速率0.001,若stage2速率也是0.001两个error就不怎么变化,目前准备stage速率改个0.0001

mariolew commented 6 years ago

@JWSunny 并非大神。我是降学习率到0.0001,stage2才训得动的。

JWSunny commented 6 years ago

谢谢,行艾,那我改个速率训练看看,之前论文没看好,训练的模型,在测试图片上将预测关键点进行标注时,嘴角误差比较偏.......就是BatchError没降到您说的0.01

mariolew commented 6 years ago

@JWSunny 如果是测你自己的图片上的效果,只用300W的数据训出来的模型应该是不算给力的,方便的话来个图看看?

JWSunny commented 6 years ago

figure_1 我按照阶段1和阶段2交替训练,testerror在变小,而batcherror却增大到了0.5,不知道这是什么原因?学习速率都是设的0.001,在服务器运行正常

JWSunny commented 6 years ago

交替训练时,重新训练stage1,是直接修改stage=1,继续走 if STAGE < 2: sess.run(tf.global_variables_initializer()) 这个环节嘛?还是要加载之前训练好的Model模型?

mariolew commented 6 years ago

stage2直接restore即可,不需要初始化了,然后,训练err增大测试减小也正常,属于正常的波动。

mariolew commented 6 years ago

然后,看上去你的结果不太对,testerr到多少了?

JWSunny commented 6 years ago

if STAGE == 1 or STAGE == 0:

sess.run(dan['S1_Optimizer'], feed_dict={dan['InputImage']:Xtrain[RandomIdx],\

            #     dan['GroundTruth']:Ytrain[RandomIdx],dan['S1_isTrain']:True,dan['S2_isTrain']:False})
            sess.run(dan['S1_Optimizer'], feed_dict={dan['InputImage']:Xvalid,\
                dan['GroundTruth']:Yvalid,dan['S1_isTrain']:True,dan['S2_isTrain']:False})
        else:
            sess.run(dan['S2_Optimizer'], feed_dict={dan['InputImage']:Xtrain[RandomIdx],\
                dan['GroundTruth']:Ytrain[RandomIdx],dan['S1_isTrain']:False,dan['S2_isTrain']:True})

看您训练stage1选的验证集在学习,是我理解错了还是说您注释错了?现在我改了,跟stage2一样选取部分随机训练集;testerror目前到0.04...左右吧

JWSunny commented 6 years ago

hi: 又来打扰了,还是有几个问题困扰着我,如若方便,给个回复,谢谢!

  1. 开始单独训练stage1时,选用的验证集100张图来进行权重学习,是否可以从训练数据中随机选取图片进行参数更新?
  2. 目前在tensorflow实现中,lr=0.0001,stage1利用训练数据集中的随机128张来更新stage1阶段的参数,迭代200epoch;
  3. 单独训练stage2,lr不变;迭代训练400;目前epoch=80;testerror是0.048左右;batcherror是0.011左右
  4. 将 S2_Ret 作为预测的点在对应测试图中进行标注时,发现倾斜图片中预测的关键点偏差较大,预测点都是正的,没有对应倾斜?
  5. 训练完stage1和stage2后,论文中说需要重复进行;是否还需要再训练stage1和stage2?
mariolew commented 6 years ago

关于1,是我的问题,因为我上传这份代码时自己并没有GPU,当时还没有训过,只是测试一下代码是否可以跑,所以选了验证集去训练,实际上要用训练集。然后交替训练不用吧,论文的开源代码也没有交替。然后不管哪个stage,都应该只用训练数据训。

JWSunny commented 6 years ago

mobile的训练模型是可以编译生成tflite文件嘛?

mariolew commented 6 years ago

tensorflow训练的模型都可以转tflite,只要op符合要求,dan的话,stage1都可以转,stage2不可以,op不支持。

JWSunny commented 6 years ago

具体怎么操作,方便给个代码看下嘛,生成的model转冻结图,生成tflite文件时,总报converting unsupported operation SquaredDifference,还有lite文件生成时input_arrays的输入等问题,方便指导下嘛