<jupyter_start><jupyter_text><jupyter_code># # OS
# !cat /etc/issue.net
# # CPU 사양
# !head /proc/cpuinfo
# # 메모리 사양
# !head -n 3 /proc/meminfo
# # 디스크 사양
# !df -h
# # 파이썬 버전
# !python --version
# # GPU 사양
# !nvidia-smi
!pip install tensorflow-gpu
from google.colab import drive
drive.mount('/content/drive')
!ls '/content/drive/'
import numpy as np
import tensorflow as tf
import csv
import os
import cv2
import re
import tempfile
import shutil
import random
import pandas as pd
from unicodedata import normalize
from PIL import Image
import pickle
from tflearn.layers.conv import global_avg_pool

print(tf.__version__)
print (os.getcwd())
print(tf.test.gpu_device_name())

csv_path = '/content/drive/My Drive/data/save364.csv'
tcsv_path = '/content/drive/My Drive/data/tsave364.csv'
train_data_folder = '/content/drive/My Drive/data/image-data/trainset'
test_data_folder = '/content/drive/My Drive/data/image-data/testset'
train_data_pickle = '/content/drive/My Drive/data/train364.pickle'
test_data_pickle = '/content/drive/My Drive/data/test364.pickle'
model_path = '/content/drive/My Drive/data/model364/model.ckpt'

text = "가각간감강같개거건검것게격결경계고공과관광괴교구국군권귄규그극근금급기긴길김깊까꽃끼낄나난날남납내너네년노농뉴느는늘능니다단달" \
       "담당대더던덜데도독동되된될두드득든들등디따때떠또라란람래량러런럽레려력련령로록론료루류르른를름리린릴립마만많말망매며면명모목못" \
       "무문물미민및바박반받발방배백버번범법변별병보복본부북분불비쁘사산살삶삼상새색생서석선설성세셀소속송수순술스슴습시식신실싫심아안" \
       "않알았야약양어억언업없었에엑여역연열였영예오온올와완왜외요용우욱운울웃원월위유육윤율으은을음응의이인일읽임입있자작잖잘장재쟁저" \
       "적전절점접정제져조족존졸종주준줄중증지직진질집짝차찬참책처천철청체초총최추축출충측치컴크큼키타태터템토통투트특팀파판퍼펭편평포" \
       "표품퓨프픈피필하학한할함합항해했행향험헬혁현협형호혹화확환활회효후훈히걷겪께넘녀랑맨뽑승싶워잠줘팅"
integer_encoding = dict(enumerate(text))
char_encoding = {v: k for k, v in integer_encoding.items()}

training_epochs = 40  # 전체 데이터셋을 train하는 횟수
num_models = 1  # 모델 개수
batch_size = 128  # 메모리에 올리는 batch data의 개수
y_size = len(text) # y클래스 개수
start_learning_rate = 1e-6
img_width = 64 
img_height = 64
crop_width = 16
crop_height = 16
def prepareData(datasetFolder=train_data_folder, testsetFolder=test_data_folder, maxAug=150):
    data = {
        'path': [],
        'label': []
    }
    tdata = {
        'path': [],
        'label': []
    }
    for img in os.listdir(datasetFolder):
        img = normalize('NFC', img)
        if os.path.isfile(datasetFolder + "/" + img):
            data['path'].append(datasetFolder + "/" + img)
            data['label'].append(img[0:1])

    for img in os.listdir(testsetFolder):
        img = normalize('NFC', img)
        if os.path.isfile(testsetFolder + "/" + img):
            tdata['path'].append(testsetFolder + "/" + img)
            tdata['label'].append(img[0:1])

    
    return data, tdata
  
class Csv:
    def __init__(self, data=None, tdata=None):
        self.data = {
            'path': [],
            'label': []
        }
        self.tdata = {
            'path': [],
            'label': []
        }
        if (data == None) and (tdata == None):
          return
        else:
          self.data['path'] = data['path']
          self.data['label'] = data['label']
          self.tdata['path'] = tdata['path']
          self.tdata['label'] = tdata['label']


    def saveCsv(self, csvPath=csv_path, tcsvPath=tcsv_path):
      try:
        df_train = pd.DataFrame(self.data)
        df_train.to_csv(csvPath, encoding='euc-kr')
      except:
        print("save csv error")
      try:
        df_test = pd.DataFrame(self.tdata)
        df_test.to_csv(tcsvPath, encoding='euc-kr')
      except:
        print("save tcsv error")
      
    def loadCsv(self, csvPath=csv_path, tcsvPath=tcsv_path):
      try:
        df_train = pd.read_csv(csvPath, sep=",", engine='python')
        df_test = pd.read_csv(tcsvPath, sep=",", engine='python')
      except:
        print("load csv, tcsv error")
      return df_train, df_test
    
#data, tdata = prepareData()
#sf = Csv(data, tdata)
sf = Csv()
#sf.saveCsv()
data, tdata = sf.loadCsv()
class LoadImage:
  def __init__(self, data, tdata):
    self.data = {
            'path': [],
            'label': []
    }
    self.tdata = {
            'path': [],
            'label': []
    }
    self.trainData = {
        'img': [],
        'label': []
    }
    self.testData = {
        'img': [],
        'label': []
    }
    
    self.data['path'] = data.path.tolist()
    self.data['label'] = data.label.tolist()
    self.tdata['path'] = tdata.path.tolist()
    self.tdata['label'] = tdata.label.tolist()
    
    self.trainData['label'] = data.label.tolist()
    self.testData['label'] = tdata.label.tolist()
    
  def imreadEX(self, image_path):
    if re.compile('[^ㄱ-ㅣ가-힣]+').sub('', image_path):
        stream = open(image_path, "rb")
        bytes = bytearray(stream.read())
        numpyarray = np.asarray(bytes, dtype=np.uint8)
        img = cv2.imdecode(numpyarray, cv2.IMREAD_COLOR)
        if not img is None:
            return img
        else:
            file_tmp = tempfile.NamedTemporaryFile().name
            shutil.copy(image_path, file_tmp)
            image_path = file_tmp
    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    
    return img

  def loadImg(self):
    for i, _ in enumerate(data['path']):
      readImg = self.imreadEX(data['path'][i])
      readImg = cv2.cvtColor(readImg, cv2.COLOR_BGR2GRAY)
      readImg = cv2.resize(readImg, (img_width+crop_width, img_height+crop_height), interpolation=cv2.INTER_AREA)
      
      #random crop
      x = np.random.randint(0, crop_width)
      y = np.random.randint(0, crop_height)
      readImg = readImg[x: x+img_width, y: y+img_height]
      
            
      readImg = np.reshape(readImg, img_width * img_height).astype(float)
      readImg /= np.max(readImg)
      self.trainData['img'].append(readImg)
      
      print('\rtrainData loading... %d' % (i/len(data['path'])*100) + '%', end='')
      
      
    for i, _ in enumerate(tdata['path']):
      readImg = self.imreadEX(tdata['path'][i])
      readImg = cv2.cvtColor(readImg, cv2.COLOR_BGR2GRAY)
      readImg = cv2.resize(readImg, (img_width, img_height), interpolation=cv2.INTER_AREA)
      readImg = np.reshape(readImg, img_width * img_height).astype(float)
      readImg /= np.max(readImg)
      self.testData['img'].append(readImg)
      
      print('\rtestData loading... %d' % (i/len(tdata['path'])*100) + '%', end='')
    

    return self.trainData, self.testData
    
    def saveImgToPickle(self, trainData, testData):
        f = open('./train.pickle', 'wb')
        pickle.dump(trainData, f, pickle.HIGHEST_PROTOCOL)
        f.close()
        f = open('./test.pickle', 'wb')
        pickle.dump(testData, f, pickle.HIGHEST_PROTOCOL)
        f.close()  

load = LoadImage(data, tdata)
#data, tdata = load.loadImg()
#load.saveImgToPickle(data, tdata)

f = open(train_data_pickle, 'rb')
data = pickle.load(f)
f.close()

f = open(test_data_pickle, 'rb')
tdata = pickle.load(f)
f.close()
class Model:
    def __init__(self, sess, name):
        self.sess = sess
        self.name = name
        self._build_net()

    def _build_net(self):
        with tf.name_scope(self.name):
            self.X = tf.placeholder(tf.float32, [None, img_width * img_height], name='X')
            # img 28X28X1 (black/white)
            X_img = tf.reshape(self.X, [-1, img_width, img_height, 1])

            self.Y = tf.placeholder(tf.float32, [None, y_size], name='Y')
            self.training = tf.placeholder(tf.bool, name='training')
            global_step = tf.Variable(0, trainable=False, name='global_step')
            learning_rate = tf.train.exponential_decay(start_learning_rate, global_step,
                                                       training_epochs, 0.99, staircase=True)
            
            

            
            # Convolutional Layer #1
            conv1 = tf.layers.conv2d(inputs=X_img, filters=64, kernel_size=[3, 3],
                                     padding="SAME", activation=tf.nn.relu)
            # Pooling Layer #1
            pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2],
                                            padding="SAME", strides=2)
            dropout1 = tf.layers.dropout(inputs=pool1,
                                         rate=0.3, training=self.training)
            print("l1", dropout1) # 32x32x32
            
            # Convolutional Layer #2 and Pooling Layer #2
            shortcut = tf.layers.conv2d(inputs=dropout1, filters=128, kernel_size=[1, 1], strides=(1, 1),
                                     padding="SAME", activation=tf.nn.relu)
            conv2 = tf.layers.conv2d(inputs=dropout1, filters=128, kernel_size=[3, 3],
                                     padding="SAME", activation=tf.nn.relu)
            conv2 = shortcut + conv2
            pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2],
                                            padding="SAME", strides=2)
            dropout2 = tf.layers.dropout(inputs=pool2,
                                         rate=0.3, training=self.training)
            print("l2", dropout2)

            # Convolutional Layer #3 and Pooling Layer #3
            shortcut = tf.layers.conv2d(inputs=dropout2, filters=256, kernel_size=[1, 1], strides=(1, 1),
                                     padding="SAME", activation=tf.nn.relu)
            conv3 = tf.layers.conv2d(inputs=dropout2, filters=256, kernel_size=[3, 3],
                                     padding="SAME", activation=tf.nn.relu)
            conv3 = shortcut + conv3
            pool3 = tf.layers.max_pooling2d(inputs=conv3, pool_size=[2, 2],
                                            padding="SAME", strides=2)
            dropout3 = tf.layers.dropout(inputs=pool3,
                                         rate=0.3, training=self.training)
            print("l3", dropout3)

            # Convolutional Layer #4 and Pooling Layer #4
            shortcut = tf.layers.conv2d(inputs=dropout3, filters=512, kernel_size=[1, 1], strides=(1, 1),
                                     padding="SAME", activation=tf.nn.relu)
            conv4 = tf.layers.conv2d(inputs=dropout3, filters=512, kernel_size=[3, 3],
                                     padding="SAME", activation=tf.nn.relu)
            conv4 = shortcut + conv4
            pool4 = tf.layers.max_pooling2d(inputs=conv4, pool_size=[2, 2],
                                            padding="SAME", strides=2)
            dropout4 = tf.layers.dropout(inputs=pool4,
                                         rate=0.3, training=self.training)
            print("l4", dropout4)

            # Convolutional Layer #5 and Pooling Layer #5
            shortcut = tf.layers.conv2d(inputs=dropout4, filters=1024, kernel_size=[1, 1], strides=(1, 1),
                                     padding="SAME", activation=tf.nn.relu)
            conv5 = tf.layers.conv2d(inputs=dropout4, filters=1024, kernel_size=[3, 3],
                                     padding="SAME", activation=tf.nn.relu)
            conv5 = shortcut + conv5
            pool5 = tf.layers.max_pooling2d(inputs=conv5, pool_size=[2, 2],
                                            padding="SAME", strides=2)
            dropout5 = tf.layers.dropout(inputs=pool5,
                                         rate=0.3, training=self.training)
            print("l5", dropout5)

            
            # Dense Layer with Relu
            flat = tf.reshape(dropout5, [-1, 2 * 2 * 1024])
            print("flat", flat)
            
            dense1 = tf.layers.dense(inputs=flat,
                                    units=10000, activation=tf.nn.relu)
            print("dense1", dense1)
            dense2 = tf.layers.dense(inputs=dense1,
                                    units=10000, activation=tf.nn.relu)
            print("dense2", dense2)
            
            dropout6 = tf.layers.dropout(inputs=dense2,
                                         rate=0.5, training=self.training)
            
            # Logits (no activation) Layer: L5 Final FC 625 inputs -> y_size outputs
            self.logits = tf.layers.dense(inputs=dropout6, units=y_size, name='logits')
            print("logits", self.logits)
        
        with tf.name_scope(self.name + '-cost'):
            self.cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=self.logits, labels=self.Y))
            self.optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(self.cost,
                                                                                          global_step=global_step)

        with tf.name_scope(self.name + '-eval'):
            correct_prediction = tf.equal(tf.math.argmax(self.logits, 1), tf.math.argmax(self.Y, 1))
            self.accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name='accuracy')

    def predict(self, x_test, training=False):
        return self.sess.run(self.logits, feed_dict={self.X: x_test, self.training: training})
        

    def get_accuracy(self, x_test, y_test, training=False):
        return self.sess.run(self.accuracy, feed_dict={self.X: x_test, self.Y: y_test, self.training: training})

    def train(self, x_data, y_data, training=True):
        return self.sess.run([self.cost, self.optimizer],
                             feed_dict={self.X: x_data, self.Y: y_data, self.training: training})

    def result(self, x_test, training=False):
        label = tf.math.argmax(self.logits, 1)
        label = self.sess.run(label, feed_dict={self.X: x_test, self.training: training})
        return list(label)


def dataTrain(trainData, testData):
    if not trainData:
        print("없는데?")
        return
    print("있는데?")
    tf.reset_default_graph()
    sess = tf.Session()
    models = []
    
    for m in range(num_models):
        models.append(Model(sess, "model" + str(m)))

    saver = tf.train.Saver(tf.global_variables())


    batch_xs, batch_ys, tbatch_xs, tbatch_ys = trans_label(trainData, testData,
                                                           sess)  # label 숫자로 변환 -> onehot encoding return.

    if tf.train.checkpoint_exists(model_path):
        print('load success')
        saver.restore(sess, model_path)
    else:
      sess.run(tf.global_variables_initializer())

    print('Learning Started')
    for epoch in range(training_epochs):
        avg_cost_list = np.zeros(len(models))
        total_batch = int(len(batch_ys) / batch_size + 1)
        batch_xs, batch_ys = data_shuffle(batch_xs, batch_ys)
        for i in range(total_batch):
            start = i * batch_size
            end = start + batch_size
            mini_xs, mini_ys = batch_xs[start:end], batch_ys[start:end]
            for m_index, m in enumerate(models):
                c, _ = m.train(mini_xs, mini_ys)
                avg_cost_list[m_index] += c / total_batch
        
        print('\rEpoch: ', '%04d' % (epoch + 1), 'cost = ', avg_cost_list)
        
        if ((epoch+1) % 20) == 0:
          saver.save(sess, model_path)
          print("model save complete")
        
    saver.save(sess, model_path) #모델저장
    print('Learning Finished')

    test_size = len(tbatch_ys)
    predictions = np.zeros([0, y_size])
    mini_predictions = np.zeros([batch_size, y_size])
    
    total_batch = int(test_size / batch_size + 1)
    for i in range(total_batch):
      start = i * batch_size
      end = start + batch_size
      mini_xs, mini_ys = tbatch_xs[start:end], tbatch_ys[start:end]
      for m_index, m in enumerate(models):
        print(m_index, "Accuracy: ", m.get_accuracy(mini_xs, mini_ys))
        p = m.predict(mini_xs)
        mini_predictions = p
      predictions = np.vstack((predictions, mini_predictions))
      
    ensemble_correct_prediction = tf.equal(
        tf.argmax(predictions, 1), tf.argmax(tbatch_ys, 1))
    ensemble_accuracy = tf.reduce_mean(
        tf.cast(ensemble_correct_prediction, tf.float32))
    print('Ensemble accuracy:', sess.run(ensemble_accuracy))
    


def trans_label(trainData, testData, sess):
    batch_xs = trainData['img']
    batch_ys = trainData['label']
    
    for i, _ in enumerate(batch_ys):
        batch_ys[i] = char_encoding[batch_ys[i]]
      
    batch_ys = tf.one_hot(batch_ys, depth=y_size).eval(session=sess)
    batch_ys = np.reshape(batch_ys, [-1, y_size])

    tbatch_xs = testData['img']
    tbatch_ys = testData['label']

    for i, _ in enumerate(tbatch_ys):
        tbatch_ys[i] = char_encoding[tbatch_ys[i]]

    tbatch_ys = tf.one_hot(tbatch_ys, depth=y_size).eval(session=sess)
    tbatch_ys = np.reshape(tbatch_ys, [-1, y_size])
    
    return batch_xs, batch_ys, tbatch_xs, tbatch_ys


def data_shuffle(data_x, data_y):
    tmp = [[x, y] for x, y in zip(data_x, data_y)]
    random.shuffle(tmp)
    x = [n[0] for n in tmp]
    y = [n[1] for n in tmp]
    return x, y


def decode_label(label):
    for i in range(len(label)):
        label[i] = integer_encoding[label[i]]

    return label


dataTrain(data, tdata)<jupyter_output>있는데?
WARNING:tensorflow:From <ipython-input-8-8ad95c6beac6>:24: conv2d (from tensorflow.python.layers.convolutional) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.keras.layers.Conv2D` instead.
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor
WARNING:tensorflow:From <ipython-input-8-8ad95c6beac6>:27: max_pooling2d (from tensorflow.python.layers.pooling) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.MaxPooling2D instead.
WARNING:tensorflow:From <ipython-input-8-8ad95c6beac6>:29: dropout (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.
Instructions[...]
{'fraction_non_alphanumeric': 0.12549633689390974, 'fraction_numerical': 0.018455343660869077, 'mean_word_length': 2.3029183598079053, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 41, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '537633', 'license': 'Apache-2.0', 'n_tokens_mistral': 6521, 'n_tokens_neox': 6720, 'n_words': 1123, 'path': 'main364.ipynb', 'repo_name': 'Jeongjibsa/PTH-Picture-To-Hangeul--OCR', 'size': '17881'}