내용

글번호 741
작성자 heojk
작성일 2017-08-30 17:03:25
제목 TensorFlow 에서 MNIST 데이터 딥러닝(CNN 이용)
내용 import numpy as np import gzip import struct def read_data(label_path, image_path): with gzip.open(label_path) as flbl: _, _ = struct.unpack(">II", flbl.read(8)) label = np.fromstring(flbl.read(), dtype=np.int8) with gzip.open(image_path, 'rb') as fimg: _, _, rows, cols = struct.unpack(">IIII", fimg.read(16)) image = np.fromstring(fimg.read(), dtype=np.uint8).reshape(len(label), rows, cols) return (label, image) from __future__ import print_function import matplotlib.pyplot as plt import tensorflow as tf import numpy as np import math from random import shuffle ''' 훈련 옵션 ''' # 미니배치 사이즈 batch_size = 100 # 학습률 learning_rate = 0.1 # 훈련 스텝 step_num = 2000 ''' 네트워크 옵션 ''' image_size = 28 class_num = 10 path = './data/MNIST/' (train_label, train_img) = read_data( path+'train-labels-idx1-ubyte.gz', path+'train-images-idx3-ubyte.gz') (val_label, val_img) = read_data( path+'t10k-labels-idx1-ubyte.gz', path+'t10k-images-idx3-ubyte.gz') # 10개의 이미지와 레이블 plotting for i in range(10): plt.subplot(1,10,i+1) plt.imshow(train_img[i], cmap='Greys_r') plt.axis('off') plt.show() print('label: %s' % (train_label[0:10])) print(train_img[0].shape) print(type(train_img[0])) print(train_img[0]) # 타입 변환 train_label = train_label.astype(np.int64) train_img = train_img.astype(np.float32) / 255 val_label = val_label.astype(np.int64) val_img = val_img.astype(np.float32) / 255 ''' 네트워크 정의 CNN(Convolution Neural Network) ''' # 입력 레이어 x = tf.placeholder(tf.float32, [None, image_size, image_size]) # 3-D shape (batch_size, width, height)을 4-D (batch_size, width, height, num_channel)로 변환 x_reshape = tf.reshape(x, [-1, image_size, image_size, 1]) # Conv 레이어 W_conv1 = tf.Variable(tf.truncated_normal([5, 5, 1, 20], stddev=0.1)) b_conv1 = tf.Variable(tf.zeros([20])) h_conv1 = tf.nn.tanh(tf.nn.conv2d(x_reshape, W_conv1, strides=[1, 1, 1, 1], padding='SAME') + b_conv1) # Pooling 레이어 h_pool1 = tf.nn.max_pool(h_conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # Conv 레이어 W_conv2 = tf.Variable(tf.truncated_normal([5, 5, 20, 50], stddev=0.1)) b_conv2 = tf.Variable(tf.zeros([50])) h_conv2 = tf.nn.tanh(tf.nn.conv2d(h_pool1, W_conv2, strides=[1, 1, 1, 1], padding='SAME') + b_conv2) # Pooling 레이어 h_pool2 = tf.nn.max_pool(h_conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # fully-connected 레이어 W_fc1 = tf.Variable(tf.truncated_normal([50*7*7, 500], stddev=0.1)) b_fc1 = tf.Variable(tf.zeros([500])) h_pool2_flat = tf.reshape(h_pool2, [-1, 50*7*7]) h_fc1 = tf.nn.tanh(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) # 출력 레이어 W_fc2 = tf.Variable(tf.truncated_normal([500, class_num], stddev=0.1)) b_fc2 = tf.Variable(tf.zeros([class_num])) model = tf.matmul(h_fc1, W_fc2) + b_fc2 # 목표 출력 y_ = tf.placeholder(tf.int64, [None]) y_ = tf.to_int64(y_) ''' 훈련하기 ''' # 손실 함수 정의 cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y_, logits=model) loss = tf.reduce_mean(cross_entropy) # 옵티마이저 초기화 (SGD) optimizer = tf.train.GradientDescentOptimizer(learning_rate) global_step = tf.Variable(0, name='global_step', trainable=False) train_op = optimizer.minimize(loss, global_step=global_step) # 세션 생성 sess = tf.InteractiveSession() # 글로벌 파라미터 초기화 tf.global_variables_initializer().run() # 학습하기 batch_num = 0 shuffle_index = [i for i in range(train_img.shape[0])] for step in range(step_num): if (batch_num+1) * batch_size <= train_img.shape[0]: batch_xs = train_img[shuffle_index[batch_num*batch_size:(batch_num+1)*batch_size> batch_ys = train_label[shuffle_index[batch_num*batch_size:(batch_num+1)*batch_size> _, loss_value = sess.run([train_op, loss], feed_dict={x: batch_xs, y_: batch_ys}) if step % 100 == 0: print('Step %d: loss = %.5f' % (step, loss_value)) batch_num += 1 else: batch_num = 0 shuffle(shuffle_index) ''' 평가하기 ''' correct_prediction = tf.equal(tf.argmax(model, 1), y_) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) eval_accuracy = 0.0 batch_num = 0 while (batch_num+1) * batch_size <= val_img.shape[0]: batch_xs = val_img[batch_num * batch_size:(batch_num + 1) * batch_size] batch_ys = val_label[batch_num * batch_size:(batch_num + 1) * batch_size] step_eval_accuracy = sess.run(accuracy, feed_dict={x: batch_xs, y_: batch_ys}) eval_accuracy = eval_accuracy + step_eval_accuracy batch_num += 1 print('Validation accuracy: %f%%' % (eval_accuracy / batch_num * 100,))