作者jikker (鲁蛇王)
看板deeplearning
标题Re: [问题] 手写数字辨识问题
时间Thu Mar 1 11:11:22 2018
有大大说想看改变後的辨识度&code
我就贴上来吧
其实我的最终目标是辨识 0~99 的手写数字
但是因为样本数不足 所以目前只辨识 0~60
资料分布如下
0 : 85 1 : 860 2 : 2231 3 : 1521 4 : 1750 5 : 1302 6 : 1511
7 : 1671 8 : 1967 9 : 2426 10 : 3000 11 : 1423 12 : 1474 13 : 1307
14 : 1189 15 : 1243 16 : 1368 17 : 1164 18 : 1129 19 : 847 20 : 790
21 : 889 22 : 694 23 : 667 24 : 693 25 : 528 26 : 369 27 : 306
28 : 222 29 : 179 30 : 194 31 : 146 32 : 192 33 : 151 34 : 101
35 : 139 36 : 100 37 : 120 38 : 83 39 : 79 40 : 107 41 : 71
42 : 76 43 : 64 44 : 66 45 : 79 46 : 101 47 : 66 48 : 59
49 : 52 50 : 75 51 : 72 52 : 91 53 : 60 54 : 90 55 : 93
56 : 48 57 : 50 58 : 64 59 : 70 60 : 54
总训练笔数为37618笔
测试资料为 每个数字随机挑选50笔
*数字56 因为样本数只有48 所以只有48笔
我使用 keras + tensorflow 每张图片的size是 48*48
为了配合MINST 强制缩小为 28*28
程式码如下
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=(9,9), padding='same',
input_shape=(28,28,1), activation='relu'))
model.add(MaxPooling2D(pool_size=(5,5)))
model.add(Conv2D(filters=32, kernel_size=(5,5), padding='same',
activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.6))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(61 ,activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam',
metrics=['accuracy'])
train_history = model.fit(x=x_train4d_normalize, y=y_trainonehot,
validation_split=0.2, epochs=20, batch_size=300, verbose=1)
model.summary() 结果如下
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_19 (Conv2D) (None, 28, 28, 16) 1312
_________________________________________________________________
max_pooling2d_19 (MaxPooling (None, 5, 5, 16) 0
_________________________________________________________________
conv2d_20 (Conv2D) (None, 5, 5, 32) 12832
_________________________________________________________________
max_pooling2d_20 (MaxPooling (None, 2, 2, 32) 0
_________________________________________________________________
dropout_25 (Dropout) (None, 2, 2, 32) 0
_________________________________________________________________
flatten_9 (Flatten) (None, 128) 0
_________________________________________________________________
dense_25 (Dense) (None, 256) 33024
_________________________________________________________________
dropout_26 (Dropout) (None, 256) 0
_________________________________________________________________
dense_26 (Dense) (None, 512) 131584
_________________________________________________________________
dropout_27 (Dropout) (None, 512) 0
_________________________________________________________________
dense_27 (Dense) (None, 61) 31293
=================================================================
Total params: 210,045
Trainable params: 210,045
Non-trainable params: 0
打散前训练状况 大概在15次左右收敛
Epoch 20/20
30094/30094 [==============================] - 29s 972us/step - loss: 0.4049
- acc: 0.8804 - val_loss: 11.8239 - val_acc: 0.1683
准确度评估是 0.84186351706
打散後训练状况 大概10次左右就收敛
Epoch 20/20
30094/30094 [==============================] - 29s 957us/step - loss: 0.4240
- acc: 0.8767 - val_loss: 0.1844 - val_acc: 0.9490
准确度评估是 0.873031496063
光看数据是差别不大
但是实际运用结果 未打散前会整批错 例如: 9全部认成7 之类的
打散後则是 某些图片会认错 但不致於整批错了
也符合版上大大的说明 前几批的资料对model影响很大
※ 引述《jikker (鲁蛇王)》之铭言:
: 哈!
: 开版後第一个技术问题就由小鲁来提问吧
: 我参考书上MNIST+CNN的范例
: 建立了以下架构
: 卷积层1 28*28 16层
: 池化层1 14*14 16层
: 卷积层2 14*14 36层
: 池化层2 7*7 36层
: 平坦层 1764 神经元
: 隐藏层 128 神经元
: 输出层 10 神经元
: 完美达成了 99.5% 的辨识率
: 可是当训练资料换成 我自己的资料时
: 辨识率就只有80%左右 而且这80% 是因为完全不认得 数字8跟9
: 所有数字8跟9的全部认错 所以只有80%
: 放大神经元数或卷积、池化层数目也得到类似的结果
: 是因为我的训练资料不足的关系吗?
: 我看MNIST是各数字都有6000多笔
: 我的资料分布如下
: 0 : 85
: 1 : 860
: 2 : 2231
: 3 : 1521
: 4 : 1750
: 5 : 1302
: 6 : 1511
: 7 : 1671
: 8 : 1967
: 9 : 2426
: 光看资料 感觉比较认不出来的应该是 0 或1 阿
: 另外为了弥补 资料量的差异 我有改变训练资料
: 每个数字各取800个 出来训练 (0太少 只能完整训练)
: 再把每个数字随机抽出50个出来验证
: 9还是每个都认错...
: 请问我的方向该怎麽修正呢?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 219.87.162.162
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/deeplearning/M.1519873885.A.955.html
1F:→ jikker: 话说 evaluate 这个准确度评估 太不准了吧 03/01 11:40
2F:→ jikker: 3048个错1476个 准确度应该是48% 评估出来居然是90%... 03/01 11:41
3F:→ aaaba: 资料要分成 train/val/test 三份,这三份的acc有各自的含义 03/01 12:03
4F:→ jikker: val的部分 我是设20% keras会自动从training的资料拿20% 03/01 12:08
5F:→ jikker: 出来当val 03/01 12:08
6F:→ aaaba: 你想知道准确度要看test acc,train acc是告诉你别的事情 03/01 12:27
7F:推 ladddddy: 请问aaab哥,假若train acc代表甚麽意思啊?是指train 03/01 15:00
8F:→ ladddddy: data 跟label永远对不起来吗? 03/01 15:00
9F:推 Kazimir: train acc就是这一个batch的准确率啊 我都是和train loss 03/01 15:21
10F:→ Kazimir: 一起看 有点像是训练进程吧 如果和val差太多就有过拟和的 03/01 15:22
11F:→ Kazimir: 可能 话说你要不要尝试把dropout关掉试试看 03/01 15:23
12F:推 ladddddy: 少打几个字...xdd ,*假若train acc过低,ex: 3,5%,这 03/01 16:07
13F:→ ladddddy: 情况是data问题吗 03/01 16:07
14F:→ Kazimir: 要看他的趋势 不过当然这麽低的话要不是你的程式写错 03/01 16:11
15F:→ Kazimir: 要不就是label有问题 譬如说你label的顺序和训练集不一样 03/01 16:12
16F:→ ycbrave: 不好意思请问一下,训练集shuffle是在model.fit时 把参 03/01 17:17
17F:→ ycbrave: 数shuffle = TRUE就是了吗? 03/01 17:17
18F:→ jikker: 天阿! 还有这麽简单的打乱方法 我是用 03/02 09:38
19F:→ jikker: np.random.permutation(data.shape[0]) 自行打乱的 03/02 09:39
20F:推 tay2510: 可以解释一下 "准确度评估" 是用哪些资料吗? 03/03 18:02
21F:→ tay2510: 喔喔 看到了 "每个数字随机挑选50笔" 03/03 18:04
22F:→ tay2510: 所以是有些数字只拿来测试? (Ex: 数字56) 03/03 18:06
23F:→ tay2510: 另外我怎麽觉得你的训练方式怪怪的? 03/03 18:10
24F:→ tay2510: 你可以训练 region proposal network 先侦测数字的位置 03/03 18:12
25F:→ tay2510: 再训练classification network (一起训练也可) 03/03 18:13
26F:→ tay2510: 就是像objection detection 那样的做法 03/03 18:14
27F:→ tay2510: object* 03/03 18:14
28F:→ tay2510: 用你原本的训练方式, 完全没办法scale啊 03/03 18:16
29F:→ tay2510: 或是跳过RPN 用传统的OCR方法把数字先切出来再分类也行 03/03 18:24
30F:→ jikker: 感谢tay大大意见 我有空再试试看 我有考虑过OCR切单独数字 03/05 10:22
31F:→ jikker: 但是手写字体很容易黏再一起 EX: 2000 这4个字都一笔写完 03/05 10:23
32F:→ jikker: 用过腐蚀+CCL 效果普通而已 现在是多蒐集资料让训练资料 03/05 10:25
33F:→ jikker: 更多 看会不会更准一点 03/05 10:25