<jupyter_start><jupyter_text>TensorFlow Tutorial - 8. CNN - from files by folder본 문서는 TensorFlow 를 사용하여 Deep Learning을 구현하기 위한 기초적인 실습 자료이다.The code and comments are written by <NAME> Upgraed to Tensorflow v1.10 by NamJungGu  This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.  Convolutional Neural Networks이번에는 이미지 인식 분야에서 가장 성공적으로 쓰이고 있는 Convolutional Neural Networks를 실습해본다.Convolutional Neural Networks, 이하 CNN은 아래와 같은 Convolutional Layer를 여러층 가진 딥러닝 모델을 뜻한다.(출처: http://ufldl.stanford.edu/tutorial/images/Cnn_layer.png)이번에는 간단한 구조를 가진 CNN을 구현하고 방금전에 사용했던 MNIST 데이터를 학습시켜 보고, MLP와의 성능 차이를 비교해본다.아래의 코드를 보면 MLP와 전체 구조는 매우 유사한데, 중간에 Convolutional을 비롯해 처음 보는 여러 연산들이 추가 된 것을 알 수 있다. 또한 CNN을 효과적으로 학습하기 위해서는 Weight의 초기화를 0으로 하는 것이 아니라, 랜덤으로 해주어야하는데, 여기서는 간단히 가우시안을 이용하여 초기화 하였다. 그밖에 dropout과 relu 등이 사용되었다.각 함수와 연산들의 자세한 설명은 아래 코드를 보면서 하나하나 분석해보자.<jupyter_code>%matplotlib inline
import tensorflow as tf
tf.reset_default_graph()


from os import listdir
from os.path import isfile, join
from pylab import *
from numpy import *

def getFolder(thePath,isFile=True):
    return [f for f in listdir(thePath) if isFile == isfile(join(thePath, f)) ]

def imgTo1D(imgPath):
#     print(imgPath)
    img_color=imread(imgPath)
    img=img_color[:,:,1]
    return img.reshape([1,-1])
def oneHotEncoder(su,d):
    return d[su]

def getImagesAndLabels(tPath):
    labels=getFolder(tPath,False)
    tImgDic={f:getFolder(join(tPath,f)) for f in labels}

    tImages=None
    tLabels=None

    ks=sorted(list(tImgDic.keys()))
    oh=np.identity(len(ks))
    d={i[1]:list(oh[i[0]]) for i in enumerate(ks)}
#     d={"0":[1,0,0],"1":[0,1,0],"2":[0,0,1]}
#     oneHotEncoder("0",d)
    for label in tImgDic.keys():
        for image in tImgDic[label]:
            l=oneHotEncoder(label,d)
            le=np.array(l,ndmin=2)
            img1d=imgTo1D(join(tPath,label,image))
            if tImages is None:
                tImages=img1d
                tLabels=le
            else:
                tImages=np.concatenate((tImages,img1d),axis=0)
                tLabels=np.concatenate((tLabels,le   ),axis=0)
        print(label,tImages.shape,tLabels.shape)
    return (tImages,tLabels)

def shuffler(arr1,arr2):
    arr1Width=arr1.shape[1]
    arr2Width=arr2.shape[1]

    train=np.hstack( (arr1,arr2) ) 
    # np.random.shuffle(train)
    return( train[:,0:arr1Width],train[:,arr1Width:arr1Width+arr2Width] )
    
class MiniBatch(object) :
    """for MiniBatch"""
    def __init__(self,arrData,arrLabel):
        self.arrData=arrData
        self.arrLabel=arrLabel
        self.wm=0
        self.train_X_cnt=len(arrData)        
    def miniBatch(self,cnt) : 
        wm_old=self.wm
        wm_new=self.wm+cnt
        self.wm=wm_new
        if self.train_X_cnt<wm_new :
            m1Data=self.arrData[range(wm_old,self.train_X_cnt)]
            m1Label=self.arrLabel[range(wm_old,self.train_X_cnt)]
            wm_new = wm_new-self.train_X_cnt
            m2Data=self.arrData[range(wm_new)]
            m2Label=self.arrLabel[range(wm_new)]
            self.wm=wm_new
            return ( np.vstack((m1Data,m2Data)) , np.vstack((m1Label,m2Label) ) )
        else : 
            return ( self.arrData[range(wm_old,wm_new)], self.arrLabel[range(wm_old,wm_new)] )

    
tPath='../../../data/MNIST_Simple/train/'
trainImages_sorted,trainLabels_sorted=getImagesAndLabels(tPath)    
tPath='../../../data/MNIST_Simple/test/'
testImages_sorted,testLabels_sorted=getImagesAndLabels(tPath)    
print('- Read Images')
testImages,testLabels = shuffler(testImages_sorted,testLabels_sorted)    
print(testImages.shape,testLabels.shape)

print('- Read Labels')
trainImages,trainLabels = shuffler(trainImages_sorted,trainLabels_sorted)    
print(testImages.shape,testLabels.shape)
# placeholder is used for feeding data.
x = tf.placeholder("float", shape=[None, 784], name = 'x') # none represents variable length of dimension. 784 is the dimension of MNIST data.
y_target = tf.placeholder("float", shape=[None, 3], name = 'y_target') # shape argument is optional, but this is useful to debug.



# reshape input data
x_image = tf.reshape(x, [-1,28,28,1], name="x_image")

# Build a convolutional layer and maxpooling with random initialization
W_conv1 = tf.Variable(tf.truncated_normal([5, 5, 1, 3], stddev=0.1), name="W_conv1") # W is [row, col, channel, feature]
b_conv1 = tf.Variable(tf.zeros([3]), name="b_conv1")
h_conv1 = tf.nn.relu(tf.nn.conv2d(x_image, W_conv1, strides=[1, 1, 1, 1], padding='SAME') + b_conv1, name="h_conv1")
h_pool1 = tf.nn.max_pool( h_conv1 , ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME', name = "h_pool1")

# Repeat again with 64 number of filters
W_conv2 = tf.Variable(tf.truncated_normal([5, 5, 3, 8], stddev=0.1), name="W_conv2") # W is [row, col, channel, feature]
b_conv2 = tf.Variable(tf.zeros([8]), name="b_conv2")
h_conv2 = tf.nn.relu(tf.nn.conv2d(h_pool1, W_conv2, strides=[1, 1, 1, 1], padding='SAME') + b_conv2, name="h_conv2")
h_pool2 = tf.nn.max_pool( h_conv2 , ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME', name = "h_pool2")

# Build a fully connected layer
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*8], name="h_pool2_flat")
W_fc1 = tf.Variable(tf.truncated_normal([7 * 7 * 8, 1024], stddev=0.1), name = 'W_fc1')
b_fc1 = tf.Variable(tf.zeros([1024]), name = 'b_fc1')
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1, name="h_fc1")


# Dropout Layer
keep_prob = tf.placeholder("float", name="keep_prob")
h_fc1 = tf.nn.dropout(h_fc1, keep_prob, name="h_fc1_drop")

# Build a fully connected layer with softmax 
W_fc2 = tf.Variable(tf.truncated_normal([1024, 3], stddev=0.1), name = 'W_fc2')
b_fc2 = tf.Variable(tf.zeros([3]), name = 'b_fc2')
y=tf.nn.softmax(tf.matmul(h_fc1, W_fc2) + b_fc2, name="y")




# define the Loss function
cross_entropy = -tf.reduce_sum(y_target*tf.log(y), name = 'cross_entropy')


# define optimization algorithm
#train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)



correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_target, 1))
# correct_prediction is list of boolean which is the result of comparing(model prediction , data)


accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) 
# tf.cast() : changes true -> 1 / false -> 0
# tf.reduce_mean() : calculate the mean



# Create Session
with tf.Session(config=tf.ConfigProto(gpu_options=tf.GPUOptions(allow_growth =True))) as sess:  # open a session which is a envrionment of computation graph.
    sess.run(tf.global_variables_initializer())# initialize the variables


    # training the MLP
    for i in range(5001): # minibatch iteraction
        batches= MiniBatch(trainImages,trainLabels)
        batch  = batches.miniBatch(10) # minibatch size
#         print(batch[0].shape,batch[1].shape)


        sess.run(train_step, feed_dict={x: batch[0], y_target: batch[1], keep_prob: 0.5}) # placeholder's none length is replaced by i:i+100 indexes
        batch[0]
        exit
        if i%500 == 0:
            train_accuracy = sess.run(accuracy, feed_dict={x:batch[0], y_target: batch[1], keep_prob: 1})
            print ("step %d, training accuracy: %.3f"%(i, train_accuracy))

#             # calculate the summary and write.
#             summary = sess.run(merged, feed_dict={x:batch[0], y_target: batch[1], keep_prob: 1})
#             summary_writer.add_summary(summary , i)

    # for given x, y_target data set
    print  ("test accuracy: %g"% sess.run(accuracy, feed_dict={x: testImages[0:250], y_target: testLabels[0:250], keep_prob: 1}))<jupyter_output>step 0, training accuracy: 0.200
step 500, training accuracy: 1.000
step 1000, training accuracy: 1.000
step 1500, training accuracy: 1.000
step 2000, training accuracy: 1.000
step 2500, training accuracy: 1.000
step 3000, training accuracy: 1.000
step 3500, training accuracy: 1.000
step 4000, training accuracy: 1.000
step 4500, training accuracy: 1.000
step 5000, training accuracy: 1.000
test accuracy: 1
{'fraction_non_alphanumeric': 0.1326808721506442, 'fraction_numerical': 0.03865213082259663, 'mean_word_length': 3.9956683168316833, 'pattern_counts': {'":': 3, '<': 6, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '155668', 'license': 'MIT', 'n_tokens_mistral': 3379, 'n_tokens_neox': 3332, 'n_words': 689, 'path': '1.tensorflow_jupyter/CNN_fromFile/CNN_fromFile.ipynb', 'repo_name': 'Finfra/DeepLearningStudy', 'size': '8080'}