728x90
반응형
In [29]:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
In [30]:
from tensorflow.keras.datasets.mnist import load_data
In [39]:
(X_train,y_train),(X_test,y_test) = load_data()
In [40]:
X_train = X_train.astype(np.float32).reshape(-1,28*28) / .255
X_test = X_test.astype(np.float32).reshape(-1,28*28) /.255
y_train = y_train.astype(np.int32)
y_test = y_test.astype(np.int32)
In [41]:
X_train = X_train[5000:]
y_train = y_train[5000:]
X_valid = X_train[:5000]
y_valid = y_train[:5000]
In [42]:
X_train.shape
Out[42]:
In [43]:
height = 28
width = 28
channels = 1
n_inputs = height * width
conv1_fmaps = 32
conv1_ksize = 3
conv1_stride = 1
conv1_pad = "SAME"
conv2_fmaps = 64
conv2_ksize = 3
conv2_stride = 1
conv2_pad = "SAME"
conv2_dropout_rate = 0.25
pool3_fmaps = conv2_fmaps
n_fc1 = 128
fc1_dropout_rate = 0.5
n_outputs = 10
tf.reset_default_graph()
with tf.name_scope("inputs"):
X = tf.placeholder(tf.float32, shape=[None, n_inputs], name="X")
X_reshaped = tf.reshape(X, shape=[-1, height, width, channels])
y = tf.placeholder(tf.int32, shape=[None], name="y")
training = tf.placeholder_with_default(False, shape=[], name='training')
conv1 = tf.layers.conv2d(X_reshaped, filters=conv1_fmaps, kernel_size=conv1_ksize,
strides=conv1_stride, padding=conv1_pad,
activation=tf.nn.relu, name="conv1")
conv2 = tf.layers.conv2d(conv1, filters=conv2_fmaps, kernel_size=conv2_ksize,
strides=conv2_stride, padding=conv2_pad,
activation=tf.nn.relu, name="conv2")
with tf.name_scope("pool3"):
pool3 = tf.nn.max_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="VALID")
pool3_flat = tf.reshape(pool3, shape=[-1, pool3_fmaps * 14 * 14])
pool3_flat_drop = tf.layers.dropout(pool3_flat, conv2_dropout_rate, training=training)
with tf.name_scope("fc1"):
fc1 = tf.layers.dense(pool3_flat_drop, n_fc1, activation=tf.nn.relu, name="fc1")
fc1_drop = tf.layers.dropout(fc1, fc1_dropout_rate, training=training)
with tf.name_scope("output"):
logits = tf.layers.dense(fc1, n_outputs, name="output")
Y_proba = tf.nn.softmax(logits, name="Y_proba")
with tf.name_scope("train"):
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y)
loss = tf.reduce_mean(xentropy)
optimizer = tf.train.AdamOptimizer()
training_op = optimizer.minimize(loss)
with tf.name_scope("eval"):
correct = tf.nn.in_top_k(logits, y, 1)
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
with tf.name_scope("init_and_save"):
init = tf.global_variables_initializer()
saver = tf.train.Saver()
In [50]:
def get_model_params():
gvars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES)
return {gvar.op.name : value for gvar, value in zip(gvars,tf.get_default_session().run(gvars))}
def restore_model_params(model_params):
gvar_names = list(model_params.keys())
assign_ops = {gvar_name: tf.get_default_graph().get_operation_by_name(gvar_name + "/Assign")
for gvar_name in gvar_names}
init_values = {gvar_name: assign_op.inputs[1] for gvar_name, assign_op in assign_ops.items()}
feed_dict = {init_values[gvar_name]: model_params[gvar_name] for gvar_name in gvar_names}
tf.get_default_session().run(assign_ops, feed_dict=feed_dict)
In [51]:
def shuffle_batch(X, y, batch_size):
rnd_idx = np.random.permutation(len(X))
n_batches = len(X) // batch_size
for batch_idx in np.array_split(rnd_idx, n_batches):
X_batch, y_batch = X[batch_idx], y[batch_idx]
yield X_batch, y_batch
In [52]:
n_epochs = 1000
batch_size = 50
best_loss_val = np.infty
check_interval = 500
checks_since_last_progress = 0
max_checks_without_progress = 20
best_model_params = None
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(n_epochs):
n_batches = len(X_train) // batch_size
for i in range(n_batches):
X_batch, y_batch = next(shuffle_batch(X_train,y_train,batch_size))
sess.run(training_op,feed_dict={X:X_batch,y:y_batch,training:True})
if i % check_interval == 0:
loss_val = loss.eval(feed_dict={X:X_valid,y:y_valid})
if loss_val < best_loss_val:
best_loss_val = loss_val
checks_since_last_progress = 0
best_model_params = get_model_params()
else:
checks_since_last_progress += 1
acc_batch = accuracy.eval(feed_dict={X:X_batch,y:y_batch})
acc_val = accuracy.eval(feed_dict={X:X_valid,y:y_valid})
print("Epoch : {0} / batch_Acc : {1:.4f}% / valid_acc : {2:.4f}% / best_loss : {3:.4f}"
.format(epoch,acc_batch*100,acc_val*100, best_loss_val))
if checks_since_last_progress > max_checks_without_progress:
print("조기 종료")
break
if best_model_params:
restore_model_params(best_model_params)
acc_test = accuracy.eval(feed_dict={X:X_test[:5000],y:y_test[:5000]})
print("Test ACC : {0:.4f}".format(acc_test))
save_path = saver.save(sess,"./my_mnist_model")
In [93]:
width = 299
height =299
channels = 3
In [94]:
import matplotlib.image as mpimg
import os
test_image = mpimg.imread(os.path.join("image.png"))[:,:,:channels]
plt.imshow(test_image)
plt.axis("off")
plt.show()
In [95]:
test_image = 2 * test_image - 1
In [96]:
import sys
import tarfile
from six.moves import urllib
TF_MODELS_URL = "http://download.tensorflow.org/models"
INCEPTION_V3_URL = TF_MODELS_URL + "/inception_v3_2016_08_28.tar.gz"
INCEPTION_PATH = os.path.join("datasets", "inception")
INCEPTION_V3_CHECKPOINT_PATH = os.path.join(INCEPTION_PATH, "inception_v3.ckpt")
def download_progress(count, block_size, total_size):
percent = count * block_size * 100 // total_size
sys.stdout.write("\rDownloading: {}%".format(percent))
sys.stdout.flush()
def fetch_pretrained_inception_v3(url=INCEPTION_V3_URL,path=INCEPTION_PATH):
if os.path.exists(INCEPTION_V3_CHECKPOINT_PATH):
return
os.makedirs(path,exist_ok=True)
tgz_path = os.path.join(path,"inception_v3.tgz")
urllib.request.urlretrieve(url,tgz_path,reporthook=download_progress)
inception_tgz = tarfile.open(tgz_path)
inception_tgz.extractall(path=path)
inception_tgz.close()
os.remove(tgz_path)
In [63]:
fetch_pretrained_inception_v3()
In [97]:
import re
CLASS_NAME_REGREX = re.compile(r"^n\d+\s+(.*)\s*$",re.M | re.U)
def load_class_names():
with open(os.path.join("datasets","inception","imagenet_class_names.txt"),"rb") as f:
content = f.read().decode("utf-8")
return CLASS_NAME_REGREX.findall(content)
In [98]:
class_names = ["background"] + load_class_names()
In [99]:
class_names[:5]
Out[99]:
In [108]:
from tensorflow.contrib.slim.nets import inception
import tensorflow.contrib.slim as slim
tf.reset_default_graph()
X = tf.placeholder(tf.float32,shape=[None,299,299,3],name="X")
with slim.arg_scope(inception.inception_v3_arg_scope()):
logits,end_points = inception.inception_v3(X,num_classes=1001,is_training=False)
predictions = end_points["Predictions"]
saver = tf.train.Saver()
In [109]:
with tf.Session() as sess:
saver.restore(sess,INCEPTION_V3_CHECKPOINT_PATH)
In [132]:
# X_test = test_image.reshape(-1, height, width, channels)
X_test = test_image
with tf.Session() as sess:
saver.restore(sess,INCEPTION_V3_CHECKPOINT_PATH)
predictions_val = predictions.eval(feed_dict={X:X_test})
In [136]:
most_likely_class_index = np.argmax(predictions_val[0])
most_likely_class_index
Out[136]:
In [139]:
class_names[most_likely_class_index]
Out[139]:
In [140]:
top_5 = np.argpartition(predictions_val[0],-5)[-5:]
top_5 = reversed(top_5[np.argsort(predictions_val[0][top_5])])
for i in top_5:
print("{0} : {1:.2f}%".format(class_names[i],100* predictions_val[0][i]))
In [149]:
# 데이터셋 먼저 다운로드
import sys
import tarfile
from six.moves import urllib
FLOWERS_URL = "http://download.tensorflow.org/example_images/flower_photos.tgz"
FLOWERS_PATH = os.path.join("datasets", "flowers")
def fetch_flowers(url=FLOWERS_URL, path=FLOWERS_PATH):
if os.path.exists(FLOWERS_PATH):
return
os.makedirs(path, exist_ok=True)
tgz_path = os.path.join(path, "flower_photos.tgz")
urllib.request.urlretrieve(url, tgz_path, reporthook=download_progress)
flowers_tgz = tarfile.open(tgz_path)
flowers_tgz.extractall(path=path)
flowers_tgz.close()
os.remove(tgz_path)
In [150]:
fetch_flowers()
In [152]:
flowers_root_path = os.path.join(FLOWERS_PATH,"flower_photos")
flower_classes = sorted([dirname for dirname in os.listdir(flowers_root_path)
if os.path.isdir(os.path.join(flowers_root_path,dirname))])
flower_classes
Out[152]:
In [156]:
from collections import defaultdict
image_paths = defaultdict(list)
for flower_class in flower_classes:
image_dir = os.path.join(flowers_root_path,flower_class)
for filepath in os.listdir(image_dir):
if filepath.endswith(".jpg"):
image_paths[flower_class].append(os.path.join(image_dir,filepath))
In [160]:
for path in image_paths.values():
path.sort()
In [172]:
import matplotlib.image as mpimg
n_class = 2
for flower_class in flower_classes:
print("클래스 : ",flower_class)
plt.figure(figsize=(10,5))
for index, example_image_path in enumerate(image_paths[flower_class][:n_class]):
example_image = mpimg.imread(example_image_path)[:, :, :channels]
plt.subplot(100 + n_class * 10 + index + 1)
plt.title("{}X{}".format(example_image.shape[1],example_image.shape[0]))
plt.imshow(example_image)
plt.axis("off")
plt.show()
In [204]:
from PIL import Image
def prepare_image(image,target_width=299,target_height=299,max_zoom=0.2):
# 이미지에서 타겟 크기에 맞는 최대 비율의 네모 상자 크기를 찾는다.
height = image.shape[0]
width = image.shape[1]
image_ratio = width / height
target_image_ratio = target_width / target_height
crop_vertically = image_ratio < target_image_ratio
crop_width = width if crop_vertically else int(height*target_image_ratio)
crop_height = int(width / target_image_ratio) if crop_vertically else height
# 상자의 크기를 랜덤한 비율로 줄이기.
resize_factor = np.random.rand() * max_zoom + 1.0
crop_width = int(crop_width / resize_factor)
crop_height = int(crop_height / resize_factor)
# 다음 상자가 놓일 이미지의 위치를 랜덤하게 선택
x0 = np.random.randint(0,width - crop_width)
y0 = np.random.randint(0,height - crop_height)
x1 = x0 + crop_width
y1 = y0 + crop_height
# 이미지 자르기
image = image[y0:y1, x0:x1]
# 50% 확률로 이미지를 수평으로 반전시킨다.
if np.random.rand() < 0.5:
image = np.fliplr(image)
# 타겟 크기에 맞게 이미지 크기를 변경
image = np.array(Image.fromarray(image).resize((target_width,target_height)))
# 마지막으로 컬러 값이 0.0 ~ 1.0사이의 32비트가 되도록 해준다
return image.astype(np.float32) / 255
In [205]:
plt.figure(figsize=(6,8))
plt.imshow(example_image)
plt.title("{}X{}".format(example_image.shape[1],example_image.shape[0]))
plt.axis('off')
plt.show()
In [206]:
prepared_image = prepare_image(example_image)
plt.figure(figsize=(8,8))
plt.imshow(prepared_image)
plt.title("{}X{}".format(prepared_image.shape[1],prepared_image.shape[0]))
plt.axis('off')
plt.show()
In [209]:
rows,cols = 2,3
plt.figure(figsize=(14,8))
for row in range(rows):
for col in range(cols):
prepared_image = prepare_image(example_image)
plt.subplot(rows,cols,row * col + col + 1)
plt.title("{}X{}".format(prepared_image.shape[1],prepared_image.shape[0]))
plt.imshow(prepared_image)
plt.axis('off')
plt.show()
In [211]:
from tensorflow.contrib.slim.nets import inception
import tensorflow.contrib.slim as slim
tf.reset_default_graph()
X = tf.placeholder(tf.float32,shape=[None,height,width,channels],name="X")
training = tf.placeholder_with_default(False,shape=[])
with slim.arg_scope(inception.inception_v3_arg_scope()):
logits, end_points = inception.inception_v3(X,num_classes=1001,is_training=training)
inception_saver = tf.train.Saver()
In [213]:
logits.op.inputs[0]
Out[213]:
In [217]:
logits.op.inputs[0].op.inputs[0]
Out[217]:
In [218]:
logits.op.inputs[0].op.inputs[0].op.inputs[0]
# 이 층이 인셉션층의 마지막 층이다. 여기에 새로운 층을 쌓아야한다.
Out[218]:
In [219]:
end_points
Out[219]:
In [221]:
prelogits = tf.squeeze(end_points["PreLogits"],axis=[1,2])
prelogits
Out[221]:
In [222]:
n_outputs = len(flower_classes)
with tf.name_scope("new_output_layer"):
flower_logits = tf.layers.dense(prelogits,n_outputs,name='flower_logits')
Y_proba = tf.nn.softmax(flower_logits,name="Y_proba")
In [223]:
y = tf.placeholder(tf.int32,shape=[None])
with tf.name_scope("train"):
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=flower_logits,labels=y)
loss = tf.reduce_mean(xentropy)
optimizer = tf.train.AdamOptimizer()
flower_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope="flower_logits")
training_op = optimizer.minimize(loss,var_list = flower_vars)
with tf.name_scope("eval"):
correct = tf.nn.in_top_k(flower_logits,y,1)
accuracy = tf.reduce_mean(tf.cast(correct,tf.float32))
with tf.name_scope("init_and_save"):
init = tf.global_variables_initializer()
saver = tf.train.Saver()
In [227]:
[v.name for v in flower_vars]
Out[227]:
In [228]:
flower_class_ids = {flower_class : index for index,flower_class in enumerate(flower_classes)}
flower_class_ids
Out[228]:
In [231]:
flower_paths_and_classes = []
for flower_class, paths in image_paths.items():
for path in paths:
flower_paths_and_classes.append((path,flower_class_ids[flower_class]))
In [239]:
test_ratio = 0.2
train_size = int(len(flower_paths_and_classes) * (1 - test_ratio))
np.random.shuffle(flower_paths_and_classes)
flower_paths_and_classes_train = flower_paths_and_classes[:train_size]
flower_paths_and_classes_test = flower_paths_and_classes[train_size:]
In [240]:
flower_paths_and_classes_train[:3]
Out[240]:
In [243]:
# 이미지 전처리 / 훈련시에는 배치만드는 용도
from random import sample
def prepare_batch(flower_paths_and_classes,batch_size):
batch_paths_and_classes = sample(flower_paths_and_classes,batch_size)
images = [mpimg.imread(path)[:,:,:channels] for path, labels in batch_paths_and_classes]
prepared_images = [prepare_image(image) for image in images]
X_batch = 2 * np.stack(prepared_images) - 1
y_batch = np.array([labels for path, labels in batch_paths_and_classes], dtype=np.int32)
return X_batch,y_batch
In [244]:
X_batch,y_batch = prepare_batch(flower_paths_and_classes_train,batch_size=4)
In [247]:
X_batch.shape,X_batch.dtype, y_batch.shape, y_batch.dtype
Out[247]:
In [248]:
X_test, y_test = prepare_batch(flower_paths_and_classes_test,batch_size=len(flower_paths_and_classes_test))
In [249]:
X_test.shape
# 훈련하는 동안 그때 그때 훈련 배치를 생성하는 것이 더 좋습니다.
# 그래야 이미지마다 변종 데이터가 많아 데이터 증식의 효과를 누릴 수 있습니다.
Out[249]:
In [251]:
n_epochs = 10
batch_size = 40
n_iter = len(flower_paths_and_classes_train) // batch_size
with tf.Session() as sess:
init.run()
inception_saver.restore(sess,INCEPTION_V3_CHECKPOINT_PATH)
for epoch in range(n_epochs):
print("Epoch :", epoch,end="")
for i in range(n_iter):
print(".",end="")
X_batch,y_batch = prepare_batch(flower_paths_and_classes_train,batch_size)
sess.run(training_op,feed_dict={X:X_batch,y:y_batch,training:True})
acc_train = accuracy.eval(feed_dict={X:X_batch,y:y_batch})
print("Training ACC :", acc_train)
save_path = saver.save(sess,"./my_flowers_model")
In [ ]:
n_test_batch = 10
X_test_batch = np.array_split(X_test,n_test_batch)
y_test_batch = np.array_split(y_test,n_test_batch)
with tf.Session() as sess:
saver.restore(sess,"./my_flowers_model")
print("Testing Time for Final ACC....")
acc_test = np.mean([
accuracy.eval(feed_dict={X:X_test_batch,y:y_test_batch})
for X_test_batch, y_test_batch in zip(X_test_batch,y_test_batch)])
print("Test Accuracy:",acc_test)
In [ ]:
# 사이트 들어가서 직접해보기
728x90
반응형