Convolutional Autoencoder

Sticking with the MNIST dataset, let's improve our autoencoder's performance using convolutional layers. Again, loading modules and the data.


In [1]:
%matplotlib inline

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

In [2]:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', validation_size=0)


Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz

In [5]:
img = mnist.train.images[2]
plt.imshow(img.reshape((28, 28)), cmap='Greys_r')

print(mnist.train.images.shape[1])


784

Network Architecture

The encoder part of the network will be a typical convolutional pyramid. Each convolutional layer will be followed by a max-pooling layer to reduce the dimensions of the layers. The decoder though might be something new to you. The decoder needs to convert from a narrow representation to a wide reconstructed image. For example, the representation could be a 4x4x8 max-pool layer. This is the output of the encoder, but also the input to the decoder. We want to get a 28x28x1 image out from the decoder so we need to work our way back up from the narrow decoder input layer. A schematic of the network is shown below.

Here our final encoder layer has size 4x4x8 = 128. The original images have size 28x28 = 784, so the encoded vector is roughly 16% the size of the original image. These are just suggested sizes for each of the layers. Feel free to change the depths and sizes, but remember our goal here is to find a small representation of the input data.

What's going on with the decoder

Okay, so the decoder has these "Upsample" layers that you might not have seen before. First off, I'll discuss a bit what these layers aren't. Usually, you'll see transposed convolution layers used to increase the width and height of the layers. They work almost exactly the same as convolutional layers, but in reverse. A stride in the input layer results in a larger stride in the transposed convolution layer. For example, if you have a 3x3 kernel, a 3x3 patch in the input layer will be reduced to one unit in a convolutional layer. Comparatively, one unit in the input layer will be expanded to a 3x3 path in a transposed convolution layer. The TensorFlow API provides us with an easy way to create the layers, tf.nn.conv2d_transpose.

However, transposed convolution layers can lead to artifacts in the final images, such as checkerboard patterns. This is due to overlap in the kernels which can be avoided by setting the stride and kernel size equal. In this Distill article from Augustus Odena, et al, the authors show that these checkerboard artifacts can be avoided by resizing the layers using nearest neighbor or bilinear interpolation (upsampling) followed by a convolutional layer. In TensorFlow, this is easily done with tf.image.resize_images, followed by a convolution. Be sure to read the Distill article to get a better understanding of deconvolutional layers and why we're using upsampling.

Exercise: Build the network shown above. Remember that a convolutional layer with strides of 1 and 'same' padding won't reduce the height and width. That is, if the input is 28x28 and the convolution layer has stride = 1 and 'same' padding, the convolutional layer will also be 28x28. The max-pool layers are used the reduce the width and height. A stride of 2 will reduce the size by 2. Odena et al claim that nearest neighbor interpolation works best for the upsampling, so make sure to include that as a parameter in tf.image.resize_images or use tf.image.resize_nearest_neighbor. For convolutional layers, use tf.layers.conv2d. For example, you would write conv1 = tf.layers.conv2d(inputs, 32, (5,5), padding='same', activation=tf.nn.relu) for a layer with a depth of 32, a 5x5 kernel, stride of (1,1), padding is 'same', and a ReLU activation. Similarly, for the max-pool layers, use tf.layers.max_pooling2d.


In [11]:
learning_rate = 0.001
# Input and target placeholders
image_size = mnist.train.images.shape[1]

inputs_ = tf.placeholder(tf.float32, shape=[None, 28, 28, 1])
targets_ = tf.placeholder(tf.float32, shape=[None, 28, 28, 1])

### Encoder
conv1 = tf.layers.conv2d(inputs_, 16, (3,3), padding='same', activation=tf.nn.relu)
# Now 28x28x16
maxpool1 = tf.layers.max_pooling2d(conv1, (2,2), (2,2), padding='same')
# Now 14x14x16
conv2 = tf.layers.conv2d(maxpool1, 8, (3,3), padding='same', activation=tf.nn.relu)
# Now 14x14x8
maxpool2 = tf.layers.max_pooling2d(conv2, (2,2), (2,2), padding='same')
# Now 7x7x8
conv3 = tf.layers.conv2d(maxpool2, 8, (3,3), padding='same', activation=tf.nn.relu)
# Now 7x7x8
encoded = tf.layers.max_pooling2d(conv3, (2,2), (2,2), padding='same')
# Now 4x4x8

### Decoder
upsample1 = tf.image.resize_nearest_neighbor(encoded, (7,7))
# Now 7x7x8
conv4 = tf.layers.conv2d(upsample1, 8, (3,3), padding='same', activation=tf.nn.relu)
# Now 7x7x8
upsample2 = tf.image.resize_nearest_neighbor(conv4, (14,14))
# Now 14x14x8
conv5 = tf.layers.conv2d(upsample2, 8, (3,3), padding='same', activation=tf.nn.relu)
# Now 14x14x8
upsample3 = tf.image.resize_nearest_neighbor(conv5, (28,28))
# Now 28x28x8
conv6 = tf.layers.conv2d(upsample3, 16, (3,3), padding='same', activation=tf.nn.relu)
# Now 28x28x16

logits = tf.layers.conv2d(conv6, 1, (3,3), padding='same', activation=None)
#Now 28x28x1

# Pass logits through sigmoid to get reconstructed image
decoded = tf.nn.sigmoid(logits, name='decoded')

# Pass logits through sigmoid and calculate the cross-entropy loss
loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=targets_, logits=logits)

# Get cost and define the optimizer
cost = tf.reduce_mean(loss)
opt = tf.train.AdamOptimizer(0.001).minimize(cost)

Training

As before, here we'll train the network. Instead of flattening the images though, we can pass them in as 28x28x1 arrays.


In [12]:
sess = tf.Session()

In [ ]:
epochs = 20
batch_size = 200
sess.run(tf.global_variables_initializer())
for e in range(epochs):
    for ii in range(mnist.train.num_examples//batch_size):
        batch = mnist.train.next_batch(batch_size)
        imgs = batch[0].reshape((-1, 28, 28, 1))
        batch_cost, _ = sess.run([cost, opt], feed_dict={inputs_: imgs,
                                                         targets_: imgs})

        print("Epoch: {}/{}...".format(e+1, epochs),
              "Training loss: {:.4f}".format(batch_cost))


Epoch: 1/20... Training loss: 0.6878
Epoch: 1/20... Training loss: 0.6825
Epoch: 1/20... Training loss: 0.6765
Epoch: 1/20... Training loss: 0.6685
Epoch: 1/20... Training loss: 0.6594
Epoch: 1/20... Training loss: 0.6476
Epoch: 1/20... Training loss: 0.6352
Epoch: 1/20... Training loss: 0.6198
Epoch: 1/20... Training loss: 0.6029
Epoch: 1/20... Training loss: 0.5835
Epoch: 1/20... Training loss: 0.5653
Epoch: 1/20... Training loss: 0.5461
Epoch: 1/20... Training loss: 0.5318
Epoch: 1/20... Training loss: 0.5228
Epoch: 1/20... Training loss: 0.5196
Epoch: 1/20... Training loss: 0.5288
Epoch: 1/20... Training loss: 0.5457
Epoch: 1/20... Training loss: 0.5372
Epoch: 1/20... Training loss: 0.5354
Epoch: 1/20... Training loss: 0.5103
Epoch: 1/20... Training loss: 0.5055
Epoch: 1/20... Training loss: 0.4951
Epoch: 1/20... Training loss: 0.4853
Epoch: 1/20... Training loss: 0.4921
Epoch: 1/20... Training loss: 0.4893
Epoch: 1/20... Training loss: 0.4748
Epoch: 1/20... Training loss: 0.4739
Epoch: 1/20... Training loss: 0.4728
Epoch: 1/20... Training loss: 0.4643
Epoch: 1/20... Training loss: 0.4594
Epoch: 1/20... Training loss: 0.4505
Epoch: 1/20... Training loss: 0.4489
Epoch: 1/20... Training loss: 0.4320
Epoch: 1/20... Training loss: 0.4192
Epoch: 1/20... Training loss: 0.4298
Epoch: 1/20... Training loss: 0.4160
Epoch: 1/20... Training loss: 0.4122
Epoch: 1/20... Training loss: 0.4047
Epoch: 1/20... Training loss: 0.3979
Epoch: 1/20... Training loss: 0.3862
Epoch: 1/20... Training loss: 0.3762
Epoch: 1/20... Training loss: 0.3687
Epoch: 1/20... Training loss: 0.3581
Epoch: 1/20... Training loss: 0.3520
Epoch: 1/20... Training loss: 0.3464
Epoch: 1/20... Training loss: 0.3424
Epoch: 1/20... Training loss: 0.3181
Epoch: 1/20... Training loss: 0.3139
Epoch: 1/20... Training loss: 0.3128
Epoch: 1/20... Training loss: 0.3015
Epoch: 1/20... Training loss: 0.3090
Epoch: 1/20... Training loss: 0.2959
Epoch: 1/20... Training loss: 0.2861
Epoch: 1/20... Training loss: 0.2864
Epoch: 1/20... Training loss: 0.2767
Epoch: 1/20... Training loss: 0.2684
Epoch: 1/20... Training loss: 0.2698
Epoch: 1/20... Training loss: 0.2666
Epoch: 1/20... Training loss: 0.2600
Epoch: 1/20... Training loss: 0.2531
Epoch: 1/20... Training loss: 0.2580
Epoch: 1/20... Training loss: 0.2541
Epoch: 1/20... Training loss: 0.2588
Epoch: 1/20... Training loss: 0.2431
Epoch: 1/20... Training loss: 0.2410
Epoch: 1/20... Training loss: 0.2422
Epoch: 1/20... Training loss: 0.2341
Epoch: 1/20... Training loss: 0.2373
Epoch: 1/20... Training loss: 0.2392
Epoch: 1/20... Training loss: 0.2346
Epoch: 1/20... Training loss: 0.2278
Epoch: 1/20... Training loss: 0.2269
Epoch: 1/20... Training loss: 0.2244
Epoch: 1/20... Training loss: 0.2189
Epoch: 1/20... Training loss: 0.2275
Epoch: 1/20... Training loss: 0.2180
Epoch: 1/20... Training loss: 0.2196
Epoch: 1/20... Training loss: 0.2289
Epoch: 1/20... Training loss: 0.2222
Epoch: 1/20... Training loss: 0.2147
Epoch: 1/20... Training loss: 0.2244
Epoch: 1/20... Training loss: 0.2128
Epoch: 1/20... Training loss: 0.2222
Epoch: 1/20... Training loss: 0.2163
Epoch: 1/20... Training loss: 0.2113
Epoch: 1/20... Training loss: 0.2105
Epoch: 1/20... Training loss: 0.2101
Epoch: 1/20... Training loss: 0.2077
Epoch: 1/20... Training loss: 0.2105
Epoch: 1/20... Training loss: 0.2078
Epoch: 1/20... Training loss: 0.2087
Epoch: 1/20... Training loss: 0.2100
Epoch: 1/20... Training loss: 0.2103
Epoch: 1/20... Training loss: 0.2061
Epoch: 1/20... Training loss: 0.2098
Epoch: 1/20... Training loss: 0.2017
Epoch: 1/20... Training loss: 0.2042
Epoch: 1/20... Training loss: 0.2028
Epoch: 1/20... Training loss: 0.2043
Epoch: 1/20... Training loss: 0.2038
Epoch: 1/20... Training loss: 0.1997
Epoch: 1/20... Training loss: 0.1956
Epoch: 1/20... Training loss: 0.1980
Epoch: 1/20... Training loss: 0.1912
Epoch: 1/20... Training loss: 0.1926
Epoch: 1/20... Training loss: 0.2037
Epoch: 1/20... Training loss: 0.1983
Epoch: 1/20... Training loss: 0.1935
Epoch: 1/20... Training loss: 0.1899
Epoch: 1/20... Training loss: 0.1935
Epoch: 1/20... Training loss: 0.1988
Epoch: 1/20... Training loss: 0.1973
Epoch: 1/20... Training loss: 0.1940
Epoch: 1/20... Training loss: 0.1876
Epoch: 1/20... Training loss: 0.1886
Epoch: 1/20... Training loss: 0.1942
Epoch: 1/20... Training loss: 0.1933
Epoch: 1/20... Training loss: 0.1954
Epoch: 1/20... Training loss: 0.1913
Epoch: 1/20... Training loss: 0.1919
Epoch: 1/20... Training loss: 0.1924
Epoch: 1/20... Training loss: 0.1902
Epoch: 1/20... Training loss: 0.1909
Epoch: 1/20... Training loss: 0.1903
Epoch: 1/20... Training loss: 0.1961
Epoch: 1/20... Training loss: 0.1907
Epoch: 1/20... Training loss: 0.1875
Epoch: 1/20... Training loss: 0.1875
Epoch: 1/20... Training loss: 0.1823
Epoch: 1/20... Training loss: 0.1882
Epoch: 1/20... Training loss: 0.1919
Epoch: 1/20... Training loss: 0.1904
Epoch: 1/20... Training loss: 0.1881
Epoch: 1/20... Training loss: 0.1897
Epoch: 1/20... Training loss: 0.1858
Epoch: 1/20... Training loss: 0.1897
Epoch: 1/20... Training loss: 0.1905
Epoch: 1/20... Training loss: 0.1852
Epoch: 1/20... Training loss: 0.1806
Epoch: 1/20... Training loss: 0.1790
Epoch: 1/20... Training loss: 0.1872
Epoch: 1/20... Training loss: 0.1858
Epoch: 1/20... Training loss: 0.1871
Epoch: 1/20... Training loss: 0.1840
Epoch: 1/20... Training loss: 0.1846
Epoch: 1/20... Training loss: 0.1835
Epoch: 1/20... Training loss: 0.1840
Epoch: 1/20... Training loss: 0.1850
Epoch: 1/20... Training loss: 0.1871
Epoch: 1/20... Training loss: 0.1813
Epoch: 1/20... Training loss: 0.1824
Epoch: 1/20... Training loss: 0.1779
Epoch: 1/20... Training loss: 0.1818
Epoch: 1/20... Training loss: 0.1872
Epoch: 1/20... Training loss: 0.1765
Epoch: 1/20... Training loss: 0.1804
Epoch: 1/20... Training loss: 0.1824
Epoch: 1/20... Training loss: 0.1791
Epoch: 1/20... Training loss: 0.1708
Epoch: 1/20... Training loss: 0.1797
Epoch: 1/20... Training loss: 0.1770
Epoch: 1/20... Training loss: 0.1733
Epoch: 1/20... Training loss: 0.1764
Epoch: 1/20... Training loss: 0.1841
Epoch: 1/20... Training loss: 0.1782
Epoch: 1/20... Training loss: 0.1761
Epoch: 1/20... Training loss: 0.1825
Epoch: 1/20... Training loss: 0.1808
Epoch: 1/20... Training loss: 0.1821
Epoch: 1/20... Training loss: 0.1777
Epoch: 1/20... Training loss: 0.1802
Epoch: 1/20... Training loss: 0.1754
Epoch: 1/20... Training loss: 0.1814
Epoch: 1/20... Training loss: 0.1760
Epoch: 1/20... Training loss: 0.1757
Epoch: 1/20... Training loss: 0.1769
Epoch: 1/20... Training loss: 0.1750
Epoch: 1/20... Training loss: 0.1782
Epoch: 1/20... Training loss: 0.1776
Epoch: 1/20... Training loss: 0.1798
Epoch: 1/20... Training loss: 0.1791
Epoch: 1/20... Training loss: 0.1769
Epoch: 1/20... Training loss: 0.1711
Epoch: 1/20... Training loss: 0.1751
Epoch: 1/20... Training loss: 0.1747
Epoch: 1/20... Training loss: 0.1836
Epoch: 1/20... Training loss: 0.1759
Epoch: 1/20... Training loss: 0.1797
Epoch: 1/20... Training loss: 0.1771
Epoch: 1/20... Training loss: 0.1775
Epoch: 1/20... Training loss: 0.1734
Epoch: 1/20... Training loss: 0.1745
Epoch: 1/20... Training loss: 0.1742
Epoch: 1/20... Training loss: 0.1747
Epoch: 1/20... Training loss: 0.1747
Epoch: 1/20... Training loss: 0.1743
Epoch: 1/20... Training loss: 0.1726
Epoch: 1/20... Training loss: 0.1746
Epoch: 1/20... Training loss: 0.1667
Epoch: 1/20... Training loss: 0.1717
Epoch: 1/20... Training loss: 0.1729
Epoch: 1/20... Training loss: 0.1663
Epoch: 1/20... Training loss: 0.1742
Epoch: 1/20... Training loss: 0.1768
Epoch: 1/20... Training loss: 0.1712
Epoch: 1/20... Training loss: 0.1707
Epoch: 1/20... Training loss: 0.1760
Epoch: 1/20... Training loss: 0.1659
Epoch: 1/20... Training loss: 0.1732
Epoch: 1/20... Training loss: 0.1668
Epoch: 1/20... Training loss: 0.1633
Epoch: 1/20... Training loss: 0.1721
Epoch: 1/20... Training loss: 0.1733
Epoch: 1/20... Training loss: 0.1707
Epoch: 1/20... Training loss: 0.1715
Epoch: 1/20... Training loss: 0.1685
Epoch: 1/20... Training loss: 0.1748
Epoch: 1/20... Training loss: 0.1635
Epoch: 1/20... Training loss: 0.1705
Epoch: 1/20... Training loss: 0.1652
Epoch: 1/20... Training loss: 0.1660
Epoch: 1/20... Training loss: 0.1683
Epoch: 1/20... Training loss: 0.1676
Epoch: 1/20... Training loss: 0.1666
Epoch: 1/20... Training loss: 0.1669
Epoch: 1/20... Training loss: 0.1642
Epoch: 1/20... Training loss: 0.1672
Epoch: 1/20... Training loss: 0.1640
Epoch: 1/20... Training loss: 0.1589
Epoch: 1/20... Training loss: 0.1651
Epoch: 1/20... Training loss: 0.1679
Epoch: 1/20... Training loss: 0.1685
Epoch: 1/20... Training loss: 0.1704
Epoch: 1/20... Training loss: 0.1613
Epoch: 1/20... Training loss: 0.1650
Epoch: 1/20... Training loss: 0.1644
Epoch: 1/20... Training loss: 0.1678
Epoch: 1/20... Training loss: 0.1642
Epoch: 1/20... Training loss: 0.1601
Epoch: 1/20... Training loss: 0.1640
Epoch: 1/20... Training loss: 0.1596
Epoch: 1/20... Training loss: 0.1682
Epoch: 1/20... Training loss: 0.1681
Epoch: 1/20... Training loss: 0.1604
Epoch: 1/20... Training loss: 0.1626
Epoch: 1/20... Training loss: 0.1684
Epoch: 1/20... Training loss: 0.1608
Epoch: 1/20... Training loss: 0.1632
Epoch: 1/20... Training loss: 0.1593
Epoch: 1/20... Training loss: 0.1651
Epoch: 1/20... Training loss: 0.1677
Epoch: 1/20... Training loss: 0.1583
Epoch: 1/20... Training loss: 0.1656
Epoch: 1/20... Training loss: 0.1634
Epoch: 1/20... Training loss: 0.1650
Epoch: 1/20... Training loss: 0.1584
Epoch: 1/20... Training loss: 0.1591
Epoch: 1/20... Training loss: 0.1611
Epoch: 1/20... Training loss: 0.1622
Epoch: 1/20... Training loss: 0.1618
Epoch: 1/20... Training loss: 0.1628
Epoch: 1/20... Training loss: 0.1603
Epoch: 1/20... Training loss: 0.1594
Epoch: 1/20... Training loss: 0.1642
Epoch: 1/20... Training loss: 0.1584
Epoch: 1/20... Training loss: 0.1593
Epoch: 1/20... Training loss: 0.1647
Epoch: 1/20... Training loss: 0.1551
Epoch: 1/20... Training loss: 0.1615
Epoch: 1/20... Training loss: 0.1612
Epoch: 1/20... Training loss: 0.1563
Epoch: 1/20... Training loss: 0.1536
Epoch: 1/20... Training loss: 0.1549
Epoch: 1/20... Training loss: 0.1537
Epoch: 1/20... Training loss: 0.1584
Epoch: 1/20... Training loss: 0.1568
Epoch: 1/20... Training loss: 0.1592
Epoch: 1/20... Training loss: 0.1599
Epoch: 1/20... Training loss: 0.1602
Epoch: 1/20... Training loss: 0.1610
Epoch: 1/20... Training loss: 0.1606
Epoch: 1/20... Training loss: 0.1560
Epoch: 1/20... Training loss: 0.1607
Epoch: 1/20... Training loss: 0.1574
Epoch: 1/20... Training loss: 0.1503
Epoch: 1/20... Training loss: 0.1554
Epoch: 1/20... Training loss: 0.1561
Epoch: 1/20... Training loss: 0.1533
Epoch: 1/20... Training loss: 0.1580
Epoch: 1/20... Training loss: 0.1539
Epoch: 1/20... Training loss: 0.1527
Epoch: 1/20... Training loss: 0.1585
Epoch: 1/20... Training loss: 0.1585
Epoch: 1/20... Training loss: 0.1576
Epoch: 1/20... Training loss: 0.1539
Epoch: 1/20... Training loss: 0.1591
Epoch: 1/20... Training loss: 0.1555
Epoch: 1/20... Training loss: 0.1565
Epoch: 1/20... Training loss: 0.1550
Epoch: 1/20... Training loss: 0.1562
Epoch: 2/20... Training loss: 0.1581
Epoch: 2/20... Training loss: 0.1523
Epoch: 2/20... Training loss: 0.1565
Epoch: 2/20... Training loss: 0.1548
Epoch: 2/20... Training loss: 0.1568
Epoch: 2/20... Training loss: 0.1543
Epoch: 2/20... Training loss: 0.1509
Epoch: 2/20... Training loss: 0.1581
Epoch: 2/20... Training loss: 0.1496
Epoch: 2/20... Training loss: 0.1542
Epoch: 2/20... Training loss: 0.1514
Epoch: 2/20... Training loss: 0.1554
Epoch: 2/20... Training loss: 0.1536
Epoch: 2/20... Training loss: 0.1564
Epoch: 2/20... Training loss: 0.1569
Epoch: 2/20... Training loss: 0.1570
Epoch: 2/20... Training loss: 0.1507
Epoch: 2/20... Training loss: 0.1576
Epoch: 2/20... Training loss: 0.1545
Epoch: 2/20... Training loss: 0.1598
Epoch: 2/20... Training loss: 0.1508
Epoch: 2/20... Training loss: 0.1501
Epoch: 2/20... Training loss: 0.1511
Epoch: 2/20... Training loss: 0.1544
Epoch: 2/20... Training loss: 0.1523
Epoch: 2/20... Training loss: 0.1541
Epoch: 2/20... Training loss: 0.1487
Epoch: 2/20... Training loss: 0.1524
Epoch: 2/20... Training loss: 0.1546
Epoch: 2/20... Training loss: 0.1496
Epoch: 2/20... Training loss: 0.1526
Epoch: 2/20... Training loss: 0.1521
Epoch: 2/20... Training loss: 0.1541
Epoch: 2/20... Training loss: 0.1479
Epoch: 2/20... Training loss: 0.1522
Epoch: 2/20... Training loss: 0.1502
Epoch: 2/20... Training loss: 0.1537
Epoch: 2/20... Training loss: 0.1537
Epoch: 2/20... Training loss: 0.1533
Epoch: 2/20... Training loss: 0.1447
Epoch: 2/20... Training loss: 0.1497
Epoch: 2/20... Training loss: 0.1454
Epoch: 2/20... Training loss: 0.1526
Epoch: 2/20... Training loss: 0.1565
Epoch: 2/20... Training loss: 0.1477
Epoch: 2/20... Training loss: 0.1551
Epoch: 2/20... Training loss: 0.1489
Epoch: 2/20... Training loss: 0.1486
Epoch: 2/20... Training loss: 0.1489
Epoch: 2/20... Training loss: 0.1454
Epoch: 2/20... Training loss: 0.1463
Epoch: 2/20... Training loss: 0.1534
Epoch: 2/20... Training loss: 0.1478
Epoch: 2/20... Training loss: 0.1415
Epoch: 2/20... Training loss: 0.1479
Epoch: 2/20... Training loss: 0.1501
Epoch: 2/20... Training loss: 0.1497
Epoch: 2/20... Training loss: 0.1577
Epoch: 2/20... Training loss: 0.1481
Epoch: 2/20... Training loss: 0.1448
Epoch: 2/20... Training loss: 0.1474
Epoch: 2/20... Training loss: 0.1418
Epoch: 2/20... Training loss: 0.1495
Epoch: 2/20... Training loss: 0.1474
Epoch: 2/20... Training loss: 0.1498
Epoch: 2/20... Training loss: 0.1508
Epoch: 2/20... Training loss: 0.1495
Epoch: 2/20... Training loss: 0.1405
Epoch: 2/20... Training loss: 0.1456
Epoch: 2/20... Training loss: 0.1440
Epoch: 2/20... Training loss: 0.1464
Epoch: 2/20... Training loss: 0.1442
Epoch: 2/20... Training loss: 0.1492
Epoch: 2/20... Training loss: 0.1463
Epoch: 2/20... Training loss: 0.1454
Epoch: 2/20... Training loss: 0.1416
Epoch: 2/20... Training loss: 0.1469
Epoch: 2/20... Training loss: 0.1444
Epoch: 2/20... Training loss: 0.1473
Epoch: 2/20... Training loss: 0.1468
Epoch: 2/20... Training loss: 0.1425
Epoch: 2/20... Training loss: 0.1416
Epoch: 2/20... Training loss: 0.1467
Epoch: 2/20... Training loss: 0.1473
Epoch: 2/20... Training loss: 0.1388
Epoch: 2/20... Training loss: 0.1426
Epoch: 2/20... Training loss: 0.1452
Epoch: 2/20... Training loss: 0.1416
Epoch: 2/20... Training loss: 0.1430
Epoch: 2/20... Training loss: 0.1484
Epoch: 2/20... Training loss: 0.1441
Epoch: 2/20... Training loss: 0.1450
Epoch: 2/20... Training loss: 0.1404
Epoch: 2/20... Training loss: 0.1470
Epoch: 2/20... Training loss: 0.1409
Epoch: 2/20... Training loss: 0.1514
Epoch: 2/20... Training loss: 0.1448
Epoch: 2/20... Training loss: 0.1433
Epoch: 2/20... Training loss: 0.1450
Epoch: 2/20... Training loss: 0.1476
Epoch: 2/20... Training loss: 0.1448
Epoch: 2/20... Training loss: 0.1451
Epoch: 2/20... Training loss: 0.1428
Epoch: 2/20... Training loss: 0.1481
Epoch: 2/20... Training loss: 0.1462
Epoch: 2/20... Training loss: 0.1480
Epoch: 2/20... Training loss: 0.1424
Epoch: 2/20... Training loss: 0.1465
Epoch: 2/20... Training loss: 0.1451
Epoch: 2/20... Training loss: 0.1387
Epoch: 2/20... Training loss: 0.1473
Epoch: 2/20... Training loss: 0.1472
Epoch: 2/20... Training loss: 0.1418
Epoch: 2/20... Training loss: 0.1413
Epoch: 2/20... Training loss: 0.1406
Epoch: 2/20... Training loss: 0.1461
Epoch: 2/20... Training loss: 0.1354
Epoch: 2/20... Training loss: 0.1484
Epoch: 2/20... Training loss: 0.1444
Epoch: 2/20... Training loss: 0.1453
Epoch: 2/20... Training loss: 0.1418
Epoch: 2/20... Training loss: 0.1475
Epoch: 2/20... Training loss: 0.1412
Epoch: 2/20... Training loss: 0.1376
Epoch: 2/20... Training loss: 0.1380
Epoch: 2/20... Training loss: 0.1416
Epoch: 2/20... Training loss: 0.1429
Epoch: 2/20... Training loss: 0.1449
Epoch: 2/20... Training loss: 0.1437
Epoch: 2/20... Training loss: 0.1399
Epoch: 2/20... Training loss: 0.1440
Epoch: 2/20... Training loss: 0.1415
Epoch: 2/20... Training loss: 0.1403
Epoch: 2/20... Training loss: 0.1462
Epoch: 2/20... Training loss: 0.1430
Epoch: 2/20... Training loss: 0.1410
Epoch: 2/20... Training loss: 0.1421
Epoch: 2/20... Training loss: 0.1380
Epoch: 2/20... Training loss: 0.1395
Epoch: 2/20... Training loss: 0.1385
Epoch: 2/20... Training loss: 0.1426
Epoch: 2/20... Training loss: 0.1376
Epoch: 2/20... Training loss: 0.1433
Epoch: 2/20... Training loss: 0.1407
Epoch: 2/20... Training loss: 0.1346
Epoch: 2/20... Training loss: 0.1363
Epoch: 2/20... Training loss: 0.1367
Epoch: 2/20... Training loss: 0.1464
Epoch: 2/20... Training loss: 0.1429
Epoch: 2/20... Training loss: 0.1422
Epoch: 2/20... Training loss: 0.1409
Epoch: 2/20... Training loss: 0.1361
Epoch: 2/20... Training loss: 0.1411
Epoch: 2/20... Training loss: 0.1380
Epoch: 2/20... Training loss: 0.1391
Epoch: 2/20... Training loss: 0.1419
Epoch: 2/20... Training loss: 0.1368
Epoch: 2/20... Training loss: 0.1382
Epoch: 2/20... Training loss: 0.1389
Epoch: 2/20... Training loss: 0.1422
Epoch: 2/20... Training loss: 0.1408
Epoch: 2/20... Training loss: 0.1380
Epoch: 2/20... Training loss: 0.1409
Epoch: 2/20... Training loss: 0.1335
Epoch: 2/20... Training loss: 0.1363
Epoch: 2/20... Training loss: 0.1351
Epoch: 2/20... Training loss: 0.1360
Epoch: 2/20... Training loss: 0.1412
Epoch: 2/20... Training loss: 0.1387
Epoch: 2/20... Training loss: 0.1365
Epoch: 2/20... Training loss: 0.1355
Epoch: 2/20... Training loss: 0.1420
Epoch: 2/20... Training loss: 0.1361
Epoch: 2/20... Training loss: 0.1354
Epoch: 2/20... Training loss: 0.1384
Epoch: 2/20... Training loss: 0.1361
Epoch: 2/20... Training loss: 0.1377
Epoch: 2/20... Training loss: 0.1420
Epoch: 2/20... Training loss: 0.1372
Epoch: 2/20... Training loss: 0.1371
Epoch: 2/20... Training loss: 0.1339
Epoch: 2/20... Training loss: 0.1370
Epoch: 2/20... Training loss: 0.1389
Epoch: 2/20... Training loss: 0.1327
Epoch: 2/20... Training loss: 0.1436
Epoch: 2/20... Training loss: 0.1379
Epoch: 2/20... Training loss: 0.1357
Epoch: 2/20... Training loss: 0.1329
Epoch: 2/20... Training loss: 0.1328
Epoch: 2/20... Training loss: 0.1390
Epoch: 2/20... Training loss: 0.1341
Epoch: 2/20... Training loss: 0.1351
Epoch: 2/20... Training loss: 0.1389
Epoch: 2/20... Training loss: 0.1361
Epoch: 2/20... Training loss: 0.1350
Epoch: 2/20... Training loss: 0.1390
Epoch: 2/20... Training loss: 0.1358
Epoch: 2/20... Training loss: 0.1352
Epoch: 2/20... Training loss: 0.1368
Epoch: 2/20... Training loss: 0.1334
Epoch: 2/20... Training loss: 0.1341
Epoch: 2/20... Training loss: 0.1355
Epoch: 2/20... Training loss: 0.1369
Epoch: 2/20... Training loss: 0.1414
Epoch: 2/20... Training loss: 0.1340
Epoch: 2/20... Training loss: 0.1328
Epoch: 2/20... Training loss: 0.1360
Epoch: 2/20... Training loss: 0.1329
Epoch: 2/20... Training loss: 0.1366
Epoch: 2/20... Training loss: 0.1340
Epoch: 2/20... Training loss: 0.1356
Epoch: 2/20... Training loss: 0.1352
Epoch: 2/20... Training loss: 0.1375
Epoch: 2/20... Training loss: 0.1338
Epoch: 2/20... Training loss: 0.1379
Epoch: 2/20... Training loss: 0.1315
Epoch: 2/20... Training loss: 0.1295
Epoch: 2/20... Training loss: 0.1327
Epoch: 2/20... Training loss: 0.1337
Epoch: 2/20... Training loss: 0.1378
Epoch: 2/20... Training loss: 0.1300
Epoch: 2/20... Training loss: 0.1349
Epoch: 2/20... Training loss: 0.1349
Epoch: 2/20... Training loss: 0.1349
Epoch: 2/20... Training loss: 0.1323
Epoch: 2/20... Training loss: 0.1345
Epoch: 2/20... Training loss: 0.1358
Epoch: 2/20... Training loss: 0.1363
Epoch: 2/20... Training loss: 0.1366
Epoch: 2/20... Training loss: 0.1320
Epoch: 2/20... Training loss: 0.1282
Epoch: 2/20... Training loss: 0.1320
Epoch: 2/20... Training loss: 0.1313
Epoch: 2/20... Training loss: 0.1292
Epoch: 2/20... Training loss: 0.1328
Epoch: 2/20... Training loss: 0.1377
Epoch: 2/20... Training loss: 0.1290
Epoch: 2/20... Training loss: 0.1313
Epoch: 2/20... Training loss: 0.1325
Epoch: 2/20... Training loss: 0.1294
Epoch: 2/20... Training loss: 0.1318
Epoch: 2/20... Training loss: 0.1353
Epoch: 2/20... Training loss: 0.1334
Epoch: 2/20... Training loss: 0.1346
Epoch: 2/20... Training loss: 0.1329
Epoch: 2/20... Training loss: 0.1344
Epoch: 2/20... Training loss: 0.1285
Epoch: 2/20... Training loss: 0.1422
Epoch: 2/20... Training loss: 0.1346
Epoch: 2/20... Training loss: 0.1326
Epoch: 2/20... Training loss: 0.1284
Epoch: 2/20... Training loss: 0.1347
Epoch: 2/20... Training loss: 0.1303
Epoch: 2/20... Training loss: 0.1405
Epoch: 2/20... Training loss: 0.1302
Epoch: 2/20... Training loss: 0.1351
Epoch: 2/20... Training loss: 0.1353
Epoch: 2/20... Training loss: 0.1336
Epoch: 2/20... Training loss: 0.1337
Epoch: 2/20... Training loss: 0.1308
Epoch: 2/20... Training loss: 0.1286
Epoch: 2/20... Training loss: 0.1361
Epoch: 2/20... Training loss: 0.1314
Epoch: 2/20... Training loss: 0.1286
Epoch: 2/20... Training loss: 0.1322
Epoch: 2/20... Training loss: 0.1335
Epoch: 2/20... Training loss: 0.1318
Epoch: 2/20... Training loss: 0.1357
Epoch: 2/20... Training loss: 0.1298
Epoch: 2/20... Training loss: 0.1354
Epoch: 2/20... Training loss: 0.1314
Epoch: 2/20... Training loss: 0.1331
Epoch: 2/20... Training loss: 0.1373
Epoch: 2/20... Training loss: 0.1278
Epoch: 2/20... Training loss: 0.1366
Epoch: 2/20... Training loss: 0.1323
Epoch: 2/20... Training loss: 0.1290
Epoch: 2/20... Training loss: 0.1363
Epoch: 2/20... Training loss: 0.1312
Epoch: 2/20... Training loss: 0.1337
Epoch: 2/20... Training loss: 0.1333
Epoch: 2/20... Training loss: 0.1341
Epoch: 2/20... Training loss: 0.1290
Epoch: 2/20... Training loss: 0.1336
Epoch: 2/20... Training loss: 0.1318
Epoch: 2/20... Training loss: 0.1361
Epoch: 2/20... Training loss: 0.1307
Epoch: 2/20... Training loss: 0.1270
Epoch: 2/20... Training loss: 0.1331
Epoch: 2/20... Training loss: 0.1266
Epoch: 2/20... Training loss: 0.1353
Epoch: 2/20... Training loss: 0.1290
Epoch: 2/20... Training loss: 0.1300
Epoch: 2/20... Training loss: 0.1272
Epoch: 2/20... Training loss: 0.1299
Epoch: 2/20... Training loss: 0.1347
Epoch: 2/20... Training loss: 0.1308
Epoch: 2/20... Training loss: 0.1307
Epoch: 2/20... Training loss: 0.1309
Epoch: 2/20... Training loss: 0.1317
Epoch: 3/20... Training loss: 0.1305
Epoch: 3/20... Training loss: 0.1289
Epoch: 3/20... Training loss: 0.1292
Epoch: 3/20... Training loss: 0.1277
Epoch: 3/20... Training loss: 0.1277
Epoch: 3/20... Training loss: 0.1256
Epoch: 3/20... Training loss: 0.1332
Epoch: 3/20... Training loss: 0.1322
Epoch: 3/20... Training loss: 0.1312
Epoch: 3/20... Training loss: 0.1305
Epoch: 3/20... Training loss: 0.1299
Epoch: 3/20... Training loss: 0.1268
Epoch: 3/20... Training loss: 0.1259
Epoch: 3/20... Training loss: 0.1283
Epoch: 3/20... Training loss: 0.1276
Epoch: 3/20... Training loss: 0.1262
Epoch: 3/20... Training loss: 0.1264
Epoch: 3/20... Training loss: 0.1310
Epoch: 3/20... Training loss: 0.1279
Epoch: 3/20... Training loss: 0.1266
Epoch: 3/20... Training loss: 0.1308
Epoch: 3/20... Training loss: 0.1307
Epoch: 3/20... Training loss: 0.1306
Epoch: 3/20... Training loss: 0.1291
Epoch: 3/20... Training loss: 0.1310
Epoch: 3/20... Training loss: 0.1288
Epoch: 3/20... Training loss: 0.1314
Epoch: 3/20... Training loss: 0.1279
Epoch: 3/20... Training loss: 0.1309
Epoch: 3/20... Training loss: 0.1267
Epoch: 3/20... Training loss: 0.1228
Epoch: 3/20... Training loss: 0.1306
Epoch: 3/20... Training loss: 0.1282
Epoch: 3/20... Training loss: 0.1294
Epoch: 3/20... Training loss: 0.1294
Epoch: 3/20... Training loss: 0.1383
Epoch: 3/20... Training loss: 0.1308
Epoch: 3/20... Training loss: 0.1325
Epoch: 3/20... Training loss: 0.1313
Epoch: 3/20... Training loss: 0.1276
Epoch: 3/20... Training loss: 0.1274
Epoch: 3/20... Training loss: 0.1260
Epoch: 3/20... Training loss: 0.1311
Epoch: 3/20... Training loss: 0.1295
Epoch: 3/20... Training loss: 0.1309
Epoch: 3/20... Training loss: 0.1295
Epoch: 3/20... Training loss: 0.1245

In [13]:
fig, axes = plt.subplots(nrows=2, ncols=10, sharex=True, sharey=True, figsize=(20,4))
in_imgs = mnist.test.images[:10]
reconstructed = sess.run(decoded, feed_dict={inputs_: in_imgs.reshape((10, 28, 28, 1))})

for images, row in zip([in_imgs, reconstructed], axes):
    for img, ax in zip(images, row):
        ax.imshow(img.reshape((28, 28)), cmap='Greys_r')
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)


fig.tight_layout(pad=0.1)



In [19]:
sess.close()

Denoising

As I've mentioned before, autoencoders like the ones you've built so far aren't too useful in practive. However, they can be used to denoise images quite successfully just by training the network on noisy images. We can create the noisy images ourselves by adding Gaussian noise to the training images, then clipping the values to be between 0 and 1. We'll use noisy images as input and the original, clean images as targets. Here's an example of the noisy images I generated and the denoised images.

Since this is a harder problem for the network, we'll want to use deeper convolutional layers here, more feature maps. I suggest something like 32-32-16 for the depths of the convolutional layers in the encoder, and the same depths going backward through the decoder. Otherwise the architecture is the same as before.

Exercise: Build the network for the denoising autoencoder. It's the same as before, but with deeper layers. I suggest 32-32-16 for the depths, but you can play with these numbers, or add more layers.


In [21]:
learning_rate = 0.001
inputs_ = tf.placeholder(tf.float32, (None, 28, 28, 1), name='inputs')
targets_ = tf.placeholder(tf.float32, (None, 28, 28, 1), name='targets')

### Encoder
conv1 = 
# Now 28x28x32
maxpool1 = 
# Now 14x14x32
conv2 = 
# Now 14x14x32
maxpool2 = 
# Now 7x7x32
conv3 = 
# Now 7x7x16
encoded = 
# Now 4x4x16

### Decoder
upsample1 = 
# Now 7x7x16
conv4 = 
# Now 7x7x16
upsample2 = 
# Now 14x14x16
conv5 = 
# Now 14x14x32
upsample3 = 
# Now 28x28x32
conv6 = 
# Now 28x28x32

logits = 
#Now 28x28x1

# Pass logits through sigmoid to get reconstructed image
decoded =

# Pass logits through sigmoid and calculate the cross-entropy loss
loss = 

# Get cost and define the optimizer
cost = tf.reduce_mean(loss)
opt = tf.train.AdamOptimizer(learning_rate).minimize(cost)

In [22]:
sess = tf.Session()

In [ ]:
epochs = 100
batch_size = 200
# Set's how much noise we're adding to the MNIST images
noise_factor = 0.5
sess.run(tf.global_variables_initializer())
for e in range(epochs):
    for ii in range(mnist.train.num_examples//batch_size):
        batch = mnist.train.next_batch(batch_size)
        # Get images from the batch
        imgs = batch[0].reshape((-1, 28, 28, 1))
        
        # Add random noise to the input images
        noisy_imgs = imgs + noise_factor * np.random.randn(*imgs.shape)
        # Clip the images to be between 0 and 1
        noisy_imgs = np.clip(noisy_imgs, 0., 1.)
        
        # Noisy images as inputs, original images as targets
        batch_cost, _ = sess.run([cost, opt], feed_dict={inputs_: noisy_imgs,
                                                         targets_: imgs})

        print("Epoch: {}/{}...".format(e+1, epochs),
              "Training loss: {:.4f}".format(batch_cost))

Checking out the performance

Here I'm adding noise to the test images and passing them through the autoencoder. It does a suprisingly great job of removing the noise, even though it's sometimes difficult to tell what the original number is.


In [29]:
fig, axes = plt.subplots(nrows=2, ncols=10, sharex=True, sharey=True, figsize=(20,4))
in_imgs = mnist.test.images[:10]
noisy_imgs = in_imgs + noise_factor * np.random.randn(*in_imgs.shape)
noisy_imgs = np.clip(noisy_imgs, 0., 1.)

reconstructed = sess.run(decoded, feed_dict={inputs_: noisy_imgs.reshape((10, 28, 28, 1))})

for images, row in zip([noisy_imgs, reconstructed], axes):
    for img, ax in zip(images, row):
        ax.imshow(img.reshape((28, 28)), cmap='Greys_r')
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)

fig.tight_layout(pad=0.1)