├── .gitignore
├── 1_Introduction
├── Introduction to Deep Learning D1.pdf
└── README.md
├── 2_Perceptron
├── README.md
├── perceptronMNIST1.py
├── perceptronMNIST2.py
├── perceptronMNIST3.py
├── perceptronMNIST4.py
├── perceptronMNIST5.py
└── perceptronMNISTv1.py
├── 3_ConvolutionalNetworks
├── Deep Learning Slides.pdf
└── convolutionalMNIST.py
├── 4_FullyConvolutionalNetworks
├── README.md
├── fc.py
└── fullyConvolutional.py
├── 5_Autoencoders
├── TensorFlowInterface.py
├── autoencoderMNIST.py
├── digitOriginal.jpg
├── digitOriginalRecon.jpg
├── digitSNR10.jpg
├── digitSNR10Recon.jpg
└── input_data.py
├── 6_MRISegmentation
├── ccseg.py
├── corpusCallosum.tar.gz
└── support
│ ├── ccseg.py
│ └── prepareData.py
├── LICENSE
├── README.md
└── tfs
├── setup.py
└── tfs
├── TensorFlowInterface.py
├── __init__.py
└── input_data.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.egg-info
3 | logs
4 | logs/*
5 | data
6 | data/*
7 | *.nii
8 | *.nii.gz
9 | MNIST_data
10 | MNIST_data/*
11 | .DS_Store
12 | __pycache__
13 | __pycache__/*
--------------------------------------------------------------------------------
/1_Introduction/Introduction to Deep Learning D1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robb-brown/IntroToDeepLearning/ac6398427d0ac829e119122dafba1981bd68ff98/1_Introduction/Introduction to Deep Learning D1.pdf
--------------------------------------------------------------------------------
/1_Introduction/README.md:
--------------------------------------------------------------------------------
1 | #An Intuitive Introduction to Artificial Neural Networks and Deep Learning
2 | These notes are an introduction to artificial neural networks, deep learning, and graph-based computation. Code that was formerly located here has been moved to Session 2.
--------------------------------------------------------------------------------
/2_Perceptron/README.md:
--------------------------------------------------------------------------------
1 | # Setup Test
2 | This session introduced TensorFlow for fully connected artificial neural networks.
3 |
4 | The code for this session requires Python, Numpy, Matplotlib and TensorFlow. Python can be obtained from python.org. We recommend pip (distributed with Python) for installation of the others.
5 |
6 | Once you have downloaded the .py files in this directory, you can test your installation using:
7 |
8 | ```python
9 | python mnistExample.py
10 | ```
11 |
12 | If you see the following output, your installation of TensorFlow is completed.
13 | ```
14 | Accuracy at step 0: train: 0.12
15 | Accuracy at step 100: train: 0.78
16 | Accuracy at step 200: train: 0.82
17 | Accuracy at step 300: train: 0.91
18 | Accuracy at step 400: train: 0.71
19 | Accuracy at step 500: train: 0.88
20 | Accuracy at step 600: train: 0.84
21 | Accuracy at step 700: train: 0.84
22 | Accuracy at step 800: train: 0.84
23 | Accuracy at step 900: train: 0.85
24 | Test accuracy: 0.8522
25 | ```
26 |
--------------------------------------------------------------------------------
/2_Perceptron/perceptronMNIST1.py:
--------------------------------------------------------------------------------
1 | """
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2015 Robert A. Brown (www.robbtech.com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | """
24 |
25 | """
26 | This program demonstrates how to create a simple model in Tensorflow and perform
27 | an iteration of training.
28 | """
29 |
30 |
31 | import tensorflow as tf
32 | import math
33 | from tfs import input_data
34 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
35 |
36 | # Grab an MNIST example. x is the input, y_ is the true label
37 | x,y_ = mnist.train.next_batch(1)
38 |
39 |
40 | # Set up the variables for our model. This is a basic logistic regression model, where
41 | # W is a tensorflow variable that holds the weights and
42 | # b holds the biases. Note their shapes.
43 | W = tf.Variable(tf.zeros([784,10]),name='W_logistic')
44 | b = tf.Variable(tf.zeros([10]),name='b_logistic')
45 |
46 | # For the next two steps we need to tell Tensorflow to keep track of what we're doing
47 | # so it can compute gradients later.
48 | with tf.GradientTape() as tape:
49 |
50 | # y is the model's prediction, compare to the true labels, y_
51 | y = tf.nn.softmax(tf.matmul(x,W) + b)
52 |
53 | # Calculate the cost, comparing y to y_
54 | crossEntropy = -tf.reduce_sum(y_*tf.math.log(y))
55 |
56 |
57 | # Compute accuracy, for our interest only
58 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
59 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
60 |
61 | # notice that our cost is high and accuracy is low, because the model is not trained.
62 | print(f'Cost: {crossEntropy}; Accuracy: {accuracy}')
63 |
64 | # we can train the model by choosing an optimizer,
65 | optimizer = tf.optimizers.Adam(learning_rate=1e-3)
66 |
67 | # computing the gradient (that's what that tape thing was for)
68 | # The gradient function computes the partial derivatives of 'target' with
69 | # respect to 'sources'. The resulting vector is the gradient.
70 | # Note that you only get to call this function once!
71 | gradient = tape.gradient(target=crossEntropy,sources=[W,b])
72 |
73 | # We can then give our optimizer the gradient and ask it to change our variables
74 | # to move our model's prediction, y closer to the output we desire, y_
75 | # The zip function rearranges our list of gradients and our list of variables into a
76 | # list of gradient-variable tuples.
77 | optimizer.apply_gradients(zip(gradient, [W, b]))
78 |
79 | # We can re-evaluate the cost and accuracy:
80 | y = tf.nn.softmax(tf.matmul(x,W) + b)
81 | newCrossEntropy = -tf.reduce_sum(y_*tf.math.log(y))
82 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
83 | newAccuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
84 |
85 | # and notice that the cost has decreased a little, and accuracy has increased
86 | print(f'Old Cost: {crossEntropy}; Old Accuracy: {accuracy}')
87 | print(f'New Cost: {newCrossEntropy}; New Accuracy: {newAccuracy}')
88 |
89 | # but if we take a different example
90 | x,y_ = mnist.train.next_batch(1)
91 |
92 | # and recalculate
93 | y = tf.nn.softmax(tf.matmul(x,W) + b)
94 | newExampleCrossEntropy = -tf.reduce_sum(y_*tf.math.log(y))
95 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
96 | newExampleAccuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
97 |
98 | # The cost is high for the new example, and accuracy is low again.
99 | print(f'Original Example Cost: {newCrossEntropy}, Accuracy: {newAccuracy}')
100 | print(f'New Example Cost: {newExampleCrossEntropy}, Accuracy: {newExampleAccuracy}')
101 |
102 |
103 | """
104 | We'd like the model to do well on all examples, so we need to train it on a
105 | representative sample of them.
106 | Repeatedly re-creating our model every time we want to run a training iteration
107 | or evaluate our result is inelegant and inefficient. Fortunately, we can clean
108 | this up using functions. See perceptronMNIST2.py.
109 | """
110 |
--------------------------------------------------------------------------------
/2_Perceptron/perceptronMNIST2.py:
--------------------------------------------------------------------------------
1 | """
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2015 Robert A. Brown (www.robbtech.com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | """
24 |
25 | """
26 | This program is very much like perceptronMNIST1 but demonstrates how to clean up
27 | the code and make it ready for training in a loop with a variety of samples by
28 | putting the model creation and cost function calculations in functions.
29 | """
30 |
31 | import tensorflow as tf
32 | import math
33 | from tfs import input_data
34 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
35 |
36 | # Define a function that creates our model
37 | def logisticModel(x,W,b):
38 | y = tf.nn.softmax(tf.matmul(x,W) + b)
39 | return y
40 |
41 | # And a function that calculates the cost
42 | def crossEntropyCost(y,y_):
43 | crossEntropy = -tf.reduce_sum(y_*tf.math.log(y))
44 | return crossEntropy
45 |
46 | # finally a function that calculates accuracy
47 | def accuracyMetric(y,y_):
48 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
49 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
50 | return accuracy
51 |
52 |
53 | # Now we can create a function that performs an optimization step
54 | def optimizationStep(optimizer,x,y_,W,b):
55 | with tf.GradientTape() as tape:
56 | tape.watch(W); tape.watch(b)
57 | y = logisticModel(x,W,b)
58 | cost = crossEntropyCost(y,y_)
59 | gradient = tape.gradient(target=cost,sources=[W,b])
60 | optimizer.apply_gradients(zip(gradient, [W, b]))
61 |
62 |
63 | # And a training function that runs the optimization step repeatedly with a
64 | # varity of examples
65 | def train(mnist,x,y_,W,b,trainingIterations=3000):
66 | optimizer = tf.optimizers.Adam(learning_rate=1e-3)
67 | for iteration in range(trainingIterations):
68 | # Grab 100 examples instead of just 1. This is called a "minibatch"
69 | x,y_ = mnist.train.next_batch(100)
70 | optimizationStep(optimizer=optimizer,x=x,y_=y_,W=W,b=b)
71 | # For every 100th iteration, print out the training accuracy
72 | if iteration % 100 == 0:
73 | y = logisticModel(x,W,b)
74 | accuracy = accuracyMetric(y,y_)
75 | print(f'Training accuracy at step {iteration}: {accuracy}')
76 |
77 |
78 | # --------------- Main Part --------------------
79 | # Now we can use our functions instead of repeating code.
80 | # First, we set up our model variables
81 | W = tf.Variable(tf.zeros([784,10]),name='W_logistic')
82 | b = tf.Variable(tf.zeros([10]),name='b_logistic')
83 |
84 | # Check our starting cost and accuracy:
85 | x,y_ = mnist.train.next_batch(1)
86 | y = logisticModel(x,W,b)
87 | crossEntropy = crossEntropyCost(y,y_)
88 | accuracy = accuracyMetric(y,y_)
89 | print(f'Starting Cost: {crossEntropy}; Accuracy: {accuracy}')
90 |
91 | # Then we can train
92 | train(mnist=mnist,x=x,y_=y_,W=W,b=b)
93 |
94 | # And check our trained cost and accuracy on a batch of held out test examples
95 | x,y_ = mnist.test.next_batch(1)
96 | y = logisticModel(x,W,b)
97 | crossEntropy = crossEntropyCost(y,y_)
98 | accuracy = accuracyMetric(y,y_)
99 | print(f'Trained Cost On Test Set: {crossEntropy}; Accuracy: {accuracy}')
100 |
101 |
102 | """
103 | This is better, but our functions are special purpose. If we want to change our
104 | model, especially if we use one with more parameters, we have to rewrite all our
105 | functions. To fix this, we have to create some software infrastructure. Tensorflow
106 | includes a module called Keras which does this, but it also hides a lot of details
107 | inside Tensorflow. We think it's important for learning that you see these details,
108 | so we're going to take the time to create our own minimal system that lets us see
109 | all the parts. See perceptronMNIST3.py.
110 |
111 | """
112 |
113 |
114 |
--------------------------------------------------------------------------------
/2_Perceptron/perceptronMNIST3.py:
--------------------------------------------------------------------------------
1 | """
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2015 Robert A. Brown (www.robbtech.com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | """
24 |
25 | """
26 | This program is very much like perceptronMNIST1 but demonstrates how to clean up
27 | the code and make it ready for training in a loop with a variety of samples by
28 | putting the model creation and cost function calculations in functions.
29 | """
30 |
31 | import tensorflow as tf
32 | import math
33 | from tfs import input_data
34 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
35 |
36 |
37 | # This is a base class that defines the basic interface for our objects.
38 | # This one is very basic: an init function that stores the object's
39 | # properties, a setup function that is called when the object is created,
40 | # and an output function that can be called to get the object's output.
41 |
42 | class Base(object):
43 |
44 | def __init__(self,name):
45 | self.name = name
46 | self.setup()
47 |
48 | def setup(self):
49 | pass
50 |
51 | def output(self):
52 | return None
53 |
54 |
55 | # We'll create a 'concrete class' implementing our logistic regression model.
56 | # We have to tell it how big our input and output will be, then it creates
57 | # and stores the W and b variables for us. The output function actually
58 | # computes the logistic regression and returns the result.
59 | # We add a variables function that returns the model's trainable variables because
60 | # our training function will need those.
61 |
62 | class LogisticModel(Base):
63 |
64 | def __init__(self,inputShape,outputShape,name):
65 | self.inputShape = inputShape
66 | self.outputShape = outputShape
67 | self.name = name
68 | self.setup()
69 |
70 | def setup(self):
71 | self.W = tf.Variable(tf.zeros([self.inputShape,self.outputShape]),name=self.name+'W_logistic')
72 | self.b = tf.Variable(tf.zeros([self.outputShape]),name=self.name+'b_logistic')
73 |
74 | def variables(self):
75 | return [self.W,self.b]
76 |
77 | def output(self,x):
78 | return tf.nn.softmax(tf.matmul(x,self.W) + self.b)
79 |
80 |
81 | # Similarly for our cost function. We don't need to create an init function
82 | # because this one will be the same as in the base class. This object "inherits"
83 | # the init from it's ancestor.
84 | class CrossEntropyCost(Base):
85 |
86 | def output(self,y,y_):
87 | return -tf.reduce_sum(y_*tf.math.log(y))
88 |
89 | # And similarly for our accuracy metric.
90 | class AccuracyMetric(Base):
91 |
92 | def output(self,y,y_):
93 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
94 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
95 | return accuracy
96 |
97 | # Our optimizationStep and train function both go into a Trainer object
98 | class Trainer(Base):
99 |
100 | def __init__(self,model,cost,metrics,name):
101 | self.model = model
102 | self.cost = cost
103 | self.metrics = metrics
104 | self.name = name
105 | self.setup()
106 |
107 | def gradient(self,x,y_):
108 | variables = self.model.variables()
109 | with tf.GradientTape() as tape:
110 | y = self.model.output(x=x)
111 | cost = self.cost.output(y=y,y_=y_)
112 | gradient = tape.gradient(target=cost,sources=variables)
113 | return gradient
114 |
115 | def train(self,data,iterations=3000,learning_rate=1e-3,batchSize=100):
116 | optimizer = tf.optimizers.Adam(learning_rate=learning_rate)
117 | variables = self.model.variables()
118 | for iteration in range(iterations):
119 | x,y_ = mnist.train.next_batch(batchSize)
120 | optimizer.apply_gradients(zip(self.gradient(x,y_),variables))
121 | if iteration % 100 == 0:
122 | y = self.model.output(x=x)
123 | print(f'Training metrics at step {iteration}:')
124 | print(f' {self.cost.name} = {self.cost.output(y=y,y_=y_)}')
125 | for metric in self.metrics:
126 | print(f' {metric.name} = {metric.output(y=y,y_=y_)}')
127 |
128 |
129 | # --------------- Main Part --------------------
130 | # Now we no longer need to create our model by hand in the main part,
131 | # we just create our objects and pass them to the trainer.
132 |
133 | model = LogisticModel(inputShape=784,outputShape=10,name='LogisticModel')
134 | cost = CrossEntropyCost(name='CrossEntropy')
135 | metrics = [AccuracyMetric(name='Accuracy')]
136 | trainer = Trainer(model=model,cost=cost,metrics=metrics,name='Trainer')
137 |
138 | # Check our starting cost and accuracy:
139 | x,y_ = mnist.train.next_batch(1)
140 | y = model.output(x)
141 | print(f'Starting Cost: {cost.output(y,y_)}; Accuracy: {metrics[0].output(y,y_)}')
142 |
143 | # Then we can train
144 | trainer.train(data=mnist)
145 |
146 | # And check our trained cost and accuracy on a batch of held out test examples
147 | x,y_ = mnist.test.next_batch(100)
148 | y = model.output(x)
149 | print(f'Trained Cost On Test Set: {cost.output(y=y,y_=y_)}; Accuracy: {metrics[0].output(y=y,y_=y_)}')
150 |
--------------------------------------------------------------------------------
/2_Perceptron/perceptronMNIST4.py:
--------------------------------------------------------------------------------
1 | """
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2015 Robert A. Brown (www.robbtech.com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | """
24 |
25 | """
26 | This program is very much like perceptronMNIST3 but demonstrates how to implement
27 | different models by first creating the necessary layers objects and then passing those
28 | to a model object.
29 | """
30 |
31 | import tensorflow as tf
32 | import math
33 | from tfs import input_data
34 | import numpy
35 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
36 |
37 |
38 | # We'll keep our base class from step 3
39 | class Base(object):
40 |
41 | def __init__(self,name):
42 | self.name = name
43 | self.setup()
44 |
45 | def setup(self):
46 | pass
47 |
48 | def output(self):
49 | return None
50 |
51 | # The "deep" part of deep learning refers to the use of sequential computation,
52 | # where the result of one calculation is used as input to another, etc., in a
53 | # a chain. In mathematics, this is function composition: y = h(g(f(x))).
54 | # It's convenient to treat each function as a "layer" of computation, then we
55 | # can connect relatively simple layers together to produce a deep (multi-layered)
56 | # computational network.
57 |
58 | # Our logistic regression model only had one layer of computation. Now we'll introduce
59 | # a layer class, and a model class that will assemble multiple layers. Our
60 | # old logist regression model will now become a layer, and quite an important one:
61 | # logistic regression is often the final layer in a deep learning classifier.
62 |
63 | # This is a 'concrete class' which will be used for creating fairly generic
64 | # fully connected deep learning layer objects. You'll see in the next section
65 | # alternatives to fully connected layers, but for now our models will be
66 | # entirely composed of them.
67 | # A fully connected layer generally has weights (W) and biases (b), and an
68 | # activation function a, and computes the function:
69 | # y = a(W @ x + b), where x is the input, y is the output and @ is matrix
70 | # multiplication. Our logistic regression layer does exactly this, using
71 | # the softmax (logistic) function for a. The activation function is important in
72 | # deep learning because it can be nonlinear. Without it, a model, no matter how big,
73 | # can only learn linear functions, like linear regression does. With a nonlinear
74 | # activation function, a model that is sufficiently large and more than two layers
75 | # deep can learn any function.
76 |
77 | # We have to tell out layer how big our input and output will be, and what activation
78 | # function to use. It then creates and stores whatever variables it needs.
79 | # The output function will assemble the computation for the layer and return it.
80 | # We can also pass in an initialization function, but we'll allow it to default to
81 | # None so that the layer can make a good choice if we don't specify a value.
82 | # As before, we have a "variables" function that returns the layer's
83 | # trainable variables, which the model object will collect and pass to
84 | # the trainer function.
85 | # Since activation functions are very well standardized in Tensorflow, we can actually
86 | # pass the Tensorflow function itself, e.g. tf.identity for a function that does
87 | # nothing (a linear layer, like linear regression), tf.softmax, which we've seen
88 | # gives us logistic regression, and tf.relu, which is a rectified linear function, the
89 | # workhorse of deep learning.
90 |
91 | # For now we'll put all of these classes right in our program so they're easy to
92 | # see, but since we're going to be using them so much, in the next step we'll
93 | # see how to make our own deep learning module out of them.
94 |
95 | class Layer(Base):
96 |
97 | def __init__(self,inputShape,outputShape,activation,name,initialization=None):
98 | self.inputShape = inputShape
99 | self.outputShape = outputShape
100 | self.activation = activation
101 | self.name = name
102 | if initialization is None:
103 | initialization = 'random'
104 | self.initialization = initialization
105 |
106 | self.setup()
107 |
108 | def setup(self):
109 | if self.initialization == 'random':
110 | self.W = tf.Variable(tf.random.truncated_normal([self.inputShape,self.outputShape],stddev= 1.0 / math.sqrt(self.outputShape)),name=self.name+'W')
111 | elif self.initialization == 'zeros':
112 | self.W = tf.Variable(tf.zeros([self.inputShape,self.outputShape]),name=self.name+'W')
113 | self.b = tf.Variable(tf.zeros([self.outputShape]),name=self.name+'b')
114 |
115 | def variables(self):
116 | return [self.W,self.b]
117 |
118 | def output(self,x):
119 | return self.activation(tf.matmul(x,self.W) + self.b)
120 |
121 | # This is our new model class.
122 | # We pass in a list of our layer objects and its job is to connect them for us.
123 | # It also needs to collect the variables from each layer when we ask for them.
124 | # The model doesn't actually need a setup function, but we'll call the ancestor's
125 | # function (which currently does nothing) anyway, because it's good practice.
126 |
127 | class Model(Base):
128 |
129 | def __init__(self,layers,name):
130 | self.layers = layers
131 | self.name = name
132 | self.setup()
133 |
134 | def variables(self):
135 | variables = []
136 | for layer in self.layers:
137 | variables = variables + layer.variables()
138 | return variables
139 |
140 | def output(self, x):
141 | for layer in self.layers:
142 | x = layer.output(x)
143 | return x
144 |
145 | # The rest of our functions don't need to change, so we just copy them from
146 | # perceptronMNIST3. In the next step we'll make a module so we don't have to
147 | # do this copying every time!
148 |
149 | # ------------------ Unchanged Stuff from before ----------------------
150 | class CrossEntropyCost(Base):
151 |
152 | def output(self,y,y_):
153 | return -tf.reduce_sum(y_*tf.math.log(y))
154 |
155 |
156 | class AccuracyMetric(Base):
157 |
158 | def output(self,y,y_):
159 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
160 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
161 | return accuracy
162 |
163 |
164 | class Trainer(Base):
165 |
166 | def __init__(self,model,cost,metrics,name):
167 | self.model = model
168 | self.cost = cost
169 | self.metrics = metrics
170 | self.name = name
171 | self.setup()
172 |
173 | def gradient(self,x,y_):
174 | variables = self.model.variables()
175 | with tf.GradientTape() as tape:
176 | y = self.model.output(x=x)
177 | cost = self.cost.output(y=y,y_=y_)
178 | gradient = tape.gradient(target=cost,sources=variables)
179 | return gradient
180 |
181 | def train(self,data,iterations=3000,learning_rate=1e-3,batchSize=100):
182 | optimizer = tf.optimizers.Adam(learning_rate=learning_rate)
183 | variables = self.model.variables()
184 | for iteration in range(iterations):
185 | x,y_ = data.train.next_batch(batchSize)
186 | optimizer.apply_gradients(zip(self.gradient(x,y_),variables))
187 | if iteration % 100 == 0:
188 | y = self.model.output(x=x)
189 | print(f'Training metrics at step {iteration}:')
190 | print(f' {self.cost.name} = {self.cost.output(y=y,y_=y_)}')
191 | for metric in self.metrics:
192 | print(f' {metric.name} = {metric.output(y=y,y_=y_)}')
193 |
194 | # --------------------- End of unchanged stuff -------------------------
195 |
196 |
197 | # --------------- Main Part --------------------
198 | # We can now implement different models by creating layer objects
199 | # and passing them to our model object. We then pass the necessary
200 | # objects to the trainer.
201 |
202 | # Here's our logistic regression model from before:
203 | logistic = Layer( inputShape=784,outputShape=10,initialization='zeros',
204 | activation=tf.nn.softmax,name='logistic')
205 | # Notice that even though we only have one layer, we put it in a list.
206 | logisticModel = Model([logistic],name='LogisticModel')
207 |
208 |
209 | # But now we can just as easily make new models. This one has two layers, a linear one
210 | # then a logistic one. This is like a logistic regression model with interactions
211 | # between variables. We'll just call the layers 1 and 2, but you might see
212 | # terminology calling them "hidden" and "output". The "input" layer is really the
213 | # input to layer 1. The output of layer 1 is "hidden" because it's not data
214 | # we observe, or the end result of the computation, it's an intermediate result.
215 | # Of course, we can see it just fine, and we'll look at it later.
216 |
217 | # Two-layer logistic Regression Model:
218 | layer1 = Layer( inputShape=784,outputShape=200,initialization='random',
219 | activation=tf.identity,name='linear')
220 |
221 | layer2 = Layer( inputShape=200,outputShape=10,initialization='zeros',
222 | activation=tf.nn.softmax,name='logistic')
223 |
224 | twoLayerRegressionModel = Model([layer1,layer2],name='TwoLayerRegressionModel')
225 |
226 |
227 | # This one is called a multilayer perceptron (MLP). It has two layers, just like the
228 | # previous one, but notice that the first layer has a proper activation function;
229 | # it's nonlinear! Our model is very small, but, if scaled up by increasing
230 | # the size of outputShape on the first layer and inputShape on the second,
231 | # this model has everything it needs to learn *any* function.
232 |
233 | # Two-layer Perceptron Model:
234 | layer1 = Layer( inputShape=784,outputShape=200,initialization='random',
235 | activation=tf.nn.relu,name='input')
236 |
237 | layer2 = Layer( inputShape=200,outputShape=10,initialization='zeros',
238 | activation=tf.nn.softmax,name='output')
239 |
240 | twoLayerPerceptronModel = Model([layer1,layer2],name='TwoLayerPerceptron')
241 |
242 |
243 | # Finally, this is pretty much the same thing, but it's got an extra layer in the
244 | # middle, for three total! We're officially doing deep learning now! Most machine
245 | # learning models, like decision trees, SVM, regression,
246 | # older neural networks, etc. are one or two layers of computation deep.
247 |
248 | # Three-Layer Deep Network Model:
249 | layer1 = Layer( inputShape=784,outputShape=100,initialization='random',
250 | activation=tf.nn.relu,name='input')
251 |
252 | layer2 = Layer( inputShape=100,outputShape=100,initialization='random',
253 | activation=tf.nn.relu,name='hidden')
254 |
255 | layer3 = Layer( inputShape=100,outputShape=10,initialization='zeros',
256 | activation=tf.nn.softmax,name='output')
257 |
258 | threeLayerPerceptronModel = Model([layer1,layer2,layer3],name='ThreeLayerDeepModel')
259 |
260 |
261 | # Now we can set up our cost function and trainer as we did before.
262 | cost = CrossEntropyCost(name='CrossEntropy')
263 | metrics = [AccuracyMetric(name='Accuracy')]
264 | trainer = Trainer(model=logisticModel,cost=cost,metrics=metrics,name='Trainer')
265 |
266 |
267 | # We can train our model just as we did before
268 | # (remember, we didn't change the training function at all)
269 | # but let's do a little experiment. Since we now have multiple models,
270 | # let's train them all and see which one works best!
271 |
272 | # We'll create a dictionary to hold our results, then loop over
273 | # our models to train each one in succession.
274 |
275 | results = dict()
276 | for model in [logisticModel,twoLayerRegressionModel,twoLayerPerceptronModel,threeLayerPerceptronModel]:
277 | print(f'Training model {model.name}')
278 |
279 | # We'll create another dictionary to store the result just for this model
280 | result = dict()
281 |
282 | # we need to (re)create our trainer inside the loop with the current model
283 | # we don't need to recreate the cost or metrics, we can reuse those.
284 | trainer = Trainer(model=model,cost=cost,metrics=metrics,name='Trainer')
285 |
286 | # Check our starting cost and accuracy:
287 | x,y_ = mnist.train.next_batch(100)
288 | y = model.output(x)
289 | result['startingCost'] = cost.output(y,y_)
290 | result['startingAccuracy'] = metrics[0].output(y,y_)
291 | print(f'Starting Cost: {result["startingCost"]}; Accuracy: {result["startingAccuracy"]}')
292 |
293 | # Then we can train
294 | trainer.train(data=mnist)
295 |
296 | # And check our trained cost and accuracy on a batch of held out test examples
297 | x,y_ = mnist.test.next_batch(100)
298 | y = model.output(x)
299 | result['testCost'] = cost.output(y,y_)
300 | result['testAccuracy'] = metrics[0].output(y,y_)
301 | print(f'Trained Cost On Test Set: {result["testCost"]}; Accuracy: {result["testAccuracy"]}')
302 |
303 | # finally, we'll put our result dictionary into our results dictionary so
304 | # we can analyze it later.
305 | results[model.name] = result
306 |
307 |
308 | # Now that we have all our results, let's print them out so they're easier to see
309 | # all together. If you look closely, I've added :0.4 after each variable we're
310 | # printing. This tells python to use four digits of precision. It makes the printout
311 | # a little easier to read.
312 |
313 | for modelName in results.keys():
314 | result = results[modelName]
315 | print()
316 | print(modelName)
317 | print(f'Starting Cost: {result["startingCost"]:0.4}; Accuracy: {result["startingAccuracy"]:0.4}')
318 | print(f'Trained Cost On Test Set: {result["testCost"]:0.4}; Accuracy: {result["testAccuracy"]:0.4}')
319 |
320 |
321 | # Congratulations, you have just completed a deep learning experiment. So, which
322 | # model performed the best? Here's what I got:
323 |
324 | # LogisticModel
325 | # Starting Cost: 230.3; Accuracy: 0.12
326 | # Trained Cost On Test Set: 20.74; Accuracy: 0.97
327 | #
328 | # TwoLayerRegressionModel
329 | # Starting Cost: 230.3; Accuracy: 0.1
330 | # Trained Cost On Test Set: 15.77; Accuracy: 0.96
331 | #
332 | # TwoLayerPerceptron
333 | # Starting Cost: 230.3; Accuracy: 0.13
334 | # Trained Cost On Test Set: 9.695; Accuracy: 0.98
335 | #
336 | # ThreeLayerDeepModel
337 | # Starting Cost: 230.3; Accuracy: 0.11
338 | # Trained Cost On Test Set: 6.637; Accuracy: 0.97
339 |
340 | # Notice that all the models did pretty well on accuracy, but remember, we only
341 | # tested with a batch of 100 examples. The cost value takes into account
342 | # how confident each of the predictions was, and shows that the two layer models
343 | # were better than one layer, and the three layer model was better than two, and
344 | # the nonlinearity in the perceptrons also helped. If you were paying attention you
345 | # might have noticed that, although the one-layer logistic model's size is fixed
346 | # by the input and output, all the two layer models had 200 hidden artificial neurons
347 | # and the three layer model also had 200 hidden neurons, 100 in each hidden layer.
348 | # This actually means the three layer model had fewer parameters, because W is a
349 | # function of inputSize * outputSize. But the three layer model did the best!
350 | # There's a proof that shows that a deeper model can use it's capacity more
351 | # efficiently (sometimes exponentially more efficiently) than a shallower model.
352 | # That's why deep learning works so well.
353 |
354 | # Three layers doesn't seem like much, but without ReLU and functions like it, three or
355 | # more layer models are very hard to train. ReLU is really the magic that enables deep
356 | # learning, and the efficiency of deep models is the reason deep learning works so well.
357 |
358 | # **An important note!**
359 | # You might have noticed that the starting costs can be a bit different, and the
360 | # starting accuracies can be quite different. If you run this program again, you might
361 | # get somewhat different results, and you probably got different results than I did.
362 | # There are a lot of random numbers in machine learning. We used random numbers to
363 | # intialize many of our parameters, and also chose random examples, in a random
364 | # order, to train and test our models. To be good scientists, we should run our program
365 | # many times, keep track of the results for each run, and compute statistics that
366 | # tell us which models were significantly better or worse. Never believe a number
367 | # or that doesn't have some kind of confidence interval! You may also notice that
368 | # lots of machine learning websites, competitions and even scientific papers
369 | # don't do this. This is really an area where the machine learning field needs
370 | # to improve. If you'd like to help, try modifying this program to train the
371 | # models multiple times, collect the results, and do a statistical comparison. Don't
372 | # forget to recreate your models each time so they're untrained! Do our initial results
373 | # still hold up?
374 |
375 |
376 |
377 |
378 |
--------------------------------------------------------------------------------
/2_Perceptron/perceptronMNIST5.py:
--------------------------------------------------------------------------------
1 | import tensorflow as tf
2 | import math
3 | from tfs import input_data
4 | import numpy
5 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
6 |
7 | # We've been importing input_data from the tfs module in order to provide
8 | # the mnist data. This module also contains the classes we've been writing
9 | # to support our model building, so instead of including this support code
10 | # in every program, we can just import it:
11 |
12 | from tfs import Layer, Model, CrossEntropyCost, AccuracyMetric, Trainer
13 |
14 |
15 | # Throughout this tutorial we'll introduce new tools in the main program
16 | # on first use so you can always see all the details, then subsequently
17 | # import them from tfs.
18 |
19 |
20 | # --------------- Main Part --------------------
21 |
22 | # Logistic regression model
23 | logistic = Layer( inputShape=784,outputShape=10,initialization='zeros',
24 | activation=tf.nn.softmax,name='logistic')
25 | logisticModel = Model([logistic],name='LogisticModel')
26 |
27 |
28 | # Two-layer logistic Regression Model:
29 | layer1 = Layer( inputShape=784,outputShape=200,initialization='random',
30 | activation=tf.identity,name='linear')
31 | layer2 = Layer( inputShape=200,outputShape=10,initialization='zeros',
32 | activation=tf.nn.softmax,name='logistic')
33 | twoLayerRegressionModel = Model([layer1,layer2],name='TwoLayerRegressionModel')
34 |
35 |
36 | # Two-layer Perceptron Model:
37 | layer1 = Layer( inputShape=784,outputShape=200,initialization='random',
38 | activation=tf.nn.relu,name='input')
39 | layer2 = Layer( inputShape=200,outputShape=10,initialization='zeros',
40 | activation=tf.nn.softmax,name='output')
41 | twoLayerPerceptronModel = Model([layer1,layer2],name='TwoLayerPerceptron')
42 |
43 |
44 | # Three-Layer Deep Network Model:
45 | layer1 = Layer( inputShape=784,outputShape=100,initialization='random',
46 | activation=tf.nn.relu,name='input')
47 | layer2 = Layer( inputShape=100,outputShape=100,initialization='random',
48 | activation=tf.nn.relu,name='hidden')
49 | layer3 = Layer( inputShape=100,outputShape=10,initialization='zeros',
50 | activation=tf.nn.softmax,name='output')
51 | threeLayerPerceptronModel = Model([layer1,layer2,layer3],name='ThreeLayerDeepModel')
52 |
53 |
54 | # Cost and trainer
55 | cost = CrossEntropyCost(name='CrossEntropy')
56 | metrics = [AccuracyMetric(name='Accuracy')]
57 | trainer = Trainer(model=logisticModel,cost=cost,metrics=metrics,name='Trainer')
58 |
59 |
60 |
61 | # Train and evaluate
62 | results = dict()
63 | for model in [logisticModel,twoLayerRegressionModel,twoLayerPerceptronModel,threeLayerPerceptronModel]:
64 | print(f'Training model {model.name}')
65 | result = dict()
66 | trainer = Trainer(model=model,cost=cost,metrics=metrics,name='Trainer')
67 | x,y_ = mnist.train.next_batch(100)
68 | y = model.output(x)
69 | result['startingCost'] = cost.output(y,y_)
70 | result['startingAccuracy'] = metrics[0].output(y,y_)
71 | print(f'Starting Cost: {result["startingCost"]}; Accuracy: {result["startingAccuracy"]}')
72 | trainer.train(data=mnist)
73 | x,y_ = mnist.test.next_batch(100)
74 | y = model.output(x)
75 | result['testCost'] = cost.output(y,y_)
76 | result['testAccuracy'] = metrics[0].output(y,y_)
77 | print(f'Trained Cost On Test Set: {result["testCost"]}; Accuracy: {result["testAccuracy"]}')
78 | results[model.name] = result
79 |
80 |
81 | for modelName in results.keys():
82 | result = results[modelName]
83 | print()
84 | print(modelName)
85 | print(f'Starting Cost: {result["startingCost"]:0.4}; Accuracy: {result["startingAccuracy"]:0.4}')
86 | print(f'Trained Cost On Test Set: {result["testCost"]:0.4}; Accuracy: {result["testAccuracy"]:0.4}')
87 |
--------------------------------------------------------------------------------
/2_Perceptron/perceptronMNISTv1.py:
--------------------------------------------------------------------------------
1 | """
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2015 Robert A. Brown (www.robbtech.com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | """
24 |
25 | import tensorflow as tf
26 | import math
27 | from tfs import input_data
28 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
29 |
30 | # Common setup
31 | sess = tf.InteractiveSession()
32 | x = tf.placeholder('float',shape=[None,784],name='input') # Input tensor
33 | y_ = tf.placeholder('float', shape=[None,10],name='correctLabels') # Correct labels
34 |
35 |
36 | # MODEL DEFINITION
37 |
38 | # Softmax regression
39 | W = tf.Variable(tf.zeros([784,10]),name='W_logistic')
40 | b = tf.Variable(tf.zeros([10]),name='b_logistic')
41 | y = tf.nn.softmax(tf.matmul(x,W) + b)
42 |
43 | # # Two-layer softmax regression
44 | # Wlin = tf.Variable(tf.truncated_normal([784,784],stddev= 1.0 / math.sqrt(784)),name='W_linear')
45 | # blin = tf.Variable(tf.zeros([784]),name='b_linear')
46 | # W = tf.Variable(tf.zeros([784,10]),name='W_logistic')
47 | # b = tf.Variable(tf.zeros([10]),name='b_logistic')
48 | # y_intermediate = tf.matmul(x,Wlin) + blin
49 | # y = tf.nn.softmax(tf.matmul(y_intermediate,W) + b)
50 |
51 | # # Two-layer perceptron
52 | # hiddenUnitN = 200
53 | # W1 = tf.Variable(tf.truncated_normal([784,hiddenUnitN],stddev= 1.0 / math.sqrt(hiddenUnitN)),name='W1')
54 | # b1 = tf.Variable(tf.zeros([hiddenUnitN]),name='b1')
55 | # y_intermediate = tf.nn.relu(tf.matmul(x,W1) + b1)
56 | #
57 | # W = tf.Variable(tf.zeros([hiddenUnitN,10]),name='W_logistic')
58 | # b = tf.Variable(tf.zeros([10]),name='b_logistic')
59 | # y = tf.nn.softmax(tf.matmul(y_intermediate,W) + b)
60 |
61 | # # Three-layer Deep Network
62 | # hiddenUnitN1 = 200; hiddenUnitN2 = 200
63 | # W1 = tf.Variable(tf.truncated_normal([784,hiddenUnitN1],stddev= 1.0 / math.sqrt(hiddenUnitN1)),name='W1')
64 | # b1 = tf.Variable(tf.zeros([hiddenUnitN1]),name='b1')
65 | # hiddenLayer1 = tf.nn.relu(tf.matmul(x,W1) + b1)
66 | #
67 | # W2 = tf.Variable(tf.truncated_normal([hiddenUnitN1,hiddenUnitN2],stddev= 1.0 / math.sqrt(hiddenUnitN2)),name='W2')
68 | # b2 = tf.Variable(tf.zeros([hiddenUnitN2]),name='b2')
69 | # hiddenLayer2 = tf.nn.relu(tf.matmul(hiddenLayer1,W2) + b2)
70 | #
71 | # WSoftmax = tf.Variable(tf.zeros([hiddenUnitN2,10]),name='W_softmax')
72 | # bSoftmax = tf.Variable(tf.zeros([10]),name='b_softmax')
73 | # y = tf.nn.softmax(tf.matmul(hiddenLayer2,WSoftmax) + bSoftmax)
74 |
75 |
76 | # END MODEL DEFINITION
77 |
78 | cross_entropy = -tf.reduce_sum(y_*tf.log(y))
79 | train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
80 | train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
81 |
82 | correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
83 | accuracy = tf.reduce_mean(tf.cast(correct_prediction,'float'))
84 |
85 | tf.initialize_all_variables().run() # Take initial values and actually put them in variables
86 |
87 | for i in range(3000): # Do some training
88 | batch = mnist.train.next_batch(100)
89 | if i%100 == 0:
90 | train_accuracy = accuracy.eval(feed_dict={x:batch[0],y_:batch[1]})
91 | print('Accuracy at step {}: train: {}'.format(i,train_accuracy))
92 |
93 | train_step.run(feed_dict={x:batch[0],y_:batch[1]})
94 |
95 | print('Test accuracy: {}'.format(accuracy.eval(feed_dict={x:mnist.test.images, y_:mnist.test.labels})))
96 |
97 |
--------------------------------------------------------------------------------
/3_ConvolutionalNetworks/Deep Learning Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robb-brown/IntroToDeepLearning/ac6398427d0ac829e119122dafba1981bd68ff98/3_ConvolutionalNetworks/Deep Learning Slides.pdf
--------------------------------------------------------------------------------
/3_ConvolutionalNetworks/convolutionalMNIST.py:
--------------------------------------------------------------------------------
1 | from tfs import *
2 | from tfs import input_data
3 | from pylab import *
4 | from numpy import *
5 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
6 | matplotlib.interactive(True)
7 | session = tf.InteractiveSession()
8 |
9 | x = tf.placeholder('float',shape=[None,784],name='input') # Input tensor
10 | y_ = tf.placeholder('float', shape=[None,10],name='correctLabels') # Correct labels
11 |
12 | # A four layer fully connected net for comparison
13 | # trainingIterations = 10000
14 | # L1 = ReLu(x,512,'relu1')
15 | # L2 = ReLu(L1.output,128,'relu2')
16 | # L3 = ReLu(L2.output,64,'relu3')
17 | # L4 = SoftMax(x,10,'softmax')
18 | # y = L4.output
19 | # trainDict = {}; testDict = trainDict
20 | ## logName = 'logs/4LayerFullyConnected'
21 |
22 |
23 | xImage = tf.reshape(x,[-1,28,28,1]) # Reshape samples to 28x28x1 images
24 | trainingIterations = 1000
25 |
26 | # Standard conv net
27 | L1 = Conv2D(xImage,[5,5,1,32],'Conv1')
28 | L2 = MaxPool2x2(L1.output,'MaxPool1')
29 | L0do = Dropout(L2.output,'dropout')
30 | L3 = Conv2D(L0do.output,[5,5,32,64],'Conv2')
31 | L4 = MaxPool2x2(L3.output,'MaxPool2')
32 | L5 = ReLu(L4.output,128,'relu1')
33 | L6 = SoftMax(L5.output,10,'softmax')
34 | y = L6.output
35 | kp = 0.5; trainDict = {L0do.keepProb:kp}
36 | kp = 1.0; testDict = {L0do.keepProb:kp}
37 | logName = None #logName = 'logs/Conv'
38 |
39 |
40 |
41 | # Training and evaluation
42 | crossEntropy = -tf.reduce_sum(y_*tf.log(y)) # cost function
43 | trainStep = tf.train.GradientDescentOptimizer(0.01).minimize(crossEntropy)
44 | trainStep = tf.train.AdamOptimizer(1e-4).minimize(crossEntropy)
45 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
46 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
47 | train(session=session,trainingData=mnist.train,testingData=mnist.test,truth=y_,input=x,cost=crossEntropy,trainingStep=trainStep,accuracy=accuracy,iterations=trainingIterations,miniBatch=100,trainDict=trainDict,testDict=testDict,logName=logName)
48 |
49 | # Mini viewer
50 | plotFields(L1,cmap=cm.coolwarm)
51 | example = mnist.test.next_batch(1); image = reshape(example[0][0],(28,28))
52 | feed_dict = {x:example[0],y_:example[1],L0do.keepProb:1.0}
53 | figure(1); clf(); subplot(231); imshow(image,cmap=cm.gray); title('Correct is %d' % where(example[1]>0)[1][0])
54 | subplot(232); plotOutput(L1,feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
55 | subplot(233); plotOutput(L2,feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
56 | subplot(235); plotOutput(L3,feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
57 | subplot(236); plotOutput(L4,feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
58 | subplot(234); plotOutput(L6,fieldShape=[10,1],feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
59 |
60 | # Individual interesting fields
61 | # plotOutput(L1,feed_dict={x:example[0],y_:example[1]},cmap=cm.inferno); figure(2); clf(); imshow(image,cmap=cm.gray)
62 | # plotOutput(L3,fieldShape=[11,12],feed_dict=feed_dict,cmap=cm.inferno); figure(2); clf(); imshow(image,cmap=cm.gray)
63 | # plotOutput(L6,fieldShape=[10,1],feed_dict=feed_dict,cmap=cm.inferno); figure(2); clf(); imshow(image,cmap=cm.gray)
64 |
65 |
66 |
--------------------------------------------------------------------------------
/4_FullyConvolutionalNetworks/README.md:
--------------------------------------------------------------------------------
1 | # Session 4 - Machine Learning With Uncertain Bounds
2 | This workshop introduces fully convolutional neural networks and illustrates the importance of using machine learning itself to do as much of the work as possible. As an example problem, we will be trying to locate and identify handwritten characters randomly placed on an arbitrary sized page.
3 |
4 | The code for this session requires Python, Numpy, Matplotlib and TensorFlow. Python can be obtained from python.org. We recommend pip (distributed with Python) for installation of the others.
5 |
6 | Once you have Python installed, you can install the required modules with the following commands:
7 |
8 | ```pip install Numpy```
9 |
10 | ```pip install Matplotlib```
11 |
12 | ```pip install TensorFlow```
13 |
14 | If you installed TensorFlow prior to July 1, 2016, use the command:
15 |
16 | ```pip install --upgrade TensorFlow```
17 |
18 | to grab the latest version.
19 |
20 | Also make sure you download the .py files in this directory. If you've got a copy of TensorFlowInterface.py from a previous session, make sure you grab this one as it has some new bits.
21 |
22 |
--------------------------------------------------------------------------------
/4_FullyConvolutionalNetworks/fc.py:
--------------------------------------------------------------------------------
1 | from tfs import *
2 | from tfs import input_data
3 | from pylab import *
4 | from numpy import *
5 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
6 | matplotlib.interactive(True)
7 | session = tf.InteractiveSession()
8 |
9 |
10 | # Hacky class to add a null option to the MNIST one hot vector (position 10)
11 | class MNISTModifier(object):
12 |
13 | def __init__(self,data):
14 | self.data = data
15 |
16 | def next_batch(self,miniBatch):
17 | batch = list(self.data.next_batch(miniBatch))
18 | batch[1] = np.hstack((batch[1],zeros([shape(batch[1])[0]]+[1])))
19 | return batch
20 |
21 | class Container(object):
22 |
23 | def __init__(self,mnist):
24 | self.train = MNISTModifier(mnist.train)
25 | self.test = MNISTModifier(mnist.test)
26 |
27 |
28 | def makeBigImage(data,Ndigits=5,width=100,height=100,overlap=False,digitShape=[28,28],maxTries=1000):
29 | newImage = zeros((height,width),float32)
30 | truthImage = zeros(list(shape(newImage))+[11],float32)
31 | batch = data.next_batch(Ndigits)
32 | tries = 0
33 | while Ndigits > 0:
34 | y,x = np.random.randint(0,height-digitShape[0],2)
35 | if not np.any(truthImage[y:y+digitShape[0],x:x+digitShape[0]]) or overlap:
36 | newImage[y:y+digitShape[0],x:x+digitShape[0]] = batch[0][Ndigits-1].reshape(digitShape)
37 | truthImage[y:y+digitShape[0],x:x+digitShape[0]] = batch[1][Ndigits-1]
38 | Ndigits -= 1; tries = 0
39 | else:
40 | tries += 1
41 | if tries > maxTries:
42 | break
43 | truthImage[:,:,10] += np.all(truthImage<0.5,axis=-1)
44 | return (newImage,truthImage)
45 |
46 |
47 |
48 | # Hack our MNIST dataset so it has a null option
49 | mnist = Container(mnist)
50 |
51 | # x = tf.placeholder('float',shape=[None,784],name='input') # Input tensor
52 | # y_ = tf.placeholder('float', shape=[None,11],name='correctLabels') # Correct labels
53 |
54 | trainingIterations = 1000
55 | height = width = 100
56 | x2 = tf.placeholder('float',shape=[None,height,width],name='input2') # Input tensor; we shouldn't need to specify dimensions except TensorFlow....
57 | y_2 = tf.placeholder('float', shape=[None,height,width,11],name='correctLabels2') # Correct labels
58 |
59 |
60 | inLayer = tf.expand_dims(x2,-1)
61 | L1 = Conv2D(inLayer,[5,5,1,32],'Conv1')
62 | L2 = MaxPool2x2(L1.output,'MaxPool1')
63 | L3 = Conv2D(L2.output,[5,5,32,64],'Conv2')
64 | L4 = MaxPool2x2(L3.output,'MaxPool2')
65 | L5 = Conv2D(L4.output,[7,7,64,128],'relu1-conv')
66 | L6 = ConvSoftMax(L5.output,[1,1,128,11],'softmax-conv')
67 | #L7 = Resample(L6.output,L1.input.get_shape().as_list()[1:3],'upsample')
68 | y = L6.output
69 |
70 | trainDict = {}
71 | testDict = {}
72 |
73 |
74 | truthDownsampleLayer = Resample(y_2,L6.output.get_shape().as_list()[1:3],'ydownsample')
75 | y2 = L6.output; y_2b = truthDownsampleLayer.output
76 |
77 | crossEntropy = -tf.reduce_sum(y_2b*tf.log(y2)) # cost function
78 | trainStep = tf.train.AdamOptimizer(1e-4).minimize(crossEntropy)
79 | correctPrediction = tf.equal(tf.argmax(y2,3), tf.argmax(y_2b,3))
80 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
81 |
82 | print("Training Image recognizer")
83 | iterations = trainingIterations; batchSize = 2
84 | lastTime = 0; lastIterations = 0; trainingStep=trainStep; accuracy=accuracy;
85 | tf.global_variables_initializer().run()
86 |
87 | for i in range(iterations): # Do some more training
88 | # batchIndices = random.choice(range(0,len(trainingData)),batchSize)
89 | # batch = [trainingData[batchIndices],truthData[batchIndices]]
90 | batch = list(zip(*[makeBigImage(data=mnist.train,Ndigits=5,width=width,height=height,overlap=False) for j in range(0,3)]))
91 | if (i%100 == 0) or (time.time()-lastTime > 5):
92 | testDict.update({x2:batch[0],y_2:batch[1]})
93 | testAccuracy = session.run([accuracy],feed_dict=testDict)[0]
94 | print('Accuracy at batch {}: {} ({} samples/s)'.format(i,testAccuracy,(i-lastIterations)/(time.time()-lastTime)*batchSize))
95 | lastTime = time.time(); lastIterations = i
96 |
97 | trainDict.update({x2:batch[0],y_2:batch[1]})
98 | trainingStep.run(feed_dict=trainDict)
99 |
--------------------------------------------------------------------------------
/4_FullyConvolutionalNetworks/fullyConvolutional.py:
--------------------------------------------------------------------------------
1 | from tfs import *
2 | from tfs import input_data
3 | from pylab import *
4 | from numpy import *
5 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
6 | matplotlib.interactive(True)
7 | session = tf.InteractiveSession()
8 |
9 | # Hacky class to add a null option to the MNIST one hot vector (position 10)
10 | class MNISTModifier(object):
11 |
12 | def __init__(self,data):
13 | self.data = data
14 |
15 | def next_batch(self,miniBatch):
16 | batch = list(self.data.next_batch(miniBatch))
17 | batch[1] = np.hstack((batch[1],zeros([shape(batch[1])[0]]+[1])))
18 | return batch
19 |
20 | class Container(object):
21 |
22 | def __init__(self,mnist):
23 | self.train = MNISTModifier(mnist.train)
24 | self.test = MNISTModifier(mnist.test)
25 |
26 |
27 | # Hack our MNIST dataset so it has a null option
28 | mnist = Container(mnist)
29 |
30 | x = tf.placeholder('float',shape=[None,784],name='input') # Input tensor
31 | y_ = tf.placeholder('float', shape=[None,11],name='correctLabels') # Correct labels
32 |
33 | xImage = tf.reshape(x,[-1,28,28,1]) # Reshape samples to 28x28x1 images
34 | trainingIterations = 1000
35 |
36 | # Standard conv net from Session 3
37 | L1 = Conv2D(xImage,[5,5,1,32],'Conv1')
38 | L2 = MaxPool2x2(L1.output,'MaxPool1')
39 | L0do = Dropout(L2.output,'dropout')
40 | L3 = Conv2D(L2.output,[5,5,32,64],'Conv2')
41 | L4 = MaxPool2x2(L3.output,'MaxPool2')
42 | L5 = ReLu(L4.output,128,'relu1')
43 | L6 = SoftMax(L5.output,11,'softmax')
44 | y = L6.output
45 | kp = 0.5; trainDict = {L0do.keepProb:kp}
46 | kp = 1.0; testDict = {L0do.keepProb:kp}
47 | logName = None #logName = 'logs/Conv'
48 |
49 |
50 | # Training and evaluation
51 | crossEntropy = -tf.reduce_sum(y_*tf.log(y)) # cost function
52 | trainStep = tf.train.GradientDescentOptimizer(0.01).minimize(crossEntropy)
53 | trainStep = tf.train.AdamOptimizer(1e-4).minimize(crossEntropy)
54 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
55 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
56 | train(session=session,trainingData=mnist.train,testingData=mnist.test,truth=y_,input=x,cost=crossEntropy,trainingStep=trainStep,accuracy=accuracy,iterations=trainingIterations,miniBatch=100,trainDict=trainDict,testDict=testDict,logName=logName)
57 |
58 |
59 |
60 | # Now turn our trained conv net into a fully convolutional network by replacing the fully
61 | # connected layers (L5 and L6) with convoluational layers
62 | # Note that I'm copying the L5 and L6 weights and biases into the new layers
63 |
64 | L5fc = Conv2D(L4.output,[7,7,64,128],'relu1-conv')
65 | L5fc.W = tf.reshape(L5.W,[7,7,64,128])
66 | L5fc.b = L5.b
67 | L5fc.setupOutput()
68 |
69 | L6fc = ConvSoftMax(L5fc.output,[1,1,128,11],'softmax-conv')
70 | L6fc.W = tf.reshape(L6.W,[1,1,128,11])
71 | L6fc.b = L6.b
72 | L6fc.setupOutput()
73 |
74 | # This last layer upsamples the output back up to the input size for comparison
75 | L7 = Resample(L6fc.output,L1.input.get_shape().as_list()[1:3],'upsample')
76 |
77 |
78 | # Choose an example and show it for comparison
79 | example = mnist.test.next_batch(1); image = reshape(example[0][0],(28,28))
80 | feed_dict = {x:example[0],y_:example[1],L0do.keepProb:1.0}
81 |
82 | # Regular convolutional network
83 | figure('Convolutional Network'); clf(); subplot(231); imshow(image,cmap=cm.gray); title('Correct is %d' % where(example[1]>0)[1][0])
84 | subplot(232); plotOutput(L1,feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
85 | subplot(233); plotOutput(L2,feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
86 | subplot(235); plotOutput(L3,feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
87 | subplot(236); plotOutput(L4,feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
88 | subplot(234); plotOutput(L6,fieldShape=[11,1],feed_dict=feed_dict,cmap=cm.inferno,figOffset=None);
89 |
90 | # Fully convolutional network
91 | figure('Fully Convolutional Network'); clf(); subplot(121); imshow(np.argmax(L7.output.eval(feed_dict=feed_dict),axis=-1)[0],vmin=0,vmax=10); colorbar(); title('Digit Identification')
92 | contour(image,[0.5],colors=['k'])
93 | subplot(122); imshow(np.max(L7.output.eval(feed_dict=feed_dict),axis=-1)[0],cmap=cm.gray); colorbar(); title('Strength of Identification')
94 | contour(image,[0.5],colors=['b'])
95 |
96 |
97 |
98 | # Do a bit more training but stick a null image in each batch to teach the network about
99 | # places where there is no value. This code copied from TensorFlowInterface
100 | nullImage = [zeros(28*28,float32)]; nullTruth = array([zeros(11,float32)]); nullTruth[:,0] = 1.
101 | trainingData = mnist.train; iterations = trainingIterations; miniBatch = 100
102 | lastTime = 0; lastIterations = 0; trainingStep=trainStep; accuracy=accuracy
103 | for i in range(iterations): # Do some more training
104 | batch = list(trainingData.next_batch(miniBatch))
105 | batch[0] = np.concatenate((batch[0],nullImage)); batch[1] = concatenate((batch[1],nullTruth))
106 | if (i%100 == 0) or (time.time()-lastTime > 5):
107 | testDict.update({x:batch[0],y_:batch[1]})
108 | testAccuracy = session.run([accuracy],feed_dict=testDict)[0]
109 | print('Accuracy at batch {}: {} ({} samples/s)'.format(i,testAccuracy,(i-lastIterations)/(time.time()-lastTime)*miniBatch))
110 | lastTime = time.time(); lastIterations = i
111 |
112 | trainDict.update({x:batch[0],y_:batch[1]})
113 | trainingStep.run(feed_dict=trainDict)
114 |
115 |
116 | # Plot again and see the difference
117 | figure('Fully Convolutional Network With Null Images'); clf(); subplot(121); imshow(np.argmax(L7.output.eval(feed_dict=feed_dict),axis=-1)[0],vmin=0,vmax=10); colorbar(); title('Digit Identification')
118 | contour(image,[0.5],colors=['k'])
119 | subplot(122); imshow(np.max(L7.output.eval(feed_dict=feed_dict),axis=-1)[0],cmap=cm.gray); colorbar(); title('Strength of Identification')
120 | contour(image,[0.5],colors=['b'])
121 |
122 |
123 |
124 | # Make a bigger image with several numbers in it and see if we can find their location
125 | # AND identify them!
126 |
127 | def makeBigImage(data,Ndigits=5,width=100,height=100,overlap=False,digitShape=[28,28],maxTries=1000):
128 | newImage = zeros((height,width),float32)
129 | truthImage = zeros(list(shape(newImage))+[11],float32)
130 | batch = data.next_batch(Ndigits)
131 | tries = 0
132 | while Ndigits > 0:
133 | y,x = np.random.randint(0,height-digitShape[0],2)
134 | if not np.any(truthImage[y:y+digitShape[0],x:x+digitShape[0]]) or overlap:
135 | newImage[y:y+digitShape[0],x:x+digitShape[0]] = batch[0][Ndigits-1].reshape(digitShape)
136 | truthImage[y:y+digitShape[0],x:x+digitShape[0]] = batch[1][Ndigits-1]
137 | Ndigits -= 1; tries = 0
138 | else:
139 | tries += 1
140 | if tries > maxTries:
141 | break
142 | truthImage[:,:,10] += np.all(truthImage<0.5,axis=-1)
143 | return (newImage,truthImage)
144 |
145 | height = width = 100
146 | newImage,truthImage = makeBigImage(data = mnist.train,Ndigits=5,width=width,height=height,overlap=False)
147 |
148 | # What's it look like?
149 | figure('Big Image and Truth'); clf(); subplot(121); imshow(newImage,cmap=cm.gray); subplot(122); imshow(np.argmax(truthImage,axis=-1),vmin=0,vmax=10); colorbar()
150 |
151 | # We need new placeholders to hold the bigger image
152 | x2 = tf.placeholder('float',shape=[None,height,width],name='input2') # Input tensor; we shouldn't need to specify dimensions except TensorFlow....
153 | y_2 = tf.placeholder('float', shape=[None,height,width,11],name='correctLabels2') # Correct labels
154 |
155 | # We now need to rebuild our network to work with the new input
156 | lastLayerOutput = tf.expand_dims(x2,-1) # Add the extra dummy dimension
157 | for layer in [L1,L2,L3,L4,L5fc,L6fc]:
158 | layer.input = lastLayerOutput;
159 | layer.setupOutput()
160 | lastLayerOutput = layer.output
161 |
162 | # Need to make a new L7 to match the input
163 | L7 = Resample(L6fc.output,L1.input.get_shape().as_list()[1:3],'upsample2')
164 |
165 |
166 |
167 | # Forward prop
168 | feed_dict = {x2:[newImage],y_2:[truthImage],L0do.keepProb:1.0}
169 | figure('Before We Train The FC Net'); clf(); subplot(121); imshow(np.argmax(L7.output.eval(feed_dict=feed_dict),axis=-1)[0],vmin=0,vmax=10); colorbar(); title('Digit Identification')
170 | contour(newImage,[0.5],colors=['k'])
171 | subplot(122); imshow(np.max(L7.output.eval(feed_dict=feed_dict),axis=-1)[0],cmap=cm.gray); colorbar(); title('Strength of Identification')
172 | contour(newImage,[0.5],colors=['b'])
173 |
174 |
175 | # Train again, on the big image specifically
176 | # Tensorflow doesn't know how to do gradients on interpolated images (!) so lets downsample
177 | # the truth to match the L6 output
178 |
179 | truthDownsampleLayer = Resample(y_2,L6fc.output.get_shape().as_list()[1:3],'ydownsample')
180 |
181 | y2 = L6fc.output; y_2b = truthDownsampleLayer.output
182 | crossEntropy = -tf.reduce_sum(y_2b*tf.log(y2)) # cost function
183 | trainStep = tf.train.AdamOptimizer(1e-4).minimize(crossEntropy)
184 | correctPrediction = tf.equal(tf.argmax(y2,3), tf.argmax(y_2b,3))
185 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
186 |
187 | tf.initialize_all_variables().run()
188 |
189 | print("Training Image recognizer")
190 | iterations = trainingIterations; batchSize = 2
191 | lastTime = 0; lastIterations = 0; trainingStep=trainStep; accuracy=accuracy;
192 | for i in range(iterations): # Do some more training
193 | # batchIndices = random.choice(range(0,len(trainingData)),batchSize)
194 | # batch = [trainingData[batchIndices],truthData[batchIndices]]
195 | batch = zip(*[makeBigImage(data=mnist.train,Ndigits=5,width=width,height=height,overlap=False) for j in range(0,3)])
196 | if (i%100 == 0) or (time.time()-lastTime > 5):
197 | testDict.update({x2:batch[0],y_2:batch[1]})
198 | testAccuracy = session.run([accuracy],feed_dict=testDict)[0]
199 | print('Accuracy at batch {}: {} ({} samples/s)'.format(i,testAccuracy,(i-lastIterations)/(time.time()-lastTime)*batchSize))
200 | lastTime = time.time(); lastIterations = i
201 |
202 | trainDict.update({x2:batch[0],y_2:batch[1]})
203 | trainingStep.run(feed_dict=trainDict)
204 |
205 |
206 | feed_dict = {x2:[newImage],y_2:[truthImage],L0do.keepProb:1.0}
207 | classification = np.argmax(L7.output.eval(feed_dict=feed_dict),axis=-1)[0]
208 | confidence = np.max(L7.output.eval(feed_dict=feed_dict),axis=-1)[0]
209 | figure('After FC Net Trained'); clf(); subplot(121); imshow(classification,vmin=0,vmax=10); colorbar(); title('Digit Identification')
210 | contour(newImage,[0.5],colors=['k'])
211 | subplot(122); imshow(confidence,cmap=cm.gray); colorbar(); title('Strength of Identification')
212 | contour(newImage,[0.5],colors=['b'])
213 |
214 | figure('Final Output'); clf(); imshow(confidence*10,cmap=cm.gray); imshow(classification,vmin=0,vmax=10,alpha=0.3); colorbar()
215 | contour(newImage,[0.5],colors=['k'])
216 |
--------------------------------------------------------------------------------
/5_Autoencoders/TensorFlowInterface.py:
--------------------------------------------------------------------------------
1 | """The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Robert A. Brown (www.robbtech.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | """
23 |
24 |
25 | import tensorflow as tf
26 | import math
27 | import pylab as mpl
28 | import numpy as np
29 | import time
30 | from collections import OrderedDict
31 |
32 |
33 | def weightVariable(shape,std=1.0,name=None):
34 | # Create a set of weights initialized with truncated normal random values
35 | name = 'weights' if name is None else name
36 | return tf.get_variable(name,shape,initializer=tf.truncated_normal_initializer(stddev=std/math.sqrt(shape[0])))
37 |
38 | def biasVariable(shape,bias=0.1,name=None):
39 | # create a set of bias nodes initialized with a constant 0.1
40 | name = 'biases' if name is None else name
41 | return tf.get_variable(name,shape,initializer=tf.constant_initializer(bias))
42 |
43 | def conv2d(x,W,name=None):
44 | # return an op that convolves x with W
45 | return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME',name=name)
46 |
47 | def conv3d(x,W,name=None):
48 | # return an op that convolves x with W
49 | return tf.nn.conv3d(x,W,strides=[1,1,1,1,1],padding='SAME',name=name)
50 |
51 | def max_pool_2x2(x,name=None):
52 | # return an op that performs max pooling across a 2D image
53 | return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME',name=name)
54 |
55 | def max_pool(x,shape,name=None):
56 | # return an op that performs max pooling across a 2D image
57 | return tf.nn.max_pool(x,ksize=[1]+shape+[1],strides=[1]+shape+[1],padding='SAME',name=name)
58 |
59 | def max_pool3d(x,shape,name=None):
60 | # return an op that performs max pooling across a 2D image
61 | return tf.nn.max_pool3d(x,ksize=[1]+shape+[1],strides=[1]+shape+[1],padding='SAME',name=name)
62 |
63 |
64 | def plotFields(layer,fieldShape=None,channel=None,maxFields=25,figName='ReceptiveFields',cmap=None,padding=0.01):
65 | # Receptive Fields Summary
66 | W = layer.W
67 | wp = W.eval().transpose();
68 | if len(np.shape(wp)) < 4: # Fully connected layer, has no shape
69 | fields = np.reshape(wp,list(wp.shape[0:-1])+fieldShape)
70 | else: # Convolutional layer already has shape
71 | features, channels, iy, ix = np.shape(wp)
72 | if channel is not None:
73 | fields = wp[:,channel,:,:]
74 | else:
75 | fields = np.reshape(wp,[features*channels,iy,ix])
76 |
77 | fieldsN = min(fields.shape[0],maxFields)
78 | perRow = int(math.floor(math.sqrt(fieldsN)))
79 | perColumn = int(math.ceil(fieldsN/float(perRow)))
80 |
81 | fig = mpl.figure(figName); mpl.clf()
82 |
83 | # Using image grid
84 | from mpl_toolkits.axes_grid1 import ImageGrid
85 | grid = ImageGrid(fig,111,nrows_ncols=(perRow,perColumn),axes_pad=padding,cbar_mode='single')
86 | for i in range(0,fieldsN):
87 | im = grid[i].imshow(fields[i],cmap=cmap);
88 |
89 | grid.cbar_axes[0].colorbar(im)
90 | mpl.title('%s Receptive Fields' % layer.name)
91 |
92 | # old way
93 | # fields2 = np.vstack([fields,np.zeros([perRow*perColumn-fields.shape[0]] + list(fields.shape[1:]))])
94 | # tiled = []
95 | # for i in range(0,perColumn*perRow,perColumn):
96 | # tiled.append(np.hstack(fields2[i:i+perColumn]))
97 | #
98 | # tiled = np.vstack(tiled)
99 | # mpl.figure(figOffset); mpl.clf(); mpl.imshow(tiled,cmap=cmap); mpl.title('%s Receptive Fields' % layer.name); mpl.colorbar();
100 | mpl.figure(figName+' Total'); mpl.clf(); mpl.imshow(np.sum(np.abs(fields),0),cmap=cmap); mpl.title('%s Total Absolute Input Dependency' % layer.name); mpl.colorbar()
101 |
102 |
103 |
104 | def plotOutput(layer,feed_dict,fieldShape=None,channel=None,figOffset=1,cmap=None):
105 | # Output summary
106 | W = layer.output
107 | wp = W.eval(feed_dict=feed_dict);
108 | if len(np.shape(wp)) < 4: # Fully connected layer, has no shape
109 | temp = np.zeros(np.product(fieldShape)); temp[0:np.shape(wp.ravel())[0]] = wp.ravel()
110 | fields = np.reshape(temp,[1]+fieldShape)
111 | else: # Convolutional layer already has shape
112 | wp = np.rollaxis(wp,3,0)
113 | features, channels, iy,ix = np.shape(wp)
114 | if channel is not None:
115 | fields = wp[:,channel,:,:]
116 | else:
117 | fields = np.reshape(wp,[features*channels,iy,ix])
118 |
119 | perRow = int(math.floor(math.sqrt(fields.shape[0])))
120 | perColumn = int(math.ceil(fields.shape[0]/float(perRow)))
121 | fields2 = np.vstack([fields,np.zeros([perRow*perColumn-fields.shape[0]] + list(fields.shape[1:]))])
122 | tiled = []
123 | for i in range(0,perColumn*perRow,perColumn):
124 | tiled.append(np.hstack(fields2[i:i+perColumn]))
125 |
126 | tiled = np.vstack(tiled)
127 | if figOffset is not None:
128 | mpl.figure(figOffset); mpl.clf();
129 |
130 | mpl.imshow(tiled,cmap=cmap); mpl.title('%s Output' % layer.name); mpl.colorbar();
131 |
132 |
133 |
134 | def train(session,trainingData,testingData,input,truth,cost,trainingStep,accuracy=None,iterations=5000,miniBatch=100,trainDict={},testDict=None,logName=None,initialize=True,addSummaryOps=True,plot=True):
135 | testDict = trainDict if testDict is None else testDict
136 |
137 | metrics = OrderedDict(cost=cost) if accuracy is None else OrderedDict(cost=cost,accuracy=accuracy)
138 | history = []
139 |
140 | if addSummaryOps:
141 | costSummary = tf.scalar_summary("Cost Function", cost)
142 | if accuracy is not None:
143 | accuracySummary = tf.scalar_summary("accuracy", accuracy)
144 | mergedSummary = tf.merge_all_summaries()
145 | if logName is not None:
146 | writer = tf.train.SummaryWriter(logName, session.graph_def)
147 |
148 | if initialize:
149 | tf.initialize_all_variables().run() # Take initial values and actually put them in variables
150 |
151 | startTime = lastTime = time.time(); lastIterations = 0
152 | if iterations < 0:
153 | print "Training for %0.2f hours" % -iterations
154 | else:
155 | print "Doing %d iterations" % iterations
156 | done = False; i = 0;
157 | while not done: # Do some training
158 | batch = trainingData.next_batch(miniBatch)
159 |
160 | now = time.time()
161 | # Print some summary stats
162 | if (i%100 == 0) or (now-lastTime > 5):
163 | testDict.update({input:batch[0],truth:batch[1]})
164 | # Training accuracy for TensorBoard
165 | if addSummaryOps:
166 | testResults = session.run([mergedSummary]+metrics.values(),feed_dict=testDict)
167 | testResults = dict(zip(['summary']+metrics.keys(),testResults))
168 | if logName is not None:
169 | writer.add_summary(testResults['summary'],i)
170 | else:
171 | if accuracy is not None:
172 | testResults = session.run(metrics.values(),feed_dict=testDict)
173 | testResults = dict(zip(metrics.keys(),testResults))
174 |
175 | testResults.pop('summary',None)
176 |
177 | print 'Training Performance at batch %d: (%g samples/s)' % (i,(i-lastIterations)/(now-lastTime)*miniBatch)
178 | for k,v in testResults.items():
179 | if not k == 'summary':
180 | print ' %s: %g' % (k,v)
181 |
182 | lastTime = time.time(); lastIterations = i
183 |
184 | testResults['iteration'] = i
185 | testResults['time'] = now
186 | history.append(testResults)
187 | if plot:
188 | timecourses = OrderedDict(zip(history[0].keys(),zip(*[hist.values() for hist in history])))
189 | elapsed = np.array(timecourses['time']) - timecourses['time'][0]
190 | for k,v in timecourses.items():
191 | if not k in ['iteration','time']:
192 | mpl.figure('Training %s' % k); mpl.clf()
193 | mpl.plot(elapsed,v,alpha=0.5,marker='o')
194 | mpl.pause(0.000000001)
195 |
196 |
197 | trainDict.update({input:batch[0],truth:batch[1]})
198 | trainingStep.run(feed_dict=trainDict)
199 | i += 1
200 | if iterations > 0:
201 | if i > iterations:
202 | done = True
203 | else:
204 | if (now - startTime) / 3600. > -iterations:
205 | done = True
206 |
207 |
208 | # try:
209 | # # Only works with mnist-type data object
210 | # testDict.update({input:testingData.images, truth:testingData.labels})
211 | # print 'Test accuracy: %g' % accuracy.eval(feed_dict=testDict)
212 | # except:
213 | # pass
214 |
215 |
216 |
217 |
218 |
219 | class Layer(object):
220 |
221 | def __init__(self,input,units,name,std=1.0,bias=0.1):
222 | self.input = input
223 | self.units = units
224 | self.name = name
225 | self.initialize(std=std,bias=bias)
226 | self.setupOutput()
227 | self.setupSummary()
228 |
229 | def initialize(self):
230 | pass
231 |
232 | def setupOutput(self):
233 | pass
234 |
235 | def setupSummary(self):
236 | pass
237 |
238 |
239 | class UtilityLayer(Layer):
240 |
241 | def __init__(self,input,name):
242 | self.input = input
243 | self.name = name
244 | self.initialize()
245 | self.setupOutput()
246 | self.setupSummary()
247 |
248 |
249 | class Linear(Layer):
250 |
251 | def initialize(self,std=1.0,bias=0.1):
252 | with tf.variable_scope(self.name):
253 | self.inputShape = np.product([i.value for i in self.input.get_shape()[1:] if i.value is not None])
254 | self.W = weightVariable([self.inputShape,self.units],std=std)
255 | self.b = biasVariable([self.units],bias=bias)
256 |
257 | def setupOutput(self):
258 | if len(self.input.get_shape()) > 2:
259 | input = tf.reshape(self.input,[-1,self.inputShape]) # flatten reduced image into a vector
260 | else:
261 | input = self.input
262 | self.output = tf.matmul(input,self.W)
263 |
264 | def setupSummary(self):
265 | self.WHist = tf.histogram_summary("%s/weights" % self.name, self.W)
266 | self.BHist = tf.histogram_summary("%s/biases" % self.name, self.b)
267 | self.outputHist = tf.histogram_summary("%s/output" % self.name, self.output)
268 |
269 |
270 |
271 | class SoftMax(Layer):
272 |
273 | def initialize(self,std=1.0,bias=0.1):
274 | with tf.variable_scope(self.name):
275 | self.inputShape = np.product([i.value for i in self.input.get_shape()[1:] if i.value is not None])
276 | self.W = weightVariable([self.inputShape,self.units],std=std)
277 | self.b = biasVariable([self.units],bias=bias)
278 |
279 | def setupOutput(self):
280 | if len(self.input.get_shape()) > 2:
281 | input = tf.reshape(self.input,[-1,self.inputShape]) # flatten reduced image into a vector
282 | else:
283 | input = self.input
284 | self.output = tf.nn.softmax(tf.matmul(input,self.W) + self.b)
285 |
286 | def setupSummary(self):
287 | self.WHist = tf.histogram_summary("%s/weights" % self.name, self.W)
288 | self.BHist = tf.histogram_summary("%s/biases" % self.name, self.b)
289 | self.outputHist = tf.histogram_summary("%s/output" % self.name, self.output)
290 |
291 |
292 | class ReLu(SoftMax):
293 |
294 | def setupOutput(self):
295 | if len(self.input.get_shape()) > 2:
296 | input = tf.reshape(self.input,[-1,self.inputShape]) # flatten reduced image into a vector
297 | else:
298 | input = self.input
299 | self.output = tf.nn.relu(tf.matmul(input,self.W) + self.b)
300 |
301 |
302 | class Conv2D(SoftMax):
303 |
304 | def __init__(self,input,shape,name,std=1.0,bias=0.1):
305 | self.input = input
306 | self.units = shape[-1]
307 | self.shape = shape
308 | self.name = name
309 | self.initialize(std=std,bias=bias)
310 | self.setupOutput()
311 | self.setupSummary()
312 |
313 |
314 | def initialize(self,std=1.0,bias=0.1):
315 | with tf.variable_scope(self.name):
316 | self.W = weightVariable(self.shape,std=std) # YxX patch, Z contrast, outputs to N neurons
317 | self.b = biasVariable([self.shape[-1]],bias=bias) # N bias variables to go with the N neurons
318 |
319 | def setupOutput(self):
320 | self.output = tf.nn.relu(conv2d(self.input,self.W) + self.b)
321 |
322 |
323 | class ConvSoftMax(Conv2D):
324 |
325 | def setupOutput(self):
326 | inputShape = self.input.get_shape()
327 | convResult = conv2d(self.input,self.W) + self.b
328 |
329 | convResult = tf.reshape(convResult,[-1,self.units]) # flatten reduced image into a vector
330 | softMaxed = tf.nn.softmax(convResult)
331 | self.output = tf.reshape(softMaxed,[-1] + inputShape[1:3].as_list() + [self.units])
332 |
333 |
334 | class Conv3D(Conv2D):
335 |
336 | def setupOutput(self):
337 | self.output = tf.nn.relu(conv3d(self.input,self.W) + self.b)
338 |
339 |
340 | class Conv3DSoftMax(ConvSoftMax):
341 |
342 | def setupOutput(self):
343 | inputShape = self.input.get_shape()
344 | convResult = conv3d(self.input,self.W) + self.b
345 |
346 | convResult = tf.reshape(convResult,[-1,self.units]) # flatten reduced image into a vector
347 | softMaxed = tf.nn.softmax(convResult)
348 | self.output = tf.reshape(softMaxed,[-1] + inputShape[1:4].as_list() + [self.units])
349 |
350 |
351 |
352 | class MaxPool2x2(UtilityLayer):
353 |
354 | def setupOutput(self):
355 | with tf.variable_scope(self.name):
356 | self.output = max_pool_2x2(self.input)
357 |
358 |
359 |
360 | class MaxPool(UtilityLayer):
361 |
362 | def __init__(self,input,shape,name):
363 | self.shape = shape
364 | super(MaxPool,self).__init__(input,name)
365 |
366 | def setupOutput(self):
367 | with tf.variable_scope(self.name):
368 | self.output = max_pool(self.input,shape=self.shape)
369 |
370 |
371 | class MaxPool3D(MaxPool):
372 |
373 | def setupOutput(self):
374 | with tf.variable_scope(self.name):
375 | self.output = max_pool3d(self.input,shape=self.shape)
376 |
377 |
378 | class L2Norm(UtilityLayer):
379 |
380 | def __init__(self,input,name):
381 | super(L2Norm,self).__init__(input,name)
382 |
383 | def setupOutput(self):
384 | with tf.variable_scope(self.name):
385 | self.output = tf.nn.l2_normalize(self.input,-1)
386 |
387 |
388 | class Resample(UtilityLayer):
389 |
390 | def __init__(self,input,outputShape,name,method=tf.image.ResizeMethod.BICUBIC,alignCorners=True):
391 | self.outputShape = outputShape
392 | self.method = method
393 | self.alignCorners = alignCorners
394 | super(Resample,self).__init__(input,name)
395 |
396 | def setupOutput(self):
397 | with tf.variable_scope(self.name):
398 | self.output = tf.image.resize_images(self.input,self.outputShape[0],self.outputShape[1],method=self.method)#,align_corners=self.alignCorners)
399 |
400 |
401 | class Dropout(UtilityLayer):
402 |
403 | def __init__(self,input,name):
404 | self.input = input
405 | self.name = name
406 | super(Dropout,self).__init__(input,name)
407 |
408 | def initialize(self):
409 | with tf.variable_scope(self.name):
410 | self.keepProb = tf.placeholder('float') # Variable to hold the dropout probability
411 |
412 | def setupOutput(self):
413 | with tf.variable_scope(self.name):
414 | self.output = tf.nn.dropout(self.input,self.keepProb)
415 | self.output.get_shape = self.input.get_shape # DEBUG: remove this whenever TensorFlow fixes this bug
416 |
417 |
418 |
419 | #*** Main Part ***
420 | if __name__ == '__main__':
421 | import input_data
422 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
423 | session = tf.InteractiveSession()
424 |
425 | x = tf.placeholder('float',shape=[None,784],name='input') # Input tensor
426 | y_ = tf.placeholder('float', shape=[None,10],name='correctLabels') # Correct labels
427 | trainingIterations = 5000
428 |
429 | # L1 = ReLu(x,512,'relu1')
430 | # L2 = ReLu(L1.output,128,'relu2')
431 | # L3 = ReLu(L2.output,64,'relu3')
432 | # L4 = SoftMax(x,10,'softmax')
433 | # y = L4.output
434 | # trainDict = {}; testDict = trainDict
435 | # logName = 'logs/softmax'
436 |
437 |
438 | xImage = tf.reshape(x,[-1,28,28,1]) # Reshape samples to 28x28x1 images
439 | L1 = Conv2D(xImage,[5,5,1,32],'Conv1')
440 | L2 = MaxPool2x2(L1.output,'MaxPool1')
441 | L3 = Conv2D(L2.output,[5,5,32,64],'Conv2')
442 | L4 = MaxPool2x2(L3.output,'MaxPool2')
443 | L5 = ReLu(L4.output,128,'relu1')
444 | L6 = Dropout(L5.output,'dropout')
445 | L7 = SoftMax(L5.output,10,'softmax')
446 | y = L7.output
447 | kp = 0.5; trainDict = {L6.keepProb:kp}
448 | kp = 1.0; testDict = {L6.keepProb:kp}
449 | logName = 'logs/Conv'
450 |
451 | # Training and evaluation
452 | crossEntropy = -tf.reduce_sum(y_*tf.log(y)) # cost function
453 | trainStep = tf.train.GradientDescentOptimizer(0.01).minimize(crossEntropy)
454 | trainStep = tf.train.AdamOptimizer(1e-4).minimize(crossEntropy)
455 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
456 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
457 | train(session=session,trainingData=mnist.train,testingData=mnist.test,truth=y_,input=x,cost=crossEntropy,trainingStep=trainStep,accuracy=accuracy,iterations=trainingIterations,miniBatch=100,trainDict=trainDict,testDict=testDict,logName=logName)
458 |
459 | #plotFields(L1,[28,28],figOffset=1)
460 |
--------------------------------------------------------------------------------
/5_Autoencoders/autoencoderMNIST.py:
--------------------------------------------------------------------------------
1 | from TensorFlowInterface import *
2 | import input_data
3 | from pylab import *
4 | from numpy import *
5 | import copy
6 |
7 | mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
8 | matplotlib.interactive(True)
9 | session = tf.InteractiveSession()
10 |
11 | x = tf.placeholder('float',shape=[None,784],name='input') # Input tensor
12 | y_ = tf.placeholder('float', shape=[None,10],name='correctLabels') # Correct labels
13 |
14 |
15 |
16 | # --------------------- Fully connected network with dropout ---------------------
17 |
18 | trainingIterations = -8
19 | yp = x
20 | inputDO = Dropout(x,'inputDropout')
21 |
22 | layerPlan = [100,50]
23 | layerPlan = [500,300,100];
24 |
25 | layers = dict(encoder=[],decoder=[]); inLayer = inputDO
26 | for l,nUnits in enumerate(layerPlan):
27 | layer = ReLu(inLayer.output,nUnits,'encoder%d'%l)
28 | dropout = Dropout(layer.output,'encoderDO%d'%l)
29 | layers['encoder'].append([layer,dropout]); inLayer = dropout
30 |
31 | for l,nUnits in enumerate(layerPlan[::-1]):
32 | layer = ReLu(inLayer.output,nUnits,'decoder%d'%l)
33 | dropout = Dropout(layer.output,'decoderDO%d'%l)
34 | layers['decoder'].append([layer,dropout]); inLayer = dropout
35 |
36 | layer = ReLu(inLayer.output,784,'decoder%d'%(l+1))
37 | layers['decoder'].append([layer,None])
38 | y = layer.output
39 |
40 | inputKP = 0.7; hiddenKP = 0.3
41 | #inputKP = 1.0; hiddenKP = 1.0
42 | trainDict = dict([(layer[1].keepProb,inputKP) for layer in layers['encoder']])
43 | trainDict.update(dict([(layer[1].keepProb,inputKP) for layer in layers['decoder'] if layer[1] is not None]))
44 | trainDict[inputDO.keepProb] = hiddenKP
45 |
46 | testDict = dict([(layer[1].keepProb,1.0) for layer in layers['encoder']])
47 | testDict.update(dict([(layer[1].keepProb,1.0) for layer in layers['decoder'] if layer[1] is not None]))
48 | testDict[inputDO.keepProb] = 1.0
49 |
50 | logName = 'logs/autoencoderFullyConnected'
51 |
52 | # ----------------------------------------------------------------------------------
53 |
54 | # --------------------- Convnet with dropout ---------------------
55 | if 0:
56 | trainingIterations = 1000
57 | xImage = tf.reshape(x,[-1,28,28,1]) # Reshape samples to 28x28x1 images
58 | yp = xImage
59 |
60 | inputDO = Dropout(xImage,'inputDropout')
61 | layerPlan = [25,9]; layers = dict(encoder=[],decoder=[]); inLayer = inputDO; lastUnits = 1
62 | for l,nUnits in enumerate(layerPlan):
63 | layer = Conv2D(inLayer.output,[5,5,lastUnits,nUnits],'encoder%d'%l)
64 | dropout = Dropout(layer.output,'encoderDO%d'%l)
65 | layers['encoder'].append([layer,dropout]); inLayer = dropout; lastUnits = nUnits
66 |
67 | for l,nUnits in enumerate(layerPlan[::-1]):
68 | layer = Conv2D(inLayer.output,[5,5,lastUnits,nUnits],'decoder%d'%l)
69 | dropout = Dropout(layer.output,'decoderDO%d'%l)
70 | layers['decoder'].append([layer,dropout]); inLayer = dropout; lastUnits = nUnits
71 |
72 | layer = Conv2D(inLayer.output,[5,5,lastUnits,nUnits],'decoder%d'%(l+1))
73 | layers['decoder'].append([layer,None])
74 | y = layer.output
75 |
76 | inputKP = 0.7; hiddenKP = 0.3
77 | #inputKP = 1.0; hiddenKP = 1.0
78 | trainDict = dict([(layer[1].keepProb,inputKP) for layer in layers['encoder']])
79 | trainDict.update(dict([(layer[1].keepProb,inputKP) for layer in layers['decoder'] if layer[1] is not None]))
80 | trainDict[inputDO.keepProb] = hiddenKP
81 |
82 | testDict = dict([(layer[1].keepProb,1.0) for layer in layers['encoder']])
83 | testDict.update(dict([(layer[1].keepProb,1.0) for layer in layers['decoder'] if layer[1] is not None]))
84 | testDict[inputDO.keepProb] = 1.0
85 |
86 | logName = 'logs/autoencoderFullyConnected'
87 |
88 |
89 | # Standard conv net
90 | # L1 = Conv2D(xImage,[5,5,1,32],'Conv1')
91 | # L2 = MaxPool2x2(L1.output,'MaxPool1')
92 | # L0do = Dropout(L2.output,'dropout')
93 | # L3 = Conv2D(L2.output,[5,5,32,64],'Conv2')
94 | # L4 = MaxPool2x2(L3.output,'MaxPool2')
95 | # L5 = ReLu(L4.output,128,'relu1')
96 | # L6 = SoftMax(L5.output,10,'softmax')
97 | # y = L6.output
98 | # kp = 0.5; trainDict = {L0do.keepProb:kp}
99 | # kp = 1.0; testDict = {L0do.keepProb:kp}
100 | # logName = None #logName = 'logs/Conv'
101 |
102 |
103 |
104 | # Training and evaluation
105 |
106 | # Mean squared error between the input and reconstruction
107 | cost = tf.sqrt(tf.reduce_mean(tf.square(yp-y)))
108 |
109 | trainStep = tf.train.AdamOptimizer(1e-4).minimize(cost)
110 | train(session=session,trainingData=mnist.train,testingData=mnist.test,truth=y_,input=x,cost=cost,trainingStep=trainStep,iterations=trainingIterations,miniBatch=100,trainDict=trainDict,testDict=testDict,logName=logName)
111 |
112 |
113 | # Mini viewer
114 | plotFields(layers['encoder'][0][0],fieldShape=[28,28],maxFields=100,cmap=cm.coolwarm)
115 |
116 |
117 |
118 | example = mnist.test.next_batch(1); image = reshape(example[0][0],(28,28))
119 | testDict.update({x:example[0],y_:example[1]})
120 |
121 | for l in range(len(layers['encoder'])):
122 | figure('Layer Output'); clf()
123 | layer = layers['encoder'][l][0]
124 | fieldShape = [ceil(sqrt(layer.units)),ceil(layer.units/ceil(sqrt(layer.units)))]
125 | plotOutput(layer,feed_dict=testDict,fieldShape=fieldShape,cmap=cm.inferno,figOffset=None);
126 | savefig('test/layer%dOutput.pdf' % l,transparent=True)
127 |
128 | figure('digitOriginal'); clf();
129 | imshow(example[0].reshape((28,28)),cmap=cm.gray)
130 | savefig('test/digitOriginal.jpg')
131 | recon = session.run(y,feed_dict=testDict)
132 | figure('digitReconstructed'); clf();
133 | imshow(recon.reshape((28,28)),cmap=cm.gray)
134 | savefig('test/digitOriginalRecon.jpg')
135 |
136 | snr = 5.1
137 | image = copy.deepcopy(example[0]);
138 | image += random.normal(0,1./snr,shape(image))
139 | figure('noisy image'); clf();
140 | imshow(image.reshape((28,28)),cmap=cm.gray)
141 | savefig('test/digitSNR%0.1f.jpg'%snr)
142 |
143 | testDict.update({x:image})
144 | recon = session.run(y,feed_dict=testDict)
145 | figure('reconstruction'); clf();
146 | imshow(recon.reshape((28,28)),cmap=cm.gray)
147 | savefig('test/digitSNR%dRecon.jpg'%snr)
148 |
--------------------------------------------------------------------------------
/5_Autoencoders/digitOriginal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robb-brown/IntroToDeepLearning/ac6398427d0ac829e119122dafba1981bd68ff98/5_Autoencoders/digitOriginal.jpg
--------------------------------------------------------------------------------
/5_Autoencoders/digitOriginalRecon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robb-brown/IntroToDeepLearning/ac6398427d0ac829e119122dafba1981bd68ff98/5_Autoencoders/digitOriginalRecon.jpg
--------------------------------------------------------------------------------
/5_Autoencoders/digitSNR10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robb-brown/IntroToDeepLearning/ac6398427d0ac829e119122dafba1981bd68ff98/5_Autoencoders/digitSNR10.jpg
--------------------------------------------------------------------------------
/5_Autoencoders/digitSNR10Recon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robb-brown/IntroToDeepLearning/ac6398427d0ac829e119122dafba1981bd68ff98/5_Autoencoders/digitSNR10Recon.jpg
--------------------------------------------------------------------------------
/5_Autoencoders/input_data.py:
--------------------------------------------------------------------------------
1 | """Functions for downloading and reading MNIST data."""
2 | from __future__ import absolute_import
3 | from __future__ import division
4 | from __future__ import print_function
5 |
6 | import gzip
7 | import os
8 |
9 | import numpy
10 | from six.moves import urllib
11 | from six.moves import xrange # pylint: disable=redefined-builtin
12 |
13 | import traceback
14 |
15 | SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/'
16 |
17 |
18 | def maybe_download(filename, work_directory):
19 | """Download the data from Yann's website, unless it's already here."""
20 | if not os.path.exists(work_directory):
21 | os.mkdir(work_directory)
22 | filepath = os.path.join(work_directory, filename)
23 | if not os.path.exists(filepath):
24 | filepath, _ = urllib.request.urlretrieve(SOURCE_URL + filename, filepath)
25 | statinfo = os.stat(filepath)
26 | print('Succesfully downloaded', filename, statinfo.st_size, 'bytes.')
27 | return filepath
28 |
29 |
30 | def _read32(bytestream):
31 | dt = numpy.dtype(numpy.uint32).newbyteorder('>')
32 | return numpy.frombuffer(bytestream.read(4), dtype=dt)
33 |
34 |
35 | def extract_images(filename):
36 | """Extract the images into a 4D uint8 numpy array [index, y, x, depth]."""
37 | print('Extracting', filename)
38 | with gzip.open(filename) as bytestream:
39 | magic = _read32(bytestream)
40 | if magic != 2051:
41 | raise ValueError(
42 | 'Invalid magic number %d in MNIST image file: %s' %
43 | (magic, filename))
44 | num_images = _read32(bytestream)
45 | rows = _read32(bytestream)
46 | cols = _read32(bytestream)
47 | buf = bytestream.read(rows * cols * num_images)
48 | data = numpy.frombuffer(buf, dtype=numpy.uint8)
49 | data = data.reshape(num_images, rows, cols, 1)
50 | return data
51 |
52 |
53 | def dense_to_one_hot(labels_dense, num_classes=10):
54 | """Convert class labels from scalars to one-hot vectors."""
55 | num_labels = labels_dense.shape[0]
56 | index_offset = numpy.arange(num_labels) * num_classes
57 | labels_one_hot = numpy.zeros((num_labels, num_classes))
58 | labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1
59 | return labels_one_hot
60 |
61 |
62 | def extract_labels(filename, one_hot=False):
63 | """Extract the labels into a 1D uint8 numpy array [index]."""
64 | print('Extracting', filename)
65 | with gzip.open(filename) as bytestream:
66 | magic = _read32(bytestream)
67 | if magic != 2049:
68 | raise ValueError(
69 | 'Invalid magic number %d in MNIST label file: %s' %
70 | (magic, filename))
71 | num_items = _read32(bytestream)
72 | buf = bytestream.read(num_items)
73 | labels = numpy.frombuffer(buf, dtype=numpy.uint8)
74 | if one_hot:
75 | return dense_to_one_hot(labels)
76 | return labels
77 |
78 |
79 | class DataSet(object):
80 |
81 | def __init__(self, images, labels, fake_data=False):
82 | if fake_data:
83 | self._num_examples = 10000
84 | else:
85 | assert images.shape[0] == labels.shape[0], (
86 | "images.shape: %s labels.shape: %s" % (images.shape,
87 | labels.shape))
88 | self._num_examples = images.shape[0]
89 |
90 | # Convert shape from [num examples, rows, columns, depth]
91 | # to [num examples, rows*columns] (assuming depth == 1)
92 | self.imageShape = images.shape[1:]
93 | self.imageChannels = self.imageShape[2]
94 |
95 | images = images.reshape(images.shape[0],
96 | images.shape[1] * images.shape[2] * images.shape[3])
97 | # Convert from [0, 255] -> [0.0, 1.0].
98 | images = images.astype(numpy.float32)
99 | images = numpy.multiply(images, 1.0 / 255.0)
100 | self._images = images
101 | self._labels = labels
102 | try:
103 | if len(numpy.shape(self._labels)) == 1:
104 | self._labels = dense_to_one_hot(self._labels,len(numpy.unique(self._labels)))
105 | except:
106 | traceback.print_exc()
107 | self._epochs_completed = 0
108 | self._index_in_epoch = 0
109 |
110 | @property
111 | def images(self):
112 | return self._images
113 |
114 | @property
115 | def labels(self):
116 | return self._labels
117 |
118 | @property
119 | def num_examples(self):
120 | return self._num_examples
121 |
122 | @property
123 | def epochs_completed(self):
124 | return self._epochs_completed
125 |
126 | def next_batch(self, batch_size, fake_data=False):
127 | """Return the next `batch_size` examples from this data set."""
128 | if fake_data:
129 | fake_image = [1.0 for _ in xrange(784)]
130 | fake_label = 0
131 | return [fake_image for _ in xrange(batch_size)], [
132 | fake_label for _ in xrange(batch_size)]
133 | start = self._index_in_epoch
134 | self._index_in_epoch += batch_size
135 | if self._index_in_epoch > self._num_examples:
136 | # Finished epoch
137 | self._epochs_completed += 1
138 | # Shuffle the data
139 | perm = numpy.arange(self._num_examples)
140 | numpy.random.shuffle(perm)
141 | self._images = self._images[perm]
142 | self._labels = self._labels[perm]
143 | # Start next epoch
144 | start = 0
145 | self._index_in_epoch = batch_size
146 | assert batch_size <= self._num_examples
147 | end = self._index_in_epoch
148 | return self._images[start:end], self._labels[start:end]
149 |
150 |
151 | def read_data_sets(train_dir, fake_data=False, one_hot=False):
152 | class DataSets(object):
153 | pass
154 | data_sets = DataSets()
155 |
156 | if fake_data:
157 | data_sets.train = DataSet([], [], fake_data=True)
158 | data_sets.validation = DataSet([], [], fake_data=True)
159 | data_sets.test = DataSet([], [], fake_data=True)
160 | return data_sets
161 |
162 | TRAIN_IMAGES = 'train-images-idx3-ubyte.gz'
163 | TRAIN_LABELS = 'train-labels-idx1-ubyte.gz'
164 | TEST_IMAGES = 't10k-images-idx3-ubyte.gz'
165 | TEST_LABELS = 't10k-labels-idx1-ubyte.gz'
166 | VALIDATION_SIZE = 5000
167 |
168 | local_file = maybe_download(TRAIN_IMAGES, train_dir)
169 | train_images = extract_images(local_file)
170 |
171 | local_file = maybe_download(TRAIN_LABELS, train_dir)
172 | train_labels = extract_labels(local_file, one_hot=one_hot)
173 |
174 | local_file = maybe_download(TEST_IMAGES, train_dir)
175 | test_images = extract_images(local_file)
176 |
177 | local_file = maybe_download(TEST_LABELS, train_dir)
178 | test_labels = extract_labels(local_file, one_hot=one_hot)
179 |
180 | validation_images = train_images[:VALIDATION_SIZE]
181 | validation_labels = train_labels[:VALIDATION_SIZE]
182 | train_images = train_images[VALIDATION_SIZE:]
183 | train_labels = train_labels[VALIDATION_SIZE:]
184 |
185 | data_sets.train = DataSet(train_images, train_labels)
186 | data_sets.validation = DataSet(validation_images, validation_labels)
187 | data_sets.test = DataSet(test_images, test_labels)
188 |
189 | return data_sets
190 |
--------------------------------------------------------------------------------
/6_MRISegmentation/ccseg.py:
--------------------------------------------------------------------------------
1 | from tfs import *
2 | from pylab import *
3 | from numpy import *
4 | import glob, os
5 | import nibabel as nib
6 | import numpy
7 |
8 | matplotlib.interactive(True)
9 | session = tf.InteractiveSession()
10 |
11 | dataPath = './corpusCallosum/'
12 |
13 |
14 |
15 | # Class to serve up segmented images
16 | def computePad(dims,depth):
17 | y1=y2=x1=x2=0;
18 | y,x = [numpy.ceil(dims[i]/float(2**depth)) * (2**depth) for i in range(-2,0)]
19 | x = float(x); y = float(y);
20 | y1 = int(numpy.floor((y - dims[-2])/2)); y2 = int(numpy.ceil((y - dims[-2])/2))
21 | x1 = int(numpy.floor((x - dims[-1])/2)); x2 = int(numpy.ceil((x - dims[-1])/2))
22 | return y1,y2,x1,x2
23 |
24 |
25 | def padImage(img,depth):
26 | """Pads (or crops) an image so it is evenly divisible by 2**depth."""
27 | y1,y2,x1,x2 = computePad(img.shape,depth)
28 | dims = [(0,0) for i in img.shape]
29 | dims[-2] = (y1,y2); dims[-1] = (x1,x2)
30 | return numpy.pad(img,dims,'constant')
31 |
32 |
33 | # Class to serve up segmented images
34 | class CCData(object):
35 |
36 | def __init__(self,paths,padding=None):
37 | self.paths = paths
38 | self.padding = padding
39 |
40 | def getSlices(self,paths):
41 | image,truth = paths
42 | image = nib.load(image).get_data(); truth = nib.load(truth).get_data()
43 | slicesWithValues = [unique(s) for s in where(truth>0)]
44 | sliceAxis = argmin([len(s) for s in slicesWithValues])
45 | slicesWithValues = slicesWithValues[sliceAxis]
46 | slc = repeat(-1,3); slc[sliceAxis] = slicesWithValues[0]
47 | if not self.padding is None:
48 | image, truth = [padImage(im,self.padding) for im in (image[slc][0],truth[slc][0])]
49 | else:
50 | image, truth = (image[slc][0],truth[slc][0])
51 | return (image,truth)
52 |
53 | def next_batch(self,miniBatch=None):
54 | if miniBatch is None or miniBatch==len(self.paths):
55 | batch = arange(0,len(self.paths))
56 | else:
57 | batch = random.choice(arange(0,len(self.paths)),miniBatch)
58 | images = [self.getSlices(self.paths[i]) for i in batch]
59 | return list(zip(*images))
60 |
61 |
62 | class Container(object):
63 |
64 | def __init__(self,dataPath,reserve=2,**args):
65 | self.dataPath = dataPath
66 | images = glob.glob(os.path.join(dataPath,'?????.nii.gz'))
67 | images = [(i,i.replace('.nii.gz','_cc.nii.gz')) for i in images]
68 | self.train = CCData(images[0:-reserve],**args)
69 | self.test = CCData(images[reserve:],**args)
70 |
71 |
72 |
73 | data = Container(dataPath,reserve=2,padding=2)
74 | batch = data.train.next_batch(2)
75 |
76 | trainingIterations = 1000
77 |
78 | x = tf.placeholder('float',shape=[None,None,None],name='input')
79 | y_ = tf.placeholder('float', shape=[None,None,None],name='truth')
80 | y_OneHot = tf.one_hot(indices=tf.cast(y_,tf.int32),depth=2,name='truthOneHot')
81 | xInput = tf.expand_dims(x,axis=3,name='xInput')
82 |
83 |
84 |
85 | #Standard conv net from Session 3 using new TensorFlow layers
86 | net = LD1 = tf.layers.conv2d(
87 | inputs=xInput,
88 | filters=4,
89 | kernel_size=[5,5],
90 | strides = 1,
91 | padding = 'same',
92 | activation=tf.nn.relu,
93 | name='convD1'
94 | )
95 |
96 | net = LO = tf.layers.conv2d(
97 | inputs=net,
98 | filters=2,
99 | kernel_size=[5,5],
100 | strides = 1,
101 | padding = 'same',
102 | activation=tf.nn.relu,
103 | name='convLO'
104 | )
105 |
106 |
107 | logits = LO
108 | y = tf.nn.softmax(logits,-1)
109 |
110 | loss = tf.losses.softmax_cross_entropy(onehot_labels=y_OneHot, logits=logits)
111 |
112 |
113 | trainDict = {}
114 | testDict = {}
115 | logName = None #logName = 'logs/Conv'
116 |
117 |
118 | # Training and evaluation
119 | trainStep = tf.train.AdamOptimizer(1e-3).minimize(loss)
120 |
121 | # Accuracy
122 | correctPrediction = tf.equal(tf.argmax(y,axis=-1), tf.argmax(y_OneHot,axis=-1))
123 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
124 |
125 | # Jaccard
126 | output = tf.cast(tf.argmax(y,axis=-1), dtype=tf.float32)
127 | truth = tf.cast(tf.argmax(y_OneHot,axis=-1), dtype=tf.float32)
128 | intersection = tf.reduce_sum(tf.reduce_sum(tf.multiply(output, truth), axis=-1),axis=-1)
129 | union = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.add(output, truth)>= 1, dtype=tf.float32), axis=-1),axis=-1)
130 | jaccard = tf.reduce_mean(intersection / union)
131 |
132 | train(session=session,trainingData=data.train,testingData=data.test,truth=y_,input=x,cost=loss,trainingStep=trainStep,accuracy=jaccard,iterations=trainingIterations,miniBatch=2,trainDict=trainDict,testDict=testDict,logName=logName)
133 | # Get a couple of test examples
134 | batch = data.test.next_batch(2)
135 | d = {x:batch[0][0:1],y_:batch[1][0:1]}
136 | print("Test set Jaccard Index: {}").format(jaccard.eval(d))
137 |
138 |
139 | # Make a figure
140 | ex = array(batch[0])
141 | segmentation = y.eval({x:ex})
142 |
143 | # Display each example
144 | figure('Example 1'); clf()
145 | imshow(batch[0][0].transpose(),cmap=cm.gray,origin='lower left');
146 | #contour(batch[1][0].transpose(),alpha=0.5,color='g');
147 | contour(segmentation[0,:,:,1].transpose(),alpha=0.5,color='b')
148 | figure('Example 2'); clf()
149 | imshow(batch[0][1].transpose(),cmap=cm.gray,origin='lower left');
150 | #contour(batch[1][1].transpose(),alpha=0.5,color='g');
151 | contour(segmentation[1,:,:,1].transpose(),alpha=0.5,color='b')
152 | plotOutput(LD1,{x:ex[0:1]},figOffset='Layer 1 Output')
153 |
--------------------------------------------------------------------------------
/6_MRISegmentation/corpusCallosum.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robb-brown/IntroToDeepLearning/ac6398427d0ac829e119122dafba1981bd68ff98/6_MRISegmentation/corpusCallosum.tar.gz
--------------------------------------------------------------------------------
/6_MRISegmentation/support/ccseg.py:
--------------------------------------------------------------------------------
1 | from tfs import *
2 | from pylab import *
3 | import numpy
4 | from numpy import *
5 | import tensorflow as tf
6 | import glob, os
7 | import nibabel as nib
8 |
9 | matplotlib.interactive(True)
10 | session = tf.InteractiveSession()
11 |
12 | dataPath = '../corpusCallosum/'
13 |
14 |
15 | def computePad(dims,depth):
16 | y1=y2=x1=x2=0;
17 | y,x = [numpy.ceil(dims[i]/float(2**depth)) * (2**depth) for i in range(-2,0)]
18 | x = float(x); y = float(y);
19 | y1 = int(numpy.floor((y - dims[-2])/2)); y2 = int(numpy.ceil((y - dims[-2])/2))
20 | x1 = int(numpy.floor((x - dims[-1])/2)); x2 = int(numpy.ceil((x - dims[-1])/2))
21 | return y1,y2,x1,x2
22 |
23 |
24 | def padImage(img,depth):
25 | """Pads (or crops) an image so it is evenly divisible by 2**depth."""
26 | y1,y2,x1,x2 = computePad(img.shape,depth)
27 | dims = [(0,0) for i in img.shape]
28 | dims[-2] = (y1,y2); dims[-1] = (x1,x2)
29 | return numpy.pad(img,dims,'constant')
30 |
31 |
32 | # Class to serve up segmented images
33 | class CCData(object):
34 |
35 | def __init__(self,paths,padding=None):
36 | self.paths = paths
37 | self.padding = padding
38 |
39 | def getSlices(self,paths):
40 | image,truth = paths
41 | image = nib.load(image).get_data(); truth = nib.load(truth).get_data()
42 | slicesWithValues = [unique(s) for s in where(truth>0)]
43 | sliceAxis = argmin([len(s) for s in slicesWithValues])
44 | slicesWithValues = slicesWithValues[sliceAxis]
45 | slc = repeat(-1,3); slc[sliceAxis] = slicesWithValues[0]
46 | if not self.padding is None:
47 | image, truth = [padImage(im,self.padding) for im in (image[slc][0],truth[slc][0])]
48 | else:
49 | image, truth = (image[slc][0],truth[slc][0])
50 | return (image,truth)
51 |
52 | def next_batch(self,miniBatch=None):
53 | if miniBatch is None or miniBatch==len(self.paths):
54 | batch = arange(0,len(self.paths))
55 | else:
56 | batch = random.choice(arange(0,len(self.paths)),miniBatch)
57 | images = [self.getSlices(self.paths[i]) for i in batch]
58 | return list(zip(*images))
59 |
60 |
61 | class Container(object):
62 |
63 | def __init__(self,dataPath,reserve=2,**args):
64 | self.dataPath = dataPath
65 | images = glob.glob(os.path.join(dataPath,'?????.nii.gz'))
66 | images = [(i,i.replace('.nii.gz','_cc.nii.gz')) for i in images]
67 | self.train = CCData(images[0:-reserve],**args)
68 | self.test = CCData(images[reserve:],**args)
69 |
70 |
71 | data = Container(dataPath,reserve=2,padding=3)
72 |
73 | trainingIterations = 5000
74 |
75 | x = tf.placeholder('float',shape=[None,None,None],name='input')
76 | y_ = tf.placeholder('float', shape=[None,None,None],name='truth')
77 | y_OneHot = tf.one_hot(indices=tf.cast(y_,tf.int32),depth=2,name='truthOneHot')
78 | xInput = tf.expand_dims(x,axis=3,name='xInput')
79 |
80 | # ------------------------ Standard conv net from Session 3 ---------------------------------
81 | # net = LD1 = Conv2D(xInput,[5,5,1,10],strides=1,name='Conv1')
82 | # net = LD2 = Conv2D(net.output,[5,5,10,20],strides=1,name='Conv2')
83 | # net = LSM = ConvSoftMax(net.output,[1,1,20,2],name='softmax-conv')
84 | # y = net.output
85 |
86 | # ------------------------- Standard conv net from Session 3 using new TensorFlow layers ---------------------------
87 | # net = LD1 = tf.layers.conv2d(
88 | # inputs=xInput,
89 | # filters=10,
90 | # kernel_size=[5,5],
91 | # strides = 1,
92 | # padding = 'same',
93 | # activation=tf.nn.relu,
94 | # name='convD1'
95 | # )
96 | # net = LD2 = tf.layers.conv2d(
97 | # inputs=net,
98 | # filters=20,
99 | # kernel_size=[5,5],
100 | # strides = 1,
101 | # padding = 'same',
102 | # activation=tf.nn.relu,
103 | # name='convD2'
104 | # )
105 | # net = LTop = tf.layers.conv2d(
106 | # inputs=net,
107 | # filters=2,
108 | # kernel_size=[5,5],
109 | # strides = 1,
110 | # padding = 'same',
111 | # activation=tf.nn.relu,
112 | # name='topRelu'
113 | # )
114 |
115 |
116 | # ---------------------------------------- U Net ---------------------------------------
117 |
118 | net = LD1 = tf.layers.conv2d(
119 | inputs=xInput,
120 | filters=10,
121 | kernel_size=[5,5],
122 | strides = 2,
123 | padding = 'same',
124 | activation=tf.nn.relu,
125 | name='convD1'
126 | )
127 | net = LD2 = tf.layers.conv2d(
128 | inputs=net,
129 | filters=20,
130 | kernel_size=[5,5],
131 | strides = 2,
132 | padding = 'same',
133 | activation=tf.nn.relu,
134 | name='convD2'
135 | )
136 | net = LB = tf.layers.conv2d(
137 | inputs=net,
138 | filters=30,
139 | kernel_size=[5,5],
140 | strides = 1,
141 | padding = 'same',
142 | activation=tf.nn.relu,
143 | name='convBottom'
144 | )
145 | net = LU2 = tf.layers.conv2d_transpose(
146 | inputs=net,
147 | filters=20,
148 | kernel_size=[5,5],
149 | strides = 2,
150 | padding = 'same',
151 | activation=tf.nn.relu,
152 | name='convU2'
153 | )
154 | net = LU1 = tf.layers.conv2d_transpose(
155 | inputs=net,
156 | filters=10,
157 | kernel_size=[5,5],
158 | strides = 2,
159 | padding = 'same',
160 | activation=tf.nn.relu,
161 | name='convU1'
162 | )
163 | net = LTop = tf.layers.conv2d(
164 | inputs=net,
165 | filters=2,
166 | kernel_size=[5,5],
167 | strides = 1,
168 | padding = 'same',
169 | activation=None,
170 | name='logits'
171 | )
172 |
173 | logits = LTop
174 | y = tf.nn.softmax(logits,-1)
175 |
176 | kp = 0.5; trainDict = {}#{L0do.keepProb:kp}
177 | kp = 1.0; testDict = {}#{L0do.keepProb:kp}
178 | logName = None #logName = 'logs/Conv'
179 |
180 |
181 | # Training and evaluation
182 | loss = tf.losses.softmax_cross_entropy(onehot_labels=y_OneHot, logits=logits)
183 | #loss = -tf.reduce_sum(y_OneHot*tf.log(y+1e-6))
184 | trainStep = tf.train.AdamOptimizer(1e-3).minimize(loss)
185 |
186 | # Accuracy
187 | correctPrediction = tf.equal(tf.argmax(y,axis=-1), tf.argmax(y_OneHot,axis=-1))
188 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
189 |
190 | # Jaccard
191 | output = tf.cast(tf.argmax(y,axis=-1), dtype=tf.float32)
192 | truth = tf.cast(tf.argmax(y_OneHot,axis=-1), dtype=tf.float32)
193 | intersection = tf.reduce_sum(tf.reduce_sum(tf.multiply(output, truth), axis=-1),axis=-1)
194 | union = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.add(output, truth)>= 1, dtype=tf.float32), axis=-1),axis=-1)
195 | jaccard = tf.reduce_mean(intersection / union)
196 |
197 |
198 | train(session=session,trainingData=data.train,testingData=data.test,truth=y_,input=x,cost=loss,trainingStep=trainStep,accuracy=jaccard,iterations=trainingIterations,miniBatch=2,trainDict=trainDict,testDict=testDict,logName=logName)
199 |
200 |
201 | # Make a figure
202 | # Get a couple of examples
203 | batch = data.test.next_batch(2)
204 | d = {x:batch[0][0:1],y_:batch[1][0:1]}
205 | ex = array(batch[0])
206 | segmentation = y.eval({x:ex})
207 |
208 | # Display each example
209 | # Display each example
210 | figure('Example 1'); clf()
211 | imshow(batch[0][0].transpose(),cmap=cm.gray,origin='lower left');
212 | #contour(batch[1][0].transpose(),alpha=0.5,color='g');
213 | contour(segmentation[0,:,:,1].transpose(),alpha=0.5,color='b')
214 | figure('Example 2'); clf()
215 | imshow(batch[0][1].transpose(),cmap=cm.gray,origin='lower left');
216 | #contour(batch[1][1].transpose(),alpha=0.5,color='g');
217 | contour(segmentation[1,:,:,1].transpose(),alpha=0.5,color='b')
218 | plotOutput(LD1,{x:ex[0:1]},figOffset='Layer 1 Output')
219 | plotOutput(LD2,{x:ex[0:1]},figOffset='Layer 2 Output')
220 | plotOutput(LU1,{x:ex[0:1]},figOffset='Layer 2 Output')
221 |
222 |
223 |
--------------------------------------------------------------------------------
/6_MRISegmentation/support/prepareData.py:
--------------------------------------------------------------------------------
1 | import nibabel as nib
2 | import glob,os
3 | import numpy
4 |
5 | dataPath = '.'
6 |
7 | images = glob.glob(os.path.join(dataPath,'?????.nii.gz'))
8 | images = [(i,i.replace('.nii.gz','_cc.nii.gz')) for i in images]
9 |
10 | for image in images:
11 | im = nib.load(image[0]); mask = nib.load(image[1])
12 | slices = numpy.unique(numpy.where(mask.get_data()>0)[0])
13 | im2 = im.get_data()[slices.min()-1:slices.max()+2]
14 | mask2 = mask.get_data()[slices.min()-1:slices.max()+2]
15 | im2 = nib.Nifti1Image(im2.astype(numpy.int16),im.affine)
16 | nib.save(im2,os.path.join(dataPath,'smaller',os.path.basename(image[0])))
17 | mask2 = nib.Nifti1Image(mask2.astype(numpy.uint8),mask.affine)
18 | nib.save(mask2,os.path.join(dataPath,'smaller',os.path.basename(image[1])))
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Robert Brown
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Notes for the Practical Deep Learning Series
2 | This repo contains workshop notes and code from a deep learning seminar series, first presented as the Practical Deep Learning Series with the Toronto Data Literacy Group.
3 |
4 | A presentation of this workshop was also livestreamed from the Montreal Neurological Institute Brain Imaging Centre. The video (8 hours, uncut) is available here (free registration required).
5 |
6 | Session 1 discuses background theory for artificial neural networks (ANNs), deep learning, and computation graph based libraries, particularly Google's TensorFlow.
7 |
8 | Session 2 introduces the ANNs covered in session 1 in the form of TensorFlow code.
9 |
10 | Session 3 covers convolutional networks
11 |
12 | Session 4 and 5 are under development, but cover fully convolutional networks and autoencoders, respectively.
13 |
14 | INSTALLATION
15 |
16 | Prerequisites:
17 |
18 | If you are using Linux, make sure you have a compiler toolchain installed (e.g. gcc). Generally Linux distributions come with this installed by default.
19 |
20 | If on OS X, you will need the developer tools from Apple installed. If you're on a recent version of OS X (El Capitan +) you can install just the command line tools by following the instructions at http://osxdaily.com/2014/02/12/install-command-line-tools-mac-os-x/.
21 |
22 | If you're using Windows, you will also need to install gcc. The easiest way to do this is probably to get the Anaconda Python distribution from https://anaconda.org/anaconda/python. If you're using Anaconda, replace "pip install" with "conda install" in the following instructions. If you have difficulty installing TensorFlow with conda, try pip install instead.
23 |
24 | Installation instructions:
25 |
26 | 1) If you do not already have a copy of python 3.6+, install it from python.org or your Linux distribution's package manager.
27 |
28 | 2) Download or clone this repository
29 |
30 | 3) From the main directory (the one with 1_Introduction, 2_Perceptron, etc.) type:
31 |
32 | pip install -e tfs
33 |
34 | This command should install the code for this workshop plus the dependencies numpy and matplotlib. The -e is optional, but installs the package with links so that if you update your github clone it will automatically update the installed module as well. Tensorflow is NOT installed as a dependency in this step because it is not available through pip for all systems.
35 |
36 | 4) Install tensorflow by following the platform specific instructions for your system at https://www.tensorflow.org/install/. Note that if you are using a Mac, pip install tensorflow will not work... you will have to use the alternate method.
37 |
38 | 5) if you change into the directory 2_Perceptron and type:
39 |
40 | python perceptronMNIST.py
41 |
42 | you should see a series of lines printed similar to "Accuracy at step 100: train: 0.77999997139".
43 |
44 |
45 |
46 | The CC-BY-ND license applies to the workshop notes only, not the code. The code is licensed under the MIT three-clause license (included here at in each source file) where applicable. The code in the file "input_data.py" found in Session1 is redistributed verbatim from Google's TensorFlow tutorial where it appears to be unlicensed. This code appears to originate with Yann LeCun.
47 |
48 | 
This work is licensed under a Creative Commons Attribution-NoDerivatives 4.0 International License.
49 |
50 |
51 | The MIT License (MIT)
52 |
53 | Copyright (c) 2015 Robert A. Brown (Github)
54 |
55 | Permission is hereby granted, free of charge, to any person obtaining a copy
56 | of this software and associated documentation files (the "Software"), to deal
57 | in the Software without restriction, including without limitation the rights
58 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
59 | copies of the Software, and to permit persons to whom the Software is
60 | furnished to do so, subject to the following conditions:
61 |
62 | The above copyright notice and this permission notice shall be included in all
63 | copies or substantial portions of the Software.
64 |
65 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
66 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
68 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
69 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
70 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
71 | SOFTWARE.
72 |
--------------------------------------------------------------------------------
/tfs/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | setup(name='tfs',
4 | version='0.1',
5 | description='Support Package for the Tensor Flow Deep Learning Seminar',
6 | url='http://github.com/robb-brown/DeepLearning',
7 | author='Robert A. Brown',
8 | author_email='robert.brown@mcgill.ca',
9 | license='MIT',
10 | packages=['tfs'],
11 | install_requires=[
12 | 'numpy',
13 | 'matplotlib',
14 | 'nibabel',
15 | ],
16 | zip_safe=False)
17 |
18 |
--------------------------------------------------------------------------------
/tfs/tfs/TensorFlowInterface.py:
--------------------------------------------------------------------------------
1 | """The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Robert A. Brown (www.robbtech.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | """
23 |
24 |
25 | import tensorflow as tf
26 | import math
27 | import pylab
28 | import numpy
29 | import time
30 |
31 |
32 | class Base(object):
33 |
34 | def __init__(self,name):
35 | self.name = name
36 | self.setup()
37 |
38 | def setup(self):
39 | pass
40 |
41 | def output(self):
42 | return None
43 |
44 |
45 | class Layer(Base):
46 |
47 | def __init__(self,inputShape,outputShape,activation,name,initialization=None):
48 | self.inputShape = inputShape
49 | self.outputShape = outputShape
50 | self.activation = activation
51 | self.name = name
52 | if initialization is None:
53 | initialization = 'random'
54 | self.initialization = initialization
55 |
56 | self.setup()
57 |
58 | def setup(self):
59 | if self.initialization == 'random':
60 | self.W = tf.Variable(tf.random.truncated_normal([self.inputShape,self.outputShape],stddev= 1.0 / math.sqrt(self.outputShape)),name=self.name+'W')
61 | elif self.initialization == 'zeros':
62 | self.W = tf.Variable(tf.zeros([self.inputShape,self.outputShape]),name=self.name+'W')
63 | self.b = tf.Variable(tf.zeros([self.outputShape]),name=self.name+'b')
64 |
65 | def variables(self):
66 | return [self.W,self.b]
67 |
68 | def output(self,x):
69 | return self.activation(tf.matmul(x,self.W) + self.b)
70 |
71 |
72 | class Model(Base):
73 |
74 | def __init__(self,layers,name):
75 | self.layers = layers
76 | self.name = name
77 | self.setup()
78 |
79 | def variables(self):
80 | variables = []
81 | for layer in self.layers:
82 | variables = variables + layer.variables()
83 | return variables
84 |
85 | def output(self, x):
86 | for layer in self.layers:
87 | x = layer.output(x)
88 | return x
89 |
90 |
91 | class CrossEntropyCost(Base):
92 |
93 | def output(self,y,y_):
94 | return -tf.reduce_sum(y_*tf.math.log(y))
95 |
96 |
97 | class AccuracyMetric(Base):
98 |
99 | def output(self,y,y_):
100 | correctPrediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
101 | accuracy = tf.reduce_mean(tf.cast(correctPrediction,'float'))
102 | return accuracy
103 |
104 |
105 | class Trainer(Base):
106 |
107 | def __init__(self,model,cost,metrics,name):
108 | self.model = model
109 | self.cost = cost
110 | self.metrics = metrics
111 | self.name = name
112 | self.setup()
113 |
114 | def gradient(self,x,y_):
115 | variables = self.model.variables()
116 | with tf.GradientTape() as tape:
117 | y = self.model.output(x=x)
118 | cost = self.cost.output(y=y,y_=y_)
119 | gradient = tape.gradient(target=cost,sources=variables)
120 | return gradient
121 |
122 | def train(self,data,iterations=3000,learning_rate=1e-3,batchSize=100):
123 | optimizer = tf.optimizers.Adam(learning_rate=learning_rate)
124 | variables = self.model.variables()
125 | for iteration in range(iterations):
126 | x,y_ = data.train.next_batch(batchSize)
127 | optimizer.apply_gradients(zip(self.gradient(x,y_),variables))
128 | if iteration % 100 == 0:
129 | y = self.model.output(x=x)
130 | print(f'Training metrics at step {iteration}:')
131 | print(f' {self.cost.name} = {self.cost.output(y=y,y_=y_)}')
132 | for metric in self.metrics:
133 | print(f' {metric.name} = {metric.output(y=y,y_=y_)}')
134 |
135 |
136 |
137 |
138 |
139 |
140 | def weightVariable(shape,std=1.0,name=None):
141 | # Create a set of weights initialized with truncated normal random values
142 | name = 'weights' if name is None else name
143 | return tf.get_variable(name,shape,initializer=tf.truncated_normal_initializer(stddev=std/math.sqrt(shape[0])))
144 |
145 | def biasVariable(shape,bias=0.1,name=None):
146 | # create a set of bias nodes initialized with a constant 0.1
147 | name = 'biases' if name is None else name
148 | return tf.get_variable(name,shape,initializer=tf.constant_initializer(bias))
149 |
150 | def conv2d(x,W,strides=[1,1,1,1],name=None):
151 | # return an op that convolves x with W
152 | strides = numpy.array(strides)
153 | if strides.size == 1:
154 | strides = numpy.array([1,strides,strides,1])
155 | elif strides.size == 2:
156 | strides = numpy.array([1,strides[0],strides[1],1])
157 | if numpy.any(strides < 1):
158 | strides = numpy.around(1./strides).astype(numpy.uint8)
159 | return tf.nn.conv2d_transpose(x,W,strides=strides.tolist(),padding='SAME',name=name)
160 | else:
161 | return tf.nn.conv2d(x,W,strides=strides.tolist(),padding='SAME',name=name)
162 |
163 |
164 | def conv3d(x,W,strides=1,name=None):
165 | # return an op that convolves x with W
166 | strides = numpy.array(strides)
167 | if strides.size == 1:
168 | strides = numpy.array([1,strides,strides,strides[0],1])
169 | elif strides.size == 3:
170 | strides = numpy.array([1,strides[0],strides[1],strides[2],1])
171 | if numpy.any(strides < 1):
172 | strides = numpy.around(1./strides).astype(numpy.uint8)
173 | return tf.nn.conv3d_transpose(x,W,strides=strides.tolist(),padding='SAME',name=name)
174 | else:
175 | return tf.nn.conv3d(x,W,strides=strides.tolist(),padding='SAME',name=name)
176 |
177 | def max_pool_2x2(x,name=None):
178 | # return an op that performs max pooling across a 2D image
179 | return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME',name=name)
180 |
181 | def max_pool(x,shape,name=None):
182 | # return an op that performs max pooling across a 2D image
183 | return tf.nn.max_pool(x,ksize=[1]+shape+[1],strides=[1]+shape+[1],padding='SAME',name=name)
184 |
185 | def max_pool3d(x,shape,name=None):
186 | # return an op that performs max pooling across a 2D image
187 | return tf.nn.max_pool3d(x,ksize=[1]+shape+[1],strides=[1]+shape+[1],padding='SAME',name=name)
188 |
189 |
190 | def plotFields(layer,fieldShape=None,channel=None,figOffset=1,cmap=None,padding=0.01):
191 | # Receptive Fields Summary
192 | try:
193 | W = layer.W
194 | except:
195 | W = layer
196 | wp = W.eval().transpose();
197 | if len(numpy.shape(wp)) < 4: # Fully connected layer, has no shape
198 | fields = numpy.reshape(wp,list(wp.shape[0:-1])+fieldShape)
199 | else: # Convolutional layer already has shape
200 | features, channels, iy, ix = numpy.shape(wp)
201 | if channel is not None:
202 | fields = wp[:,channel,:,:]
203 | else:
204 | fields = numpy.reshape(wp,[features*channels,iy,ix])
205 |
206 | perRow = int(math.floor(math.sqrt(fields.shape[0])))
207 | perColumn = int(math.ceil(fields.shape[0]/float(perRow)))
208 |
209 | fig = pylab.figure(figOffset); pylab.clf()
210 |
211 | # Using image grid
212 | from mpl_toolkits.axes_grid1 import ImageGrid
213 | grid = ImageGrid(fig,111,nrows_ncols=(perRow,perColumn),axes_pad=padding,cbar_mode='single')
214 | for i in range(0,numpy.shape(fields)[0]):
215 | im = grid[i].imshow(fields[i],cmap=cmap);
216 |
217 | grid.cbar_axes[0].colorbar(im)
218 | pylab.title('%s Receptive Fields' % layer.name)
219 |
220 | # old way
221 | # fields2 = numpy.vstack([fields,numpy.zeros([perRow*perColumn-fields.shape[0]] + list(fields.shape[1:]))])
222 | # tiled = []
223 | # for i in range(0,perColumn*perRow,perColumn):
224 | # tiled.append(numpy.hstack(fields2[i:i+perColumn]))
225 | #
226 | # tiled = numpy.vstack(tiled)
227 | # pylab.figure(figOffset); pylab.clf(); pylab.imshow(tiled,cmap=cmap); pylab.title('%s Receptive Fields' % layer.name); pylab.colorbar();
228 | pylab.figure(figOffset+1); pylab.clf(); pylab.imshow(numpy.sum(numpy.abs(fields),0),cmap=cmap); pylab.title('%s Total Absolute Input Dependency' % layer.name); pylab.colorbar()
229 |
230 |
231 |
232 | def plotOutput(layer,feed_dict,fieldShape=None,channel=None,figOffset=1,cmap=None):
233 | # Output summary
234 | try:
235 | W = layer.output
236 | except:
237 | W = layer
238 | wp = W.eval(feed_dict=feed_dict);
239 | if len(numpy.shape(wp)) < 4: # Fully connected layer, has no shape
240 | temp = numpy.zeros(numpy.product(fieldShape)); temp[0:numpy.shape(wp.ravel())[0]] = wp.ravel()
241 | fields = numpy.reshape(temp,[1]+fieldShape)
242 | else: # Convolutional layer already has shape
243 | wp = numpy.rollaxis(wp,3,0)
244 | features, channels, iy,ix = numpy.shape(wp)
245 | if channel is not None:
246 | fields = wp[:,channel,:,:]
247 | else:
248 | fields = numpy.reshape(wp,[features*channels,iy,ix])
249 |
250 | perRow = int(math.floor(math.sqrt(fields.shape[0])))
251 | perColumn = int(math.ceil(fields.shape[0]/float(perRow)))
252 | fields2 = numpy.vstack([fields,numpy.zeros([perRow*perColumn-fields.shape[0]] + list(fields.shape[1:]))])
253 | tiled = []
254 | for i in range(0,perColumn*perRow,perColumn):
255 | tiled.append(numpy.hstack(fields2[i:i+perColumn]))
256 |
257 | tiled = numpy.vstack(tiled)
258 | if figOffset is not None:
259 | pylab.figure(figOffset); pylab.clf();
260 |
261 | pylab.imshow(tiled,cmap=cmap); pylab.title('%s Output' % layer.name); pylab.colorbar();
262 |
263 |
264 |
265 | def train(session,trainingData,testingData,input,truth,cost,trainingStep,accuracy,iterations=5000,miniBatch=100,trainDict={},testDict=None,logName=None,initialize=True,addSummaryOps=True):
266 | testDict = trainDict if testDict is None else testDict
267 |
268 | if addSummaryOps:
269 | costSummary = tf.summary.scalar("Cost Function", cost)
270 | if accuracy is None:
271 | accuracy = cost
272 | accuracySummary = tf.summary.scalar("accuracy", accuracy)
273 | mergedSummary = tf.summary.merge_all()
274 | if logName is not None:
275 | writer = tf.train.SummaryWriter(logName, session.graph_def)
276 |
277 | if initialize:
278 | tf.global_variables_initializer().run() # Take initial values and actually put them in variables
279 |
280 | lastTime = 0; lastIterations = 0
281 | print("Doing {} iterations".format(iterations))
282 | for i in range(iterations): # Do some training
283 | batch = trainingData.next_batch(miniBatch)
284 | if (i%100 == 0) or (time.time()-lastTime > 5):
285 |
286 | testDict.update({input:batch[0],truth:batch[1]})
287 | # trainAccuracy = accuracy.eval(feed_dict=testDict)
288 |
289 | # Test accuracy for TensorBoard
290 | # testDict.update({input:testingData.images,truth:testingData.labels})
291 | if addSummaryOps:
292 | summary,testAccuracy,testCost = session.run([mergedSummary,accuracy,cost],feed_dict=testDict)
293 | if logName is not None:
294 | writer.add_summary(summary,i)
295 | else:
296 | testAccuracy,testCost = session.run([accuracy,cost],feed_dict=testDict)[0]
297 |
298 | print('At batch {}: accuracy: {} cost: {} ({} samples/s)'.format(i,testAccuracy,testCost,(i-lastIterations)/(time.time()-lastTime)*miniBatch))
299 | lastTime = time.time(); lastIterations = i
300 |
301 | trainDict.update({input:batch[0],truth:batch[1]})
302 | trainingStep.run(feed_dict=trainDict)
303 |
304 | try:
305 | # Only works with mnist-type data object
306 | testDict.update({input:testingData.images, truth:testingData.labels})
307 | print('Test accuracy: {}'.format(accuracy.eval(feed_dict=testDict)))
308 | except:
309 | pass
310 |
311 |
312 |
313 |
--------------------------------------------------------------------------------
/tfs/tfs/__init__.py:
--------------------------------------------------------------------------------
1 | import sys
2 | if sys.version_info[0] >= 3:
3 | from .TensorFlowInterface import *
4 | from . import input_data
5 | else:
6 | from TensorFlowInterface import *
7 | import input_data
8 |
--------------------------------------------------------------------------------
/tfs/tfs/input_data.py:
--------------------------------------------------------------------------------
1 | """Functions for downloading and reading MNIST data."""
2 | from __future__ import absolute_import
3 | from __future__ import division
4 | from __future__ import print_function
5 |
6 | import gzip
7 | import os
8 |
9 | import numpy
10 | from six.moves import urllib
11 | from six.moves import xrange # pylint: disable=redefined-builtin
12 |
13 | import traceback
14 |
15 | SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/'
16 |
17 |
18 | def maybe_download(filename, work_directory):
19 | """Download the data from Yann's website, unless it's already here."""
20 | if not os.path.exists(work_directory):
21 | os.mkdir(work_directory)
22 | filepath = os.path.join(work_directory, filename)
23 | if not os.path.exists(filepath):
24 | filepath, _ = urllib.request.urlretrieve(SOURCE_URL + filename, filepath)
25 | statinfo = os.stat(filepath)
26 | print('Succesfully downloaded', filename, statinfo.st_size, 'bytes.')
27 | return filepath
28 |
29 |
30 | def _read32(bytestream):
31 | dt = numpy.dtype(numpy.uint32).newbyteorder('>')
32 | return numpy.frombuffer(bytestream.read(4), dtype=dt)[0]
33 |
34 |
35 | def extract_images(filename):
36 | """Extract the images into a 4D uint8 numpy array [index, y, x, depth]."""
37 | print('Extracting', filename)
38 | with gzip.open(filename) as bytestream:
39 | magic = _read32(bytestream)
40 | if magic != 2051:
41 | raise ValueError(
42 | 'Invalid magic number %d in MNIST image file: %s' %
43 | (magic, filename))
44 | num_images = _read32(bytestream)
45 | rows = _read32(bytestream)
46 | cols = _read32(bytestream)
47 | buf = bytestream.read(rows * cols * num_images)
48 | data = numpy.frombuffer(buf, dtype=numpy.uint8)
49 | data = data.reshape(num_images, rows, cols, 1)
50 | return data
51 |
52 |
53 | def dense_to_one_hot(labels_dense, num_classes=10):
54 | """Convert class labels from scalars to one-hot vectors."""
55 | num_labels = labels_dense.shape[0]
56 | index_offset = numpy.arange(num_labels) * num_classes
57 | labels_one_hot = numpy.zeros((num_labels, num_classes))
58 | labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1
59 | return labels_one_hot
60 |
61 |
62 | def extract_labels(filename, one_hot=False):
63 | """Extract the labels into a 1D uint8 numpy array [index]."""
64 | print('Extracting', filename)
65 | with gzip.open(filename) as bytestream:
66 | magic = _read32(bytestream)
67 | if magic != 2049:
68 | raise ValueError(
69 | 'Invalid magic number %d in MNIST label file: %s' %
70 | (magic, filename))
71 | num_items = _read32(bytestream)
72 | buf = bytestream.read(num_items)
73 | labels = numpy.frombuffer(buf, dtype=numpy.uint8)
74 | if one_hot:
75 | return dense_to_one_hot(labels)
76 | return labels
77 |
78 |
79 | class DataSet(object):
80 |
81 | def __init__(self, images, labels, fake_data=False):
82 | if fake_data:
83 | self._num_examples = 10000
84 | else:
85 | assert images.shape[0] == labels.shape[0], (
86 | "images.shape: %s labels.shape: %s" % (images.shape,
87 | labels.shape))
88 | self._num_examples = images.shape[0]
89 |
90 | # Convert shape from [num examples, rows, columns, depth]
91 | # to [num examples, rows*columns] (assuming depth == 1)
92 | self.imageShape = images.shape[1:]
93 | self.imageChannels = self.imageShape[2]
94 |
95 | images = images.reshape(images.shape[0],
96 | images.shape[1] * images.shape[2] * images.shape[3])
97 | # Convert from [0, 255] -> [0.0, 1.0].
98 | images = images.astype(numpy.float32)
99 | images = numpy.multiply(images, 1.0 / 255.0)
100 | self._images = images
101 | self._labels = labels
102 | try:
103 | if len(numpy.shape(self._labels)) == 1:
104 | self._labels = dense_to_one_hot(self._labels,len(numpy.unique(self._labels)))
105 | except:
106 | traceback.print_exc()
107 | self._epochs_completed = 0
108 | self._index_in_epoch = 0
109 |
110 | @property
111 | def images(self):
112 | return self._images
113 |
114 | @property
115 | def labels(self):
116 | return self._labels
117 |
118 | @property
119 | def num_examples(self):
120 | return self._num_examples
121 |
122 | @property
123 | def epochs_completed(self):
124 | return self._epochs_completed
125 |
126 | def next_batch(self, batch_size, fake_data=False):
127 | """Return the next `batch_size` examples from this data set."""
128 | if fake_data:
129 | fake_image = [1.0 for _ in xrange(784)]
130 | fake_label = 0
131 | return [fake_image for _ in xrange(batch_size)], [
132 | fake_label for _ in xrange(batch_size)]
133 | start = self._index_in_epoch
134 | self._index_in_epoch += batch_size
135 | if self._index_in_epoch > self._num_examples:
136 | # Finished epoch
137 | self._epochs_completed += 1
138 | # Shuffle the data
139 | perm = numpy.arange(self._num_examples)
140 | numpy.random.shuffle(perm)
141 | self._images = self._images[perm]
142 | self._labels = self._labels[perm]
143 | # Start next epoch
144 | start = 0
145 | self._index_in_epoch = batch_size
146 | assert batch_size <= self._num_examples
147 | end = self._index_in_epoch
148 | return self._images[start:end], self._labels[start:end]
149 |
150 |
151 | def read_data_sets(train_dir, fake_data=False, one_hot=False):
152 | class DataSets(object):
153 | pass
154 | data_sets = DataSets()
155 |
156 | if fake_data:
157 | data_sets.train = DataSet([], [], fake_data=True)
158 | data_sets.validation = DataSet([], [], fake_data=True)
159 | data_sets.test = DataSet([], [], fake_data=True)
160 | return data_sets
161 |
162 | TRAIN_IMAGES = 'train-images-idx3-ubyte.gz'
163 | TRAIN_LABELS = 'train-labels-idx1-ubyte.gz'
164 | TEST_IMAGES = 't10k-images-idx3-ubyte.gz'
165 | TEST_LABELS = 't10k-labels-idx1-ubyte.gz'
166 | VALIDATION_SIZE = 5000
167 |
168 | local_file = maybe_download(TRAIN_IMAGES, train_dir)
169 | train_images = extract_images(local_file)
170 |
171 | local_file = maybe_download(TRAIN_LABELS, train_dir)
172 | train_labels = extract_labels(local_file, one_hot=one_hot)
173 |
174 | local_file = maybe_download(TEST_IMAGES, train_dir)
175 | test_images = extract_images(local_file)
176 |
177 | local_file = maybe_download(TEST_LABELS, train_dir)
178 | test_labels = extract_labels(local_file, one_hot=one_hot)
179 |
180 | validation_images = train_images[:VALIDATION_SIZE]
181 | validation_labels = train_labels[:VALIDATION_SIZE]
182 | train_images = train_images[VALIDATION_SIZE:]
183 | train_labels = train_labels[VALIDATION_SIZE:]
184 |
185 | data_sets.train = DataSet(train_images, train_labels)
186 | data_sets.validation = DataSet(validation_images, validation_labels)
187 | data_sets.test = DataSet(test_images, test_labels)
188 |
189 | return data_sets
190 |
--------------------------------------------------------------------------------