1D Mirror Detection Learner

Goal: correctly identify whether an abstract mirror object is within the vision range


In [1]:
import tensorflow as tf
import numpy

Define constants


In [2]:
# image_width = 28
# image_height = 28
# vision_range = image_width * image_height
# category_count = 10
# label_type_count = 2  # mirror or not
# sample_count = {
#     "training": 80,
#     "test": 13,
#     "validation": 7
#     }
# learning_rate = 0.5

In [3]:
image_width = 28
image_height = 28
vision_range = image_width * image_height
category_count = 10
label_type_count = 2  # mirror or not

segment_count = {
    "training": 8,
    "test": 4,
    "validation": 7
    }
sample_count = {
    "training": segment_count['training'] * vision_range,
    "test": segment_count['test'] * vision_range,
    "validation": segment_count['validation'] * vision_range
    }
learning_rate = 0.5

Auxiliary functions

Show result


In [4]:
def show_result(x):
    """Print the result"""
    print("{:.0f}%".format(x * 100))

Automaticaly generate data sets


In [5]:
def mirror_label(x):
    if x is True:
        return [1, 0]
    else:
        return [0, 1]
    
def random_mirror(vision_range, category_count):
    """Return a n-array with either a randomly placed mirror
        or no mirror at all.
    
    Args:
        vision_range (int): how many objects to be seen at a time
        category_count (int): total number of different objects
            including the mirror type
    Return:
        2-tuple:
             [0]: an array of size same as the "vision_range".
             [1]: 1 one-hot 2-array [1, 0] (has mirror) or [0, 1] (no mirror).
    """

    p1 = numpy.random.randint(1, high=category_count, size=vision_range-1)
    p2 = numpy.random.randint(0, category_count, 1)
    data = numpy.random.permutation(numpy.concatenate((p1, p2)))
    return (data, mirror_label(0 in data))

In [6]:
def mirror_data(n, vision_range, category_count):
    """Return a n x size matrix
    Args:
        n (int): number of data points
        vision_range (int): number of objects to be seen at a time
        category_count (int): total number of different object categories
            including the mirror
    Returns:
        A dictionary:
            data: (n, v)-sized 2D numpy array where v is the vision_range
            labels: (n,)-sized 1D numpy array (each element is either 1 or 0)
    """
    raw = [random_mirror(vision_range, category_count) for i in range(n)]
    return {
        "data": numpy.array([x[0] for x in raw]),
        "labels": numpy.array([x[1] for x in raw])
    }

In [7]:
def mirror_data_with_overlap(n, vision_range, category_count):
    """Return a n x size matrix
    Args:
        n (int): number of non-overlapping segments
        vision_range (int): number of objects to be seen at a time
        category_count (int): total number of different object categories
            including the mirror
    Returns:
        A dictionary:
            data: (n, v)-sized 2D numpy array where v is the vision_range
            labels: (n,)-sized 1D numpy array (each element is either 1 or 0)
    """
    
    raw = [random_mirror(vision_range, category_count) for i in range(n)]
    merged = numpy.concatenate([x[0] for x in raw])
    data_set = [merged[i:i+vision_range] for i in range(len(merged)-vision_range)]
    labels = [mirror_label(0 in x) for x in data_set]
    return {
        "data": numpy.array(data_set),
        "labels": labels
    }

Dataset


In [8]:
dataset = {
    "training": mirror_data_with_overlap(segment_count['training'], vision_range, category_count),
    "test": mirror_data_with_overlap(segment_count['test'], vision_range, category_count),
    "validation": mirror_data_with_overlap(segment_count['validation'], vision_range, category_count)
}

Start a TensorFlow session


In [9]:
session = tf.InteractiveSession()

Memory allocation


In [10]:
W = tf.Variable(tf.zeros([vision_range, label_type_count]))

In [11]:
b = tf.Variable(tf.zeros([label_type_count]))

In [12]:
x = tf.placeholder(tf.float32, [None, vision_range])

In [13]:
y_ = tf.placeholder(tf.float32, [None, label_type_count])

In [14]:
session.run(tf.global_variables_initializer())

Predictions and losses


In [15]:
y = tf.matmul(x, W) + b

Convolutionary Neural Net

Weight Initialization


In [16]:
def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

In [17]:
def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)

In [18]:
def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding="SAME")

In [19]:
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                         strides=[1, 2, 2, 1],
                         padding="SAME")

In [20]:
W_conv1 = weight_variable([5, 5, 1, 32])

In [21]:
b_conv1 = bias_variable([32])

In [22]:
x_image = tf.reshape(x, [-1, image_width, image_height, 1])

In [23]:
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) +  b_conv1)

In [24]:
h_pool1 = max_pool_2x2(h_conv1)

Second Convolutional Layer


In [25]:
W_conv2 = weight_variable([5, 5, 32, 64])

In [26]:
b_conv2 = bias_variable([64])

In [27]:
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) +  b_conv2)

In [28]:
h_pool2 = max_pool_2x2(h_conv2)

Densely connected layer


In [29]:
W_fc1 = weight_variable([7 * 7 *64, 1024])
b_fc1 = bias_variable([1024])

In [30]:
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 *64])

In [31]:
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

Dropout


In [32]:
keep_prob = tf.placeholder(tf.float32)

In [33]:
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

Readout layer


In [34]:
W_fc2 = weight_variable([1024, label_type_count])

In [35]:
b_fc2 = bias_variable([label_type_count])

In [36]:
y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2

Training and evaluation


In [37]:
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_conv, y_))

In [38]:
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

In [39]:
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))

In [40]:
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

In [41]:
session.run(tf.global_variables_initializer())

In [42]:
train_accuracy = accuracy.eval(
    feed_dict={x: dataset['training']['data'], y_: dataset['training']['labels'], keep_prob: 1.0})

In [43]:
train_step.run(feed_dict={x: dataset['training']['data'], y_: dataset['training']['labels'], 
                         keep_prob: 1.0})


---------------------------------------------------------------------------
ResourceExhaustedError                    Traceback (most recent call last)
D:\install\Miniconda\lib\site-packages\tensorflow\python\client\session.py in _do_call(self, fn, *args)
   1020     try:
-> 1021       return fn(*args)
   1022     except errors.OpError as e:

D:\install\Miniconda\lib\site-packages\tensorflow\python\client\session.py in _run_fn(session, feed_dict, fetch_list, target_list, options, run_metadata)
   1002                                  feed_dict, fetch_list, target_list,
-> 1003                                  status, run_metadata)
   1004 

D:\install\Miniconda\lib\contextlib.py in __exit__(self, type, value, traceback)
     65             try:
---> 66                 next(self.gen)
     67             except StopIteration:

D:\install\Miniconda\lib\site-packages\tensorflow\python\framework\errors_impl.py in raise_exception_on_not_ok_status()
    468           compat.as_text(pywrap_tensorflow.TF_Message(status)),
--> 469           pywrap_tensorflow.TF_GetCode(status))
    470   finally:

ResourceExhaustedError: OOM when allocating tensor with shape[5488,64,7,7]
	 [[Node: gradients/MaxPool_1_grad/MaxPoolGrad = MaxPoolGrad[T=DT_FLOAT, data_format="NHWC", ksize=[1, 2, 2, 1], padding="SAME", strides=[1, 2, 2, 1], _device="/job:localhost/replica:0/task:0/gpu:0"](Relu_1, MaxPool_1, gradients/Reshape_1_grad/Reshape)]]

During handling of the above exception, another exception occurred:

ResourceExhaustedError                    Traceback (most recent call last)
<ipython-input-43-2e674d617875> in <module>()
      1 train_step.run(feed_dict={x: dataset['training']['data'], y_: dataset['training']['labels'], 
----> 2                          keep_prob: 1.0})

D:\install\Miniconda\lib\site-packages\tensorflow\python\framework\ops.py in run(self, feed_dict, session)
   1447         none, the default session will be used.
   1448     """
-> 1449     _run_using_default_session(self, feed_dict, self.graph, session)
   1450 
   1451 

D:\install\Miniconda\lib\site-packages\tensorflow\python\framework\ops.py in _run_using_default_session(operation, feed_dict, graph, session)
   3666                        "the operation's graph is different from the session's "
   3667                        "graph.")
-> 3668   session.run(operation, feed_dict)
   3669 
   3670 

D:\install\Miniconda\lib\site-packages\tensorflow\python\client\session.py in run(self, fetches, feed_dict, options, run_metadata)
    764     try:
    765       result = self._run(None, fetches, feed_dict, options_ptr,
--> 766                          run_metadata_ptr)
    767       if run_metadata:
    768         proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

D:\install\Miniconda\lib\site-packages\tensorflow\python\client\session.py in _run(self, handle, fetches, feed_dict, options, run_metadata)
    962     if final_fetches or final_targets:
    963       results = self._do_run(handle, final_targets, final_fetches,
--> 964                              feed_dict_string, options, run_metadata)
    965     else:
    966       results = []

D:\install\Miniconda\lib\site-packages\tensorflow\python\client\session.py in _do_run(self, handle, target_list, fetch_list, feed_dict, options, run_metadata)
   1012     if handle is None:
   1013       return self._do_call(_run_fn, self._session, feed_dict, fetch_list,
-> 1014                            target_list, options, run_metadata)
   1015     else:
   1016       return self._do_call(_prun_fn, self._session, handle, feed_dict,

D:\install\Miniconda\lib\site-packages\tensorflow\python\client\session.py in _do_call(self, fn, *args)
   1032         except KeyError:
   1033           pass
-> 1034       raise type(e)(node_def, op, message)
   1035 
   1036   def _extend_graph(self):

ResourceExhaustedError: OOM when allocating tensor with shape[5488,64,7,7]
	 [[Node: gradients/MaxPool_1_grad/MaxPoolGrad = MaxPoolGrad[T=DT_FLOAT, data_format="NHWC", ksize=[1, 2, 2, 1], padding="SAME", strides=[1, 2, 2, 1], _device="/job:localhost/replica:0/task:0/gpu:0"](Relu_1, MaxPool_1, gradients/Reshape_1_grad/Reshape)]]

Caused by op 'gradients/MaxPool_1_grad/MaxPoolGrad', defined at:
  File "D:\install\Miniconda\lib\runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
  File "D:\install\Miniconda\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "D:\install\Miniconda\lib\site-packages\ipykernel\__main__.py", line 3, in <module>
    app.launch_new_instance()
  File "D:\install\Miniconda\lib\site-packages\traitlets\config\application.py", line 596, in launch_instance
    app.start()
  File "D:\install\Miniconda\lib\site-packages\ipykernel\kernelapp.py", line 442, in start
    ioloop.IOLoop.instance().start()
  File "D:\install\Miniconda\lib\site-packages\zmq\eventloop\ioloop.py", line 162, in start
    super(ZMQIOLoop, self).start()
  File "D:\install\Miniconda\lib\site-packages\tornado\ioloop.py", line 883, in start
    handler_func(fd_obj, events)
  File "D:\install\Miniconda\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
    return fn(*args, **kwargs)
  File "D:\install\Miniconda\lib\site-packages\zmq\eventloop\zmqstream.py", line 440, in _handle_events
    self._handle_recv()
  File "D:\install\Miniconda\lib\site-packages\zmq\eventloop\zmqstream.py", line 472, in _handle_recv
    self._run_callback(callback, msg)
  File "D:\install\Miniconda\lib\site-packages\zmq\eventloop\zmqstream.py", line 414, in _run_callback
    callback(*args, **kwargs)
  File "D:\install\Miniconda\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
    return fn(*args, **kwargs)
  File "D:\install\Miniconda\lib\site-packages\ipykernel\kernelbase.py", line 276, in dispatcher
    return self.dispatch_shell(stream, msg)
  File "D:\install\Miniconda\lib\site-packages\ipykernel\kernelbase.py", line 228, in dispatch_shell
    handler(stream, idents, msg)
  File "D:\install\Miniconda\lib\site-packages\ipykernel\kernelbase.py", line 391, in execute_request
    user_expressions, allow_stdin)
  File "D:\install\Miniconda\lib\site-packages\ipykernel\ipkernel.py", line 199, in do_execute
    shell.run_cell(code, store_history=store_history, silent=silent)
  File "D:\install\Miniconda\lib\site-packages\IPython\core\interactiveshell.py", line 2705, in run_cell
    interactivity=interactivity, compiler=compiler, result=result)
  File "D:\install\Miniconda\lib\site-packages\IPython\core\interactiveshell.py", line 2809, in run_ast_nodes
    if self.run_code(code, result):
  File "D:\install\Miniconda\lib\site-packages\IPython\core\interactiveshell.py", line 2869, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-38-49ab7eb67a28>", line 1, in <module>
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\training\optimizer.py", line 269, in minimize
    grad_loss=grad_loss)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\training\optimizer.py", line 335, in compute_gradients
    colocate_gradients_with_ops=colocate_gradients_with_ops)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\ops\gradients_impl.py", line 482, in gradients
    in_grads = grad_fn(op, *out_grads)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\ops\nn_grad.py", line 404, in _MaxPoolGrad
    data_format=op.get_attr("data_format"))
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\ops\gen_nn_ops.py", line 1697, in _max_pool_grad
    data_format=data_format, name=name)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 759, in apply_op
    op_def=op_def)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\framework\ops.py", line 2240, in create_op
    original_op=self._default_original_op, op_def=op_def)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\framework\ops.py", line 1128, in __init__
    self._traceback = _extract_stack()

...which was originally created as op 'MaxPool_1', defined at:
  File "D:\install\Miniconda\lib\runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
[elided 17 identical lines from previous traceback]
  File "D:\install\Miniconda\lib\site-packages\IPython\core\interactiveshell.py", line 2869, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-28-174e94f6b9dd>", line 1, in <module>
    h_pool2 = max_pool_2x2(h_conv2)
  File "<ipython-input-19-4973371641a4>", line 4, in max_pool_2x2
    padding="SAME")
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 1617, in max_pool
    name=name)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\ops\gen_nn_ops.py", line 1598, in _max_pool
    data_format=data_format, name=name)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 759, in apply_op
    op_def=op_def)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\framework\ops.py", line 2240, in create_op
    original_op=self._default_original_op, op_def=op_def)
  File "D:\install\Miniconda\lib\site-packages\tensorflow\python\framework\ops.py", line 1128, in __init__
    self._traceback = _extract_stack()

ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[5488,64,7,7]
	 [[Node: gradients/MaxPool_1_grad/MaxPoolGrad = MaxPoolGrad[T=DT_FLOAT, data_format="NHWC", ksize=[1, 2, 2, 1], padding="SAME", strides=[1, 2, 2, 1], _device="/job:localhost/replica:0/task:0/gpu:0"](Relu_1, MaxPool_1, gradients/Reshape_1_grad/Reshape)]]

Test


In [ ]:
test_accuracy = accuracy.eval(feed_dict={
        x: dataset['test']['data'],
        y_: dataset['test']['labels'],
        keep_prob: 1.0
    })

In [ ]:
show_result(test_accuracy)

Validation


In [ ]:
validation_accuracy = accuracy.eval(
    feed_dict={
        x: dataset['validation']['data'],
        y_: dataset['validation']['labels'],
        keep_prob: 1.0
    }
)

In [ ]:
show_result(validation_accuracy)

In [ ]: