2017/10/19

Python - 電腦字體數字辨識

markdown 續前篇:[Python - draw text on image and image to numpy array](http://etrex.blogspot.tw/2017/10/python-draw-text-on-image-and-image-to.html) ## 目標 嘗試建立一個簡單的類神經網路,只針對電腦字體數字 0~9 共 10 張圖片作訓練,訓練資料就是測試資料,在 40 次左右的訓練後正確度可達到 100%。 ## 本文包含 * keras 的使用 * keras Model 輸出成圖片 ## 程式碼 ``` import numpy as np from PIL import Image from PIL import ImageFont from PIL import ImageDraw image_size = (8,13) font_size = 10 x_train = np.array([]) y_train = np.array([]) for i in range(10): # 空白圖片生成 image = Image.new('L', image_size, 0) # 取得繪圖器 draw = ImageDraw.Draw(image) # 字型設定 # font = ImageFont.truetype("C:/Windows/Fonts/cour.ttf", font_size) font = ImageFont.truetype("C:/Windows/Fonts/msjh.ttc", font_size) # 關閉反鋸齒 draw.fontmode = '1' # 測量文字尺寸 text_size = draw.textsize(str(i),font) # print('text_size:', text_size) # 文字置中 text_position = ((image_size[0]-text_size[0])//2,(image_size[1]-text_size[1])//2) # print('text_position:', text_position) # 畫上文字 draw.text(text_position, str(i), 255, font) # 存檔 image.save(str(i)+'.bmp') # 轉成 numpy array na = np.array(image.getdata()).reshape(image.size[1], image.size[0]) # 加入訓練資料 x_train = np.append(x_train,na) y_train = np.append(y_train,i) import keras from keras.models import Sequential from keras.layers import Dense from keras.optimizers import RMSprop # 每次更新時所採用的資料筆數 batch_size = 1 # 總共有幾種數字 num_classes = 10 # 要更新幾次 epochs = 100 # 把資料轉成 model 需要的格式 x_train = x_train.reshape(10, 104) x_train = x_train.astype('float32') x_train /= 255 print(x_train.shape[0], 'train samples') y_train = keras.utils.to_categorical(y_train, num_classes) # 建立 model model = Sequential() # 一層 + softmax model.add(Dense(num_classes, input_shape=(104,), activation='softmax')) # ?? model.summary() # 選擇 loss function 和 optimizer model.compile(loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy']) # 開始訓練 history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_train, y_train)) # 計算分數 score = model.evaluate(x_train, y_train, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) # 儲存 model 至圖片 from keras.utils import plot_model plot_model(model, to_file='model.png') ``` ## 輸出 ``` Using TensorFlow backend. 10 train samples _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_1 (Dense) (None, 10) 1050 ================================================================= Total params: 1,050 Trainable params: 1,050 Non-trainable params: 0 _________________________________________________________________ Train on 10 samples, validate on 10 samples Epoch 1/100 10/10 [==============================] - ETA: 0s - loss: 2.5473 - acc: 0.0000e+00 - val_loss: 2.4555 - val_acc: 0.1000 Epoch 2/100 10/10 [==============================] - ETA: 0s - loss: 2.4563 - acc: 0.1000 - val_loss: 2.3924 - val_acc: 0.1000 Epoch 3/100 10/10 [==============================] - ETA: 0s - loss: 2.3926 - acc: 0.1000 - val_loss: 2.3334 - val_acc: 0.2000 Epoch 4/100 10/10 [==============================] - ETA: 0s - loss: 2.3336 - acc: 0.2000 - val_loss: 2.2760 - val_acc: 0.2000 Epoch 5/100 10/10 [==============================] - ETA: 0s - loss: 2.2766 - acc: 0.2000 - val_loss: 2.2196 - val_acc: 0.2000 Epoch 6/100 10/10 [==============================] - ETA: 0s - loss: 2.2203 - acc: 0.2000 - val_loss: 2.1636 - val_acc: 0.4000 Epoch 7/100 10/10 [==============================] - ETA: 0s - loss: 2.1640 - acc: 0.4000 - val_loss: 2.1090 - val_acc: 0.5000 Epoch 8/100 10/10 [==============================] - ETA: 0s - loss: 2.1096 - acc: 0.4000 - val_loss: 2.0545 - val_acc: 0.5000 Epoch 9/100 10/10 [==============================] - ETA: 0s - loss: 2.0556 - acc: 0.5000 - val_loss: 2.0013 - val_acc: 0.5000 Epoch 10/100 10/10 [==============================] - ETA: 0s - loss: 2.0023 - acc: 0.5000 - val_loss: 1.9484 - val_acc: 0.5000 Epoch 11/100 10/10 [==============================] - ETA: 0s - loss: 1.9493 - acc: 0.5000 - val_loss: 1.8971 - val_acc: 0.5000 Epoch 12/100 10/10 [==============================] - ETA: 0s - loss: 1.8985 - acc: 0.5000 - val_loss: 1.8453 - val_acc: 0.5000 Epoch 13/100 10/10 [==============================] - ETA: 0s - loss: 1.8464 - acc: 0.5000 - val_loss: 1.7949 - val_acc: 0.5000 Epoch 14/100 10/10 [==============================] - ETA: 0s - loss: 1.7962 - acc: 0.5000 - val_loss: 1.7448 - val_acc: 0.5000 Epoch 15/100 10/10 [==============================] - ETA: 0s - loss: 1.7464 - acc: 0.5000 - val_loss: 1.6958 - val_acc: 0.5000 Epoch 16/100 10/10 [==============================] - ETA: 0s - loss: 1.6971 - acc: 0.5000 - val_loss: 1.6471 - val_acc: 0.5000 Epoch 17/100 10/10 [==============================] - ETA: 0s - loss: 1.6486 - acc: 0.5000 - val_loss: 1.5994 - val_acc: 0.5000 Epoch 18/100 10/10 [==============================] - ETA: 0s - loss: 1.6007 - acc: 0.5000 - val_loss: 1.5520 - val_acc: 0.7000 Epoch 19/100 10/10 [==============================] - ETA: 0s - loss: 1.5538 - acc: 0.7000 - val_loss: 1.5064 - val_acc: 0.7000 Epoch 20/100 10/10 [==============================] - ETA: 0s - loss: 1.5078 - acc: 0.7000 - val_loss: 1.4612 - val_acc: 0.7000 Epoch 21/100 10/10 [==============================] - ETA: 0s - loss: 1.4629 - acc: 0.7000 - val_loss: 1.4168 - val_acc: 0.7000 Epoch 22/100 10/10 [==============================] - ETA: 0s - loss: 1.4190 - acc: 0.7000 - val_loss: 1.3736 - val_acc: 0.7000 Epoch 23/100 10/10 [==============================] - ETA: 0s - loss: 1.3758 - acc: 0.7000 - val_loss: 1.3311 - val_acc: 0.8000 Epoch 24/100 10/10 [==============================] - ETA: 0s - loss: 1.3331 - acc: 0.8000 - val_loss: 1.2891 - val_acc: 0.8000 Epoch 25/100 10/10 [==============================] - ETA: 0s - loss: 1.2913 - acc: 0.8000 - val_loss: 1.2488 - val_acc: 0.9000 Epoch 26/100 10/10 [==============================] - ETA: 0s - loss: 1.2513 - acc: 0.9000 - val_loss: 1.2091 - val_acc: 0.9000 Epoch 27/100 10/10 [==============================] - ETA: 0s - loss: 1.2114 - acc: 0.9000 - val_loss: 1.1701 - val_acc: 0.9000 Epoch 28/100 10/10 [==============================] - ETA: 0s - loss: 1.1721 - acc: 0.9000 - val_loss: 1.1324 - val_acc: 0.9000 Epoch 29/100 10/10 [==============================] - ETA: 0s - loss: 1.1349 - acc: 0.9000 - val_loss: 1.0957 - val_acc: 0.9000 Epoch 30/100 10/10 [==============================] - ETA: 0s - loss: 1.0984 - acc: 0.9000 - val_loss: 1.0596 - val_acc: 0.9000 Epoch 31/100 10/10 [==============================] - ETA: 0s - loss: 1.0620 - acc: 0.9000 - val_loss: 1.0243 - val_acc: 0.9000 Epoch 32/100 10/10 [==============================] - ETA: 0s - loss: 1.0269 - acc: 0.9000 - val_loss: 0.9905 - val_acc: 1.0000 Epoch 33/100 10/10 [==============================] - ETA: 0s - loss: 0.9932 - acc: 1.0000 - val_loss: 0.9571 - val_acc: 1.0000 Epoch 34/100 10/10 [==============================] - ETA: 0s - loss: 0.9597 - acc: 1.0000 - val_loss: 0.9247 - val_acc: 1.0000 Epoch 35/100 10/10 [==============================] - ETA: 0s - loss: 0.9276 - acc: 1.0000 - val_loss: 0.8934 - val_acc: 1.0000 Epoch 36/100 10/10 [==============================] - ETA: 0s - loss: 0.8962 - acc: 1.0000 - val_loss: 0.8629 - val_acc: 1.0000 Epoch 37/100 10/10 [==============================] - ETA: 0s - loss: 0.8655 - acc: 1.0000 - val_loss: 0.8330 - val_acc: 1.0000 Epoch 38/100 10/10 [==============================] - ETA: 0s - loss: 0.8359 - acc: 1.0000 - val_loss: 0.8047 - val_acc: 1.0000 Epoch 39/100 10/10 [==============================] - ETA: 0s - loss: 0.8077 - acc: 1.0000 - val_loss: 0.7766 - val_acc: 1.0000 Epoch 40/100 10/10 [==============================] - ETA: 0s - loss: 0.7797 - acc: 1.0000 - val_loss: 0.7501 - val_acc: 1.0000 Epoch 41/100 10/10 [==============================] - ETA: 0s - loss: 0.7529 - acc: 1.0000 - val_loss: 0.7239 - val_acc: 1.0000 Epoch 42/100 10/10 [==============================] - ETA: 0s - loss: 0.7270 - acc: 1.0000 - val_loss: 0.6988 - val_acc: 1.0000 Epoch 43/100 10/10 [==============================] - ETA: 0s - loss: 0.7018 - acc: 1.0000 - val_loss: 0.6744 - val_acc: 1.0000 Epoch 44/100 10/10 [==============================] - ETA: 0s - loss: 0.6773 - acc: 1.0000 - val_loss: 0.6511 - val_acc: 1.0000 Epoch 45/100 10/10 [==============================] - ETA: 0s - loss: 0.6542 - acc: 1.0000 - val_loss: 0.6283 - val_acc: 1.0000 Epoch 46/100 10/10 [==============================] - ETA: 0s - loss: 0.6312 - acc: 1.0000 - val_loss: 0.6065 - val_acc: 1.0000 Epoch 47/100 10/10 [==============================] - ETA: 0s - loss: 0.6097 - acc: 1.0000 - val_loss: 0.5852 - val_acc: 1.0000 Epoch 48/100 10/10 [==============================] - ETA: 0s - loss: 0.5882 - acc: 1.0000 - val_loss: 0.5647 - val_acc: 1.0000 Epoch 49/100 10/10 [==============================] - ETA: 0s - loss: 0.5677 - acc: 1.0000 - val_loss: 0.5451 - val_acc: 1.0000 Epoch 50/100 10/10 [==============================] - ETA: 0s - loss: 0.5482 - acc: 1.0000 - val_loss: 0.5261 - val_acc: 1.0000 Epoch 51/100 10/10 [==============================] - ETA: 0s - loss: 0.5291 - acc: 1.0000 - val_loss: 0.5078 - val_acc: 1.0000 Epoch 52/100 10/10 [==============================] - ETA: 0s - loss: 0.5108 - acc: 1.0000 - val_loss: 0.4900 - val_acc: 1.0000 Epoch 53/100 10/10 [==============================] - ETA: 0s - loss: 0.4928 - acc: 1.0000 - val_loss: 0.4729 - val_acc: 1.0000 Epoch 54/100 10/10 [==============================] - ETA: 0s - loss: 0.4759 - acc: 1.0000 - val_loss: 0.4567 - val_acc: 1.0000 Epoch 55/100 10/10 [==============================] - ETA: 0s - loss: 0.4596 - acc: 1.0000 - val_loss: 0.4409 - val_acc: 1.0000 Epoch 56/100 10/10 [==============================] - ETA: 0s - loss: 0.4440 - acc: 1.0000 - val_loss: 0.4258 - val_acc: 1.0000 Epoch 57/100 10/10 [==============================] - ETA: 0s - loss: 0.4286 - acc: 1.0000 - val_loss: 0.4113 - val_acc: 1.0000 Epoch 58/100 10/10 [==============================] - ETA: 0s - loss: 0.4143 - acc: 1.0000 - val_loss: 0.3971 - val_acc: 1.0000 Epoch 59/100 10/10 [==============================] - ETA: 0s - loss: 0.4001 - acc: 1.0000 - val_loss: 0.3835 - val_acc: 1.0000 Epoch 60/100 10/10 [==============================] - ETA: 0s - loss: 0.3864 - acc: 1.0000 - val_loss: 0.3706 - val_acc: 1.0000 Epoch 61/100 10/10 [==============================] - ETA: 0s - loss: 0.3735 - acc: 1.0000 - val_loss: 0.3580 - val_acc: 1.0000 Epoch 62/100 10/10 [==============================] - ETA: 0s - loss: 0.3611 - acc: 1.0000 - val_loss: 0.3459 - val_acc: 1.0000 Epoch 63/100 10/10 [==============================] - ETA: 0s - loss: 0.3487 - acc: 1.0000 - val_loss: 0.3343 - val_acc: 1.0000 Epoch 64/100 10/10 [==============================] - ETA: 0s - loss: 0.3370 - acc: 1.0000 - val_loss: 0.3232 - val_acc: 1.0000 Epoch 65/100 10/10 [==============================] - ETA: 0s - loss: 0.3261 - acc: 1.0000 - val_loss: 0.3125 - val_acc: 1.0000 Epoch 66/100 10/10 [==============================] - ETA: 0s - loss: 0.3152 - acc: 1.0000 - val_loss: 0.3023 - val_acc: 1.0000 Epoch 67/100 10/10 [==============================] - ETA: 0s - loss: 0.3049 - acc: 1.0000 - val_loss: 0.2925 - val_acc: 1.0000 Epoch 68/100 10/10 [==============================] - ETA: 0s - loss: 0.2953 - acc: 1.0000 - val_loss: 0.2828 - val_acc: 1.0000 Epoch 69/100 10/10 [==============================] - ETA: 0s - loss: 0.2854 - acc: 1.0000 - val_loss: 0.2736 - val_acc: 1.0000 Epoch 70/100 10/10 [==============================] - ETA: 0s - loss: 0.2762 - acc: 1.0000 - val_loss: 0.2648 - val_acc: 1.0000 Epoch 71/100 10/10 [==============================] - ETA: 0s - loss: 0.2675 - acc: 1.0000 - val_loss: 0.2563 - val_acc: 1.0000 Epoch 72/100 10/10 [==============================] - ETA: 0s - loss: 0.2588 - acc: 1.0000 - val_loss: 0.2481 - val_acc: 1.0000 Epoch 73/100 10/10 [==============================] - ETA: 0s - loss: 0.2506 - acc: 1.0000 - val_loss: 0.2403 - val_acc: 1.0000 Epoch 74/100 10/10 [==============================] - ETA: 0s - loss: 0.2429 - acc: 1.0000 - val_loss: 0.2327 - val_acc: 1.0000 Epoch 75/100 10/10 [==============================] - ETA: 0s - loss: 0.2351 - acc: 1.0000 - val_loss: 0.2254 - val_acc: 1.0000 Epoch 76/100 10/10 [==============================] - ETA: 0s - loss: 0.2279 - acc: 1.0000 - val_loss: 0.2184 - val_acc: 1.0000 Epoch 77/100 10/10 [==============================] - ETA: 0s - loss: 0.2209 - acc: 1.0000 - val_loss: 0.2117 - val_acc: 1.0000 Epoch 78/100 10/10 [==============================] - ETA: 0s - loss: 0.2140 - acc: 1.0000 - val_loss: 0.2053 - val_acc: 1.0000 Epoch 79/100 10/10 [==============================] - ETA: 0s - loss: 0.2078 - acc: 1.0000 - val_loss: 0.1989 - val_acc: 1.0000 Epoch 80/100 10/10 [==============================] - ETA: 0s - loss: 0.2011 - acc: 1.0000 - val_loss: 0.1929 - val_acc: 1.0000 Epoch 81/100 10/10 [==============================] - ETA: 0s - loss: 0.1954 - acc: 1.0000 - val_loss: 0.1872 - val_acc: 1.0000 Epoch 82/100 10/10 [==============================] - ETA: 0s - loss: 0.1894 - acc: 1.0000 - val_loss: 0.1817 - val_acc: 1.0000 Epoch 83/100 10/10 [==============================] - ETA: 0s - loss: 0.1841 - acc: 1.0000 - val_loss: 0.1763 - val_acc: 1.0000 Epoch 84/100 10/10 [==============================] - ETA: 0s - loss: 0.1784 - acc: 1.0000 - val_loss: 0.1711 - val_acc: 1.0000 Epoch 85/100 10/10 [==============================] - ETA: 0s - loss: 0.1732 - acc: 1.0000 - val_loss: 0.1662 - val_acc: 1.0000 Epoch 86/100 10/10 [==============================] - ETA: 0s - loss: 0.1684 - acc: 1.0000 - val_loss: 0.1614 - val_acc: 1.0000 Epoch 87/100 10/10 [==============================] - ETA: 0s - loss: 0.1636 - acc: 1.0000 - val_loss: 0.1568 - val_acc: 1.0000 Epoch 88/100 10/10 [==============================] - ETA: 0s - loss: 0.1590 - acc: 1.0000 - val_loss: 0.1523 - val_acc: 1.0000 Epoch 89/100 10/10 [==============================] - ETA: 0s - loss: 0.1542 - acc: 1.0000 - val_loss: 0.1480 - val_acc: 1.0000 Epoch 90/100 10/10 [==============================] - ETA: 0s - loss: 0.1501 - acc: 1.0000 - val_loss: 0.1438 - val_acc: 1.0000 Epoch 91/100 10/10 [==============================] - ETA: 0s - loss: 0.1457 - acc: 1.0000 - val_loss: 0.1399 - val_acc: 1.0000 Epoch 92/100 10/10 [==============================] - ETA: 0s - loss: 0.1418 - acc: 1.0000 - val_loss: 0.1360 - val_acc: 1.0000 Epoch 93/100 10/10 [==============================] - ETA: 0s - loss: 0.1379 - acc: 1.0000 - val_loss: 0.1323 - val_acc: 1.0000 Epoch 94/100 10/10 [==============================] - ETA: 0s - loss: 0.1343 - acc: 1.0000 - val_loss: 0.1287 - val_acc: 1.0000 Epoch 95/100 10/10 [==============================] - ETA: 0s - loss: 0.1306 - acc: 1.0000 - val_loss: 0.1252 - val_acc: 1.0000 Epoch 96/100 10/10 [==============================] - ETA: 0s - loss: 0.1271 - acc: 1.0000 - val_loss: 0.1218 - val_acc: 1.0000 Epoch 97/100 10/10 [==============================] - ETA: 0s - loss: 0.1237 - acc: 1.0000 - val_loss: 0.1185 - val_acc: 1.0000 Epoch 98/100 10/10 [==============================] - ETA: 0s - loss: 0.1204 - acc: 1.0000 - val_loss: 0.1154 - val_acc: 1.0000 Epoch 99/100 10/10 [==============================] - ETA: 0s - loss: 0.1172 - acc: 1.0000 - val_loss: 0.1124 - val_acc: 1.0000 Epoch 100/100 10/10 [==============================] - ETA: 0s - loss: 0.1141 - acc: 1.0000 - val_loss: 0.1095 - val_acc: 1.0000 Test loss: 0.109465420246 Test accuracy: 1.0 ``` ## 輸出的圖片 plot_model 的執行,需要安裝 pydot 和 graphviz ``` pip3 install pydot ``` ## plot_model 的環境安裝 在 windows 上,graphviz 必須手動安裝,安裝檔可以到他們官網下載。 [http://www.graphviz.org/Download_windows.php](http://www.graphviz.org/Download_windows.php) 安裝好之後必須在環境變數 path 加上 C:\Program Files (x86)\Graphviz2.30\bin 才能使用。 cmd 下輸入指令: ``` dot -version ``` 若顯示以下訊息,表示正確安裝。 ``` dot - graphviz version 2.30.1 (20130214.1330) libdir = "C:\Program Files (x86)\Graphviz2.30\bin" Activated plugin library: gvplugin_pango.dll Using textlayout: textlayout:cairo Activated plugin library: gvplugin_dot_layout.dll Using layout: dot:dot_layout Activated plugin library: gvplugin_core.dll Using render: dot:core Using device: dot:dot:core The plugin configuration file: C:\Program Files (x86)\Graphviz2.30\bin\config6 was successfully loaded. render : cairo dot fig gd gdiplus map pic pov ps svg tk vml vrml xdot layout : circo dot fdp neato nop nop1 nop2 osage patchwork sfdp twopi textlayout : textlayout device : bmp canon cmap cmapx cmapx_np dot emf emfplus eps fig gd gd2 gif gv imap imap_np ismap jpe jpeg jpg metafile pdf p ic plain plain-ext png pov ps ps2 svg svgz tif tiff tk vml vmlz vrml wbmp xdot loadimage : (lib) bmp eps gd gd2 gif jpe jpeg jpg png ps svg ``` ## 參考文件 plot_model 在 windows 上的環境建立:[https://zhuanlan.zhihu.com/p/28158957](https://zhuanlan.zhihu.com/p/28158957) graphviz 的使用:[https://www.openfoundry.org/tw/foss-programs/8820-graphviz-](https://www.openfoundry.org/tw/foss-programs/8820-graphviz-)

沒有留言: