captcha_break icon indicating copy to clipboard operation
captcha_break copied to clipboard

用keras2的api改写后,无法收敛

Open camperr opened this issue 8 years ago • 18 comments

因为我使用的keras版本是keras2, 所以把网络结构定义和训练的代码做了一些修改,但是输出的每个字符的准确率一直在0.028左右徘徊,这个就是完全随机1/36的概率,烦请看一下代码是不是有问题 我使用的python版本是2.7.13,keras版本是2.0.2,都是使用anaconda安装的 我已经尝试过修改参数初始化方式(使用Xavier方法),修改优化方法(sgd,RMSprop等),调节学习率(0.1-10),修改batch_size等都没有效果。 我修改后的代码如下:

from keras.models import *
from keras.layers import *
from keras.optimizers import *

input_tensor = Input(shape = (height, width, 3))
x = input_tensor

for i in range(4):
    x = Conv2D(32 * 2 ** i, (3, 3), activation = 'relu')(x)
    x = Conv2D(32 * 2 ** i, (3, 3), activation = 'relu')(x)
    x = MaxPooling2D((2, 2))(x)

x = Flatten()(x)
x = Dropout(rate = 0.25)(x)
x = [Dense(n_class, activation='softmax', name='c{}'.format(i))(x) for i in range(n_len)]

model = Model(inputs = input_tensor, outputs = x)

model.compile(optimizer = 'adadelta', loss='categorical_crossentropy', metrics=['accuracy']) 
from keras.callbacks import EarlyStopping
#early_stop = EarlyStopping(monitor='val_loss', patience=2)
model.fit_generator(gen(), steps_per_epoch = 1600, epochs = 10, validation_steps = 40, validation_data = gen())

camperr avatar Jun 07 '17 16:06 camperr

卷积层数太少,每代训练次数太低。

发自我的 iPhone

在 2017年6月8日,00:14,camperr [email protected] 写道:

因为我使用的keras版本是keras2, 所以把网络结构定义和训练的代码做了一些修改,但是输出的每个字符的准确率一直在0.028左右徘徊,这个就是完全随机1/36的概率,烦请看一下代码是不是有问题 我使用的python版本是2.7.13,keras版本是2.0.2,都是使用anaconda安装的 我已经尝试过修改参数初始化方式(使用Xavier方法),修改优化方法(sgd,RMSprop等),调节学习率(0.1-10),修改batch_size等都没有效果。 我修改后的代码如下: ` from keras.models import * from keras.layers import * from keras.optimizers import *

input_tensor = Input(shape = (height, width, 3)) x = input_tensor

for i in range(1): x = Conv2D(32 * 2 ** i, (3, 3), activation = 'relu')(x) x = Conv2D(32 * 2 ** i, (3, 3), activation = 'relu')(x) x = MaxPooling2D((2, 2))(x)

x = Flatten()(x) x = Dropout(rate = 0.25)(x) x = [Dense(n_class, activation='softmax', name='c{}'.format(i))(x) for i in range(n_len)]

model = Model(inputs = input_tensor, outputs = x)

model.compile(optimizer = 'adadelta', loss='categorical_crossentropy', metrics=['accuracy']) from keras.callbacks import EarlyStopping #early_stop = EarlyStopping(monitor='val_loss', patience=2) model.fit_generator(gen(), steps_per_epoch = 256, epochs = 10, validation_steps = 40, validation_data = gen()) `

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

ypwhs avatar Jun 07 '17 16:06 ypwhs

抱歉,这两个地方我忘记说了,开始尝试的时候完全按照您的版本改的,循环次数是4,step_per_epoch是51200/32=1600,仍然存在同样的问题,为了快速调试问题才把参数改小的。 我预想的损失函数应该是先快速下降,然后在接近终点的时候出现振荡,但是我在第一轮epoch 中训练到几百个batch之后loss就不在降低了,而且这时候预测的精度等同于随机猜测, 这可能是什么问题呢

camperr avatar Jun 08 '17 01:06 camperr

终于调出来了,修改的参数是batch_size = 16, 并且在每个pooling层之前需要添加BatchNormalization层

camperr avatar Jun 14 '17 02:06 camperr

你调的都是可以加速训练的部分,所以你的问题可能真的是电脑速度太慢。

ypwhs avatar Jun 14 '17 02:06 ypwhs

确实没有GPU,但是我租了一个8核的云服务器跑的,原来跑一个小时预测结果完全没提升2.8%,但是修改了之后十分钟就可以看到单字符的准确度超过10%了,而且调试过程中我观察到传递到底层的梯度在迭代一段时间之后就变为0了,这也是为啥我加上了一个BN层

camperr avatar Jun 14 '17 06:06 camperr

8核怎么可能比得上显卡的三千多个CUDA……买显卡吧,准确率轻松上90%

发自我的 iPhone

在 2017年6月14日,14:55,camperr [email protected] 写道:

确实没有GPU,但是我租了一个8核的云服务器跑的,原来跑一个小时预测结果完全没提升2.8%,但是修改了之后十分钟就可以看到单字符的准确度超过10%了,而且调试过程中我观察到传递到底层的梯度在迭代一段时间之后就变为0了,这也是为啥我加上了一个BN层

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

ypwhs avatar Jun 14 '17 06:06 ypwhs

好吧,最近在考虑买,GTX1080怎么样

camperr avatar Jun 14 '17 07:06 camperr

买1080ti吧,比1080快35%

发自我的 iPhone

在 2017年6月14日,15:17,camperr [email protected] 写道:

好吧,最近在考虑买,GTX1080怎么样

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

ypwhs avatar Jun 14 '17 07:06 ypwhs

加了BN层之后,效果起飞, 我想问一下,Kreas怎么在调试中看参数的 梯度 呢? 官方文档我没看见有说怎么看参数的 梯度 @camperr

cyz520 avatar Mar 19 '18 07:03 cyz520

自定义callback @cyz520

camperr avatar Mar 23 '18 15:03 camperr

不知道你的 自定义callback代码 还在吗?我想看看你是怎么写的?你如果有时间可以这里回复我 或者 发我邮箱 [email protected] @camperr 谢谢你

cyz520 avatar Mar 27 '18 06:03 cyz520

描述

没有改任何代码

在第一、二轮表现很好,在第三轮之后的正确率就直接下降了,第四轮开始接近随机猜测

具体进度信息:

Epoch 1/5
51200/51200 [==============================] - 3628s 71ms/step - loss: 3.4468 - c1_loss: 0.8615 - c2_loss: 0.8547 - c3_loss: 0.8698 - c4_loss: 0.8608 - c1_acc: 0.7672 - c2_acc: 0.7688 - c3_acc: 0.7646 - c4_acc: 0.7674 - val_loss: 0.1561 - val_c1_loss: 0.0307 - val_c2_loss: 0.0438 - val_c3_loss: 0.0440 - val_c4_loss: 0.0376 - val_c1_acc: 0.9908 - val_c2_acc: 0.9865 - val_c3_acc: 0.9868 - val_c4_acc: 0.9889
Epoch 2/5
51200/51200 [==============================] - 3647s 71ms/step - loss: 0.2433 - c1_loss: 0.0569 - c2_loss: 0.0600 - c3_loss: 0.0650 - c4_loss: 0.0614 - c1_acc: 0.9883 - c2_acc: 0.9871 - c3_acc: 0.9855 - c4_acc: 0.9869 - val_loss: 0.1456 - val_c1_loss: 0.0320 - val_c2_loss: 0.0395 - val_c3_loss: 0.0455 - val_c4_loss: 0.0287 - val_c1_acc: 0.9911 - val_c2_acc: 0.9875 - val_c3_acc: 0.9858 - val_c4_acc: 0.9920
Epoch 3/5
51200/51200 [==============================] - 3645s 71ms/step - loss: 6.5301 - c1_loss: 1.6301 - c2_loss: 1.6325 - c3_loss: 1.6346 - c4_loss: 1.6328 - c1_acc: 0.5596 - c2_acc: 0.5587 - c3_acc: 0.5582 - c4_acc: 0.5587 - val_loss: 14.3357 - val_c1_loss: 3.5840 - val_c2_loss: 3.5838 - val_c3_loss: 3.5839 - val_c4_loss: 3.5839 - val_c1_acc: 0.0268 - val_c2_acc: 0.0271 - val_c3_acc: 0.0287 - val_c4_acc: 0.0270
Epoch 4/5
51200/51200 [==============================] - 3648s 71ms/step - loss: 14.3351 - c1_loss: 3.5838 - c2_loss: 3.5838 - c3_loss: 3.5838 - c4_loss: 3.5838 - c1_acc: 0.0278 - c2_acc: 0.0277 - c3_acc: 0.0282 - c4_acc: 0.0279 - val_loss: 14.3352 - val_c1_loss: 3.5838 - val_c2_loss: 3.5838 - val_c3_loss: 3.5838 - val_c4_loss: 3.5837 - val_c1_acc: 0.0283 - val_c2_acc: 0.0273 - val_c3_acc: 0.0280 - val_c4_acc: 0.0271
Epoch 5/5
 6829/51200 [===>..........................] - ETA: 51:23 - loss: 14.3351 - c1_loss: 3.5838 - c2_loss: 3.5838 - c3_loss: 3.5837 - c4_loss: 3.5838 - c1_acc: 0.0277 - c2_acc: 0.0280 - c3_acc: 0.0287 - c4_acc: 0.0282

版本情况:

  • Anaconda 3.6.3
  • keras版本:2.1.4
  • tensorflow版本:1.4.1
  • 显卡:1080ti

YYChildren avatar Apr 17 '18 07:04 YYChildren

@YYChildren 你可以加点 BN 试试。

ypwhs avatar Apr 17 '18 08:04 ypwhs

稍作修改,正确率超过99%

from keras.models import *
from keras.layers import *

input_tensor = Input((height, width, 3))
x = input_tensor
for i in range(4):
    x = Convolution2D(32*2**i, 3, 3)(x)
    x = Activation('relu')(x)
    x = Convolution2D(32*2**i, 3, 3)(x)
    x = Activation('relu')(x)
    x = BatchNormalization()(x)
    x = MaxPooling2D((2, 2))(x)

x = Flatten()(x)
x = Dropout(0.25)(x)
x = [Dense(n_class, activation='softmax', name='c%d'%(i+1))(x) for i in range(4)]
model = Model(input=input_tensor, output=x)

model.compile(loss='categorical_crossentropy',
              optimizer='adadelta',
              metrics=['accuracy'])

YYChildren avatar Apr 18 '18 01:04 YYChildren

加BN是可以的

cyz520 avatar Apr 18 '18 02:04 cyz520

终于调出来了,修改的参数是batch_size = 16, 并且在每个pooling层之前需要添加BatchNormalization层

我按照你说的,在MaxPooling层之前增加了BN层,然后把batch_size修改我了16,然后确实看到单个字符的准确率上升了。

MichealRay avatar May 04 '19 11:05 MichealRay

我也是这样,没有修改原始的cnn模型,直接用GPU 2080 Ti训练,3个epoch得到的acc都是0.028左右徘徊,加上一个BN,效果立马出来了。

RayDean avatar Jun 12 '19 05:06 RayDean

2019 更新了代码,现在使用了最新的 tensorflow 1.13.1,在模型里添加了 BN 层,训练速度加快了,模型精度也提高了,可以看看最新的代码。

ypwhs avatar Jun 16 '19 14:06 ypwhs