- TensorFlow Machine Learning Cookbook
- Nick McClure
- 756字
- 2021-04-09 23:30:57
Working with Multiple Layers
Now that we have covered multiple operations, we will cover how to connect various layers that have data propagating through them.
Getting ready
In this recipe, we will introduce how to best connect various layers, including custom layers. The data we will generate and use will be representative of small random images. It is best to understand these types of operation on a simple example and how we can use some built-in layers to perform calculations. We will perform a small moving window average across a 2D image and then flow the resulting output through a custom operation layer.
In this section, we will see that the computational graph can get large and hard to look at. To address this, we will also introduce ways to name operations and create scopes for layers. To start, load numpy
and tensorflow
and create a graph, using the following:
import tensorflow as tf import numpy as np sess = tf.Session()
How to do it…
- First we create our sample 2D image with
numpy
. This image will be a 4x4 pixel image. We will create it in four dimensions; the first and last dimension will have a size of one. Note that some TensorFlow image functions will operate on four-dimensional images. Those four dimensions are image number, height, width, and channel, and to make it one image with one channel, we set two of the dimensions to 1, as follows:x_shape = [1, 4, 4, 1] x_val = np.random.uniform(size=x_shape)
- Now we have to create the placeholder in our graph where we can feed in the sample image, as follows:
x_data = tf.placeholder(tf.float32, shape=x_shape)
- To create a moving window average across our 4x4 image, we will use a built-in function that will convolute a constant across a window of the shape 2x2. This function is quite common to use in image processing and in TensorFlow, the function we will use is
conv2d()
. This function takes a piecewise product of the window and a filter we specify. We must also specify a stride for the moving window in both directions. Here we will compute four moving window averages, the top left, top right, bottom left, and bottom right four pixels. We do this by creating a 2x2 window and having strides of length 2 in each direction. To take the average, we will convolute the 2x2 window with a constant of0.25
., as follows:my_filter = tf.constant(0.25, shape=[2, 2, 1, 1]) my_strides = [1, 2, 2, 1] mov_avg_layer= tf.nn.conv2d(x_data, my_filter, my_strides, padding='SAME''', name='Moving'_Avg_Window')
- Note that we are also naming this layer
Moving_Avg_Window
by using the name argument of the function. - Now we define a custom layer that will operate on the 2x2 output of the moving window average. The custom function will first multiply the input by another 2x2 matrix tensor, and then add one to each entry. After this we take the
sigmoid
of each element and return the 2x2 matrix. Since matrix multiplication only operates on two-dimensional matrices, we need to drop the extra dimensions of our image that are of size 1. TensorFlow can do this with the built-in functionsqueeze()
. Here we define the new layer:def custom_layer(input_matrix): input_matrix_sqeezed = tf.squeeze(input_matrix) A = tf.constant([[1., 2.], [-1., 3.]]) b = tf.constant(1., shape=[2, 2]) temp1 = tf.matmul(A, input_matrix_sqeezed) temp = tf.add(temp1, b) # Ax + b return(tf.sigmoid(temp))
- Now we have to place the new layer on the graph. We will do this with a named scope so that it is identifiable and collapsible/expandable on the computational graph, as follows:
with tf.name_scope('Custom_Layer') as scope: custom_layer1 = custom_layer(mov_avg_layer)
- Now we just feed in the 4x4 image in the placeholder and tell TensorFlow to run the graph, as follows:
print(sess.run(custom_layer1, feed_dict={x_data: x_val})) [[ 0.91914582 0.96025133] [ 0.87262219 0.9469803 ]]