텐서플로 프로젝트) mnist 손글씨 인식을 사용한 숫자인식 그림판
2017. 12. 2. 20:03ㆍ프로그래밍(주력)/PYTHON
tkinter모듈의 canvas기능을 활용하여
학습 한뒤, 이미지를 불러와 이미 학습된 것에 mnist화 된 이미지를 넣어
결론을 도출할 수 있게 만들었다.
학습을 하는 과정은
드롭아웃을 활용해 1024개짜리 레이어 5개를 거쳐 학습하게 만들었다.
실행사진
코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | import tensorflow as tf import numpy as np from PIL import Image, ImageFilter from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("./mnist/data/", one_hot=True) def imageprepare(argv): im = Image.open(argv).convert('L') width = float(im.size[0]) height = float(im.size[1]) newImage = Image.new('L', (28, 28), (255)) if width > height: nheight = int(round((20.0 / width * height), 0)) if (nheight == 0): nheight = 1 img = im.resize((20, nheight), Image.ANTIALIAS).filter(ImageFilter.SHARPEN) wtop = int(round(((28 - nheight) / 2), 0)) newImage.paste(img, (4, wtop)) else: nwidth = int(round((20.0 / height * width), 0)) if (nwidth == 0): nwidth = 1 img = im.resize((nwidth, 20), Image.ANTIALIAS).filter(ImageFilter.SHARPEN) wleft = int(round(((28 - nwidth) / 2), 0)) newImage.paste(img, (wleft, 4)) tv = list(newImage.getdata()) tva = [(255 - x) * 1.0 / 255.0 for x in tv] return tva X = tf.placeholder(tf.float32, [None, 784]) Y = tf.placeholder(tf.float32, [None, 10]) keep_prob = tf.placeholder(tf.float32) W1 = tf.Variable(tf.random_normal([784, 256], stddev=0.01)) L1 = tf.nn.relu(tf.matmul(X, W1)) L1 = tf.nn.dropout(L1, keep_prob) W2 = tf.Variable(tf.random_normal([256, 256], stddev=0.01)) L2 = tf.nn.relu(tf.matmul(L1, W2)) L2 = tf.nn.dropout(L2, keep_prob) W3 = tf.Variable(tf.random_normal([256, 256], stddev=0.01)) L3 = tf.nn.relu(tf.matmul(X, W1)) L3 = tf.nn.dropout(L1, keep_prob) W4 = tf.Variable(tf.random_normal([256, 256], stddev=0.01)) L4 = tf.nn.relu(tf.matmul(X, W1)) L4 = tf.nn.dropout(L1, keep_prob) W5 = tf.Variable(tf.random_normal([256, 10], stddev=0.01)) model = tf.matmul(L4, W5) cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=model, labels=Y)) optimizer = tf.train.AdamOptimizer(0.00001).minimize(cost) init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) batch_size = 100 total_batch = int(mnist.train.num_examples / batch_size) for epoch in range(10000): total_cost = 0 for i in range(total_batch): batch_xs, batch_ys = mnist.train.next_batch(batch_size) _, cost_val = sess.run([optimizer, cost], feed_dict={X: batch_xs, Y: batch_ys, keep_prob: 0.8}) total_cost += cost_val print('Epoch:', '%04d' % (epoch + 1), 'Avg. cost =', '{:.3f}'.format(total_cost / total_batch)) print('최적화 완료!') is_correct = tf.equal(tf.argmax(model, 1), tf.argmax(Y, 1)) accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32)) print('정확도:', sess.run(accuracy, feed_dict={X: mnist.test.images, Y: mnist.test.labels, keep_prob: 1})) current_num = -1; def check(): global current_num global textLabel x=[imageprepare('./img.png')] newArr=[] for i in range(784): newArr.append(x[0][i]) newArr2 = [] newArr2.append(newArr) labels = sess.run(model, feed_dict={X: newArr2, Y:[[0,0,0,0,0,0,0,0,0,0]], keep_prob: 1}) return np.argmax(labels[0]) def checkgo(): try: a = check() return a except: checkgo() import tkinter as tk from PIL import Image,ImageDraw class ImageGenerator: def __init__(self,parent,posx,posy,*kwargs): self.parent = parent self.posx = posx self.posy = posy self.sizex = 200 self.sizey = 200 self.b1 = "up" self.xold = None self.yold = None self.drawing_area=tk.Canvas(self.parent,width=self.sizex,height=self.sizey+10) self.drawing_area.place(x=self.posx,y=self.posy) self.drawing_area.bind("<Motion>", self.motion) self.drawing_area.bind("<ButtonPress-1>", self.b1down) self.drawing_area.bind("<ButtonRelease-1>", self.b1up) self.drawing_area.place(x=self.sizex/7,y=self.sizex/7) self.button=tk.Button(self.parent,text="Done!",width=8,command=self.save) self.button.place(x=30,y=self.sizey+50) self.button1=tk.Button(self.parent,text="Clear!",width=8,command=self.clear) self.button1.place(x=135,y=self.sizey+50) self.text = tk.Text(self.parent,width=10,height=1) self.text.insert(tk.INSERT, "예상숫자 : ") self.text.pack() self.text.place(x=90,y=4) self.image=Image.new("RGB",(200,200),(255,255,255)) self.draw=ImageDraw.Draw(self.image) def save(self): filename = "img.png" self.image.save(filename) print("예상숫자 : "+ str(checkgo())) a = "예상숫자 : "+ str(checkgo()) self.text.delete('1.0',tk.END) self.text.insert(tk.INSERT,a) def clear(self): self.drawing_area.delete("all") self.image=Image.new("RGB",(200,200),(255,255,255)) self.draw=ImageDraw.Draw(self.image) def b1down(self,event): self.b1 = "down" def b1up(self,event): self.b1 = "up" self.xold = None self.yold = None def motion(self,event): if self.b1 == "down": if self.xold is not None and self.yold is not None: event.widget.create_line(self.xold,self.yold,event.x,event.y,smooth='true',width=3,fill='blue') self.draw.line(((self.xold,self.yold),(event.x,event.y)),(0,128,0),width=10) self.xold = event.x self.yold = event.y if __name__ == "__main__": root=tk.Tk() root.wm_geometry("%dx%d+%d+%d" % (265, 300, 10, 10)) root.config(bg='gray') ImageGenerator(root,10,10) root.mainloop() | cs |
주인장은 장난이자 실험으로 드롭아웃 5레이어를 만번까지 돌려 보았지만
98.1%의 정확도에서 더이상 올라가지 않았다.(코스트는 0.001까지 봄)
이 코드는 상당히 최적화가 없고, 단순한 기능 구현과 설명만 하기 위해 만든 코드이다.
그대로 쓰진 말고 조금 더 각색해서 쓰길 바란다.
'프로그래밍(주력) > PYTHON' 카테고리의 다른 글
파이썬 프로젝트) 콘솔형 지뢰찾기 만들기 (0) | 2017.08.07 |
---|---|
텐서플로 프로젝트) 주가(코인) 예측 프로그램 기획 (2) | 2017.07.03 |
파이썬 보고서) 0621 수업 5일차 - 파이썬의 예외처리, 파일입출력 (0) | 2017.06.28 |
파이썬 보고서) 0609 수업 2일차 - 파이썬의 연산자 (0) | 2017.06.16 |
파이썬 보고서) 0603 수업 1일차 - 파이썬의 기본 (0) | 2017.06.14 |