import matplotlib.pyplot as pp
import numpy as np
import tensorflow as tf
import tensorflow.examples.tutorials.mnist as mnist
from tensorflow.python.framework import ops
import warnings
import random
import os
warnings.filterwarnings("ignore")
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
ops.reset_default_graph()
# MNIST 데이터를 로드한다.
print("MNIST 데이터 로드를 시작합니다.")
mnistDatasets = mnist.input_data.read_data_sets("data", one_hot = True)
print("MNIST 데이터 로드를 종료합니다.")
# 네트워크 파라미터
inputLayerNodeCount = 784
learningRate = 0.001
batchSize = 128
epochCount = 50
n1 = 16
n2 = 32
n3 = 64
ksize = 5
inputLayerTensor = tf.placeholder(tf.float32, [None, inputLayerNodeCount])
inputLayerTensorReshape = tf.reshape(inputLayerTensor, shape = [-1, 28, 28, 1])
correctOutputTensor = tf.placeholder(tf.float32, [None, inputLayerNodeCount])
correctOutputTensorReshape = tf.reshape(correctOutputTensor, shape = [-1, 28, 28, 1])
dropoutRateTensor = tf.placeholder(tf.float32)
encoderConvolutionLayer1WeightVariable = tf.Variable(tf.random_normal([ksize, ksize, 1 , n1], stddev = 0.1))
encoderConvolutionLayer2WeightVariable = tf.Variable(tf.random_normal([ksize, ksize, n1, n2], stddev = 0.1))
encoderConvolutionLayer3WeightVariable = tf.Variable(tf.random_normal([ksize, ksize, n2, n3], stddev = 0.1))
decoderConvolutionLayer3WeightVariable = tf.Variable(tf.random_normal([ksize, ksize, n2, n3], stddev = 0.1))
decoderConvolutionLayer2WeightVariable = tf.Variable(tf.random_normal([ksize, ksize, n1, n2], stddev = 0.1))
decoderConvolutionLayer1WeightVariable = tf.Variable(tf.random_normal([ksize, ksize, 1 , n1], stddev = 0.1))
encoderConvolutionLayer1BiasVariable = tf.Variable(tf.random_normal([n1], stddev = 0.1))
encoderConvolutionLayer2BiasVariable = tf.Variable(tf.random_normal([n2], stddev = 0.1))
encoderConvolutionLayer3BiasVariable = tf.Variable(tf.random_normal([n3], stddev = 0.1))
decoderConvolutionLayer3BiasVariable = tf.Variable(tf.random_normal([n2], stddev = 0.1))
decoderConvolutionLayer2BiasVariable = tf.Variable(tf.random_normal([n1], stddev = 0.1))
decoderConvolutionLayer1BiasVariable = tf.Variable(tf.random_normal([1 ], stddev = 0.1))
# 인코더
encoderConvolutionLayer1OutputTensor = tf.nn.sigmoid(tf.add(tf.nn.conv2d(inputLayerTensorReshape ,\
encoderConvolutionLayer1WeightVariable, strides = [1, 2, 2, 1], padding = "SAME"), encoderConvolutionLayer1BiasVariable))
encoderConvolutionLayer1OutputTensorDropout = tf.nn.dropout(encoderConvolutionLayer1OutputTensor, dropoutRateTensor)
encoderConvolutionLayer2OutputTensor = tf.nn.sigmoid(tf.add(tf.nn.conv2d(encoderConvolutionLayer1OutputTensorDropout,\
encoderConvolutionLayer2WeightVariable, strides = [1, 2, 2, 1], padding = "SAME"), encoderConvolutionLayer2BiasVariable))
encoderConvolutionLayer2OutputTensorDropout = tf.nn.dropout(encoderConvolutionLayer2OutputTensor, dropoutRateTensor)
encoderConvolutionLayer3OutputTensor = tf.nn.sigmoid(tf.add(tf.nn.conv2d(encoderConvolutionLayer2OutputTensorDropout,\
encoderConvolutionLayer3WeightVariable, strides = [1, 2, 2, 1], padding = "SAME"), encoderConvolutionLayer3BiasVariable))
encoderConvolutionLayer3OutputTensorDropout = tf.nn.dropout(encoderConvolutionLayer3OutputTensor, dropoutRateTensor)
# 디코더
decoderConvolutionLayer3OutputTensor = tf.nn.sigmoid(tf.add(tf.nn.conv2d_transpose(encoderConvolutionLayer3OutputTensorDropout,\
decoderConvolutionLayer3WeightVariable, tf.stack([tf.shape(inputLayerTensor)[0], 7 , 7 , n2]), strides = [1, 2, 2, 1], padding = "SAME"),\
decoderConvolutionLayer3BiasVariable))
decoderConvolutionLayer3OutputTensorDropout = tf.nn.dropout(decoderConvolutionLayer3OutputTensor, dropoutRateTensor)
decoderConvolutionLayer2OutputTensor = tf.nn.sigmoid(tf.add(tf.nn.conv2d_transpose(decoderConvolutionLayer3OutputTensorDropout,\
decoderConvolutionLayer2WeightVariable, tf.stack([tf.shape(inputLayerTensor)[0], 14, 14, n1]), strides = [1, 2, 2, 1], padding = "SAME"),\
decoderConvolutionLayer2BiasVariable))
decoderConvolutionLayer2OutputTensorDropout = tf.nn.dropout(decoderConvolutionLayer2OutputTensor, dropoutRateTensor)
decoderConvolutionLayer1OutputTensor = tf.nn.sigmoid(tf.add(tf.nn.conv2d_transpose(decoderConvolutionLayer2OutputTensorDropout,\
decoderConvolutionLayer1WeightVariable, tf.stack([tf.shape(inputLayerTensor)[0], 28, 28, 1 ]), strides = [1, 2, 2, 1], padding = "SAME"),\
decoderConvolutionLayer1BiasVariable))
decoderConvolutionLayer1OutputTensorDropout = tf.nn.dropout(decoderConvolutionLayer1OutputTensor, dropoutRateTensor)
outputLayerOuputTensor = decoderConvolutionLayer1OutputTensorDropout
costTensor = tf.reduce_sum(tf.square(outputLayerOuputTensor - correctOutputTensorReshape))
optimizerOperation = tf.train.AdamOptimizer(learningRate).minimize(costTensor)
# 그래프를 실행한다.
print("학습을 시작합니다.")
with tf.Session() as session:
session.run(tf.global_variables_initializer())
meanImageNDArray = np.zeros((inputLayerNodeCount))
for epoch in range(epochCount):
totalBatch = mnistDatasets.train.num_examples // batchSize
for batch in range(totalBatch):
batchInputNDArray, _ = mnistDatasets.train.next_batch(batchSize)
trainInputNDArray = np.array([sourceImageNDArray - meanImageNDArray for sourceImageNDArray in batchInputNDArray])
noiseTrainInputNDArray = trainInputNDArray + 0.3 * np.random.randn(trainInputNDArray.shape[0], inputLayerNodeCount)
session.run(optimizerOperation, feed_dict = {inputLayerTensor : noiseTrainInputNDArray, correctOutputTensor : trainInputNDArray, dropoutRateTensor : 0.7})
print("[%02d/%02d] 비용 : %.4f" % (epoch, epochCount, session.run(costTensor, feed_dict = {inputLayerTensor : noiseTrainInputNDArray,\
correctOutputTensor : trainInputNDArray, dropoutRateTensor: 1.})))
if (epoch % 1) == 0:
exampleCount = 5
testInputNDArray, _ = mnistDatasets.test.next_batch(exampleCount)
noisyTestInputNDArray = testInputNDArray + 0.3 * np.random.randn(testInputNDArray.shape[0], inputLayerNodeCount)
outputNDArray = session.run(outputLayerOuputTensor, feed_dict = {inputLayerTensor : noisyTestInputNDArray, dropoutRateTensor : 1.})
figure, axesNDArray = pp.subplots(2, exampleCount, figsize = (15, 4))
for example in range(exampleCount):
axesNDArray[0][example].matshow(np.reshape(noisyTestInputNDArray[example, :], (28, 28)), cmap = pp.get_cmap("gray"))
axesNDArray[1][example].matshow(np.reshape(np.reshape(outputNDArray[example, ...], (inputLayerNodeCount,)) + meanImageNDArray, (28, 28)),\
cmap = pp.get_cmap("gray"))
pp.show()