{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.0"}},"nbformat":4,"nbformat_minor":0,"cells":[{"metadata":{"_cell_guid":"f5503ea1-1927-380e-afc1-7c48b6192eb9","_active":false,"collapsed":false},"source":"# These are all the modules we'll be using later. Make sure you can import them\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nimport os\nimport cv2\n\nTRAIN_DIR = '../input/train/'\n\n# used for scaling/normalization\nIMAGE_SIZE = 128; # 96x96.  Also, 224, 96, 64, and 32 are also common\nCHANNELS = 3\npixel_depth = 255.0  # Number of levels per pixel.\n\n# for small-sample testing\nTRAINING_AND_VALIDATION_SIZE_DOGS = 1000\nTRAINING_AND_VALIDATION_SIZE_CATS = 1000 \nTRAINING_AND_VALIDATION_SIZE_ALL  = 2000\nTRAINING_SIZE = 1600  # TRAINING_SIZE + VALID_SIZE must equal TRAINING_AND_VALIDATION_SIZE_ALL\nVALID_SIZE = 400\n\nif (TRAINING_SIZE + VALID_SIZE != TRAINING_AND_VALIDATION_SIZE_ALL):\n   print (\"Error, check that TRAINING_SIZE+VALID_SIZE is equal to TRAINING_AND_VALIDATION_SIZE_ALL\")\n   exit ()\n\ntrain_images = [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR)] \ntrain_dogs =   [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR) if 'dog' in i]\ntrain_cats =   [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR) if 'cat' in i]\n\ntrain_images = train_dogs[:TRAINING_AND_VALIDATION_SIZE_DOGS] + train_cats[:TRAINING_AND_VALIDATION_SIZE_CATS]\ntrain_labels = np.array ((['dogs'] * TRAINING_AND_VALIDATION_SIZE_DOGS) + (['cats'] * TRAINING_AND_VALIDATION_SIZE_CATS))\n\n# resizes to IMAGE_SIZE/IMAGE_SIZE while keeping aspect ratio the same.  pads on right/bottom as appropriate \ndef read_image(file_path):\n    img = cv2.imread(file_path, cv2.IMREAD_COLOR) #cv2.IMREAD_GRAYSCALE\n    if (img.shape[0] >= img.shape[1]): # height is greater than width\n       resizeto = (IMAGE_SIZE, int (round (IMAGE_SIZE * (float (img.shape[1])  / img.shape[0]))));\n    else:\n       resizeto = (int (round (IMAGE_SIZE * (float (img.shape[0])  / img.shape[1]))), IMAGE_SIZE);\n    \n    img2 = cv2.resize(img, (resizeto[1], resizeto[0]), interpolation=cv2.INTER_CUBIC)\n    img3 = cv2.copyMakeBorder(img2, 0, IMAGE_SIZE - img2.shape[0], 0, IMAGE_SIZE - img2.shape[1], cv2.BORDER_CONSTANT, 0)\n        \n    return img3[:,:,::-1]  # turn into rgb format\n\ndef prep_data(images):\n    count = len(images)\n    data = np.ndarray((count, IMAGE_SIZE, IMAGE_SIZE, CHANNELS), dtype=np.float32)\n\n    for i, image_file in enumerate(images):\n        image = read_image(image_file);\n        image_data = np.array (image, dtype=np.float32);\n        image_data[:,:,0] = (image_data[:,:,0].astype(float) - pixel_depth / 2) / pixel_depth\n        image_data[:,:,1] = (image_data[:,:,1].astype(float) - pixel_depth / 2) / pixel_depth\n        image_data[:,:,2] = (image_data[:,:,2].astype(float) - pixel_depth / 2) / pixel_depth\n        \n        data[i] = image_data; # image_data.T\n        if i%250 == 0: print('Processed {} of {}'.format(i, count))    \n    return data\n\ntrain_normalized = prep_data(train_images)\n\nprint(\"Train shape: {}\".format(train_normalized.shape))\n\nnp.random.seed (133)\ndef randomize(dataset, labels):\n  permutation = np.random.permutation(labels.shape[0])\n  shuffled_dataset = dataset[permutation,:,:,:]\n  shuffled_labels = labels[permutation]\n  return shuffled_dataset, shuffled_labels\n\ntrain_dataset_rand, train_labels_rand = randomize(train_normalized, train_labels)\n\n# split up into training + valid\nvalid_dataset = train_dataset_rand[:VALID_SIZE,:,:,:]\nvalid_labels =   train_labels_rand[:VALID_SIZE]\ntrain_dataset = train_dataset_rand[VALID_SIZE:VALID_SIZE+TRAINING_SIZE,:,:,:]\ntrain_labels  = train_labels_rand[VALID_SIZE:VALID_SIZE+TRAINING_SIZE]\nprint ('Training', train_dataset.shape, train_labels.shape)\nprint ('Validation', valid_dataset.shape, valid_labels.shape)\n\nimport tensorflow as tf\nimage_size = IMAGE_SIZE # TODO: redundant, consolidate\nnum_labels = 2\nnum_channels = 3 # rg\n\ndef reformat(dataset, labels):\n  dataset = dataset.reshape(\n    (-1, image_size, image_size, num_channels)).astype(np.float32)\n  labels = (labels=='cats').astype(np.float32); # set dogs to 0 and cats to 1\n  labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)\n  return dataset, labels\ntrain_dataset, train_labels = reformat(train_dataset, train_labels)\nvalid_dataset, valid_labels = reformat(valid_dataset, valid_labels)\n\nprint ('Training set', train_dataset.shape, train_labels.shape)\nprint ('Validation set', valid_dataset.shape, valid_labels.shape)\n\nbatch_size = 16\npatch_size = 5\ndepth = 16\nnum_hidden = 64\n\ngraph = tf.Graph()\n\nwith graph.as_default():\n\n  # Input data.\n  tf_train_dataset = tf.placeholder(\n    tf.float32, shape=(batch_size, image_size, image_size, num_channels))\n  tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels))\n  tf_valid_dataset = tf.constant(valid_dataset)\n  \n  # Variables.\n  layer1_weights = tf.Variable(tf.truncated_normal(\n      [patch_size, patch_size, num_channels, depth], stddev=0.1))\n  layer1_biases = tf.Variable(tf.zeros([depth]))\n  layer2_weights = tf.Variable(tf.truncated_normal(\n      [patch_size, patch_size, depth, depth], stddev=0.1))\n  layer2_biases = tf.Variable(tf.constant(1.0, shape=[depth]))\n  layer3_weights = tf.Variable(tf.truncated_normal(\n      [int (image_size / 4 * image_size / 4 * depth), num_hidden], stddev=0.1))\n  layer3_biases = tf.Variable(tf.constant(1.0, shape=[num_hidden]))\n  layer4_weights = tf.Variable(tf.truncated_normal(\n      [num_hidden, num_labels], stddev=0.1))\n  layer4_biases = tf.Variable(tf.constant(1.0, shape=[num_labels]))\n  \n  # Model.\n  def model(data):\n    conv = tf.nn.conv2d(data, layer1_weights, [1, 2, 2, 1], padding='SAME')\n    hidden = tf.nn.relu(conv + layer1_biases)\n    conv = tf.nn.conv2d(hidden, layer2_weights, [1, 2, 2, 1], padding='SAME')\n    hidden = tf.nn.relu(conv + layer2_biases)\n    shape = hidden.get_shape().as_list()\n    reshape = tf.reshape(hidden, [shape[0], shape[1] * shape[2] * shape[3]])\n    hidden = tf.nn.relu(tf.matmul(reshape, layer3_weights) + layer3_biases)\n    return tf.matmul(hidden, layer4_weights) + layer4_biases\n  \n  # Training computation.\n  logits = model(tf_train_dataset)\n  loss = tf.reduce_mean(\n    tf.nn.softmax_cross_entropy_with_logits(logits, tf_train_labels))\n    \n  # Optimizer.\n  optimizer = tf.train.GradientDescentOptimizer(0.05).minimize(loss)\n  \n  # Predictions for the training, validation, and test data.\n  train_prediction = tf.nn.softmax(logits)\n  valid_prediction = tf.nn.softmax(model(tf_valid_dataset))\n\ndef accuracy(predictions, labels):\n   return (100.0 * np.sum(np.argmax(predictions, 1) == np.argmax(labels, 1)) / predictions.shape[0])\n\nnum_steps = 1001\nwith tf.Session(graph=graph) as session:\n  tf.global_variables_initializer().run()\n  print (\"Initialized\")\n  for step in range(num_steps):\n    offset = (step * batch_size) % (train_labels.shape[0] - batch_size)\n    batch_data = train_dataset[offset:(offset + batch_size), :, :, :]\n    batch_labels = train_labels[offset:(offset + batch_size), :]\n    feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels}\n    _, l, predictions = session.run(\n      [optimizer, loss, train_prediction], feed_dict=feed_dict)\n    if (step % 50 == 0):\n      print (\"Minibatch loss at step\", step, \":\", l)\n      print (\"Minibatch accuracy: %.1f%%\" % accuracy(predictions, batch_labels))\n      print (\"Validation accuracy: %.1f%%\" % accuracy(valid_prediction.eval(), valid_labels))","execution_count":1,"cell_type":"code","outputs":[],"execution_state":"idle"}]}