[
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 deeperic\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# SpikeFlow\nA Chinese OCR with TensorFlow\n\n*** Warning: The source codes in this repository may not work well with the latest version of Tensorflow. ***\n\nTo play around, follow these steps:\n\n1/ Use Ocropy to generate Chinese character images. linegen is the tool used. You will need a font file. Put the images under folder training-character.gh.\n\n2/ Run labelling-character.py to generate the labels on images.\n\n3/ Run tf/convert-to-tfrecords.py to convert the images and labels in Tensorflow format.\n\n4/ Modify the tf/helper.py for the characters you want to recognise.\n\n5/ Run tf/train_model.py to train a model. The training will save a checkpoint on a regular interval.\n\n6/ In receipt, run the find_contour_character.py to generate the images which may contain Chinese characters. You will have a \"bw\" folder containing all images. Run: python find_contour_character.py {image filename}\n\n7/ Test the model by running: python test_one_char.py {the name of your model} {the image to be recognised}\n\n\nBlog: https://deeperic.wordpress.com/2017/02/18/chinese-ocr-tensorflow\n\nYoutube: https://youtu.be/9N9OUruPZd4\n\nGitHub: https://github.com/deeperic/SpikeFlow\n"
  },
  {
    "path": "receipt.gh/find_contour_character.py",
    "content": "#i need this to generate chinese character images\n\nimport cv2\nimport os\nimport sys\n\n\ndef createFolder(folder):\n    if not os.path.exists(folder):\n        os.makedirs(folder)\n        \n        \ndef sort_bounding_boxes(cnts, method=\"left-to-right\"):\n\t# initialize the reverse flag and sort index\n\treverse = False\n\ti = 0\n \n\t# handle if we need to sort in reverse\n\tif method == \"right-to-left\" or method == \"bottom-to-top\":\n\t\treverse = True\n \n\t# handle if we are sorting against the y-coordinate rather than\n\t# the x-coordinate of the bounding box\n\tif method == \"top-to-bottom\" or method == \"bottom-to-top\":\n\t\ti = 1\n \n\t# construct the list of bounding boxes and sort them from top to\n\t# bottom\n\tboundingBoxes = cnts\n\t(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),\n\t\tkey=lambda b:b[1][i], reverse=reverse))\n \n\t# return the list of sorted contours and bounding boxes\n\treturn (cnts, boundingBoxes)\n\t\ndef sort_contours(cnts, method=\"left-to-right\"):\n\t# initialize the reverse flag and sort index\n\treverse = False\n\ti = 0\n \n\t# handle if we need to sort in reverse\n\tif method == \"right-to-left\" or method == \"bottom-to-top\":\n\t\treverse = True\n \n\t# handle if we are sorting against the y-coordinate rather than\n\t# the x-coordinate of the bounding box\n\tif method == \"top-to-bottom\" or method == \"bottom-to-top\":\n\t\ti = 1\n \n\t# construct the list of bounding boxes and sort them from top to\n\t# bottom\n\tboundingBoxes = [cv2.boundingRect(c) for c in cnts]\n\t(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),\n\t\tkey=lambda b:b[1][i], reverse=reverse))\n \n\t# return the list of sorted contours and bounding boxes\n\treturn (cnts, boundingBoxes)\n\t\ndef captch_ex(file_name, folder1, folder2 ):\n    img  = cv2.imread(file_name)\n    img2 = cv2.imread(file_name) #for saving\n    img2gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n    \n    new_img = cv2.adaptiveThreshold(img2gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 9, 10)\n    need_img = cv2.adaptiveThreshold(img2gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 15, 15)\n\n    kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3 , 3)) # to manipulate the orientation of dilution , large x means horizonatally dilating  more, large y means vertically dilating more \n    dilated = cv2.dilate(new_img,kernel,iterations = 2) # dilate , more the iteration more the dilation #find section\n    \n    _, contours, hierarchy = cv2.findContours(dilated,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE) # get contours\n    \n    cnts, sorted = sort_contours(contours, \"top-to-bottom\")\n    \n    index = 0 \n    dimension = 32\n    for contour in sorted:\n\n        [x,y,w,h] = contour\n\n        #Don't plot small false positives that aren't text\n        if w < 50:\n            continue\n\n        #chinese is a square, so try to get a character\n        capw = w\n        if(h > w):\n          capw = h\n        \n        # draw rectangle around contour on original image\n        cv2.rectangle(img,(x,y),(x+capw,y+capw),(255,0,255),2)\n                \n        cropped = img2[y :y + capw , x : x + capw]\n        croppedBW = need_img[y :y + capw , x : x + capw]\n\n        #cropped32 = cv2.resize(cropped, (dimension, dimension)) \n        #s = './' + folder1 + '/' + str(index) + '.png' \n        #cv2.imwrite(s , cropped32)\n        \n        croppedbw32 = cv2.resize(croppedBW, (dimension, dimension)) \n        s = './' + folder2 + '/'  + str(index) + '-bw.png' \n        cv2.imwrite(s , croppedbw32)\n        \n        index = index + 1\n\n        \n    cv2.namedWindow('captcha_result', cv2.WINDOW_NORMAL)    \n    # write original image with added contours to disk  \n    \n    #resize for display\n    height, width, channels = img.shape\n    print(height)\n    ratio = height / width\n    newheight = 900\n    newwidth = newheight / ratio\n    \n    imS = cv2.resize(img, (newheight, newwidth)) \n    cv2.imshow('captcha_result' , imS)\n    cv2.waitKey()\n    \n    #cv2.imshow('captcha_result' , new_img)\n    #cv2.waitKey()\n\n\nfile_name = sys.argv[1]\nprint file_name\n\nfilename_split = os.path.splitext(file_name)\n\nfolder1 = filename_split[0]\nfolder2 = filename_split[0] + 'bw'\n\ncreateFolder(folder1)\ncreateFolder(folder2)\n        \ncaptch_ex(file_name, folder1, folder2)"
  },
  {
    "path": "tf/convert_to_tfrecords.py",
    "content": "# deeperic\n\n\"\"\"Converts images and labels to TFRecords file format.\"\"\"\n\nimport csv\nimport glob\nimport os\nimport numpy as np\nimport tensorflow as tf\nfrom PIL import Image\nimport helper\n\ntf.app.flags.DEFINE_string('directory', '../tfrec',\n                           'Directory to write the '\n                           'converted result')\n\nFLAGS = tf.app.flags.FLAGS\n\n\ndef _int64_feature(value):\n  return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))\n\n\ndef _bytes_feature(value):\n  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))\n\n\ndef convert_to(images, labels, name):\n  num_examples = labels.shape[0]\n  #print('labels shape is ' + str(labels.shape[0]))\n  if images.shape[0] != num_examples:\n    raise ValueError(\"Images size %d does not match label size %d.\" %\n                     (images.shape[0], num_examples))\n  rows = images.shape[1]\n  cols = images.shape[2]\n  depth = images.shape[3]\n\n  filename = os.path.join(FLAGS.directory, name + '.tfrecords')\n  #print('Writing', filename)\n  writer = tf.python_io.TFRecordWriter(filename)\n  for index in range(num_examples):\n    image_raw = images[index].tostring()\n    example = tf.train.Example(features=tf.train.Features(feature={\n        'height': _int64_feature(rows),\n        'width': _int64_feature(cols),\n        'depth': _int64_feature(depth),\n        'label': _int64_feature(int(labels[index])),\n        'image_raw': _bytes_feature(image_raw)}))\n    writer.write(example.SerializeToString())\n\n\n\ndef read_images(path):\n  print('Reading images')\n  images = []\n  png_files_path = glob.glob(os.path.join(path, './', '*.[pP][nN][gG]'))\n  for filename in png_files_path:\n    #print('read file:' + filename)\n    im = Image.open(filename)  # .convert(\"L\")  # Convert to greyscale\n    im = np.asarray(im, np.uint8)\n\n    # get only images name, not path\n    image_name = filename.split('/')[-1].split('.')[0]\n    images.append([int(image_name), im])\n\n  images = sorted(images, key=lambda image: image[0])\n  \n  images_only = [np.asarray(image[1], np.uint8) for image in images]  # Use unint8 or you will be !!!\n  images_only = np.array(images_only)\n\n  return images_only\n\ndef read_labels(path, filename):\n  print('Reading labels')\n  with open(os.path.join(path, filename), 'r') as dest_f:\n    data_iter = csv.reader(dest_f)\n    train_labels = [data for data in data_iter]\n\n  # pre process labels to int\n  train_labels = _label_to_int(train_labels)\n  train_labels = np.array(train_labels, dtype=np.uint32)\n\n  return train_labels\n\n\ndef _label_to_int(labels):\n  chars = helper.char_list\n  new_labels = []\n\n  for label in labels:\n    new_labels.append(chars.index(label[1]))\n  return new_labels\n\ndef main(argv):\n\n  train_images = read_images('../training-character/train')\n  train_labels = read_labels('../training-character', 'trainLabels.csv')\n  validation_images = read_images('../training-character/val')\n  validation_labels = read_labels('../training-character', 'valLabels.csv')\n  \n  print('train shape:' + str(train_images.shape))\n  print('validation shape:' + str(validation_images.shape))\n\n  convert_to(train_images, train_labels, 'train')\n  convert_to(validation_images, validation_labels, 'validation')\n\n\n\nif __name__ == '__main__':\n  tf.app.run()\n"
  },
  {
    "path": "tf/helper.py",
    "content": "#!/usr/bin/env python\n# -*- coding: UTF-8 -*-\n\n# deeperic\n\n\nchar_list = ['cheung', 'chin2', 'chiu', 'cup', 'ho', 'ka', 'ma', 'sheung', 'shi', 'yi', 'sin', 'ngou', 'lai']\nchar_list_chinese = ['場', '錢', '超', '級', '號', '卡', '碼', '賞', '市', '易', '鮮', '牛', '奶']"
  },
  {
    "path": "tf/ocr_model.py",
    "content": "#!/usr/bin/env python\n# -*- coding: UTF-8 -*-\n\n#deep eric\n\n\"\"\"The network model\"\"\"\n\nimport tensorflow as tf\n\n\n\n# Network Parameters\nIMAGE_SIZE = 32\nn_input = IMAGE_SIZE * IMAGE_SIZE * 3  # (img shape: 32*32)\n\nout_conv_1 = 64\nout_conv_2 = 64\n\nn_hidden_1 = 384 \nn_hidden_2 = 192 \n\ndropout = 0.90  # Dropout, probability to keep units\n\nNUM_CLASSES = 13 \nNUM_EXAMPLES_PER_EPOCH_FOR_TRAIN = 40000\nNUM_EXAMPLES_PER_EPOCH_FOR_EVAL = 10000\n\n# Constants describing the training process.\nNUM_EPOCHS_PER_DECAY = 10.0  # Epochs after which learning rate decays.\nLEARNING_RATE_DECAY_FACTOR = 0.60  # Learning rate decay factor.\nINITIAL_LEARNING_RATE = 0.001  # Initial learning rate.\n\nFLAGS = tf.app.flags.FLAGS\n\n\n# Create model\ndef conv2d(img, w, b):\n  return tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(img, w, strides=[1, 1, 1, 1], padding='SAME'), b))\n\n\ndef max_pool(img, k):\n  return tf.nn.max_pool(img, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding='SAME')\n\n\ndef inference(images):\n  \"\"\"Build the model up to where it may be used for inference.\n  Args:\n\n  Returns:\n    logits: Output tensor with the   computed logits.\n  \"\"\"\n\n  # Reshape input picture\n  images = tf.reshape(images, shape=[-1, IMAGE_SIZE, IMAGE_SIZE, 3])\n\n  _dropout = tf.Variable(dropout)  # dropout (keep probability)\n\n#random_normal\n#truncated_normal\n\n  # Store layers weight & bias\n  _weights = {\n    'wc1': tf.Variable(tf.random_normal([5, 5, 3, out_conv_1], stddev=1e-3)),  # 5x5 conv, 3 input, 64 outputs\n    'wc2': tf.Variable(tf.random_normal([5, 5, out_conv_1, out_conv_2], stddev=1e-3)),\n  # 5x5 conv, 64 inputs, 64 outputs\n    'wd1': tf.Variable(tf.random_normal([out_conv_2 * 8 * 8, n_hidden_1], stddev=1e-3)),\n    'wd2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2], stddev=1e-3)),\n    'out': tf.Variable(tf.random_normal([n_hidden_2, NUM_CLASSES], stddev=1e-3))\n  }\n\n  _biases = {\n    'bc1': tf.Variable(tf.random_normal([out_conv_1])),\n    'bc2': tf.Variable(tf.random_normal([out_conv_2])),\n    'bd1': tf.Variable(tf.random_normal([n_hidden_1])),\n    'bd2': tf.Variable(tf.random_normal([n_hidden_2])),\n    'out': tf.Variable(tf.random_normal([NUM_CLASSES]))\n  }\n\n  # Convolution Layer 1\n  with tf.name_scope('Conv1'):\n    conv1 = conv2d(images, _weights['wc1'], _biases['bc1'])\n    # Max Pooling (down-sampling)\n    conv1 = max_pool(conv1, k=2)\n    # norm1\n    conv1 = tf.nn.lrn(conv1, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75,\n                      name='norm1')\n    # Apply Dropout\n    conv1 = tf.nn.dropout(conv1, _dropout)\n\n  # Convolution Layer 2\n  with tf.name_scope('Conv2'):\n    conv2 = conv2d(conv1, _weights['wc2'], _biases['bc2'])\n    # norm2\n    conv2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75,\n                      name='norm2')\n    # # Max Pooling (down-sampling)\n    conv2 = max_pool(conv2, k=2)\n    # Apply Dropout\n    conv2 = tf.nn.dropout(conv2, _dropout)\n\n  # Fully connected layer 1\n  with tf.name_scope('Dense1'):\n    dense1 = tf.reshape(conv2,\n                        [-1, _weights['wd1'].get_shape().as_list()[0]])  # Reshape conv2 output to fit dense layer input\n    dense1 = tf.nn.relu_layer(dense1, _weights['wd1'], _biases['bd1'])  # Relu activation\n    dense1 = tf.nn.dropout(dense1, _dropout)  # Apply Dropout\n\n  # Fully connected layer 2\n  with tf.name_scope('Dense2'):\n    dense2 = tf.nn.relu_layer(dense1, _weights['wd2'], _biases['bd2'])  # Relu activation\n\n  # Output, class prediction\n  logits = tf.add(tf.matmul(dense2, _weights['out']), _biases['out'])\n\n  return logits\n\n\ndef loss(logits, labels):\n  \"\"\"Add L2Loss to all the trainable variables.\n\n  Add summary for for \"Loss\" and \"Loss/avg\".\n\n  Args:\n    logits: Logits from inference().\n    labels: Labels from distorted_inputs or inputs(). 1-D tensor\n            of shape [batch_size]\n\n  Returns:\n    Loss tensor of type float.\n  \"\"\"\n  # Reshape the labels into a dense Tensor of\n  # shape [batch_size, NUM_CLASSES].\n  sparse_labels = tf.reshape(labels, [FLAGS.batch_size, 1])\n  indices = tf.reshape(tf.range(0, FLAGS.batch_size), [FLAGS.batch_size, 1])\n  concated = tf.concat(axis=1, values=[indices, sparse_labels])\n  dense_labels = tf.sparse_to_dense(concated,\n                                    [FLAGS.batch_size, NUM_CLASSES],\n                                    1.0, 0.0)\n  \n  # Calculate the average cross entropy loss across the batch.\n  cross_entropy = tf.nn.softmax_cross_entropy_with_logits(\n    logits=logits, labels=dense_labels, name='cross_entropy_per_example')\n  cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')\n  tf.add_to_collection('losses', cross_entropy_mean)\n\n  # The total loss is defined as the cross entropy loss plus all of the weight\n  # decay terms (L2 loss).\n  return tf.add_n(tf.get_collection('losses'), name='total_loss')\n\n\ndef training(loss, global_step):\n  \"\"\"Sets up the training Ops.\n  Creates a summarizer to track the loss over time in TensorBoard.\n  Creates an optimizer and applies the gradients to all trainable variables.\n  The Op returned by this function is what must be passed to the\n  `sess.run()` call to cause the model to train.\n  Args:\n    loss: Loss tensor, from loss().\n    learning_rate: The learning rate to use for gradient descent.\n  Returns:\n    train_op: The Op for training.\n  \"\"\"\n  # Variables that affect learning rate.\n  num_batches_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN / FLAGS.batch_size\n  decay_steps = int(num_batches_per_epoch * NUM_EPOCHS_PER_DECAY)\n\n  #print('Decay steps is: ', decay_steps)\n  # Decay the learning rate exponentially based on the number of steps.\n  lr = tf.train.exponential_decay(INITIAL_LEARNING_RATE,\n                                  global_step,\n                                  decay_steps,\n                                  LEARNING_RATE_DECAY_FACTOR,\n                                  staircase=True)\n  tf.summary.scalar('learning_rate', lr)\n  # Add a scalar summary for the snapshot loss.\n  tf.summary.scalar(loss.op.name, loss)\n\n  # Create the adam or gradient descent optimizer with the given learning rate.\n  optimizer = tf.train.AdamOptimizer(lr)\n  # optimizer = tf.train.GradientDescentOptimizer(lr)\n\n  # Use the optimizer to apply the gradients that minimize the loss\n  # (and also increment the global step counter) as a single training step.\n  train_op = optimizer.minimize(loss, global_step=global_step)\n\n  return train_op\n\n\ndef evaluation(logits, labels):\n  \"\"\"Evaluate the quality of the logits at predicting the label.\n  Args:\n    logits: Logits tensor, float - [batch_size, NUM_CLASSES].\n    labels: Labels tensor, int32 - [batch_size], with values in the\n      range [0, NUM_CLASSES).\n  Returns:\n    A scalar int32 tensor with the number of examples (out of batch_size)\n    that were predicted correctly.\n  \"\"\"\n  print('Evaluation..')\n  # For a classifier model, we can use the in_top_k Op.\n  # It returns a bool tensor with shape [batch_size] that is true for\n  # the examples where the label's is was in the top k (here k=1)\n  # of all logits for that example.\n  correct = tf.nn.in_top_k(logits, labels, 1)\n  num_correct = tf.reduce_sum(tf.cast(correct, tf.float32))\n\n  acc_percent = num_correct / FLAGS.batch_size\n\n  # Return the number of true entries.\n  return acc_percent * 100.0, num_correct\n\n\ndef main(argv=None):\n  return 0\n\n\nif __name__ == '__main__':\n  tf.app.run()\n"
  },
  {
    "path": "tf/reader.py",
    "content": "#deeperic\n\nimport os\nimport glob\nimport csv\nimport tensorflow as tf\nimport numpy as np\nfrom PIL import Image\n\n\ndef _read_raw_images(path, is_directory=True):\n  \"\"\"Reads directory of images in tensorflow\n  Args:\n    path:\n    is_directory:\n\n  Returns:\n\n  \"\"\"\n  images = []\n  png_files = []\n  jpeg_files = []\n\n  reader = tf.WholeFileReader()\n\n  png_files_path = glob.glob(os.path.join(path, '*.[pP][nN][gG]'))\n  jpeg_files_path = glob.glob(os.path.join(path, '*.[jJ][pP][eE][gG]'))\n  jpg_files_path = glob.glob(os.path.join(path, '*.[jJ][pP][gG]'))\n\n  if is_directory:\n    for filename in png_files_path:\n      png_files.append(filename)\n    for filename in jpeg_files_path:\n      jpeg_files.append(filename)\n    for filename in jpg_files_path:\n      jpeg_files.append(filename)\n  else:\n    raise ValueError('Currently only batch read from directory supported')\n\n  # Decode if there is a PNG file:\n  if len(png_files) > 0:\n    png_file_queue = tf.train.string_input_producer(png_files)\n    pkey, pvalue = reader.read(png_file_queue)\n    p_img = tf.image.decode_png(pvalue)\n\n  if len(jpeg_files) > 0:\n    jpeg_file_queue = tf.train.string_input_producer(jpeg_files)\n    jkey, jvalue = reader.read(jpeg_file_queue)\n    j_img = tf.image.decode_jpeg(jvalue)\n\n  return  # TODO: return normal thing\n\n\ndef read_and_decode(filename_queue, imshape, normalize=False, flatten=True):\n  \"\"\"Reads\n  Args:\n    filename_queue:\n    imshape:\n    normalize:\n    flatten:\n\n  Returns:\n\n  \"\"\"\n  reader = tf.TFRecordReader()\n  _, serialized_example = reader.read(filename_queue)\n  features = tf.parse_single_example(\n    serialized_example,\n    features={\n      'image_raw': tf.FixedLenFeature([], tf.string),\n      'label': tf.FixedLenFeature([], tf.int64)\n    })\n\n  # Convert from a scalar string tensor (whose single string has\n  # length mnist.IMAGE_PIXELS) to a uint8 tensor with shape\n  # [mnist.IMAGE_PIXELS].\n  image = tf.decode_raw(features['image_raw'], tf.uint8)\n\n  if flatten:\n    num_elements = 1\n    for i in imshape: num_elements = num_elements * i\n    #print num_elements\n    image = tf.reshape(image, [num_elements])\n    image.set_shape(num_elements)\n  else:\n    image = tf.reshape(image, imshape)\n    image.set_shape(imshape)\n\n  if normalize:\n    # Convert from [0, 255] -> [-0.5, 0.5] floats.\n    image = tf.cast(image, tf.float32)\n    image = tf.cast(image, tf.float32) * (1. / 255) - 0.5\n\n  # Convert label from a scalar uint8 tensor to an int32 scalar.\n  label = tf.cast(features['label'], tf.int32)\n\n  return image, label\n\n\n# Helper, Examples\ndef _read_labels_csv_from(path, num_classes, one_hot=False):\n  \"\"\"Reads\n  Args:\n\n  Returns:\n\n  \"\"\"\n  print('Reading labels')\n  with open(os.path.join(path), 'r') as dest_f:\n    data_iter = csv.reader(dest_f)\n    train_labels = [data for data in data_iter]\n\n  train_labels = np.array(train_labels, dtype=np.uint32)\n\n  if one_hot:\n    labels_one_hot = utils.dense_to_one_hot(train_labels, num_classes)\n    labels_one_hot = np.asarray(labels_one_hot)\n    return labels_one_hot\n\n  return train_labels\n\n\ndef _read_pngs_from(path):\n  \"\"\"Reads directory of images.\n  Args:\n    path: path to the directory\n\n  Returns:\n    A list of all images in the directory in the TF format (You need to call sess.run() or .eval() to get the value).\n  \"\"\"\n  images = []\n  png_files_path = glob.glob(os.path.join(path, '*.[pP][nN][gG]'))\n  for filename in png_files_path:\n    im = Image.open(filename)\n    im = np.asarray(im, np.uint8)\n\n    # get only images name, not path\n    image_name = filename.split('/')[-1].split('.')[0]\n    images.append([int(image_name), im])\n\n  images = sorted(images, key=lambda image: image[0])\n\n  images_only = [np.asarray(image[1], np.uint8) for image in images]  # Use unint8 or you will be !!!\n  images_only = np.array(images_only)\n\n  #print(images_only.shape)\n  return images_only\n\n\n\ndef read_and_decode_wholefile(filename_queue, imshape, normalize=False, flatten=True):\n  \"\"\"Reads\n  Args:\n    filename_queue:\n    imshape:\n    normalize:\n    flatten:\n\n  Returns:\n\n  \"\"\"\n  reader = tf.WholeFileReader()\n  key, value = reader.read(filename_queue)\n\n  image = tf.image.decode_png(value, channels=3)\n\n  if flatten:\n    num_elements = 1\n    for i in imshape: num_elements = num_elements * i\n    #print num_elements\n    image = tf.reshape(image, [num_elements])\n    image.set_shape(num_elements)\n  else:\n    image = tf.reshape(image, imshape)\n    image.set_shape(imshape)\n\n  if normalize:\n    # Convert from [0, 255] -> [-0.5, 0.5] floats.\n    image = tf.cast(image, tf.float32)\n    image = tf.cast(image, tf.float32) * (1. / 255) - 0.5\n  \n  # don't care\n  label = 1\n\n  return image, label\n\n\n\ndef dense_to_one_hot(labels_dense, num_classes):\n  \"\"\"\n  Convert class labels from scalars to one-hot vectors.\n\n\n  \"\"\"\n  num_labels = labels_dense.shape[0]\n  index_offset = np.arange(num_labels) * num_classes\n  labels_one_hot = np.zeros((num_labels, num_classes))\n  labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1\n  print(labels_one_hot[0])\n\n  return labels_one_hot"
  },
  {
    "path": "tf/spikeflow.py",
    "content": "#deeperic\n\nimport convert_to_tfrecords\nimport reader\n\n\nfrom numpy.random import shuffle\nimport tensorflow as tf\n\n\n\ndef inputs_test_files(filename, batch_size, num_epochs2, num_threads,\n           imshape, num_examples_per_epoch=128):\n  \"\"\"Reads input tfrecord file num_epochs times. Use it for validation.\n\n  Args:\n    filename: The path to the .tfrecords file to be read\n    batch_size: Number of examples per returned batch.\n    num_epochs: Number of times to read the input ckpt, or 0/None to\n       train forever.\n    num_threads: Number of reader workers to enqueue\n    imshape: The shape of image in the format\n    num_examples_per_epoch: Number of images to use per epoch\n\n  Returns:\n    A tuple (images, labels), where:\n    * images is a float tensor with shape [batch_size, mnist.IMAGE_PIXELS]\n      in the range [-0.5, 0.5].\n    * labels is an int32 tensor with shape [batch_size] with the true label,\n      a number in the range [0, mnist.NUM_CLASSES).\n    Note that an tf.train.QueueRunner is added to the graph, which\n    must be run using e.g. tf.train.start_queue_runners().\n  \"\"\"\n\n\n  tf.local_variables_initializer()\n  \n  if not num_epochs2:\n    num_epochs2 = None\n\n  with tf.name_scope('input'):\n    filename_queue = tf.train.string_input_producer(\n      #[filename], num_epochs=num_epochs2, name='string_input_producer')\n      \n      #['../character-data/test/170.png',\n      #'../character-data/test/214.png',\n      #'../character-data/test/2579.png'],\n      ['../project/pricesplit_/0.png',\n      '../project/pricesplit_/1.png',\n      '../project/pricesplit_/2.png',\n      '../project/pricesplit_/3.png',\n      '../project/pricesplit_/4.png',\n      '../project/pricesplit_/5.png',\n      '../project/pricesplit_/6.png',\n      '../project/pricesplit_/7.png'],\n       num_epochs=num_epochs2, \n       shuffle=False,#must be false otherwise will shuffle everytime\n       name='string_input_producer')\n\n\n\n    # Even when reading in multiple threads, share the filename\n    # queue.\n    image, label = reader.read_and_decode_eric(filename_queue, imshape, normalize=True)\n\t\n    # Convert from [0, 255] -> [-0.5, 0.5] floats. The normalize param in read_and_decode will do the same job.\n    # image = tf.cast(image, tf.float32)\n    # image = tf.cast(image, tf.float32) * (1. / 255) - 0.5\n\n    # Shuffle the examples and collect them into batch_size batches.\n    # (Internally uses a RandomShuffleQueue.)\n    # We run this in two threads to avoid being a bottleneck.\n    # Ensure that the random shuffling has good mixing properties.\n    #min_fraction_of_examples_in_queue = 0.4\n    #min_queue_examples = int(num_examples_per_epoch *\n    #                         min_fraction_of_examples_in_queue)\n\n    #images, sparse_labels = tf.train.shuffle_batch(\n    #  [image, label], batch_size=batch_size, num_threads=num_threads,\n    #  capacity=min_queue_examples + 3 * batch_size, enqueue_many=False,\n    #  # Ensures a minimum amount of shuffling of examples.\n    #  min_after_dequeue=min_queue_examples, name='batching_shuffling')\n      \n    #print('erieric')\n      \n    images, sparse_labels = tf.train.batch(\n      [image, label], batch_size=batch_size, num_threads=num_threads)\n\n    return images, sparse_labels\n    \ndef inputs_test(filename, batch_size, num_epochs, num_threads,\n           imshape, num_examples_per_epoch=128):\n \n  tf.local_variables_initializer()\n  \n  if not num_epochs:\n    num_epochs = None\n\n  with tf.name_scope('input'):\n    filename_queue = tf.train.string_input_producer(\n      [filename], num_epochs=num_epochs, name='string_input_producer')\n      \n    image, label = reader.read_and_decode_wholefile(filename_queue, imshape, normalize=True)\n\t\n    images, sparse_labels = tf.train.batch([image, label], batch_size=batch_size)  \n \n    return images, sparse_labels\n    \n  \n\ndef inputs(filename, batch_size, num_epochs2, num_threads,\n           imshape, num_examples_per_epoch=128):\n  \"\"\"Reads input tfrecord file num_epochs times. Use it for validation.\n\n  Args:\n    filename: The path to the .tfrecords file to be read\n    batch_size: Number of examples per returned batch.\n    num_epochs: Number of times to read the input ckpt, or 0/None to\n       train forever.\n    num_threads: Number of reader workers to enqueue\n    imshape: The shape of image in the format\n    num_examples_per_epoch: Number of images to use per epoch\n\n  Returns:\n    A tuple (images, labels), where:\n    * images is a float tensor with shape [batch_size, mnist.IMAGE_PIXELS]\n      in the range [-0.5, 0.5].\n    * labels is an int32 tensor with shape [batch_size] with the true label,\n      a number in the range [0, mnist.NUM_CLASSES).\n    Note that an tf.train.QueueRunner is added to the graph, which\n    must be run using e.g. tf.train.start_queue_runners().\n  \"\"\"\n\n\n  tf.local_variables_initializer()\n  \n  if not num_epochs2:\n    num_epochs2 = None\n\n  with tf.name_scope('input'):\n    filename_queue = tf.train.string_input_producer(\n      [filename], num_epochs=num_epochs2, name='string_input_producer')\n\n    # Even when reading in multiple threads, share the filename\n    # queue.\n    #image, label = reader.read_and_decode(filename_queue, imshape, normalize=True, flatten=False)\n    image, label = reader.read_and_decode(filename_queue, imshape, normalize=True)\n\n    # Convert from [0, 255] -> [-0.5, 0.5] floats. The normalize param in read_and_decode will do the same job.\n    # image = tf.cast(image, tf.float32)\n    # image = tf.cast(image, tf.float32) * (1. / 255) - 0.5\n\n    # Shuffle the examples and collect them into batch_size batches.\n    # (Internally uses a RandomShuffleQueue.)\n    # We run this in two threads to avoid being a bottleneck.\n    # Ensure that the random shuffling has good mixing properties.\n    min_fraction_of_examples_in_queue = 0.4\n    min_queue_examples = int(num_examples_per_epoch *\n                             min_fraction_of_examples_in_queue)\n\n    images, sparse_labels = tf.train.shuffle_batch(  \n      [image, label], batch_size=batch_size, num_threads=num_threads,\n      capacity=min_queue_examples + 3 * batch_size, enqueue_many=False,\n      # Ensures a minimum amount of shuffling of examples.\n      min_after_dequeue=min_queue_examples, name='batching_shuffling')\n      \n    return images, sparse_labels\n\ndef _random_brightness_helper(image):\n  return tf.image.random_brightness(image, max_delta=63)\n    \ndef _random_contrast_helper(image):  \n  return tf.image.random_contrast(image, lower=0.2, upper=1.8)\n\ndef distorted_inputs(filename, batch_size, num_epochs, num_threads,\n                     imshape, num_examples_per_epoch=128, flatten=True):\n  \"\"\"Construct distorted input for training using the Reader ops.\n\n  Raises:\n    ValueError: if no data_dir\n\n  Args:\n    filename: The name of the file containing the images\n    batch_size: The number of images per batch\n    num_epochs: The number of epochs passed to string_input_producer\n    num_threads: The number of threads passed to shuffle_batch\n    imshape: Shape of image in [height, width, n_channels] format\n    num_examples_per_epoch: Number of images to use per epoch\n    flatten: Whether to flatten image after image transformations\n\n  Returns:\n    images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.\n    labels: Labels. 1D tensor of [batch_size] size.\n  \"\"\"\n  \n  tf.local_variables_initializer()\n  tf.global_variables_initializer()\n  \n  if not num_epochs:\n    num_epochs = None\n\n  with tf.name_scope('input'):\n    filename_queue = tf.train.string_input_producer(\n      [filename], num_epochs=num_epochs, name='string_DISTORTED_input_producer')\n\n    # Even when reading in multiple threads, share the filename\n    # queue.\n    image, label = reader.read_and_decode(filename_queue, imshape)\n\n    # Reshape to imshape as distortion methods need this shape\n    image = tf.reshape(image, imshape)\n\n    # Image processing for training the network. Note the many random\n    # distortions applied to the image.\n\n    # Removed random_crop in new TensorFlow release.\n    # Randomly crop a [height, width] section of the image.\n    # distorted_image = tf.image.random_crop(image, [height, width])\n    #\n    # Randomly flip the image horizontally.\n    distorted_image = tf.image.random_flip_left_right(image)\n    #\n    # Randomly apply image transformations in random_functions list\n    random_functions = [_random_brightness_helper, _random_contrast_helper]\n    shuffle(random_functions)\n    for fcn in random_functions:\n      distorted_image = fcn(distorted_image)\n\n    # # Subtract off the mean and divide by the variance of the pixels.\n    float_image = tf.image.per_image_standardization(distorted_image)\n\n    if flatten:\n      num_elements = 1\n      for i in imshape: num_elements = num_elements * i\n      image = tf.reshape(float_image, [num_elements])\n    else:\n      image = float_image\n\n    # Ensure that the random shuffling has good mixing properties.\n    min_fraction_of_examples_in_queue = 0.4\n    min_queue_examples = int(num_examples_per_epoch *\n                             min_fraction_of_examples_in_queue)\n    images, sparse_labels = tf.train.shuffle_batch([image, label],\n                                                   batch_size=batch_size,\n                                                   num_threads=num_threads,\n                                                   capacity=min_queue_examples + 3 * batch_size,\n                                                   enqueue_many=False,\n                                                   # Ensures a minimum amount of shuffling of examples.\n                                                   min_after_dequeue=min_queue_examples,\n                                                   name='batching_shuffling_distortion')\n\n  return images, sparse_labels\n\n\n"
  },
  {
    "path": "tf/test_one_char.py",
    "content": "#!/usr/bin/env python\n# -*- coding: UTF-8 -*-\n\n\n\n#deeperic\n\nimport os.path\nimport time\nfrom datetime import datetime\n\nimport numpy as np\nimport tensorflow as tf\n\nimport glob\nfrom PIL import Image\nimport sys\n\nimport spikeflow\nimport ocr_model\nimport helper\n\n#import input_data\n\n# Basic model parameters as external flags.\nflags = tf.app.flags\nFLAGS = flags.FLAGS\n\nflags.DEFINE_integer('num_epochs', 50000, 'Number of epochs to run trainer.')\n\nflags.DEFINE_integer('batch_size', 32, 'Batch size.')\n\n\nIMAGE_PIXELS = 32 * 32 * 3\n\n\ndef placeholder_inputs(batch_size):\n  \"\"\"Generate placeholder variables to represent the the input tensors.\n  These placeholders are used as inputs by the rest of the model building\n  code and will be fed from the downloaded ckpt in the .run() loop, below.\n  Args:\n    batch_size: The batch size will be baked into both placeholders.\n  Returns:\n    images_placeholder: Images placeholder.\n    labels_placeholder: Labels placeholder.\n  \"\"\"\n  # Note that the shapes of the placeholders match the shapes of the full\n  # image and label tensors, except the first dimension is now batch_size\n  # rather than the full size of the train or test ckpt sets.\n  # batch_size = -1\n  images_placeholder = tf.placeholder(tf.float32, shape=(batch_size,\n                                                         IMAGE_PIXELS))\n                                                         \n  labels_placeholder = tf.placeholder(tf.int32, shape=batch_size)\n\n  return images_placeholder, labels_placeholder\n\n  \ndef test(argv):\n\n  with tf.Graph().as_default():\n    global_step = tf.Variable(0, trainable=False)\n\n    images_placeholder, labels_placeholder = placeholder_inputs(FLAGS.batch_size)\n    \n    test_images, test_labels = spikeflow.inputs_test(filename=argv[1], batch_size=FLAGS.batch_size,\n                                    num_epochs=FLAGS.num_epochs,\n                                    num_threads=5, imshape=[32, 32, 3])\n\n    \n    # Build a Graph that computes the logits predictions from the inference model.\n    logits = ocr_model.inference(images_placeholder)\n\n    # Create a saver.\n    saver = tf.train.Saver()\n\n    init = tf.group(tf.global_variables_initializer(),\n                   tf.local_variables_initializer())\n\n    # Start running operations on the Graph.\n    NUM_CORES = 5  # Choose how many cores to use.\n    \n    sess = tf.Session(config=tf.ConfigProto(inter_op_parallelism_threads=NUM_CORES,\n                   intra_op_parallelism_threads=NUM_CORES))\n                               \n    sess.run(init)\n\n    # Start the queue runners.\n    coord = tf.train.Coordinator()\n    threads = tf.train.start_queue_runners(sess=sess, coord=coord)\n                                    \n    #print('Model:' + argv[0])\n    saver.restore(sess, argv[0])\n    #print('Model Restored!')\n    \n        \n    images_test_r, labels_test_r = sess.run([test_images, test_labels])\n        \n    val_feed_test = {images_placeholder: images_test_r,\n                    labels_placeholder: labels_test_r}\n                    \n    acc_r = sess.run(tf.argmax(logits,1), feed_dict=val_feed_test)\n        \n    chars = helper.char_list_chinese\n          \n    print('The character is: ' + str(chars[acc_r[0]]))\n    \n    #print predictions\n    prediction=tf.argmax(logits,1)\n    print \"Predictions:\", prediction.eval(feed_dict=val_feed_test, session=sess)[0]\n\n    #print probabilities\n    probabilities=logits\n    print \"Probabilities:\", probabilities.eval(feed_dict=val_feed_test, session=sess)[0]\n      \n    coord.request_stop()\n    coord.join(threads)\n    sess.close()\n\n\n\ndef main(argv=None):\n#python test_one_char.py {model_name} {image_name}\n  test(sys.argv[1:]) #predict\n\nif __name__ == '__main__':\n  tf.app.run()\n"
  },
  {
    "path": "tf/train_model.py",
    "content": "#!/usr/bin/env python\n# -*- coding: UTF-8 -*-\n\n#deeperic\n\n\"\"\"Training the model\"\"\"\n\n\nimport os.path\nimport time\nfrom datetime import datetime\n\nimport numpy as np\nimport tensorflow as tf\nimport glob\nfrom PIL import Image\n\nimport spikeflow\nimport ocr_model\n\n#import input_data\n\n# Basic model parameters as external flags.\nflags = tf.app.flags\nFLAGS = flags.FLAGS\nflags.DEFINE_float('learning_rate', 0.01, 'Initial learning rate.')\nflags.DEFINE_integer('num_epochs', 50000, 'Number of epochs to run trainer.')\nflags.DEFINE_integer('batch_size', 32, 'Batch size.')\n\n\nFLAGS = tf.app.flags.FLAGS\n\ntf.app.flags.DEFINE_string('model_dir', '../tmp/my-model',\n                           \"\"\"Directory where to write model proto \"\"\"\n                           \"\"\" to import in c++\"\"\")\n                           \ntf.app.flags.DEFINE_string('train_dir', '../tmp/log',\n                           \"\"\"Directory where to write event logs \"\"\"\n                           \"\"\"and checkpoint.\"\"\")\n\ntf.app.flags.DEFINE_integer('max_steps', 100000,\n                            \"\"\"Number of batches to run.\"\"\")\n                            \ntf.app.flags.DEFINE_string('checkpoint_dir', '../checkpoint',\n                           \"\"\"Directory where to read/write model checkpoints.\"\"\")\n\n# Parameters\ndisplay_step = 100\nval_step = 500\nsave_step = 500\nPIXEL_DIM = 32\nIMAGE_PIXELS = PIXEL_DIM * PIXEL_DIM * 3\nNEW_LINE = '\\n'\n\n\n\ndef placeholder_inputs(batch_size):\n  \"\"\"Generate placeholder variables to represent the the input tensors.\n  These placeholders are used as inputs by the rest of the model building\n  code and will be fed from the downloaded ckpt in the .run() loop, below.\n  Args:\n    batch_size: The batch size will be baked into both placeholders.\n  Returns:\n    images_placeholder: Images placeholder.\n    labels_placeholder: Labels placeholder.\n  \"\"\"\n  # Note that the shapes of the placeholders match the shapes of the full\n  # image and label tensors, except the first dimension is now batch_size\n  # rather than the full size of the train or test ckpt sets.\n  # batch_size = -1\n  images_placeholder = tf.placeholder(tf.float32, shape=(batch_size,\n                                                         IMAGE_PIXELS))\n                                                        \n  labels_placeholder = tf.placeholder(tf.int32, shape=batch_size)\n\n  return images_placeholder, labels_placeholder\n\n  \ndef train(continue_from_pre = False):\n  \n  with tf.Graph().as_default():\n    global_step = tf.Variable(0, trainable=False)\n\n    images_placeholder, labels_placeholder = placeholder_inputs(FLAGS.batch_size)\n    \n    #read the TF Records\n    images, labels = spikeflow.inputs(filename='../tfrec/train.tfrecords', batch_size=FLAGS.batch_size,\n                                      num_epochs2=FLAGS.num_epochs,\n                                      num_threads=5, imshape=[PIXEL_DIM, PIXEL_DIM, 3])\n                                      \n                                      \n    val_images, val_labels = spikeflow.inputs(filename='../tfrec/validation.tfrecords', batch_size=FLAGS.batch_size,\n                                    num_epochs2=FLAGS.num_epochs,\n                                    num_threads=5, imshape=[PIXEL_DIM, PIXEL_DIM, 3])\n                                    \n    # Build a Graph that computes the logits predictions from the inference model.\n    logits = ocr_model.inference(images_placeholder)\n\n    # Calculate loss.\n    loss = ocr_model.loss(logits, labels_placeholder)\n\n    # Build a Graph that trains the model with one batch of examples and\n    # updates the model parameters.\n    train_op = ocr_model.training(loss, global_step)\n\n    # Calculate accuracy #\n    acc, n_correct = ocr_model.evaluation(logits, labels_placeholder)\n\n    # Create a saver.\n    saver = tf.train.Saver()\n\n    tf.summary.scalar('Acc', acc)\n    tf.summary.scalar('Loss', loss)\n \n    # Build the summary operation based on the TF collection of Summaries.\n    summary_op = tf.summary.merge_all()\n\n    # Build an initialization operation to run below.\n\n    init = tf.group(tf.global_variables_initializer(),\n                   tf.local_variables_initializer())\n\n    # Start running operations on the Graph.\n    NUM_CORES = 5  # Choose how many cores to use.\n    \n    sess = tf.Session(config=tf.ConfigProto(inter_op_parallelism_threads=NUM_CORES,\n                   intra_op_parallelism_threads=NUM_CORES))\n                   \n    sess.run(init)\n\n    # Write all terminal output results here\n    val_f = open(\"../tmp/val.txt\", \"ab\")\n\n    # Start the queue runners.\n    coord = tf.train.Coordinator()\n    threads = tf.train.start_queue_runners(sess=sess, coord=coord)\n\n    summary_writer = tf.summary.FileWriter(FLAGS.train_dir,\n                                            graph=sess.graph)\n\n    # Export graph to import it later in c++\n    # tf.train.write_graph(sess.graph, FLAGS.model_dir, 'train.pbtxt') # TODO: uncomment to get graph and use in c++\n\n    #reload previous saved check points\n    continue_from_pre = False\n\n    if continue_from_pre:\n      ckpt = tf.train.get_checkpoint_state(checkpoint_dir=FLAGS.checkpoint_dir)\n      print ckpt.model_checkpoint_path\n      if ckpt and ckpt.model_checkpoint_path:\n        saver.restore(sess, ckpt.model_checkpoint_path)\n        print('Session Restored!')\n\n    try:\n      while not coord.should_stop():\n\n        for step in xrange(FLAGS.max_steps):\n\n          images_r, labels_r = sess.run([images, labels])\n          images_val_r, labels_val_r = sess.run([val_images, val_labels])\n\n          train_feed = {images_placeholder: images_r,\n                          labels_placeholder: labels_r}\n\n          val_feed = {images_placeholder: images_val_r,\n                        labels_placeholder: labels_val_r}\n\n          start_time = time.time()\n\n          _, loss_value = sess.run([train_op, loss], feed_dict=train_feed)\n          duration = time.time() - start_time\n\n          assert not np.isnan(loss_value), 'Model diverged with loss = NaN'\n\n          if step % display_step == 0:\n            num_examples_per_step = FLAGS.batch_size\n            examples_per_sec = num_examples_per_step / duration\n            sec_per_batch = float(duration)\n\n            format_str = ('%s: step %d, loss = %.6f (%.1f examples/sec; %.3f '\n                            'sec/batch)')\n            print_str_loss = format_str % (datetime.now(), step, loss_value,\n                                             examples_per_sec, sec_per_batch)\n            print (print_str_loss)\n            val_f.write(print_str_loss + NEW_LINE)\n            summary_str = sess.run([summary_op], feed_dict=train_feed)\n            summary_writer.add_summary(summary_str[0], step)\n\n          if step % val_step == 0:\n            acc_value, num_corroect = sess.run([acc, n_correct], feed_dict=train_feed)\n\n            format_str = '%s: step %d,  train acc = %.2f, n_correct= %d'\n            print_str_train = format_str % (datetime.now(), step, acc_value, num_corroect)\n            val_f.write(print_str_train + NEW_LINE)\n            print (print_str_train)\n\n          # Save the model checkpoint periodically.\n          if step % save_step == 0 or (step + 1) == FLAGS.max_steps:\n            val_acc_r, val_n_correct_r = sess.run([acc, n_correct], feed_dict=val_feed)\n\n            frmt_str = '%s: step %d, Val Acc = %.2f, num correct = %d'\n            print_str_val = frmt_str % (datetime.now(), step, val_acc_r, val_n_correct_r)\n            val_f.write(print_str_val + NEW_LINE)\n            print(print_str_val)\n\n            checkpoint_path = os.path.join(FLAGS.checkpoint_dir, 'model.ckpt')\n            savedpath = saver.save(sess, checkpoint_path, global_step=step)\n            print('model saved: ' + savedpath)\n\n\n    except tf.errors.OutOfRangeError:\n      print ('Done training -- epoch limit reached')\n\n    finally:\n      # When done, ask the threads to stop.\n      val_f.write(NEW_LINE +\n                    NEW_LINE +\n                    '############################ FINISHED ############################' +\n                    NEW_LINE)\n      val_f.close()\n      coord.request_stop()\n\n      # Wait for threads to finish.\n    coord.join(threads)\n    sess.close()\n\n  \ndef main(argv=None):\n  train() \n\nif __name__ == '__main__':\n  tf.app.run()\n\n"
  },
  {
    "path": "training-character.gh/labelling-character.py",
    "content": "import os\nfrom shutil import copyfile\nimport cv2\n\naggregatedPath = 'train'\ntrainPath = 'train'\nvalPath = 'val'\nimagesPath = ['cheung', 'chin2', 'chiu', 'cup', 'ho', 'ka', 'ma', 'sheung', 'shi', 'yi', 'sin', 'ngou', 'lai']\n\n\nlabelsFileTrain = './trainLabels.csv'\nlabelsFileVal = './valLabels.csv'\n\n\nnumVal = 160 #200 images, 80%  training, 20% validation\n\nf = open(labelsFileTrain,'w')\nf2 = open(labelsFileVal,'w')\n\naggregatedPath = trainPath #init with train path\nwriteFile = f\n\ncount = 0\neachClassCount = 0\n\nfor imagedir in imagesPath:  \n    print(imagedir)    \n    aggregatedPath = trainPath #init with train path\n    writeFile = f\n    eachClassCount = 0\n        \n    for fileName in os.listdir(imagedir):\n        print(fileName)\n        if(fileName == \".DS_Store\"):\n            continue\n        filename_split = os.path.splitext(fileName)\n        \n        if eachClassCount >= numVal: #validation files\n        \taggregatedPath = valPath\n        \twriteFile = f2\n        \t\n        oldFileName = imagedir + \"/\" + fileName\n        newFileOnlyName = '{0:05d}'.format(count) + \".\" + \"png\"\n        newFileName = \"./\" + aggregatedPath + \"/\" + newFileOnlyName\n        print(oldFileName)\n        print(newFileName)\n        \n        copyfile(oldFileName, newFileName)\n        writeFile.write('{0:05d}'.format(count) + \",\" + imagedir + '\\n')\n        \n        \n        count = count + 1\n        eachClassCount = eachClassCount + 1\n        \n        \nf.close()\nf2.close()\n\ndef resizeme(path):\n\n  #resize 32x32\n  for fileName in os.listdir(path):\n    if(fileName == \".DS_Store\"):\n      continue\n    print(\"resize:\" + fileName)\n    image = cv2.imread(path + \"/\" + fileName)\n    resized_image = cv2.resize(image, (32, 32)) \n    cv2.imwrite(path + \"/\" + fileName, resized_image)\n\n\n\nresizeme(trainPath)\nresizeme(valPath)\n"
  },
  {
    "path": "training-character.gh/trainLabels.csv",
    "content": "00000,cheung\n00001,cheung\n00002,cheung\n00003,cheung\n00004,cheung\n00005,cheung\n00006,cheung\n00007,cheung\n00008,cheung\n00009,cheung\n00010,cheung\n00011,cheung\n00012,cheung\n00013,cheung\n00014,cheung\n00015,cheung\n00016,cheung\n00017,cheung\n00018,cheung\n00019,cheung\n00020,cheung\n00021,cheung\n00022,cheung\n00023,cheung\n00024,cheung\n00025,cheung\n00026,cheung\n00027,cheung\n00028,cheung\n00029,cheung\n00030,cheung\n00031,cheung\n00032,cheung\n00033,cheung\n00034,cheung\n00035,cheung\n00036,cheung\n00037,cheung\n00038,cheung\n00039,cheung\n00040,cheung\n00041,cheung\n00042,cheung\n00043,cheung\n00044,cheung\n00045,cheung\n00046,cheung\n00047,cheung\n00048,cheung\n00049,cheung\n00050,cheung\n00051,cheung\n00052,cheung\n00053,cheung\n00054,cheung\n00055,cheung\n00056,cheung\n00057,cheung\n00058,cheung\n00059,cheung\n00060,cheung\n00061,cheung\n00062,cheung\n00063,cheung\n00064,cheung\n00065,cheung\n00066,cheung\n00067,cheung\n00068,cheung\n00069,cheung\n00070,cheung\n00071,cheung\n00072,cheung\n00073,cheung\n00074,cheung\n00075,cheung\n00076,cheung\n00077,cheung\n00078,cheung\n00079,cheung\n00080,cheung\n00081,cheung\n00082,cheung\n00083,cheung\n00084,cheung\n00085,cheung\n00086,cheung\n00087,cheung\n00088,cheung\n00089,cheung\n00090,cheung\n00091,cheung\n00092,cheung\n00093,cheung\n00094,cheung\n00095,cheung\n00096,cheung\n00097,cheung\n00098,cheung\n00099,cheung\n00100,cheung\n00101,cheung\n00102,cheung\n00103,cheung\n00104,cheung\n00105,cheung\n00106,cheung\n00107,cheung\n00108,cheung\n00109,cheung\n00110,cheung\n00111,cheung\n00112,cheung\n00113,cheung\n00114,cheung\n00115,cheung\n00116,cheung\n00117,cheung\n00118,cheung\n00119,cheung\n00120,cheung\n00121,cheung\n00122,cheung\n00123,cheung\n00124,cheung\n00125,cheung\n00126,cheung\n00127,cheung\n00128,cheung\n00129,cheung\n00130,cheung\n00131,cheung\n00132,cheung\n00133,cheung\n00134,cheung\n00135,cheung\n00136,cheung\n00137,cheung\n00138,cheung\n00139,cheung\n00140,cheung\n00141,cheung\n00142,cheung\n00143,cheung\n00144,cheung\n00145,cheung\n00146,cheung\n00147,cheung\n00148,cheung\n00149,cheung\n00150,cheung\n00151,cheung\n00152,cheung\n00153,cheung\n00154,cheung\n00155,cheung\n00156,cheung\n00157,cheung\n00158,cheung\n00159,cheung\n00200,chin2\n00201,chin2\n00202,chin2\n00203,chin2\n00204,chin2\n00205,chin2\n00206,chin2\n00207,chin2\n00208,chin2\n00209,chin2\n00210,chin2\n00211,chin2\n00212,chin2\n00213,chin2\n00214,chin2\n00215,chin2\n00216,chin2\n00217,chin2\n00218,chin2\n00219,chin2\n00220,chin2\n00221,chin2\n00222,chin2\n00223,chin2\n00224,chin2\n00225,chin2\n00226,chin2\n00227,chin2\n00228,chin2\n00229,chin2\n00230,chin2\n00231,chin2\n00232,chin2\n00233,chin2\n00234,chin2\n00235,chin2\n00236,chin2\n00237,chin2\n00238,chin2\n00239,chin2\n00240,chin2\n00241,chin2\n00242,chin2\n00243,chin2\n00244,chin2\n00245,chin2\n00246,chin2\n00247,chin2\n00248,chin2\n00249,chin2\n00250,chin2\n00251,chin2\n00252,chin2\n00253,chin2\n00254,chin2\n00255,chin2\n00256,chin2\n00257,chin2\n00258,chin2\n00259,chin2\n00260,chin2\n00261,chin2\n00262,chin2\n00263,chin2\n00264,chin2\n00265,chin2\n00266,chin2\n00267,chin2\n00268,chin2\n00269,chin2\n00270,chin2\n00271,chin2\n00272,chin2\n00273,chin2\n00274,chin2\n00275,chin2\n00276,chin2\n00277,chin2\n00278,chin2\n00279,chin2\n00280,chin2\n00281,chin2\n00282,chin2\n00283,chin2\n00284,chin2\n00285,chin2\n00286,chin2\n00287,chin2\n00288,chin2\n00289,chin2\n00290,chin2\n00291,chin2\n00292,chin2\n00293,chin2\n00294,chin2\n00295,chin2\n00296,chin2\n00297,chin2\n00298,chin2\n00299,chin2\n00300,chin2\n00301,chin2\n00302,chin2\n00303,chin2\n00304,chin2\n00305,chin2\n00306,chin2\n00307,chin2\n00308,chin2\n00309,chin2\n00310,chin2\n00311,chin2\n00312,chin2\n00313,chin2\n00314,chin2\n00315,chin2\n00316,chin2\n00317,chin2\n00318,chin2\n00319,chin2\n00320,chin2\n00321,chin2\n00322,chin2\n00323,chin2\n00324,chin2\n00325,chin2\n00326,chin2\n00327,chin2\n00328,chin2\n00329,chin2\n00330,chin2\n00331,chin2\n00332,chin2\n00333,chin2\n00334,chin2\n00335,chin2\n00336,chin2\n00337,chin2\n00338,chin2\n00339,chin2\n00340,chin2\n00341,chin2\n00342,chin2\n00343,chin2\n00344,chin2\n00345,chin2\n00346,chin2\n00347,chin2\n00348,chin2\n00349,chin2\n00350,chin2\n00351,chin2\n00352,chin2\n00353,chin2\n00354,chin2\n00355,chin2\n00356,chin2\n00357,chin2\n00358,chin2\n00359,chin2\n00400,chiu\n00401,chiu\n00402,chiu\n00403,chiu\n00404,chiu\n00405,chiu\n00406,chiu\n00407,chiu\n00408,chiu\n00409,chiu\n00410,chiu\n00411,chiu\n00412,chiu\n00413,chiu\n00414,chiu\n00415,chiu\n00416,chiu\n00417,chiu\n00418,chiu\n00419,chiu\n00420,chiu\n00421,chiu\n00422,chiu\n00423,chiu\n00424,chiu\n00425,chiu\n00426,chiu\n00427,chiu\n00428,chiu\n00429,chiu\n00430,chiu\n00431,chiu\n00432,chiu\n00433,chiu\n00434,chiu\n00435,chiu\n00436,chiu\n00437,chiu\n00438,chiu\n00439,chiu\n00440,chiu\n00441,chiu\n00442,chiu\n00443,chiu\n00444,chiu\n00445,chiu\n00446,chiu\n00447,chiu\n00448,chiu\n00449,chiu\n00450,chiu\n00451,chiu\n00452,chiu\n00453,chiu\n00454,chiu\n00455,chiu\n00456,chiu\n00457,chiu\n00458,chiu\n00459,chiu\n00460,chiu\n00461,chiu\n00462,chiu\n00463,chiu\n00464,chiu\n00465,chiu\n00466,chiu\n00467,chiu\n00468,chiu\n00469,chiu\n00470,chiu\n00471,chiu\n00472,chiu\n00473,chiu\n00474,chiu\n00475,chiu\n00476,chiu\n00477,chiu\n00478,chiu\n00479,chiu\n00480,chiu\n00481,chiu\n00482,chiu\n00483,chiu\n00484,chiu\n00485,chiu\n00486,chiu\n00487,chiu\n00488,chiu\n00489,chiu\n00490,chiu\n00491,chiu\n00492,chiu\n00493,chiu\n00494,chiu\n00495,chiu\n00496,chiu\n00497,chiu\n00498,chiu\n00499,chiu\n00500,chiu\n00501,chiu\n00502,chiu\n00503,chiu\n00504,chiu\n00505,chiu\n00506,chiu\n00507,chiu\n00508,chiu\n00509,chiu\n00510,chiu\n00511,chiu\n00512,chiu\n00513,chiu\n00514,chiu\n00515,chiu\n00516,chiu\n00517,chiu\n00518,chiu\n00519,chiu\n00520,chiu\n00521,chiu\n00522,chiu\n00523,chiu\n00524,chiu\n00525,chiu\n00526,chiu\n00527,chiu\n00528,chiu\n00529,chiu\n00530,chiu\n00531,chiu\n00532,chiu\n00533,chiu\n00534,chiu\n00535,chiu\n00536,chiu\n00537,chiu\n00538,chiu\n00539,chiu\n00540,chiu\n00541,chiu\n00542,chiu\n00543,chiu\n00544,chiu\n00545,chiu\n00546,chiu\n00547,chiu\n00548,chiu\n00549,chiu\n00550,chiu\n00551,chiu\n00552,chiu\n00553,chiu\n00554,chiu\n00555,chiu\n00556,chiu\n00557,chiu\n00558,chiu\n00559,chiu\n00600,cup\n00601,cup\n00602,cup\n00603,cup\n00604,cup\n00605,cup\n00606,cup\n00607,cup\n00608,cup\n00609,cup\n00610,cup\n00611,cup\n00612,cup\n00613,cup\n00614,cup\n00615,cup\n00616,cup\n00617,cup\n00618,cup\n00619,cup\n00620,cup\n00621,cup\n00622,cup\n00623,cup\n00624,cup\n00625,cup\n00626,cup\n00627,cup\n00628,cup\n00629,cup\n00630,cup\n00631,cup\n00632,cup\n00633,cup\n00634,cup\n00635,cup\n00636,cup\n00637,cup\n00638,cup\n00639,cup\n00640,cup\n00641,cup\n00642,cup\n00643,cup\n00644,cup\n00645,cup\n00646,cup\n00647,cup\n00648,cup\n00649,cup\n00650,cup\n00651,cup\n00652,cup\n00653,cup\n00654,cup\n00655,cup\n00656,cup\n00657,cup\n00658,cup\n00659,cup\n00660,cup\n00661,cup\n00662,cup\n00663,cup\n00664,cup\n00665,cup\n00666,cup\n00667,cup\n00668,cup\n00669,cup\n00670,cup\n00671,cup\n00672,cup\n00673,cup\n00674,cup\n00675,cup\n00676,cup\n00677,cup\n00678,cup\n00679,cup\n00680,cup\n00681,cup\n00682,cup\n00683,cup\n00684,cup\n00685,cup\n00686,cup\n00687,cup\n00688,cup\n00689,cup\n00690,cup\n00691,cup\n00692,cup\n00693,cup\n00694,cup\n00695,cup\n00696,cup\n00697,cup\n00698,cup\n00699,cup\n00700,cup\n00701,cup\n00702,cup\n00703,cup\n00704,cup\n00705,cup\n00706,cup\n00707,cup\n00708,cup\n00709,cup\n00710,cup\n00711,cup\n00712,cup\n00713,cup\n00714,cup\n00715,cup\n00716,cup\n00717,cup\n00718,cup\n00719,cup\n00720,cup\n00721,cup\n00722,cup\n00723,cup\n00724,cup\n00725,cup\n00726,cup\n00727,cup\n00728,cup\n00729,cup\n00730,cup\n00731,cup\n00732,cup\n00733,cup\n00734,cup\n00735,cup\n00736,cup\n00737,cup\n00738,cup\n00739,cup\n00740,cup\n00741,cup\n00742,cup\n00743,cup\n00744,cup\n00745,cup\n00746,cup\n00747,cup\n00748,cup\n00749,cup\n00750,cup\n00751,cup\n00752,cup\n00753,cup\n00754,cup\n00755,cup\n00756,cup\n00757,cup\n00758,cup\n00759,cup\n00800,ho\n00801,ho\n00802,ho\n00803,ho\n00804,ho\n00805,ho\n00806,ho\n00807,ho\n00808,ho\n00809,ho\n00810,ho\n00811,ho\n00812,ho\n00813,ho\n00814,ho\n00815,ho\n00816,ho\n00817,ho\n00818,ho\n00819,ho\n00820,ho\n00821,ho\n00822,ho\n00823,ho\n00824,ho\n00825,ho\n00826,ho\n00827,ho\n00828,ho\n00829,ho\n00830,ho\n00831,ho\n00832,ho\n00833,ho\n00834,ho\n00835,ho\n00836,ho\n00837,ho\n00838,ho\n00839,ho\n00840,ho\n00841,ho\n00842,ho\n00843,ho\n00844,ho\n00845,ho\n00846,ho\n00847,ho\n00848,ho\n00849,ho\n00850,ho\n00851,ho\n00852,ho\n00853,ho\n00854,ho\n00855,ho\n00856,ho\n00857,ho\n00858,ho\n00859,ho\n00860,ho\n00861,ho\n00862,ho\n00863,ho\n00864,ho\n00865,ho\n00866,ho\n00867,ho\n00868,ho\n00869,ho\n00870,ho\n00871,ho\n00872,ho\n00873,ho\n00874,ho\n00875,ho\n00876,ho\n00877,ho\n00878,ho\n00879,ho\n00880,ho\n00881,ho\n00882,ho\n00883,ho\n00884,ho\n00885,ho\n00886,ho\n00887,ho\n00888,ho\n00889,ho\n00890,ho\n00891,ho\n00892,ho\n00893,ho\n00894,ho\n00895,ho\n00896,ho\n00897,ho\n00898,ho\n00899,ho\n00900,ho\n00901,ho\n00902,ho\n00903,ho\n00904,ho\n00905,ho\n00906,ho\n00907,ho\n00908,ho\n00909,ho\n00910,ho\n00911,ho\n00912,ho\n00913,ho\n00914,ho\n00915,ho\n00916,ho\n00917,ho\n00918,ho\n00919,ho\n00920,ho\n00921,ho\n00922,ho\n00923,ho\n00924,ho\n00925,ho\n00926,ho\n00927,ho\n00928,ho\n00929,ho\n00930,ho\n00931,ho\n00932,ho\n00933,ho\n00934,ho\n00935,ho\n00936,ho\n00937,ho\n00938,ho\n00939,ho\n00940,ho\n00941,ho\n00942,ho\n00943,ho\n00944,ho\n00945,ho\n00946,ho\n00947,ho\n00948,ho\n00949,ho\n00950,ho\n00951,ho\n00952,ho\n00953,ho\n00954,ho\n00955,ho\n00956,ho\n00957,ho\n00958,ho\n00959,ho\n01000,ka\n01001,ka\n01002,ka\n01003,ka\n01004,ka\n01005,ka\n01006,ka\n01007,ka\n01008,ka\n01009,ka\n01010,ka\n01011,ka\n01012,ka\n01013,ka\n01014,ka\n01015,ka\n01016,ka\n01017,ka\n01018,ka\n01019,ka\n01020,ka\n01021,ka\n01022,ka\n01023,ka\n01024,ka\n01025,ka\n01026,ka\n01027,ka\n01028,ka\n01029,ka\n01030,ka\n01031,ka\n01032,ka\n01033,ka\n01034,ka\n01035,ka\n01036,ka\n01037,ka\n01038,ka\n01039,ka\n01040,ka\n01041,ka\n01042,ka\n01043,ka\n01044,ka\n01045,ka\n01046,ka\n01047,ka\n01048,ka\n01049,ka\n01050,ka\n01051,ka\n01052,ka\n01053,ka\n01054,ka\n01055,ka\n01056,ka\n01057,ka\n01058,ka\n01059,ka\n01060,ka\n01061,ka\n01062,ka\n01063,ka\n01064,ka\n01065,ka\n01066,ka\n01067,ka\n01068,ka\n01069,ka\n01070,ka\n01071,ka\n01072,ka\n01073,ka\n01074,ka\n01075,ka\n01076,ka\n01077,ka\n01078,ka\n01079,ka\n01080,ka\n01081,ka\n01082,ka\n01083,ka\n01084,ka\n01085,ka\n01086,ka\n01087,ka\n01088,ka\n01089,ka\n01090,ka\n01091,ka\n01092,ka\n01093,ka\n01094,ka\n01095,ka\n01096,ka\n01097,ka\n01098,ka\n01099,ka\n01100,ka\n01101,ka\n01102,ka\n01103,ka\n01104,ka\n01105,ka\n01106,ka\n01107,ka\n01108,ka\n01109,ka\n01110,ka\n01111,ka\n01112,ka\n01113,ka\n01114,ka\n01115,ka\n01116,ka\n01117,ka\n01118,ka\n01119,ka\n01120,ka\n01121,ka\n01122,ka\n01123,ka\n01124,ka\n01125,ka\n01126,ka\n01127,ka\n01128,ka\n01129,ka\n01130,ka\n01131,ka\n01132,ka\n01133,ka\n01134,ka\n01135,ka\n01136,ka\n01137,ka\n01138,ka\n01139,ka\n01140,ka\n01141,ka\n01142,ka\n01143,ka\n01144,ka\n01145,ka\n01146,ka\n01147,ka\n01148,ka\n01149,ka\n01150,ka\n01151,ka\n01152,ka\n01153,ka\n01154,ka\n01155,ka\n01156,ka\n01157,ka\n01158,ka\n01159,ka\n01200,ma\n01201,ma\n01202,ma\n01203,ma\n01204,ma\n01205,ma\n01206,ma\n01207,ma\n01208,ma\n01209,ma\n01210,ma\n01211,ma\n01212,ma\n01213,ma\n01214,ma\n01215,ma\n01216,ma\n01217,ma\n01218,ma\n01219,ma\n01220,ma\n01221,ma\n01222,ma\n01223,ma\n01224,ma\n01225,ma\n01226,ma\n01227,ma\n01228,ma\n01229,ma\n01230,ma\n01231,ma\n01232,ma\n01233,ma\n01234,ma\n01235,ma\n01236,ma\n01237,ma\n01238,ma\n01239,ma\n01240,ma\n01241,ma\n01242,ma\n01243,ma\n01244,ma\n01245,ma\n01246,ma\n01247,ma\n01248,ma\n01249,ma\n01250,ma\n01251,ma\n01252,ma\n01253,ma\n01254,ma\n01255,ma\n01256,ma\n01257,ma\n01258,ma\n01259,ma\n01260,ma\n01261,ma\n01262,ma\n01263,ma\n01264,ma\n01265,ma\n01266,ma\n01267,ma\n01268,ma\n01269,ma\n01270,ma\n01271,ma\n01272,ma\n01273,ma\n01274,ma\n01275,ma\n01276,ma\n01277,ma\n01278,ma\n01279,ma\n01280,ma\n01281,ma\n01282,ma\n01283,ma\n01284,ma\n01285,ma\n01286,ma\n01287,ma\n01288,ma\n01289,ma\n01290,ma\n01291,ma\n01292,ma\n01293,ma\n01294,ma\n01295,ma\n01296,ma\n01297,ma\n01298,ma\n01299,ma\n01300,ma\n01301,ma\n01302,ma\n01303,ma\n01304,ma\n01305,ma\n01306,ma\n01307,ma\n01308,ma\n01309,ma\n01310,ma\n01311,ma\n01312,ma\n01313,ma\n01314,ma\n01315,ma\n01316,ma\n01317,ma\n01318,ma\n01319,ma\n01320,ma\n01321,ma\n01322,ma\n01323,ma\n01324,ma\n01325,ma\n01326,ma\n01327,ma\n01328,ma\n01329,ma\n01330,ma\n01331,ma\n01332,ma\n01333,ma\n01334,ma\n01335,ma\n01336,ma\n01337,ma\n01338,ma\n01339,ma\n01340,ma\n01341,ma\n01342,ma\n01343,ma\n01344,ma\n01345,ma\n01346,ma\n01347,ma\n01348,ma\n01349,ma\n01350,ma\n01351,ma\n01352,ma\n01353,ma\n01354,ma\n01355,ma\n01356,ma\n01357,ma\n01358,ma\n01359,ma\n01400,sheung\n01401,sheung\n01402,sheung\n01403,sheung\n01404,sheung\n01405,sheung\n01406,sheung\n01407,sheung\n01408,sheung\n01409,sheung\n01410,sheung\n01411,sheung\n01412,sheung\n01413,sheung\n01414,sheung\n01415,sheung\n01416,sheung\n01417,sheung\n01418,sheung\n01419,sheung\n01420,sheung\n01421,sheung\n01422,sheung\n01423,sheung\n01424,sheung\n01425,sheung\n01426,sheung\n01427,sheung\n01428,sheung\n01429,sheung\n01430,sheung\n01431,sheung\n01432,sheung\n01433,sheung\n01434,sheung\n01435,sheung\n01436,sheung\n01437,sheung\n01438,sheung\n01439,sheung\n01440,sheung\n01441,sheung\n01442,sheung\n01443,sheung\n01444,sheung\n01445,sheung\n01446,sheung\n01447,sheung\n01448,sheung\n01449,sheung\n01450,sheung\n01451,sheung\n01452,sheung\n01453,sheung\n01454,sheung\n01455,sheung\n01456,sheung\n01457,sheung\n01458,sheung\n01459,sheung\n01460,sheung\n01461,sheung\n01462,sheung\n01463,sheung\n01464,sheung\n01465,sheung\n01466,sheung\n01467,sheung\n01468,sheung\n01469,sheung\n01470,sheung\n01471,sheung\n01472,sheung\n01473,sheung\n01474,sheung\n01475,sheung\n01476,sheung\n01477,sheung\n01478,sheung\n01479,sheung\n01480,sheung\n01481,sheung\n01482,sheung\n01483,sheung\n01484,sheung\n01485,sheung\n01486,sheung\n01487,sheung\n01488,sheung\n01489,sheung\n01490,sheung\n01491,sheung\n01492,sheung\n01493,sheung\n01494,sheung\n01495,sheung\n01496,sheung\n01497,sheung\n01498,sheung\n01499,sheung\n01500,sheung\n01501,sheung\n01502,sheung\n01503,sheung\n01504,sheung\n01505,sheung\n01506,sheung\n01507,sheung\n01508,sheung\n01509,sheung\n01510,sheung\n01511,sheung\n01512,sheung\n01513,sheung\n01514,sheung\n01515,sheung\n01516,sheung\n01517,sheung\n01518,sheung\n01519,sheung\n01520,sheung\n01521,sheung\n01522,sheung\n01523,sheung\n01524,sheung\n01525,sheung\n01526,sheung\n01527,sheung\n01528,sheung\n01529,sheung\n01530,sheung\n01531,sheung\n01532,sheung\n01533,sheung\n01534,sheung\n01535,sheung\n01536,sheung\n01537,sheung\n01538,sheung\n01539,sheung\n01540,sheung\n01541,sheung\n01542,sheung\n01543,sheung\n01544,sheung\n01545,sheung\n01546,sheung\n01547,sheung\n01548,sheung\n01549,sheung\n01550,sheung\n01551,sheung\n01552,sheung\n01553,sheung\n01554,sheung\n01555,sheung\n01556,sheung\n01557,sheung\n01558,sheung\n01559,sheung\n01600,shi\n01601,shi\n01602,shi\n01603,shi\n01604,shi\n01605,shi\n01606,shi\n01607,shi\n01608,shi\n01609,shi\n01610,shi\n01611,shi\n01612,shi\n01613,shi\n01614,shi\n01615,shi\n01616,shi\n01617,shi\n01618,shi\n01619,shi\n01620,shi\n01621,shi\n01622,shi\n01623,shi\n01624,shi\n01625,shi\n01626,shi\n01627,shi\n01628,shi\n01629,shi\n01630,shi\n01631,shi\n01632,shi\n01633,shi\n01634,shi\n01635,shi\n01636,shi\n01637,shi\n01638,shi\n01639,shi\n01640,shi\n01641,shi\n01642,shi\n01643,shi\n01644,shi\n01645,shi\n01646,shi\n01647,shi\n01648,shi\n01649,shi\n01650,shi\n01651,shi\n01652,shi\n01653,shi\n01654,shi\n01655,shi\n01656,shi\n01657,shi\n01658,shi\n01659,shi\n01660,shi\n01661,shi\n01662,shi\n01663,shi\n01664,shi\n01665,shi\n01666,shi\n01667,shi\n01668,shi\n01669,shi\n01670,shi\n01671,shi\n01672,shi\n01673,shi\n01674,shi\n01675,shi\n01676,shi\n01677,shi\n01678,shi\n01679,shi\n01680,shi\n01681,shi\n01682,shi\n01683,shi\n01684,shi\n01685,shi\n01686,shi\n01687,shi\n01688,shi\n01689,shi\n01690,shi\n01691,shi\n01692,shi\n01693,shi\n01694,shi\n01695,shi\n01696,shi\n01697,shi\n01698,shi\n01699,shi\n01700,shi\n01701,shi\n01702,shi\n01703,shi\n01704,shi\n01705,shi\n01706,shi\n01707,shi\n01708,shi\n01709,shi\n01710,shi\n01711,shi\n01712,shi\n01713,shi\n01714,shi\n01715,shi\n01716,shi\n01717,shi\n01718,shi\n01719,shi\n01720,shi\n01721,shi\n01722,shi\n01723,shi\n01724,shi\n01725,shi\n01726,shi\n01727,shi\n01728,shi\n01729,shi\n01730,shi\n01731,shi\n01732,shi\n01733,shi\n01734,shi\n01735,shi\n01736,shi\n01737,shi\n01738,shi\n01739,shi\n01740,shi\n01741,shi\n01742,shi\n01743,shi\n01744,shi\n01745,shi\n01746,shi\n01747,shi\n01748,shi\n01749,shi\n01750,shi\n01751,shi\n01752,shi\n01753,shi\n01754,shi\n01755,shi\n01756,shi\n01757,shi\n01758,shi\n01759,shi\n01800,yi\n01801,yi\n01802,yi\n01803,yi\n01804,yi\n01805,yi\n01806,yi\n01807,yi\n01808,yi\n01809,yi\n01810,yi\n01811,yi\n01812,yi\n01813,yi\n01814,yi\n01815,yi\n01816,yi\n01817,yi\n01818,yi\n01819,yi\n01820,yi\n01821,yi\n01822,yi\n01823,yi\n01824,yi\n01825,yi\n01826,yi\n01827,yi\n01828,yi\n01829,yi\n01830,yi\n01831,yi\n01832,yi\n01833,yi\n01834,yi\n01835,yi\n01836,yi\n01837,yi\n01838,yi\n01839,yi\n01840,yi\n01841,yi\n01842,yi\n01843,yi\n01844,yi\n01845,yi\n01846,yi\n01847,yi\n01848,yi\n01849,yi\n01850,yi\n01851,yi\n01852,yi\n01853,yi\n01854,yi\n01855,yi\n01856,yi\n01857,yi\n01858,yi\n01859,yi\n01860,yi\n01861,yi\n01862,yi\n01863,yi\n01864,yi\n01865,yi\n01866,yi\n01867,yi\n01868,yi\n01869,yi\n01870,yi\n01871,yi\n01872,yi\n01873,yi\n01874,yi\n01875,yi\n01876,yi\n01877,yi\n01878,yi\n01879,yi\n01880,yi\n01881,yi\n01882,yi\n01883,yi\n01884,yi\n01885,yi\n01886,yi\n01887,yi\n01888,yi\n01889,yi\n01890,yi\n01891,yi\n01892,yi\n01893,yi\n01894,yi\n01895,yi\n01896,yi\n01897,yi\n01898,yi\n01899,yi\n01900,yi\n01901,yi\n01902,yi\n01903,yi\n01904,yi\n01905,yi\n01906,yi\n01907,yi\n01908,yi\n01909,yi\n01910,yi\n01911,yi\n01912,yi\n01913,yi\n01914,yi\n01915,yi\n01916,yi\n01917,yi\n01918,yi\n01919,yi\n01920,yi\n01921,yi\n01922,yi\n01923,yi\n01924,yi\n01925,yi\n01926,yi\n01927,yi\n01928,yi\n01929,yi\n01930,yi\n01931,yi\n01932,yi\n01933,yi\n01934,yi\n01935,yi\n01936,yi\n01937,yi\n01938,yi\n01939,yi\n01940,yi\n01941,yi\n01942,yi\n01943,yi\n01944,yi\n01945,yi\n01946,yi\n01947,yi\n01948,yi\n01949,yi\n01950,yi\n01951,yi\n01952,yi\n01953,yi\n01954,yi\n01955,yi\n01956,yi\n01957,yi\n01958,yi\n01959,yi\n02000,sin\n02001,sin\n02002,sin\n02003,sin\n02004,sin\n02005,sin\n02006,sin\n02007,sin\n02008,sin\n02009,sin\n02010,sin\n02011,sin\n02012,sin\n02013,sin\n02014,sin\n02015,sin\n02016,sin\n02017,sin\n02018,sin\n02019,sin\n02020,sin\n02021,sin\n02022,sin\n02023,sin\n02024,sin\n02025,sin\n02026,sin\n02027,sin\n02028,sin\n02029,sin\n02030,sin\n02031,sin\n02032,sin\n02033,sin\n02034,sin\n02035,sin\n02036,sin\n02037,sin\n02038,sin\n02039,sin\n02040,sin\n02041,sin\n02042,sin\n02043,sin\n02044,sin\n02045,sin\n02046,sin\n02047,sin\n02048,sin\n02049,sin\n02050,sin\n02051,sin\n02052,sin\n02053,sin\n02054,sin\n02055,sin\n02056,sin\n02057,sin\n02058,sin\n02059,sin\n02060,sin\n02061,sin\n02062,sin\n02063,sin\n02064,sin\n02065,sin\n02066,sin\n02067,sin\n02068,sin\n02069,sin\n02070,sin\n02071,sin\n02072,sin\n02073,sin\n02074,sin\n02075,sin\n02076,sin\n02077,sin\n02078,sin\n02079,sin\n02080,sin\n02081,sin\n02082,sin\n02083,sin\n02084,sin\n02085,sin\n02086,sin\n02087,sin\n02088,sin\n02089,sin\n02090,sin\n02091,sin\n02092,sin\n02093,sin\n02094,sin\n02095,sin\n02096,sin\n02097,sin\n02098,sin\n02099,sin\n02100,sin\n02101,sin\n02102,sin\n02103,sin\n02104,sin\n02105,sin\n02106,sin\n02107,sin\n02108,sin\n02109,sin\n02110,sin\n02111,sin\n02112,sin\n02113,sin\n02114,sin\n02115,sin\n02116,sin\n02117,sin\n02118,sin\n02119,sin\n02120,sin\n02121,sin\n02122,sin\n02123,sin\n02124,sin\n02125,sin\n02126,sin\n02127,sin\n02128,sin\n02129,sin\n02130,sin\n02131,sin\n02132,sin\n02133,sin\n02134,sin\n02135,sin\n02136,sin\n02137,sin\n02138,sin\n02139,sin\n02140,sin\n02141,sin\n02142,sin\n02143,sin\n02144,sin\n02145,sin\n02146,sin\n02147,sin\n02148,sin\n02149,sin\n02150,sin\n02151,sin\n02152,sin\n02153,sin\n02154,sin\n02155,sin\n02156,sin\n02157,sin\n02158,sin\n02159,sin\n02200,ngou\n02201,ngou\n02202,ngou\n02203,ngou\n02204,ngou\n02205,ngou\n02206,ngou\n02207,ngou\n02208,ngou\n02209,ngou\n02210,ngou\n02211,ngou\n02212,ngou\n02213,ngou\n02214,ngou\n02215,ngou\n02216,ngou\n02217,ngou\n02218,ngou\n02219,ngou\n02220,ngou\n02221,ngou\n02222,ngou\n02223,ngou\n02224,ngou\n02225,ngou\n02226,ngou\n02227,ngou\n02228,ngou\n02229,ngou\n02230,ngou\n02231,ngou\n02232,ngou\n02233,ngou\n02234,ngou\n02235,ngou\n02236,ngou\n02237,ngou\n02238,ngou\n02239,ngou\n02240,ngou\n02241,ngou\n02242,ngou\n02243,ngou\n02244,ngou\n02245,ngou\n02246,ngou\n02247,ngou\n02248,ngou\n02249,ngou\n02250,ngou\n02251,ngou\n02252,ngou\n02253,ngou\n02254,ngou\n02255,ngou\n02256,ngou\n02257,ngou\n02258,ngou\n02259,ngou\n02260,ngou\n02261,ngou\n02262,ngou\n02263,ngou\n02264,ngou\n02265,ngou\n02266,ngou\n02267,ngou\n02268,ngou\n02269,ngou\n02270,ngou\n02271,ngou\n02272,ngou\n02273,ngou\n02274,ngou\n02275,ngou\n02276,ngou\n02277,ngou\n02278,ngou\n02279,ngou\n02280,ngou\n02281,ngou\n02282,ngou\n02283,ngou\n02284,ngou\n02285,ngou\n02286,ngou\n02287,ngou\n02288,ngou\n02289,ngou\n02290,ngou\n02291,ngou\n02292,ngou\n02293,ngou\n02294,ngou\n02295,ngou\n02296,ngou\n02297,ngou\n02298,ngou\n02299,ngou\n02300,ngou\n02301,ngou\n02302,ngou\n02303,ngou\n02304,ngou\n02305,ngou\n02306,ngou\n02307,ngou\n02308,ngou\n02309,ngou\n02310,ngou\n02311,ngou\n02312,ngou\n02313,ngou\n02314,ngou\n02315,ngou\n02316,ngou\n02317,ngou\n02318,ngou\n02319,ngou\n02320,ngou\n02321,ngou\n02322,ngou\n02323,ngou\n02324,ngou\n02325,ngou\n02326,ngou\n02327,ngou\n02328,ngou\n02329,ngou\n02330,ngou\n02331,ngou\n02332,ngou\n02333,ngou\n02334,ngou\n02335,ngou\n02336,ngou\n02337,ngou\n02338,ngou\n02339,ngou\n02340,ngou\n02341,ngou\n02342,ngou\n02343,ngou\n02344,ngou\n02345,ngou\n02346,ngou\n02347,ngou\n02348,ngou\n02349,ngou\n02350,ngou\n02351,ngou\n02352,ngou\n02353,ngou\n02354,ngou\n02355,ngou\n02356,ngou\n02357,ngou\n02358,ngou\n02359,ngou\n02400,lai\n02401,lai\n02402,lai\n02403,lai\n02404,lai\n02405,lai\n02406,lai\n02407,lai\n02408,lai\n02409,lai\n02410,lai\n02411,lai\n02412,lai\n02413,lai\n02414,lai\n02415,lai\n02416,lai\n02417,lai\n02418,lai\n02419,lai\n02420,lai\n02421,lai\n02422,lai\n02423,lai\n02424,lai\n02425,lai\n02426,lai\n02427,lai\n02428,lai\n02429,lai\n02430,lai\n02431,lai\n02432,lai\n02433,lai\n02434,lai\n02435,lai\n02436,lai\n02437,lai\n02438,lai\n02439,lai\n02440,lai\n02441,lai\n02442,lai\n02443,lai\n02444,lai\n02445,lai\n02446,lai\n02447,lai\n02448,lai\n02449,lai\n02450,lai\n02451,lai\n02452,lai\n02453,lai\n02454,lai\n02455,lai\n02456,lai\n02457,lai\n02458,lai\n02459,lai\n02460,lai\n02461,lai\n02462,lai\n02463,lai\n02464,lai\n02465,lai\n02466,lai\n02467,lai\n02468,lai\n02469,lai\n02470,lai\n02471,lai\n02472,lai\n02473,lai\n02474,lai\n02475,lai\n02476,lai\n02477,lai\n02478,lai\n02479,lai\n02480,lai\n02481,lai\n02482,lai\n02483,lai\n02484,lai\n02485,lai\n02486,lai\n02487,lai\n02488,lai\n02489,lai\n02490,lai\n02491,lai\n02492,lai\n02493,lai\n02494,lai\n02495,lai\n02496,lai\n02497,lai\n02498,lai\n02499,lai\n02500,lai\n02501,lai\n02502,lai\n02503,lai\n02504,lai\n02505,lai\n02506,lai\n02507,lai\n02508,lai\n02509,lai\n02510,lai\n02511,lai\n02512,lai\n02513,lai\n02514,lai\n02515,lai\n02516,lai\n02517,lai\n02518,lai\n02519,lai\n02520,lai\n02521,lai\n02522,lai\n02523,lai\n02524,lai\n02525,lai\n02526,lai\n02527,lai\n02528,lai\n02529,lai\n02530,lai\n02531,lai\n02532,lai\n02533,lai\n02534,lai\n02535,lai\n02536,lai\n02537,lai\n02538,lai\n02539,lai\n02540,lai\n02541,lai\n02542,lai\n02543,lai\n02544,lai\n02545,lai\n02546,lai\n02547,lai\n02548,lai\n02549,lai\n02550,lai\n02551,lai\n02552,lai\n02553,lai\n02554,lai\n02555,lai\n02556,lai\n02557,lai\n02558,lai\n02559,lai\n"
  },
  {
    "path": "training-character.gh/valLabels.csv",
    "content": "00160,cheung\n00161,cheung\n00162,cheung\n00163,cheung\n00164,cheung\n00165,cheung\n00166,cheung\n00167,cheung\n00168,cheung\n00169,cheung\n00170,cheung\n00171,cheung\n00172,cheung\n00173,cheung\n00174,cheung\n00175,cheung\n00176,cheung\n00177,cheung\n00178,cheung\n00179,cheung\n00180,cheung\n00181,cheung\n00182,cheung\n00183,cheung\n00184,cheung\n00185,cheung\n00186,cheung\n00187,cheung\n00188,cheung\n00189,cheung\n00190,cheung\n00191,cheung\n00192,cheung\n00193,cheung\n00194,cheung\n00195,cheung\n00196,cheung\n00197,cheung\n00198,cheung\n00199,cheung\n00360,chin2\n00361,chin2\n00362,chin2\n00363,chin2\n00364,chin2\n00365,chin2\n00366,chin2\n00367,chin2\n00368,chin2\n00369,chin2\n00370,chin2\n00371,chin2\n00372,chin2\n00373,chin2\n00374,chin2\n00375,chin2\n00376,chin2\n00377,chin2\n00378,chin2\n00379,chin2\n00380,chin2\n00381,chin2\n00382,chin2\n00383,chin2\n00384,chin2\n00385,chin2\n00386,chin2\n00387,chin2\n00388,chin2\n00389,chin2\n00390,chin2\n00391,chin2\n00392,chin2\n00393,chin2\n00394,chin2\n00395,chin2\n00396,chin2\n00397,chin2\n00398,chin2\n00399,chin2\n00560,chiu\n00561,chiu\n00562,chiu\n00563,chiu\n00564,chiu\n00565,chiu\n00566,chiu\n00567,chiu\n00568,chiu\n00569,chiu\n00570,chiu\n00571,chiu\n00572,chiu\n00573,chiu\n00574,chiu\n00575,chiu\n00576,chiu\n00577,chiu\n00578,chiu\n00579,chiu\n00580,chiu\n00581,chiu\n00582,chiu\n00583,chiu\n00584,chiu\n00585,chiu\n00586,chiu\n00587,chiu\n00588,chiu\n00589,chiu\n00590,chiu\n00591,chiu\n00592,chiu\n00593,chiu\n00594,chiu\n00595,chiu\n00596,chiu\n00597,chiu\n00598,chiu\n00599,chiu\n00760,cup\n00761,cup\n00762,cup\n00763,cup\n00764,cup\n00765,cup\n00766,cup\n00767,cup\n00768,cup\n00769,cup\n00770,cup\n00771,cup\n00772,cup\n00773,cup\n00774,cup\n00775,cup\n00776,cup\n00777,cup\n00778,cup\n00779,cup\n00780,cup\n00781,cup\n00782,cup\n00783,cup\n00784,cup\n00785,cup\n00786,cup\n00787,cup\n00788,cup\n00789,cup\n00790,cup\n00791,cup\n00792,cup\n00793,cup\n00794,cup\n00795,cup\n00796,cup\n00797,cup\n00798,cup\n00799,cup\n00960,ho\n00961,ho\n00962,ho\n00963,ho\n00964,ho\n00965,ho\n00966,ho\n00967,ho\n00968,ho\n00969,ho\n00970,ho\n00971,ho\n00972,ho\n00973,ho\n00974,ho\n00975,ho\n00976,ho\n00977,ho\n00978,ho\n00979,ho\n00980,ho\n00981,ho\n00982,ho\n00983,ho\n00984,ho\n00985,ho\n00986,ho\n00987,ho\n00988,ho\n00989,ho\n00990,ho\n00991,ho\n00992,ho\n00993,ho\n00994,ho\n00995,ho\n00996,ho\n00997,ho\n00998,ho\n00999,ho\n01160,ka\n01161,ka\n01162,ka\n01163,ka\n01164,ka\n01165,ka\n01166,ka\n01167,ka\n01168,ka\n01169,ka\n01170,ka\n01171,ka\n01172,ka\n01173,ka\n01174,ka\n01175,ka\n01176,ka\n01177,ka\n01178,ka\n01179,ka\n01180,ka\n01181,ka\n01182,ka\n01183,ka\n01184,ka\n01185,ka\n01186,ka\n01187,ka\n01188,ka\n01189,ka\n01190,ka\n01191,ka\n01192,ka\n01193,ka\n01194,ka\n01195,ka\n01196,ka\n01197,ka\n01198,ka\n01199,ka\n01360,ma\n01361,ma\n01362,ma\n01363,ma\n01364,ma\n01365,ma\n01366,ma\n01367,ma\n01368,ma\n01369,ma\n01370,ma\n01371,ma\n01372,ma\n01373,ma\n01374,ma\n01375,ma\n01376,ma\n01377,ma\n01378,ma\n01379,ma\n01380,ma\n01381,ma\n01382,ma\n01383,ma\n01384,ma\n01385,ma\n01386,ma\n01387,ma\n01388,ma\n01389,ma\n01390,ma\n01391,ma\n01392,ma\n01393,ma\n01394,ma\n01395,ma\n01396,ma\n01397,ma\n01398,ma\n01399,ma\n01560,sheung\n01561,sheung\n01562,sheung\n01563,sheung\n01564,sheung\n01565,sheung\n01566,sheung\n01567,sheung\n01568,sheung\n01569,sheung\n01570,sheung\n01571,sheung\n01572,sheung\n01573,sheung\n01574,sheung\n01575,sheung\n01576,sheung\n01577,sheung\n01578,sheung\n01579,sheung\n01580,sheung\n01581,sheung\n01582,sheung\n01583,sheung\n01584,sheung\n01585,sheung\n01586,sheung\n01587,sheung\n01588,sheung\n01589,sheung\n01590,sheung\n01591,sheung\n01592,sheung\n01593,sheung\n01594,sheung\n01595,sheung\n01596,sheung\n01597,sheung\n01598,sheung\n01599,sheung\n01760,shi\n01761,shi\n01762,shi\n01763,shi\n01764,shi\n01765,shi\n01766,shi\n01767,shi\n01768,shi\n01769,shi\n01770,shi\n01771,shi\n01772,shi\n01773,shi\n01774,shi\n01775,shi\n01776,shi\n01777,shi\n01778,shi\n01779,shi\n01780,shi\n01781,shi\n01782,shi\n01783,shi\n01784,shi\n01785,shi\n01786,shi\n01787,shi\n01788,shi\n01789,shi\n01790,shi\n01791,shi\n01792,shi\n01793,shi\n01794,shi\n01795,shi\n01796,shi\n01797,shi\n01798,shi\n01799,shi\n01960,yi\n01961,yi\n01962,yi\n01963,yi\n01964,yi\n01965,yi\n01966,yi\n01967,yi\n01968,yi\n01969,yi\n01970,yi\n01971,yi\n01972,yi\n01973,yi\n01974,yi\n01975,yi\n01976,yi\n01977,yi\n01978,yi\n01979,yi\n01980,yi\n01981,yi\n01982,yi\n01983,yi\n01984,yi\n01985,yi\n01986,yi\n01987,yi\n01988,yi\n01989,yi\n01990,yi\n01991,yi\n01992,yi\n01993,yi\n01994,yi\n01995,yi\n01996,yi\n01997,yi\n01998,yi\n01999,yi\n02160,sin\n02161,sin\n02162,sin\n02163,sin\n02164,sin\n02165,sin\n02166,sin\n02167,sin\n02168,sin\n02169,sin\n02170,sin\n02171,sin\n02172,sin\n02173,sin\n02174,sin\n02175,sin\n02176,sin\n02177,sin\n02178,sin\n02179,sin\n02180,sin\n02181,sin\n02182,sin\n02183,sin\n02184,sin\n02185,sin\n02186,sin\n02187,sin\n02188,sin\n02189,sin\n02190,sin\n02191,sin\n02192,sin\n02193,sin\n02194,sin\n02195,sin\n02196,sin\n02197,sin\n02198,sin\n02199,sin\n02360,ngou\n02361,ngou\n02362,ngou\n02363,ngou\n02364,ngou\n02365,ngou\n02366,ngou\n02367,ngou\n02368,ngou\n02369,ngou\n02370,ngou\n02371,ngou\n02372,ngou\n02373,ngou\n02374,ngou\n02375,ngou\n02376,ngou\n02377,ngou\n02378,ngou\n02379,ngou\n02380,ngou\n02381,ngou\n02382,ngou\n02383,ngou\n02384,ngou\n02385,ngou\n02386,ngou\n02387,ngou\n02388,ngou\n02389,ngou\n02390,ngou\n02391,ngou\n02392,ngou\n02393,ngou\n02394,ngou\n02395,ngou\n02396,ngou\n02397,ngou\n02398,ngou\n02399,ngou\n02560,lai\n02561,lai\n02562,lai\n02563,lai\n02564,lai\n02565,lai\n02566,lai\n02567,lai\n02568,lai\n02569,lai\n02570,lai\n02571,lai\n02572,lai\n02573,lai\n02574,lai\n02575,lai\n02576,lai\n02577,lai\n02578,lai\n02579,lai\n02580,lai\n02581,lai\n02582,lai\n02583,lai\n02584,lai\n02585,lai\n02586,lai\n02587,lai\n02588,lai\n02589,lai\n02590,lai\n02591,lai\n02592,lai\n02593,lai\n02594,lai\n02595,lai\n02596,lai\n02597,lai\n02598,lai\n02599,lai\n"
  }
]