├── .github
├── ISSUE_TEMPLATE
│ └── bug_report.md
└── PULL_REQUEST_TEMPLATE.md
├── CODE_OF_CONDUCT.md
├── LICENSE
├── Part 1-Getting started with TensorFlow and Deep Learning
├── Excercise_1_Solution.ipynb
├── Hello_Neural_Nets.ipynb
└── README.md
├── Part 2-Computer Vision with TensorFlow
├── Callbacks_example_Notebook.ipynb
├── Computer_vision_examples_Notebook.ipynb
├── Excercise2_question.ipynb
├── Excercise2_solution.ipynb
└── README.md
├── Part 3-Using Convolutional Neural Networks with TensorFlow
└── README.md
├── Part 4-Extending what Convolutional Neural Nets can do
├── CNN_with_Fashion_MNIST_Notebook.ipynb
├── Convolutions_from_scratch.ipynb
├── Excercise2_question.ipynb
├── Excercise2_solution.ipynb
└── README.md
├── Part 5-Working with Complex Image data for CNNs
├── Complex image data.ipynb
└── README.md
└── README.md
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## :camera: Screenshots
2 |
3 |
4 | ## :page_facing_up: Context
5 |
6 |
7 | ## :pencil: Changes
8 |
9 |
10 | ## :paperclip: Related PR
11 |
12 |
13 | ## :no_entry_sign: Breaking
14 |
15 |
16 | ## :hammer_and_wrench: How to test
17 |
18 |
19 | ## :stopwatch: Next steps
20 |
21 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at rishit.dagli@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.rishit.tech/codeofconduct
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/Part 1-Getting started with TensorFlow and Deep Learning/README.md:
--------------------------------------------------------------------------------
1 | # Get started with TensorFlow and Deep Learning
2 |
3 | This same blog is availaible on Medium [here](https://medium.com/@rishit.dagli/get-started-with-tensorflow-and-deep-learning-part-1-72c7d67f99fc)
4 |
5 | 
6 |
Source: cognitiveclass.ai
7 |
8 | This is the first part of a series where I will be posting many blog posts about coding Machine Learning and Deep Learning algorithms. I believe in hands-on coding so we will have many exercises and demos which you can try yourself too. I would recommend you to play around with these exercises and change the hyper-parameters and experiment with the code. That is the best way to learn and code efficiently. If you don’t know what hyper-parameters are don’t worry. We will walk through Tensor Flow’s core capabilities and then also explore high level API’s in TensorFlow and so on.
9 |
10 | ## Is this series for me?
11 |
12 | If you are a person who is looking to get started with Tensor Flow, Machine Learning and Deep Learning but don’t have any knowledge about Machine Learning you can do this.
13 | If you already know about Machine Learning and Deep Learning and don’t know about Tensor Flow you can follow these. As you might be using some other frameworks or libraries like Caffe, Theano, CNTK, Apple ML or PyTorch and might also be knowing about the maths behind it you can skip the sections marked OPTIONAL.
14 | If you know about the basics of Tensor Flow then you can skip some of the blog posts.
15 |
16 | ## Is any software setup needed?
17 |
18 | No!!
19 |
20 | Not at all, you don’t need to install any software at all to complete the exercises and follow the code at all. We will be using [Google Colaboratory](http://colab.research.google.com/). Colaboratory is a research tool for machine learning education and research. It’s a Jupyter notebook environment that requires no setup to use. Colaboratory works with most major browsers and is most thoroughly tested with the latest versions of [Chrome](https://www.google.com/chrome/browser/desktop/index.html), [Firefox](https://www.mozilla.org/en-US/firefox/), and [Safari](https://www.apple.com/safari/). And what more, it is completely free to use. All Colaboratory notebooks are stored in Google Drive. Colaboratory notebooks can be shared just as you would with Google Docs or Sheets. Simply click the Share button at the top right of any Colaboratory notebook, or follow these Google Drive [file sharing instructions](https://support.google.com/drive/answer/2494822?co=GENIE.Platform%3DDesktop&hl=en). Before, you ask me Colaboratory is really reliable and fast too.
21 |
22 | However, you can also use a local development environment preferably Jupyter Notebooks but we will not be covering how to set up the local environment in these blogs.
23 |
24 | ## Which Version of Tensor Flow?
25 |
26 | The answer to this question is that in this blog we will cover both. If you are using Colab notebooks add this code.
27 |
28 | ```python
29 | try:
30 | # %tensorflow_version only exists in Colab.
31 | %tensorflow_version 2.x
32 | except Exception:
33 | pass
34 |
35 | import tensorflow as tf
36 | ```
37 |
38 | ## Introduction
39 |
40 | Coding has been the bread and butter for developers since the dawn of computing. We’re used to creating applications by breaking down requirements into composable problems that can then be coded against. So for example, if we have to write an application that figures out a stock analytic, maybe the price divided by the ratio, we can usually write code to get the values from a data source, do the calculation and then return the result. Or if we’re writing a game we can usually figure out the rules. For example, if the ball hits the brick then the brick should vanish and the ball should rebound. But if the ball falls off the bottom of the screen then maybe the player loses their life.
41 |
42 | We can represent that with this diagram. Rules and data go in answers come out. Rules are expressed in a programming language and data can come from a variety of sources from local variables up to databases. Machine learning rearranges this diagram where we put answers in data in and then we get rules out. So instead of us as developers figuring out the rules when should the brick be removed, when should the player’s life end, or what’s the desired analytic for any other concept, what we will do is we can get a bunch of examples for what we want to see and then have the computer figure out the rules.
43 |
44 | 
45 |
Traditional Programming vs Machine Learning
46 |
47 | So consider this example, activity recognition. If I’m building a device that detects if somebody is say walking and I have data about their speed, I might write code like this and if they’re running well that’s a faster speed so I could adapt my code to this and if they’re biking, well that’s not too bad either. I can adapt my code like this. But then I have to do golf recognition too, now my concept becomes broken. But not only that, doing it by speed alone of course is quite naive. We walk and run at different speeds uphill and downhill and other people walk and run at different speeds to us.
48 |
49 | 
50 |
A traditional programming logic
51 |
52 | The new paradigm is that I get lots and lots of examples and then I have labels on those examples and I use the data to say this is what walking looks like, this is what running looks like, this is what biking looks like and yes, even this is what golfing looks like. So, then it becomes answers and data in with rules being inferred by the machine. A machine learning algorithm then figures out the specific patterns in each set of data that determines the distinctiveness of each. That’s what’s so powerful and exciting about this programming paradigm. It’s more than just a new way of doing the same old thing. It opens up new possibilities that were infeasible to do before.
53 |
54 | So, now I am going to show you the basics of creating a neural network for doing this type of pattern recognition. A neural network is just a slightly more advanced implementation of machine learning and we call that deep learning. But fortunately it's actually very easy to code. So, we're just going to jump straight into deep learning. We'll start with a simple one and then we'll move on to one that does computer vision in about 10 lines of code.
55 | Hello Neural Networks
56 |
57 | To show how that works, let’s take a look at a set of numbers and see if you can determine the pattern between them. Okay, here are the numbers.
58 |
59 | x = -1, 0, 1, 2, 3, 4
60 |
61 | y = -3, -1, 1, 3, 5, 7
62 |
63 | You easily figure this out `y = 2x — 1`
64 |
65 | You probably tried that out with a couple of other values and see that it fits. Congratulations, you’ve just done the basics of machine learning in your head.
66 |
67 | Okay, here’s our first line of code. This is written using Python and TensorFlow and an API in TensorFlow called keras. Keras makes it really easy to define neural networks. A neural network is basically a set of functions which can learn patterns.
68 |
69 | ```python
70 | model = keras.Sequential([keras.layers.Dense(units = 1, input_shape = [1])])
71 | ```
72 |
73 | The simplest possible neural network is one that has only one neuron in it, and that’s what this line of code does. In keras we use the word Dense to define a layer of connected neurons. There is only one Dense here means that there is only one layer and there is only single unit in it so there is only one neuron. Successive layers in keras are defined in a sequence so the word Sequential . You define the shape of what's input to the neural network in the first and in this case the only layer, and you can see that our input shape is super simple. It's just one value. You've probably seen that for machine learning, you need to know and use a lot of math, calculus probability and the like. It's really good to understand that as you want to optimize your models but the nice thing for now about TensorFlow and keras is that a lot of that math is implemented for you in functions. There are two function roles that you should be aware of though and these are loss functions and optimizers.
74 |
75 | ```python
76 | model.compile(optimizer = 'sgd', loss = 'mean_squared_error')
77 | ```
78 |
79 | This lines defines that for us. So, lets understand what it is.
80 |
81 | Understand it like this the neural network has no idea of the relation between `X` and `Y` so it makes a random guess say `y=x+3` . It will then use the data that it knows about, that’s the set of Xs and Ys that we’ve already seen to measure how good or how bad its guess was. The loss function measures this and then gives the data to the optimizer which figures out the next guess. So the optimizer thinks about how good or how badly the guess was done using the data from the loss function. Then the logic is that each guess should be better than the one before. As the guesses get better and better, an accuracy approaches 100 percent, the term convergence is used.
82 |
83 | Here we have used the loss function as mean squared error and optimizer as SGD or stochactic gradient descent.
84 |
85 | Our next step is to represent the known data. These are the Xs and the Ys that you saw earlier. The np.array is using a Python library called numpy that makes data representation particularly enlists much easier. So here you can see we have one list for the Xs and another one for the Ys. The training takes place in the fit command. Here we’re asking the model to figure out how to fit the X values to the Y values. The epochs equals 500 value means that it will go through the training loop 500 times. This training loop is what we described earlier. Make a guess, measure how good or how bad the guesses with the loss function, then use the optimizer and the data to make another guess and repeat this. When the model has finished training, it will then give you back values using the predict method.
86 |
87 | Here’s the code of what we talked about.
88 |
89 | ```python
90 | xs = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
91 | ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)model.fit(xs, ys, epochs=500)
92 | print(model.predict([10.0]))
93 | ```
94 |
95 | So, what output do you except — 19, right?
96 |
97 | But when you try this in the workbook yourself you will see it gives me a value close to 19 not 19. Like you might receive-
98 |
99 | ```python
100 | [[18.987219]]
101 | ```
102 |
103 | Why do you think this happens because the equation is `y = 2x-1` .
104 |
105 | There are two main reasons:
106 |
107 | The first is that you trained it using very little data. There’s only six points. Those six points are linear but there’s no guarantee that for every X, the relationship will be Y equals 2X minus 1. There’s a very high probability that Y equals 19 for X equals 10, but the neural network isn’t positive. So it will figure out a realistic value for Y. The the second main reason. When using neural networks, as they try to figure out the answers for everything, they deal in probability. You’ll see that a lot and you’ll have to adjust how you handle answers to fit. Keep that in mind as you work through the code. Okay, enough talking. Now let’s get hands-on and write the code that we just saw and then we can run it.
108 |
109 | ## Hands-on Hello with Neural Nets
110 |
111 | If you have used Jupyter before you will find Colab easy to use. If you have not used Colab before consider watching this intro to it.
112 |
113 | Introduction to Google Colab
114 |
115 | [](https://www.youtube.com/watch?v=inN8seMm7UI)
116 |
Introduction to Google Colab
117 |
118 | Now you know how to use Colab so let’s get started.
119 |
120 | If you are using Jupyter Notebooks in your local environment download the code file [here](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Blog-series/blob/master/Part%201-Getting%20started%20with%20TensorFlow%20and%20Deep%20Learning/Hello_Neural_Nets.ipynb).
121 |
122 | If you are using Colab follow the link [here](https://colab.research.google.com/github/Rishit-dagli/Artificial-Intelligence_resources-and-notebooks/blob/master/Hello_Neural_Nets.ipynb). You need to sign in with your Google account to run the code and receive a hosted run time.
123 |
124 | I recommend you to spend some time with the notebook and try changing the epochs and see the effect on loss and accuracy and experiment with the code.
125 |
126 | ## Exercise — 1
127 |
128 | In this exercise you’ll try to build a neural network that predicts the price of a house according to a simple formula. So, imagine if house pricing was as easy as a house costs 50k + 50k per bedroom, so that a 1 bedroom house costs 100k, a 2 bedroom house costs 150k etc. How would you create a neural network that learns this relationship so that it would predict a 7 bedroom house as costing close to 400k etc.
129 |
130 | Hint: Your network might work better if you scale the house price down. You don’t have to give the answer 400…it might be better to create something that predicts the number 4, and then your answer is in the ‘hundreds of thousands’ etc.
131 |
132 | Note: The maximum error allowed is 400 dollars
133 |
134 | Make a new Colab Notebook and write your solution for this exercise and try it with some numbers the model has not seen.
135 |
136 | ## My Solution
137 |
138 | Wonderful, you just created a neural net all by yourself and some of you must be feeling like this (it’s perfectly ok)-
139 |
140 | 
141 |
Source: me.me
142 |
143 | Let’s see my solution to this.
144 |
145 | ```python
146 | def house_model(y_new):
147 | xs=[]
148 | ys=[]
149 | for i in range(1,10):
150 | xs.append(i)
151 | ys.append((1+float(i))*50)
152 |
153 | xs=np.array(xs,dtype=float)
154 | ys=np.array(ys, dtype=float)model = keras.Sequential([keras.layers.Dense(units = 1, input_shape = [1])])
155 | model.compile(optimizer='sgd', loss='mean_squared_error')
156 |
157 | model.fit(xs, ys, epochs = 4500)
158 | return (model.predict(y_new)[0]/100)
159 | ```
160 |
161 | And this gives me the answer to the required tolerate limit.
162 |
163 | Here’s the Solution to this exercise — [here](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Blog-series/blob/master/Part%201-Getting%20started%20with%20TensorFlow%20and%20Deep%20Learning/Excercise_1_Solution.ipynb)
164 |
165 | If you want to try this out in Colab you can go to the link and click open on colab button.
166 |
167 | That was it, the basics. You even created a neural net all by yourself and made pretty accurate predictions too. Next, we will see about using some image classifiers with Tensor Flow so, stay tuned and explore till then.
168 |
169 | Some useful resources for further reading
170 |
171 | * Learn more about Colab [here](https://colab.research.google.com/notebooks/welcome.ipynb)
172 | * TensorFlow website [here](https://www.tensorflow.org/)
173 | * TensorFlow docs [here](https://github.com/tensorflow/docs)
174 | * GitHub repository [here](https://github.com/tensorflow/tensorflow)
175 | * A wonderful Neural Nets research paper [here](https://www.sciencedirect.com/science/article/abs/pii/S0893608014002135)
176 | * A wonderful visualization tool by TensorFlow [here](http://projector.tensorflow.org/)
177 | * TensorFlow models and data sets [here](https://www.tensorflow.org/resources/models-datasets)
178 |
179 | Some TensorFlow research papers
180 |
181 | * Large scale Machine Learning with TensorFlow [here](http://download.tensorflow.org/paper/whitepaper2015.pdf)
182 | * A Deep Level Understanding of Recurrent Neural Network & LSTM with Practical Implementation in Keras & Tensorflow [here](https://www.academia.edu/41209114/A_Deep_Level_Understanding_of_Recurrent_Neural_Network_and_LSTM_with_Practical_Implementation_in_Keras_and_Tensorflow)
183 |
184 | ## About Me
185 |
186 | Hi everyone I am Rishit Dagli
187 |
188 | [Twitter](https://twitter.com/rishit_dagli)
189 |
190 | [Website](https://rishit.tech/)
191 |
192 | If you want to ask me some questions, report any mistake, suggest improvements, give feedback you are free to do so by emailing me at —
193 |
194 | * [rishit.dagli@gmail.com](mailto:rishit.dagli@gmail.com)
195 |
196 | * [hello@rishit.tech](mailto:hello@rishit.tech)
197 |
198 |
--------------------------------------------------------------------------------
/Part 2-Computer Vision with TensorFlow/Callbacks_example_Notebook.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "Callbacks example Notebook.ipynb",
7 | "provenance": [],
8 | "collapsed_sections": [],
9 | "include_colab_link": true
10 | },
11 | "kernelspec": {
12 | "name": "python3",
13 | "display_name": "Python 3"
14 | }
15 | },
16 | "cells": [
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {
20 | "id": "view-in-github",
21 | "colab_type": "text"
22 | },
23 | "source": [
24 | ""
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "metadata": {
30 | "id": "N9-BCmi15L93",
31 | "colab_type": "code",
32 | "colab": {}
33 | },
34 | "source": [
35 | "import tensorflow as tf\n",
36 | "\n",
37 | "class myCallback(tf.keras.callbacks.Callback):\n",
38 | " def on_epoch_end(self, epoch, logs={}):\n",
39 | " if(logs.get('acc') > 0.6):\n",
40 | " print(\"\\nReached 60% accuracy so cancelling training!\")\n",
41 | " self.model.stop_training = True\n",
42 | "\n",
43 | "mnist = tf.keras.datasets.fashion_mnist\n",
44 | "\n",
45 | "(x_train, y_train),(x_test, y_test) = mnist.load_data()\n",
46 | "x_train, x_test = x_train / 255.0, x_test / 255.0\n",
47 | "\n",
48 | "callbacks = myCallback()\n",
49 | "\n",
50 | "model = tf.keras.models.Sequential([\n",
51 | " tf.keras.layers.Flatten(input_shape=(28, 28)),\n",
52 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n",
53 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n",
54 | "])\n",
55 | "model.compile(optimizer='adam',\n",
56 | " loss='sparse_categorical_crossentropy',\n",
57 | " metrics=['accuracy'])\n",
58 | "\n",
59 | "model.fit(x_train, y_train, epochs=10, callbacks=[callbacks])"
60 | ],
61 | "execution_count": 0,
62 | "outputs": []
63 | }
64 | ]
65 | }
--------------------------------------------------------------------------------
/Part 2-Computer Vision with TensorFlow/Computer_vision_examples_Notebook.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "Computer vision examples Notebook.ipynb",
7 | "provenance": [],
8 | "collapsed_sections": [],
9 | "include_colab_link": true
10 | },
11 | "kernelspec": {
12 | "name": "python3",
13 | "display_name": "Python 3"
14 | }
15 | },
16 | "cells": [
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {
20 | "id": "view-in-github",
21 | "colab_type": "text"
22 | },
23 | "source": [
24 | ""
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {
30 | "id": "qnyTxjK_GbOD",
31 | "colab_type": "text"
32 | },
33 | "source": [
34 | "# Beyond Hello Neural Nets, A Computer Vision Example\n",
35 | "\n",
36 | "In the previous exercise you saw how to create a neural network that figured out the problem you were trying to solve. This gave an explicit example of learned behavior. Of course, in that instance, it was a bit of overkill because it would have been easier to write the function $Y=2x-1$ directly, instead of bothering with using Machine Learning to learn the relationship between X and Y for a fixed set of values, and extending that for all values.\n",
37 | "\n",
38 | "But what about a scenario where writing rules like that is much more difficult -- for example a computer vision problem? Let's take a look at a scenario where we can recognize different items of clothing, trained from a dataset containing 10 different types."
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {
44 | "id": "H41FYgtlHPjW",
45 | "colab_type": "text"
46 | },
47 | "source": [
48 | "## Start Coding\n",
49 | "\n",
50 | "Let's start with our import of TensorFlow"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "metadata": {
56 | "id": "q3KzJyjv3rnA",
57 | "colab_type": "code",
58 | "outputId": "2e0ae277-b2e5-4a1d-b153-a6542b6c68e9",
59 | "colab": {
60 | "base_uri": "https://localhost:8080/",
61 | "height": 54
62 | }
63 | },
64 | "source": [
65 | "try:\n",
66 | " %tensorflow_version 2.x\n",
67 | "except Exception:\n",
68 | " pass\n",
69 | "import tensorflow as tf\n",
70 | "print(tf.__version__)"
71 | ],
72 | "execution_count": 0,
73 | "outputs": [
74 | {
75 | "output_type": "stream",
76 | "text": [
77 | "TensorFlow 2.x selected.\n",
78 | "2.1.0-rc1\n"
79 | ],
80 | "name": "stdout"
81 | }
82 | ]
83 | },
84 | {
85 | "cell_type": "markdown",
86 | "metadata": {
87 | "id": "n_n1U5do3u_F",
88 | "colab_type": "text"
89 | },
90 | "source": [
91 | "The Fashion MNIST data is available directly in the tf.keras datasets API. You load it like this:"
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "metadata": {
97 | "id": "PmxkHFpt31bM",
98 | "colab_type": "code",
99 | "colab": {}
100 | },
101 | "source": [
102 | "mnist = tf.keras.datasets.fashion_mnist"
103 | ],
104 | "execution_count": 0,
105 | "outputs": []
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {
110 | "id": "GuoLQQBT4E-_",
111 | "colab_type": "text"
112 | },
113 | "source": [
114 | "Calling load_data on this object will give you two sets of two lists, these will be the training and testing values for the graphics that contain the clothing items and their labels.\n"
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "metadata": {
120 | "id": "BTdRgExe4TRB",
121 | "colab_type": "code",
122 | "colab": {}
123 | },
124 | "source": [
125 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()"
126 | ],
127 | "execution_count": 0,
128 | "outputs": []
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {
133 | "id": "rw395ROx4f5Q",
134 | "colab_type": "text"
135 | },
136 | "source": [
137 | "What does these values look like? Let's print a training image, and a training label to see...Experiment with different indices in the array. For example, also take a look at index 42...that's a a different boot than the one at index 0\n"
138 | ]
139 | },
140 | {
141 | "cell_type": "code",
142 | "metadata": {
143 | "id": "FPc9d3gJ3jWF",
144 | "colab_type": "code",
145 | "outputId": "cb7fd9ae-fcad-4d3e-81ad-0d3635c1fd1a",
146 | "colab": {
147 | "base_uri": "https://localhost:8080/",
148 | "height": 1000
149 | }
150 | },
151 | "source": [
152 | "import matplotlib.pyplot as plt\n",
153 | "plt.imshow(training_images[0])\n",
154 | "print(training_labels[0])\n",
155 | "print(training_images[0])"
156 | ],
157 | "execution_count": 0,
158 | "outputs": [
159 | {
160 | "output_type": "stream",
161 | "text": [
162 | "9\n",
163 | "[[0. 0. 0. 0. 0. 0.\n",
164 | " 0. 0. 0. 0. 0. 0.\n",
165 | " 0. 0. 0. 0. 0. 0.\n",
166 | " 0. 0. 0. 0. 0. 0.\n",
167 | " 0. 0. 0. 0. ]\n",
168 | " [0. 0. 0. 0. 0. 0.\n",
169 | " 0. 0. 0. 0. 0. 0.\n",
170 | " 0. 0. 0. 0. 0. 0.\n",
171 | " 0. 0. 0. 0. 0. 0.\n",
172 | " 0. 0. 0. 0. ]\n",
173 | " [0. 0. 0. 0. 0. 0.\n",
174 | " 0. 0. 0. 0. 0. 0.\n",
175 | " 0. 0. 0. 0. 0. 0.\n",
176 | " 0. 0. 0. 0. 0. 0.\n",
177 | " 0. 0. 0. 0. ]\n",
178 | " [0. 0. 0. 0. 0. 0.\n",
179 | " 0. 0. 0. 0. 0. 0.\n",
180 | " 0.00392157 0. 0. 0.05098039 0.28627451 0.\n",
181 | " 0. 0.00392157 0.01568627 0. 0. 0.\n",
182 | " 0. 0.00392157 0.00392157 0. ]\n",
183 | " [0. 0. 0. 0. 0. 0.\n",
184 | " 0. 0. 0. 0. 0. 0.\n",
185 | " 0.01176471 0. 0.14117647 0.53333333 0.49803922 0.24313725\n",
186 | " 0.21176471 0. 0. 0. 0.00392157 0.01176471\n",
187 | " 0.01568627 0. 0. 0.01176471]\n",
188 | " [0. 0. 0. 0. 0. 0.\n",
189 | " 0. 0. 0. 0. 0. 0.\n",
190 | " 0.02352941 0. 0.4 0.8 0.69019608 0.5254902\n",
191 | " 0.56470588 0.48235294 0.09019608 0. 0. 0.\n",
192 | " 0. 0.04705882 0.03921569 0. ]\n",
193 | " [0. 0. 0. 0. 0. 0.\n",
194 | " 0. 0. 0. 0. 0. 0.\n",
195 | " 0. 0. 0.60784314 0.9254902 0.81176471 0.69803922\n",
196 | " 0.41960784 0.61176471 0.63137255 0.42745098 0.25098039 0.09019608\n",
197 | " 0.30196078 0.50980392 0.28235294 0.05882353]\n",
198 | " [0. 0. 0. 0. 0. 0.\n",
199 | " 0. 0. 0. 0. 0. 0.00392157\n",
200 | " 0. 0.27058824 0.81176471 0.8745098 0.85490196 0.84705882\n",
201 | " 0.84705882 0.63921569 0.49803922 0.4745098 0.47843137 0.57254902\n",
202 | " 0.55294118 0.34509804 0.6745098 0.25882353]\n",
203 | " [0. 0. 0. 0. 0. 0.\n",
204 | " 0. 0. 0. 0.00392157 0.00392157 0.00392157\n",
205 | " 0. 0.78431373 0.90980392 0.90980392 0.91372549 0.89803922\n",
206 | " 0.8745098 0.8745098 0.84313725 0.83529412 0.64313725 0.49803922\n",
207 | " 0.48235294 0.76862745 0.89803922 0. ]\n",
208 | " [0. 0. 0. 0. 0. 0.\n",
209 | " 0. 0. 0. 0. 0. 0.\n",
210 | " 0. 0.71764706 0.88235294 0.84705882 0.8745098 0.89411765\n",
211 | " 0.92156863 0.89019608 0.87843137 0.87058824 0.87843137 0.86666667\n",
212 | " 0.8745098 0.96078431 0.67843137 0. ]\n",
213 | " [0. 0. 0. 0. 0. 0.\n",
214 | " 0. 0. 0. 0. 0. 0.\n",
215 | " 0. 0.75686275 0.89411765 0.85490196 0.83529412 0.77647059\n",
216 | " 0.70588235 0.83137255 0.82352941 0.82745098 0.83529412 0.8745098\n",
217 | " 0.8627451 0.95294118 0.79215686 0. ]\n",
218 | " [0. 0. 0. 0. 0. 0.\n",
219 | " 0. 0. 0. 0.00392157 0.01176471 0.\n",
220 | " 0.04705882 0.85882353 0.8627451 0.83137255 0.85490196 0.75294118\n",
221 | " 0.6627451 0.89019608 0.81568627 0.85490196 0.87843137 0.83137255\n",
222 | " 0.88627451 0.77254902 0.81960784 0.20392157]\n",
223 | " [0. 0. 0. 0. 0. 0.\n",
224 | " 0. 0. 0. 0. 0.02352941 0.\n",
225 | " 0.38823529 0.95686275 0.87058824 0.8627451 0.85490196 0.79607843\n",
226 | " 0.77647059 0.86666667 0.84313725 0.83529412 0.87058824 0.8627451\n",
227 | " 0.96078431 0.46666667 0.65490196 0.21960784]\n",
228 | " [0. 0. 0. 0. 0. 0.\n",
229 | " 0. 0. 0. 0.01568627 0. 0.\n",
230 | " 0.21568627 0.9254902 0.89411765 0.90196078 0.89411765 0.94117647\n",
231 | " 0.90980392 0.83529412 0.85490196 0.8745098 0.91764706 0.85098039\n",
232 | " 0.85098039 0.81960784 0.36078431 0. ]\n",
233 | " [0. 0. 0.00392157 0.01568627 0.02352941 0.02745098\n",
234 | " 0.00784314 0. 0. 0. 0. 0.\n",
235 | " 0.92941176 0.88627451 0.85098039 0.8745098 0.87058824 0.85882353\n",
236 | " 0.87058824 0.86666667 0.84705882 0.8745098 0.89803922 0.84313725\n",
237 | " 0.85490196 1. 0.30196078 0. ]\n",
238 | " [0. 0.01176471 0. 0. 0. 0.\n",
239 | " 0. 0. 0. 0.24313725 0.56862745 0.8\n",
240 | " 0.89411765 0.81176471 0.83529412 0.86666667 0.85490196 0.81568627\n",
241 | " 0.82745098 0.85490196 0.87843137 0.8745098 0.85882353 0.84313725\n",
242 | " 0.87843137 0.95686275 0.62352941 0. ]\n",
243 | " [0. 0. 0. 0. 0.07058824 0.17254902\n",
244 | " 0.32156863 0.41960784 0.74117647 0.89411765 0.8627451 0.87058824\n",
245 | " 0.85098039 0.88627451 0.78431373 0.80392157 0.82745098 0.90196078\n",
246 | " 0.87843137 0.91764706 0.69019608 0.7372549 0.98039216 0.97254902\n",
247 | " 0.91372549 0.93333333 0.84313725 0. ]\n",
248 | " [0. 0.22352941 0.73333333 0.81568627 0.87843137 0.86666667\n",
249 | " 0.87843137 0.81568627 0.8 0.83921569 0.81568627 0.81960784\n",
250 | " 0.78431373 0.62352941 0.96078431 0.75686275 0.80784314 0.8745098\n",
251 | " 1. 1. 0.86666667 0.91764706 0.86666667 0.82745098\n",
252 | " 0.8627451 0.90980392 0.96470588 0. ]\n",
253 | " [0.01176471 0.79215686 0.89411765 0.87843137 0.86666667 0.82745098\n",
254 | " 0.82745098 0.83921569 0.80392157 0.80392157 0.80392157 0.8627451\n",
255 | " 0.94117647 0.31372549 0.58823529 1. 0.89803922 0.86666667\n",
256 | " 0.7372549 0.60392157 0.74901961 0.82352941 0.8 0.81960784\n",
257 | " 0.87058824 0.89411765 0.88235294 0. ]\n",
258 | " [0.38431373 0.91372549 0.77647059 0.82352941 0.87058824 0.89803922\n",
259 | " 0.89803922 0.91764706 0.97647059 0.8627451 0.76078431 0.84313725\n",
260 | " 0.85098039 0.94509804 0.25490196 0.28627451 0.41568627 0.45882353\n",
261 | " 0.65882353 0.85882353 0.86666667 0.84313725 0.85098039 0.8745098\n",
262 | " 0.8745098 0.87843137 0.89803922 0.11372549]\n",
263 | " [0.29411765 0.8 0.83137255 0.8 0.75686275 0.80392157\n",
264 | " 0.82745098 0.88235294 0.84705882 0.7254902 0.77254902 0.80784314\n",
265 | " 0.77647059 0.83529412 0.94117647 0.76470588 0.89019608 0.96078431\n",
266 | " 0.9372549 0.8745098 0.85490196 0.83137255 0.81960784 0.87058824\n",
267 | " 0.8627451 0.86666667 0.90196078 0.2627451 ]\n",
268 | " [0.18823529 0.79607843 0.71764706 0.76078431 0.83529412 0.77254902\n",
269 | " 0.7254902 0.74509804 0.76078431 0.75294118 0.79215686 0.83921569\n",
270 | " 0.85882353 0.86666667 0.8627451 0.9254902 0.88235294 0.84705882\n",
271 | " 0.78039216 0.80784314 0.72941176 0.70980392 0.69411765 0.6745098\n",
272 | " 0.70980392 0.80392157 0.80784314 0.45098039]\n",
273 | " [0. 0.47843137 0.85882353 0.75686275 0.70196078 0.67058824\n",
274 | " 0.71764706 0.76862745 0.8 0.82352941 0.83529412 0.81176471\n",
275 | " 0.82745098 0.82352941 0.78431373 0.76862745 0.76078431 0.74901961\n",
276 | " 0.76470588 0.74901961 0.77647059 0.75294118 0.69019608 0.61176471\n",
277 | " 0.65490196 0.69411765 0.82352941 0.36078431]\n",
278 | " [0. 0. 0.29019608 0.74117647 0.83137255 0.74901961\n",
279 | " 0.68627451 0.6745098 0.68627451 0.70980392 0.7254902 0.7372549\n",
280 | " 0.74117647 0.7372549 0.75686275 0.77647059 0.8 0.81960784\n",
281 | " 0.82352941 0.82352941 0.82745098 0.7372549 0.7372549 0.76078431\n",
282 | " 0.75294118 0.84705882 0.66666667 0. ]\n",
283 | " [0.00784314 0. 0. 0. 0.25882353 0.78431373\n",
284 | " 0.87058824 0.92941176 0.9372549 0.94901961 0.96470588 0.95294118\n",
285 | " 0.95686275 0.86666667 0.8627451 0.75686275 0.74901961 0.70196078\n",
286 | " 0.71372549 0.71372549 0.70980392 0.69019608 0.65098039 0.65882353\n",
287 | " 0.38823529 0.22745098 0. 0. ]\n",
288 | " [0. 0. 0. 0. 0. 0.\n",
289 | " 0. 0.15686275 0.23921569 0.17254902 0.28235294 0.16078431\n",
290 | " 0.1372549 0. 0. 0. 0. 0.\n",
291 | " 0. 0. 0. 0. 0. 0.\n",
292 | " 0. 0. 0. 0. ]\n",
293 | " [0. 0. 0. 0. 0. 0.\n",
294 | " 0. 0. 0. 0. 0. 0.\n",
295 | " 0. 0. 0. 0. 0. 0.\n",
296 | " 0. 0. 0. 0. 0. 0.\n",
297 | " 0. 0. 0. 0. ]\n",
298 | " [0. 0. 0. 0. 0. 0.\n",
299 | " 0. 0. 0. 0. 0. 0.\n",
300 | " 0. 0. 0. 0. 0. 0.\n",
301 | " 0. 0. 0. 0. 0. 0.\n",
302 | " 0. 0. 0. 0. ]]\n"
303 | ],
304 | "name": "stdout"
305 | },
306 | {
307 | "output_type": "display_data",
308 | "data": {
309 | "image/png": "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\ngg==\n",
310 | "text/plain": [
311 | ""
312 | ]
313 | },
314 | "metadata": {
315 | "tags": []
316 | }
317 | }
318 | ]
319 | },
320 | {
321 | "cell_type": "markdown",
322 | "metadata": {
323 | "id": "3cbrdH225_nH",
324 | "colab_type": "text"
325 | },
326 | "source": [
327 | "You'll notice that all of the values in the number are between 0 and 255. If we are training a neural network, for various reasons it's easier if we treat all values as between 0 and 1, a process called '**normalizing**'...and fortunately in Python it's easy to normalize a list like this without looping. You do it like this:"
328 | ]
329 | },
330 | {
331 | "cell_type": "code",
332 | "metadata": {
333 | "id": "kRH19pWs6ZDn",
334 | "colab_type": "code",
335 | "colab": {}
336 | },
337 | "source": [
338 | "training_images = training_images / 255.0\n",
339 | "test_images = test_images / 255.0"
340 | ],
341 | "execution_count": 0,
342 | "outputs": []
343 | },
344 | {
345 | "cell_type": "markdown",
346 | "metadata": {
347 | "id": "3DkO0As46lRn",
348 | "colab_type": "text"
349 | },
350 | "source": [
351 | "Now you might be wondering why there are 2 sets...training and testing -- remember we spoke about this in the intro? The idea is to have 1 set of data for training, and then another set of data...that the model hasn't yet seen...to see how good it would be at classifying values. After all, when you're done, you're going to want to try it out with data that it hadn't previously seen!"
352 | ]
353 | },
354 | {
355 | "cell_type": "markdown",
356 | "metadata": {
357 | "id": "dIn7S9gf62ie",
358 | "colab_type": "text"
359 | },
360 | "source": [
361 | "Let's now design the model. There's quite a few new concepts here, but don't worry, you'll get the hang of them. "
362 | ]
363 | },
364 | {
365 | "cell_type": "code",
366 | "metadata": {
367 | "id": "7mAyndG3kVlK",
368 | "colab_type": "code",
369 | "colab": {}
370 | },
371 | "source": [
372 | "model = tf.keras.models.Sequential([\n",
373 | " tf.keras.layers.Flatten(), \n",
374 | " tf.keras.layers.Dense(128, activation=tf.nn.relu), \n",
375 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])"
376 | ],
377 | "execution_count": 0,
378 | "outputs": []
379 | },
380 | {
381 | "cell_type": "markdown",
382 | "metadata": {
383 | "id": "-lUcWaiX7MFj",
384 | "colab_type": "text"
385 | },
386 | "source": [
387 | "**Sequential**: That defines a SEQUENCE of layers in the neural network\n",
388 | "\n",
389 | "**Flatten**: Remember earlier where our images were a square, when you printed them out? Flatten just takes that square and turns it into a 1 dimensional set.\n",
390 | "\n",
391 | "**Dense**: Adds a layer of neurons\n",
392 | "\n",
393 | "Each layer of neurons need an **activation function** to tell them what to do. There's lots of options, but just use these for now. \n",
394 | "\n",
395 | "**Relu** effectively means \"If X>0 return X, else return 0\" -- so what it does it it only passes values 0 or greater to the next layer in the network.\n",
396 | "\n",
397 | "**Softmax** takes a set of values, and effectively picks the biggest one, so, for example, if the output of the last layer looks like [0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05], it saves you from fishing through it looking for the biggest value, and turns it into [0,0,0,0,1,0,0,0,0] -- The goal is to save a lot of coding!\n"
398 | ]
399 | },
400 | {
401 | "cell_type": "markdown",
402 | "metadata": {
403 | "id": "c8vbMCqb9Mh6",
404 | "colab_type": "text"
405 | },
406 | "source": [
407 | "The next thing to do, now the model is defined, is to actually build it. You do this by compiling it with an optimizer and loss function as before -- and then you train it by calling **model.fit ** asking it to fit your training data to your training labels -- i.e. have it figure out the relationship between the training data and its actual labels, so in future if you have data that looks like the training data, then it can make a prediction for what that data would look like. "
408 | ]
409 | },
410 | {
411 | "cell_type": "code",
412 | "metadata": {
413 | "id": "BLMdl9aP8nQ0",
414 | "colab_type": "code",
415 | "outputId": "10c469b5-3d06-4f8c-9853-7df86091c846",
416 | "colab": {
417 | "base_uri": "https://localhost:8080/",
418 | "height": 421
419 | }
420 | },
421 | "source": [
422 | "model.compile(optimizer = tf.optimizers.Adam(),\n",
423 | " loss = 'sparse_categorical_crossentropy',\n",
424 | " metrics=['accuracy'])\n",
425 | "\n",
426 | "model.fit(training_images, training_labels, epochs=10)"
427 | ],
428 | "execution_count": 0,
429 | "outputs": [
430 | {
431 | "output_type": "stream",
432 | "text": [
433 | "Train on 60000 samples\n",
434 | "Epoch 1/10\n",
435 | "60000/60000 [==============================] - 5s 76us/sample - loss: 0.2801 - accuracy: 0.8963\n",
436 | "Epoch 2/10\n",
437 | "60000/60000 [==============================] - 4s 72us/sample - loss: 0.2666 - accuracy: 0.9005\n",
438 | "Epoch 3/10\n",
439 | "60000/60000 [==============================] - 4s 71us/sample - loss: 0.2571 - accuracy: 0.9053\n",
440 | "Epoch 4/10\n",
441 | "60000/60000 [==============================] - 5s 76us/sample - loss: 0.2470 - accuracy: 0.9087\n",
442 | "Epoch 5/10\n",
443 | "60000/60000 [==============================] - 5s 78us/sample - loss: 0.2379 - accuracy: 0.9117\n",
444 | "Epoch 6/10\n",
445 | "60000/60000 [==============================] - 4s 72us/sample - loss: 0.2317 - accuracy: 0.9129\n",
446 | "Epoch 7/10\n",
447 | "60000/60000 [==============================] - 4s 73us/sample - loss: 0.2214 - accuracy: 0.9174\n",
448 | "Epoch 8/10\n",
449 | "60000/60000 [==============================] - 4s 73us/sample - loss: 0.2161 - accuracy: 0.9183\n",
450 | "Epoch 9/10\n",
451 | "60000/60000 [==============================] - 4s 72us/sample - loss: 0.2079 - accuracy: 0.9220\n",
452 | "Epoch 10/10\n",
453 | "60000/60000 [==============================] - 4s 73us/sample - loss: 0.2047 - accuracy: 0.9238\n"
454 | ],
455 | "name": "stdout"
456 | },
457 | {
458 | "output_type": "execute_result",
459 | "data": {
460 | "text/plain": [
461 | ""
462 | ]
463 | },
464 | "metadata": {
465 | "tags": []
466 | },
467 | "execution_count": 16
468 | }
469 | ]
470 | },
471 | {
472 | "cell_type": "markdown",
473 | "metadata": {
474 | "id": "-JJMsvSB-1UY",
475 | "colab_type": "text"
476 | },
477 | "source": [
478 | "Once it's done training -- you should see an accuracy value at the end of the final epoch. It might look something like 0.9098. This tells you that your neural network is about 91% accurate in classifying the training data. I.E., it figured out a pattern match between the image and the labels that worked 91% of the time. Not great, but not bad considering it was only trained for 5 epochs and done quite quickly.\n",
479 | "\n",
480 | "But how would it work with unseen data? That's why we have the test images. We can call model.evaluate, and pass in the two sets, and it will report back the loss for each. Let's give it a try:"
481 | ]
482 | },
483 | {
484 | "cell_type": "code",
485 | "metadata": {
486 | "id": "WzlqsEzX9s5P",
487 | "colab_type": "code",
488 | "outputId": "f59ba959-942a-49c7-99e8-3204c35eeeba",
489 | "colab": {
490 | "base_uri": "https://localhost:8080/",
491 | "height": 54
492 | }
493 | },
494 | "source": [
495 | "model.evaluate(test_images, test_labels)"
496 | ],
497 | "execution_count": 0,
498 | "outputs": [
499 | {
500 | "output_type": "stream",
501 | "text": [
502 | "10000/10000 [==============================] - 0s 47us/sample - loss: 0.3291 - accuracy: 0.8907\n"
503 | ],
504 | "name": "stdout"
505 | },
506 | {
507 | "output_type": "execute_result",
508 | "data": {
509 | "text/plain": [
510 | "[0.3290795144557953, 0.8907]"
511 | ]
512 | },
513 | "metadata": {
514 | "tags": []
515 | },
516 | "execution_count": 17
517 | }
518 | ]
519 | },
520 | {
521 | "cell_type": "markdown",
522 | "metadata": {
523 | "id": "6tki-Aro_Uax",
524 | "colab_type": "text"
525 | },
526 | "source": [
527 | "For me, that returned a accuracy of about .8838, which means it was about 88% accurate. As expected it probably would not do as well with *unseen* data as it did with data it was trained on! As you go through this course, you'll look at ways to improve this. \n",
528 | "\n",
529 | "To explore further, try the below exercises:\n"
530 | ]
531 | },
532 | {
533 | "cell_type": "markdown",
534 | "metadata": {
535 | "id": "htldZNWcIPSN",
536 | "colab_type": "text"
537 | },
538 | "source": [
539 | "# Exploration Exercises"
540 | ]
541 | },
542 | {
543 | "cell_type": "markdown",
544 | "metadata": {
545 | "id": "rquQqIx4AaGR",
546 | "colab_type": "text"
547 | },
548 | "source": [
549 | "###Exercise 1:\n",
550 | "For this first exercise run the below code: It creates a set of classifications for each of the test images, and then prints the first entry in the classifications. The output, after you run it is a list of numbers. Why do you think this is, and what do those numbers represent? "
551 | ]
552 | },
553 | {
554 | "cell_type": "code",
555 | "metadata": {
556 | "id": "RyEIki0z_hAD",
557 | "colab_type": "code",
558 | "outputId": "56955fc4-c2bf-4f34-98f4-ec1f3d90594c",
559 | "colab": {
560 | "base_uri": "https://localhost:8080/",
561 | "height": 72
562 | }
563 | },
564 | "source": [
565 | "classifications = model.predict(test_images)\n",
566 | "\n",
567 | "print(classifications[0])"
568 | ],
569 | "execution_count": 0,
570 | "outputs": [
571 | {
572 | "output_type": "stream",
573 | "text": [
574 | "[1.43039443e-07 3.13800902e-10 1.32899425e-08 1.52091117e-09\n",
575 | " 2.32312054e-08 3.99441233e-05 1.55064903e-08 3.33322119e-03\n",
576 | " 6.15887119e-10 9.96626616e-01]\n"
577 | ],
578 | "name": "stdout"
579 | }
580 | ]
581 | },
582 | {
583 | "cell_type": "markdown",
584 | "metadata": {
585 | "id": "MdzqbQhRArzm",
586 | "colab_type": "text"
587 | },
588 | "source": [
589 | "Hint: try running print(test_labels[0]) -- and you'll get a 9. Does that help you understand why this list looks the way it does? "
590 | ]
591 | },
592 | {
593 | "cell_type": "code",
594 | "metadata": {
595 | "id": "WnBGOrMiA1n5",
596 | "colab_type": "code",
597 | "outputId": "17b25d97-83cb-4e15-af95-71cd889a7586",
598 | "colab": {
599 | "base_uri": "https://localhost:8080/",
600 | "height": 35
601 | }
602 | },
603 | "source": [
604 | "print(test_labels[0])"
605 | ],
606 | "execution_count": 0,
607 | "outputs": [
608 | {
609 | "output_type": "stream",
610 | "text": [
611 | "9\n"
612 | ],
613 | "name": "stdout"
614 | }
615 | ]
616 | },
617 | {
618 | "cell_type": "markdown",
619 | "metadata": {
620 | "id": "uUs7eqr7uSvs",
621 | "colab_type": "text"
622 | },
623 | "source": [
624 | "### What does this list represent?\n",
625 | "\n",
626 | "\n",
627 | "1. It's 10 random meaningless values\n",
628 | "2. It's the first 10 classifications that the computer made\n",
629 | "3. It's the probability that this item is each of the 10 classes\n",
630 | "\n"
631 | ]
632 | },
633 | {
634 | "cell_type": "markdown",
635 | "metadata": {
636 | "id": "wAbr92RTA67u",
637 | "colab_type": "text"
638 | },
639 | "source": [
640 | "####Answer: \n",
641 | "The correct answer is (3)\n",
642 | "\n",
643 | "The output of the model is a list of 10 numbers. These numbers are a probability that the value being classified is the corresponding value, i.e. the first value in the list is the probability that the handwriting is of a '0', the next is a '1' etc. Notice that they are all VERY LOW probabilities.\n",
644 | "\n",
645 | "For the 7, the probability was .999+, i.e. the neural network is telling us that it's almost certainly a 7."
646 | ]
647 | },
648 | {
649 | "cell_type": "markdown",
650 | "metadata": {
651 | "id": "CD4kC6TBu-69",
652 | "colab_type": "text"
653 | },
654 | "source": [
655 | "### How do you know that this list tells you that the item is an ankle boot?\n",
656 | "\n",
657 | "\n",
658 | "1. There's not enough information to answer that question\n",
659 | "2. The 10th element on the list is the biggest, and the ankle boot is labelled 9\n",
660 | "2. The ankle boot is label 9, and there are 0->9 elements in the list\n",
661 | "\n",
662 | "\n"
663 | ]
664 | },
665 | {
666 | "cell_type": "markdown",
667 | "metadata": {
668 | "id": "I-haLncrva5L",
669 | "colab_type": "text"
670 | },
671 | "source": [
672 | "####Answer\n",
673 | "The correct answer is (2). Both the list and the labels are 0 based, so the ankle boot having label 9 means that it is the 10th of the 10 classes. The list having the 10th element being the highest value means that the Neural Network has predicted that the item it is classifying is most likely an ankle boot"
674 | ]
675 | },
676 | {
677 | "cell_type": "markdown",
678 | "metadata": {
679 | "id": "OgQSIfDSOWv6",
680 | "colab_type": "text"
681 | },
682 | "source": [
683 | "##Exercise 2: \n",
684 | "Let's now look at the layers in your model. Experiment with different values for the dense layer with 512 neurons. What different results do you get for loss, training time etc? Why do you think that's the case? \n",
685 | "\n"
686 | ]
687 | },
688 | {
689 | "cell_type": "code",
690 | "metadata": {
691 | "id": "GSZSwV5UObQP",
692 | "colab_type": "code",
693 | "colab": {}
694 | },
695 | "source": [
696 | "import tensorflow as tf\n",
697 | "print(tf.__version__)\n",
698 | "\n",
699 | "mnist = tf.keras.datasets.mnist\n",
700 | "\n",
701 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n",
702 | "\n",
703 | "training_images = training_images/255.0\n",
704 | "test_images = test_images/255.0\n",
705 | "\n",
706 | "model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),\n",
707 | " tf.keras.layers.Dense(1024, activation=tf.nn.relu),\n",
708 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])\n",
709 | "\n",
710 | "model.compile(optimizer = 'adam',\n",
711 | " loss = 'sparse_categorical_crossentropy')\n",
712 | "\n",
713 | "model.fit(training_images, training_labels, epochs=5)\n",
714 | "\n",
715 | "model.evaluate(test_images, test_labels)\n",
716 | "\n",
717 | "classifications = model.predict(test_images)\n",
718 | "\n",
719 | "print(classifications[0])\n",
720 | "print(test_labels[0])"
721 | ],
722 | "execution_count": 0,
723 | "outputs": []
724 | },
725 | {
726 | "cell_type": "markdown",
727 | "metadata": {
728 | "id": "bOOEnHZFv5cS",
729 | "colab_type": "text"
730 | },
731 | "source": [
732 | "###Question 1. Increase to 1024 Neurons -- What's the impact?\n",
733 | "\n",
734 | "1. Training takes longer, but is more accurate\n",
735 | "2. Training takes longer, but no impact on accuracy\n",
736 | "3. Training takes the same time, but is more accurate\n"
737 | ]
738 | },
739 | {
740 | "cell_type": "markdown",
741 | "metadata": {
742 | "id": "U73MUP2lwrI2",
743 | "colab_type": "text"
744 | },
745 | "source": [
746 | "####Answer\n",
747 | "The correct answer is (1) by adding more Neurons we have to do more calculations, slowing down the process, but in this case they have a good impact -- we do get more accurate. That doesn't mean it's always a case of 'more is better', you can hit the law of diminishing returns very quickly!"
748 | ]
749 | },
750 | {
751 | "cell_type": "markdown",
752 | "metadata": {
753 | "id": "WtWxK16hQxLN",
754 | "colab_type": "text"
755 | },
756 | "source": [
757 | "##Exercise 3: \n",
758 | "\n",
759 | "What would happen if you remove the Flatten() layer. Why do you think that's the case? \n",
760 | "\n",
761 | "You get an error about the shape of the data. It may seem vague right now, but it reinforces the rule of thumb that the first layer in your network should be the same shape as your data. Right now our data is 28x28 images, and 28 layers of 28 neurons would be infeasible, so it makes more sense to 'flatten' that 28,28 into a 784x1. Instead of wriitng all the code to handle that ourselves, we add the Flatten() layer at the begining, and when the arrays are loaded into the model later, they'll automatically be flattened for us."
762 | ]
763 | },
764 | {
765 | "cell_type": "code",
766 | "metadata": {
767 | "id": "ExNxCwhcQ18S",
768 | "colab_type": "code",
769 | "colab": {}
770 | },
771 | "source": [
772 | "import tensorflow as tf\n",
773 | "print(tf.__version__)\n",
774 | "\n",
775 | "mnist = tf.keras.datasets.mnist\n",
776 | "\n",
777 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n",
778 | "\n",
779 | "training_images = training_images/255.0\n",
780 | "test_images = test_images/255.0\n",
781 | "\n",
782 | "model = tf.keras.models.Sequential([#tf.keras.layers.Flatten(),\n",
783 | " tf.keras.layers.Dense(64, activation=tf.nn.relu),\n",
784 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])\n",
785 | "\n",
786 | "model.compile(optimizer = 'adam',\n",
787 | " loss = 'sparse_categorical_crossentropy')\n",
788 | "\n",
789 | "model.fit(training_images, training_labels, epochs=5)\n",
790 | "\n",
791 | "model.evaluate(test_images, test_labels)\n",
792 | "\n",
793 | "classifications = model.predict(test_images)\n",
794 | "\n",
795 | "print(classifications[0])\n",
796 | "print(test_labels[0])"
797 | ],
798 | "execution_count": 0,
799 | "outputs": []
800 | },
801 | {
802 | "cell_type": "markdown",
803 | "metadata": {
804 | "id": "VqoCR-ieSGDg",
805 | "colab_type": "text"
806 | },
807 | "source": [
808 | "##Exercise 4: \n",
809 | "\n",
810 | "Consider the final (output) layers. Why are there 10 of them? What would happen if you had a different amount than 10? For example, try training the network with 5\n",
811 | "\n",
812 | "You get an error as soon as it finds an unexpected value. Another rule of thumb -- the number of neurons in the last layer should match the number of classes you are classifying for. In this case it's the digits 0-9, so there are 10 of them, hence you should have 10 neurons in your final layer."
813 | ]
814 | },
815 | {
816 | "cell_type": "code",
817 | "metadata": {
818 | "id": "MMckVntcSPvo",
819 | "colab_type": "code",
820 | "colab": {}
821 | },
822 | "source": [
823 | "import tensorflow as tf\n",
824 | "print(tf.__version__)\n",
825 | "\n",
826 | "mnist = tf.keras.datasets.mnist\n",
827 | "\n",
828 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n",
829 | "\n",
830 | "training_images = training_images/255.0\n",
831 | "test_images = test_images/255.0\n",
832 | "\n",
833 | "model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),\n",
834 | " tf.keras.layers.Dense(64, activation=tf.nn.relu),\n",
835 | " tf.keras.layers.Dense(5, activation=tf.nn.softmax)])\n",
836 | "\n",
837 | "model.compile(optimizer = 'adam',\n",
838 | " loss = 'sparse_categorical_crossentropy')\n",
839 | "\n",
840 | "model.fit(training_images, training_labels, epochs=5)\n",
841 | "\n",
842 | "model.evaluate(test_images, test_labels)\n",
843 | "\n",
844 | "classifications = model.predict(test_images)\n",
845 | "\n",
846 | "print(classifications[0])\n",
847 | "print(test_labels[0])"
848 | ],
849 | "execution_count": 0,
850 | "outputs": []
851 | },
852 | {
853 | "cell_type": "markdown",
854 | "metadata": {
855 | "id": "-0lF5MuvSuZF",
856 | "colab_type": "text"
857 | },
858 | "source": [
859 | "##Exercise 5: \n",
860 | "\n",
861 | "Consider the effects of additional layers in the network. What will happen if you add another layer between the one with 512 and the final layer with 10. \n",
862 | "\n",
863 | "Ans: There isn't a significant impact -- because this is relatively simple data. For far more complex data (including color images to be classified as flowers that you'll see in the next lesson), extra layers are often necessary. "
864 | ]
865 | },
866 | {
867 | "cell_type": "code",
868 | "metadata": {
869 | "id": "b1YPa6UhS8Es",
870 | "colab_type": "code",
871 | "colab": {}
872 | },
873 | "source": [
874 | "import tensorflow as tf\n",
875 | "print(tf.__version__)\n",
876 | "\n",
877 | "mnist = tf.keras.datasets.mnist\n",
878 | "\n",
879 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n",
880 | "\n",
881 | "training_images = training_images/255.0\n",
882 | "test_images = test_images/255.0\n",
883 | "\n",
884 | "model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),\n",
885 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n",
886 | " tf.keras.layers.Dense(256, activation=tf.nn.relu),\n",
887 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])\n",
888 | "\n",
889 | "model.compile(optimizer = 'adam',\n",
890 | " loss = 'sparse_categorical_crossentropy')\n",
891 | "\n",
892 | "model.fit(training_images, training_labels, epochs=5)\n",
893 | "\n",
894 | "model.evaluate(test_images, test_labels)\n",
895 | "\n",
896 | "classifications = model.predict(test_images)\n",
897 | "\n",
898 | "print(classifications[0])\n",
899 | "print(test_labels[0])"
900 | ],
901 | "execution_count": 0,
902 | "outputs": []
903 | },
904 | {
905 | "cell_type": "code",
906 | "metadata": {
907 | "id": "sE7PDe6LWAHb",
908 | "colab_type": "code",
909 | "colab": {}
910 | },
911 | "source": [
912 | ""
913 | ],
914 | "execution_count": 0,
915 | "outputs": []
916 | },
917 | {
918 | "cell_type": "markdown",
919 | "metadata": {
920 | "id": "Bql9fyaNUSFy",
921 | "colab_type": "text"
922 | },
923 | "source": [
924 | "#Exercise 6: \n",
925 | "\n",
926 | "Consider the impact of training for more or less epochs. Why do you think that would be the case? \n",
927 | "\n",
928 | "Try 15 epochs -- you'll probably get a model with a much better loss than the one with 5\n",
929 | "Try 30 epochs -- you might see the loss value stops decreasing, and sometimes increases. This is a side effect of something called 'overfitting' which you can learn about [somewhere] and it's something you need to keep an eye out for when training neural networks. There's no point in wasting your time training if you aren't improving your loss, right! :)"
930 | ]
931 | },
932 | {
933 | "cell_type": "code",
934 | "metadata": {
935 | "id": "uE3esj9BURQe",
936 | "colab_type": "code",
937 | "colab": {}
938 | },
939 | "source": [
940 | "import tensorflow as tf\n",
941 | "print(tf.__version__)\n",
942 | "\n",
943 | "mnist = tf.keras.datasets.mnist\n",
944 | "\n",
945 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n",
946 | "\n",
947 | "training_images = training_images/255.0\n",
948 | "test_images = test_images/255.0\n",
949 | "\n",
950 | "model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),\n",
951 | " tf.keras.layers.Dense(128, activation=tf.nn.relu),\n",
952 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])\n",
953 | "\n",
954 | "model.compile(optimizer = 'adam',\n",
955 | " loss = 'sparse_categorical_crossentropy')\n",
956 | "\n",
957 | "model.fit(training_images, training_labels, epochs=30)\n",
958 | "\n",
959 | "model.evaluate(test_images, test_labels)\n",
960 | "\n",
961 | "classifications = model.predict(test_images)\n",
962 | "\n",
963 | "print(classifications[34])\n",
964 | "print(test_labels[34])"
965 | ],
966 | "execution_count": 0,
967 | "outputs": []
968 | },
969 | {
970 | "cell_type": "markdown",
971 | "metadata": {
972 | "id": "HS3vVkOgCDGZ",
973 | "colab_type": "text"
974 | },
975 | "source": [
976 | "#Exercise 7: \n",
977 | "\n",
978 | "Before you trained, you normalized the data, going from values that were 0-255 to values that were 0-1. What would be the impact of removing that? Here's the complete code to give it a try. Why do you think you get different results? "
979 | ]
980 | },
981 | {
982 | "cell_type": "code",
983 | "metadata": {
984 | "id": "JDqNAqrpCNg0",
985 | "colab_type": "code",
986 | "colab": {}
987 | },
988 | "source": [
989 | "import tensorflow as tf\n",
990 | "print(tf.__version__)\n",
991 | "mnist = tf.keras.datasets.mnist\n",
992 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()\n",
993 | "training_images=training_images/255.0\n",
994 | "test_images=test_images/255.0\n",
995 | "model = tf.keras.models.Sequential([\n",
996 | " tf.keras.layers.Flatten(),\n",
997 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n",
998 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n",
999 | "])\n",
1000 | "model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')\n",
1001 | "model.fit(training_images, training_labels, epochs=5)\n",
1002 | "model.evaluate(test_images, test_labels)\n",
1003 | "classifications = model.predict(test_images)\n",
1004 | "print(classifications[0])\n",
1005 | "print(test_labels[0])"
1006 | ],
1007 | "execution_count": 0,
1008 | "outputs": []
1009 | },
1010 | {
1011 | "cell_type": "markdown",
1012 | "metadata": {
1013 | "id": "E7W2PT66ZBHQ",
1014 | "colab_type": "text"
1015 | },
1016 | "source": [
1017 | "#Exercise 8: \n",
1018 | "\n",
1019 | "Earlier when you trained for extra epochs you had an issue where your loss might change. It might have taken a bit of time for you to wait for the training to do that, and you might have thought 'wouldn't it be nice if I could stop the training when I reach a desired value?' -- i.e. 95% accuracy might be enough for you, and if you reach that after 3 epochs, why sit around waiting for it to finish a lot more epochs....So how would you fix that? Like any other program...you have callbacks! Let's see them in action..."
1020 | ]
1021 | },
1022 | {
1023 | "cell_type": "code",
1024 | "metadata": {
1025 | "id": "pkaEHHgqZbYv",
1026 | "colab_type": "code",
1027 | "colab": {}
1028 | },
1029 | "source": [
1030 | "import tensorflow as tf\n",
1031 | "print(tf.__version__)\n",
1032 | "\n",
1033 | "class myCallback(tf.keras.callbacks.Callback):\n",
1034 | " def on_epoch_end(self, epoch, logs={}):\n",
1035 | " if(logs.get('loss')<0.4):\n",
1036 | " print(\"\\nReached 60% accuracy so cancelling training!\")\n",
1037 | " self.model.stop_training = True\n",
1038 | "\n",
1039 | "callbacks = myCallback()\n",
1040 | "mnist = tf.keras.datasets.fashion_mnist\n",
1041 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()\n",
1042 | "training_images=training_images/255.0\n",
1043 | "test_images=test_images/255.0\n",
1044 | "model = tf.keras.models.Sequential([\n",
1045 | " tf.keras.layers.Flatten(),\n",
1046 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n",
1047 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n",
1048 | "])\n",
1049 | "model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')\n",
1050 | "model.fit(training_images, training_labels, epochs=5, callbacks=[callbacks])\n",
1051 | "\n",
1052 | "\n"
1053 | ],
1054 | "execution_count": 0,
1055 | "outputs": []
1056 | }
1057 | ]
1058 | }
--------------------------------------------------------------------------------
/Part 2-Computer Vision with TensorFlow/Excercise2_question.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "Excercise2 question.ipynb",
7 | "provenance": [],
8 | "include_colab_link": true
9 | },
10 | "kernelspec": {
11 | "name": "python3",
12 | "display_name": "Python 3"
13 | }
14 | },
15 | "cells": [
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {
19 | "id": "view-in-github",
20 | "colab_type": "text"
21 | },
22 | "source": [
23 | ""
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {
29 | "id": "I5tcbh0IWTmQ",
30 | "colab_type": "text"
31 | },
32 | "source": [
33 | "\n",
34 | "You learned how to do classificaiton using Fashion MNIST, a data set containing items of clothing. There's another, similar dataset called MNIST which has items of handwriting - the digits 0 through 9.\n",
35 | "Write an MNIST classifier that trains to 99% accuracy or above, and does it without a fixed number of epochs - i.e. you should stop training once you reach that level of accuracy.\n",
36 | "\n",
37 | "Some notes:\n",
38 | "\n",
39 | "1. It should succeed in less than 10 epochs, so it is okay to change epochs = to 10, but nothing larger\n",
40 | "2. When it reaches 99% or greater it should print out the string \"Reached 99% accuracy so cancelling training!\"\n",
41 | "\n",
42 | "Use this code line to get MNIST handwriting data set:\n",
43 | "\n",
44 | "```\n",
45 | "mnist = tf.keras.datasets.mnist\n",
46 | "```\n",
47 | "\n"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "metadata": {
53 | "id": "aXwpXnljWIji",
54 | "colab_type": "code",
55 | "colab": {}
56 | },
57 | "source": [
58 | "# YOUR CODE SHOULD START HERE\n",
59 | "# YOUR CODE SHOULD END HERE\n",
60 | "import tensorflow as tf\n",
61 | "mnist = tf.keras.datasets.mnist\n",
62 | "\n",
63 | "(x_train, y_train),(x_test, y_test) = mnist.load_data()\n",
64 | "# YOUR CODE SHOULD START HERE\n",
65 | "\n",
66 | "# YOUR CODE SHOULD END HERE\n",
67 | "model = tf.keras.models.Sequential([\n",
68 | "# YOUR CODE SHOULD START HERE\n",
69 | " \n",
70 | "# YOUR CODE SHOULD END HERE\n",
71 | "])\n",
72 | "\n",
73 | "model.compile(optimizer='adam',\n",
74 | " loss='sparse_categorical_crossentropy',\n",
75 | " metrics=['accuracy'])\n",
76 | "\n",
77 | "# YOUR CODE SHOULD START HERE\n",
78 | "# YOUR CODE SHOULD END HERE"
79 | ],
80 | "execution_count": 0,
81 | "outputs": []
82 | }
83 | ]
84 | }
--------------------------------------------------------------------------------
/Part 2-Computer Vision with TensorFlow/Excercise2_solution.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "Excercise2_solution.ipynb",
7 | "provenance": [],
8 | "authorship_tag": "ABX9TyMSE3HNT4DRkyfFTeuF+fhi",
9 | "include_colab_link": true
10 | },
11 | "kernelspec": {
12 | "name": "python3",
13 | "display_name": "Python 3"
14 | }
15 | },
16 | "cells": [
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {
20 | "id": "view-in-github",
21 | "colab_type": "text"
22 | },
23 | "source": [
24 | ""
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "metadata": {
30 | "id": "nyV34YajcGuP",
31 | "colab_type": "code",
32 | "colab": {}
33 | },
34 | "source": [
35 | "def train_mnist():\n",
36 | " # Please write your code only where you are indicated.\n",
37 | " # please do not remove # model fitting inline comments.\n",
38 | "\n",
39 | " # YOUR CODE SHOULD START HERE\n",
40 | " class myCallback(tf.keras.callbacks.Callback):\n",
41 | " def on_epoch_end(self, epoch, logs={}):\n",
42 | " if(logs.get('acc')>0.99):\n",
43 | " print(\"/nReached 99% accuracy so cancelling training!\")\n",
44 | " self.model.stop_training = True\n",
45 | " # YOUR CODE SHOULD END HERE\n",
46 | "\n",
47 | " mnist = tf.keras.datasets.mnist\n",
48 | "\n",
49 | " (x_train, y_train),(x_test, y_test) = mnist.load_data()\n",
50 | " # YOUR CODE SHOULD START HERE\n",
51 | " x_train, x_test = x_train / 255.0, x_test / 255.0\n",
52 | " \n",
53 | "\n",
54 | " callbacks = myCallback()\n",
55 | " # YOUR CODE SHOULD END HERE\n",
56 | " model = tf.keras.models.Sequential([\n",
57 | " # YOUR CODE SHOULD START HERE\n",
58 | " tf.keras.layers.Flatten(input_shape=(28, 28)),\n",
59 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n",
60 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n",
61 | " # YOUR CODE SHOULD END HERE\n",
62 | " ])\n",
63 | "\n",
64 | " model.compile(optimizer='adam',\n",
65 | " loss='sparse_categorical_crossentropy',\n",
66 | " metrics=['accuracy'])\n",
67 | " \n",
68 | " # model fitting\n",
69 | " history = model.fit(# YOUR CODE SHOULD START HERE\n",
70 | " x_train,\n",
71 | " y_train,\n",
72 | " epochs=10,\n",
73 | " callbacks=[callbacks]\n",
74 | " # YOUR CODE SHOULD END HERE\n",
75 | " )\n",
76 | " # model fitting\n",
77 | " return history.epoch, history.history['acc'][-1]"
78 | ],
79 | "execution_count": 0,
80 | "outputs": []
81 | }
82 | ]
83 | }
--------------------------------------------------------------------------------
/Part 2-Computer Vision with TensorFlow/README.md:
--------------------------------------------------------------------------------
1 | # Computer Vision with TensorFlow
2 |
3 | This same blog is availaible on Medium [here](https://medium.com/@rishit.dagli/computer-vision-with-tensorflow-part-2-57e95cd0551)
4 |
5 | 
6 |
Source: cognitiveclass.ai
7 |
8 | This is the second part of the series where I post about TensorFlow for Deep Learning and Machine Learning.
9 | In the earlier blog post you learned all about how Machine Learning and Deep Learning is a new programming paradigm.
10 | This time you’re going to take that to the next level by beginning to solve problems of computer vision with just a few lines of
11 | code! I believe in hands-on coding so we will have many exercises and demos which you can try yourself too. I would recommend
12 | you to play around with these exercises and change the hyper-parameters and experiment with the code. We will also be working with
13 | some real life data sets and apply the discussed algorithms on them too. If you have not read the previous article consider
14 | reading it once before you read this one [here](https://medium.com/@rishit.dagli/computer-vision-with-tensorflow-part-2-57e95cd0551).
15 |
16 | ## Introduction
17 |
18 | So fitting straight lines seems like the “Hello, world” most basic implementation learning algorithm.
19 | But one of the most amazing things about machine learning is that,
20 | that core of the idea of fitting the x and y relationship is what lets us do amazing things like, have computers look at the
21 | picture and do activity recognition, or look at the picture and tell us, is this a dress, or a pair of pants, or a pair of shoes;
22 | really hard for humans, and amazing that computers can now use this to do these things as well. Right, like computer vision is a
23 | really hard problem to solve, right? Because you’re saying like dress or shoes. It’s like how would I write rules for that?
24 | How would I say, if this pixel then it’s a shoe, if that pixel then its a dress. It’s really hard to do, so the labeled samples
25 | are the right way to go. One of the non-intuitive things about vision is that it’s so easy for a person to look at you and say,
26 | you’re wearing a shirt, it’s so hard for a computer to figure it out.
27 |
28 | Because it’s so easy for humans to recognize objects, it’s almost difficult to understand why this is a complicated thing
29 | for a computer to do. What the computer has to do is look at all numbers, all the pixel brightness value,
30 | saying look at all of these numbers saying, these numbers correspond to a black shirt, and it’s amazing that with machine
31 | and deep learning computers are getting really good at this.
32 |
33 | ## Computer Vision
34 |
35 | Computer vision is the field of having a computer understand and label what is present in an image.
36 | When you look at this image below, you can interpret what a shirt is or what a shoe is, but how would you
37 | program for that? If an extra terrestrial who had never seen clothing walked into the room with you, how would
38 | you explain the shoes to him? It’s really difficult, if not impossible to do right? And it’s the same problem with
39 | computer vision.
40 | So one way to solve that is to use lots of pictures of clothing and tell the computer
41 | what that’s a picture of and then have the computer figure out the patterns that give you the difference between a shoe,
42 | and a shirt, and a handbag, and a coat.
43 |
44 | 
45 |
Image example
46 |
47 | ## Let’s Get started
48 |
49 | Fortunately, there’s a data set called Fashion MNIST
50 | (not to be confused with handwriting MNIST data set- that’s your excercise) which gives a 70,000
51 | images spread across 10 different items of clothing. These images have been scaled down to 28 by 28 pixels.
52 | Now usually, the smaller the better because the computer has less processing to do. But of course,
53 | you need to retain enough information to be sure that the features and the object can still be distinguished.
54 | If you look at the image you can still tell the difference between shirts, shoes, and handbags.
55 | So this size does seem to be ideal, and it makes it great for training a neural network. The images are also in gray scale,
56 | so the amount of information is also reduced. Each pixel can be represented in values from zero to 255 and so it’s
57 | only one byte per pixel. With 28 by 28 pixels in an image, only 784 bytes are needed to store the entire image.
58 | Despite that, we can still see what’s in the image below and in this case, it’s an ankle boot, right?
59 |
60 | 
61 |
An image from the dataset
62 |
63 | You can know more about the fashion MNIST data set at this GitHub repository [here](https://github.com/zalandoresearch/fashion-mnist).
64 | You can also download the data set from [here](https://github.com/zalandoresearch/fashion-mnist).
65 |
66 | So what will handling this look like in code?
67 | In the previous blog post, you learned about TensorFlow and Keras, and how to define a simple neural network with them.
68 | Here, you are going to use them to go a little deeper but the overall API should look familiar.
69 | The one big difference will be in the data. The last time you had just your six pairs of numbers, so you could hard code it.
70 | This time you have to load 70,000 images off the disk, so there will be a bit of code to handle that. Fortunately,
71 | it’s still quite simple because Fashion MNIST is available as a data set with an API call in TensorFlow.
72 |
73 | ```python
74 | fashion_mnist = keras.datasets.fashion_mnist
75 | (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
76 | ```
77 |
78 | Consider the code `fashion_mnist.load_data()` .
79 | What we are doing here is creating an object of type MNIST and loading it from the `Keras` data base.
80 | Now, on this class we are running a method called `load_data()` which will return four lists to us `train_images` ,
81 | `train_labels` , `test_images` and `test_labels` .
82 | Now, what are these you might wonder.
83 | So, when building a neural network like this, it's a nice strategy to use some of your data to train the neural network and
84 | similar data that the model hasn't yet seen to test how good it is at recognizing the images.
85 | So in the Fashion MNIST data set, 60,000 of the 70,000 images are used to train the network,
86 | and then 10,000 images, one that it hasn't previously seen,
87 | can be used to test just how good or how bad the model is performing. So this code will give you those sets.
88 |
89 | 
90 |
An image from data set and the code used
91 |
92 | So for example, the training data will contain images like this one, and a label that describes the image like this.
93 | While this image is an ankle boot, the label describing it is the number nine.
94 | Now, why do you think that is? There’s two main reasons.
95 | First, of course, is that computers do better with numbers than they do with texts.
96 | Second, importantly, is that this is something that can help us reduce bias.
97 | If we labeled it as an ankle boot, we would be of course biasing towards English speakers.
98 | But with it being a numeric label, we can then refer to it in our appropriate language be it English, Hindi,
99 | German, Mandarin or here, even Irish. You can learn more about bias and techniques to avoid it here.
100 |
101 | Coding a Neural Network for this
102 |
103 | Okay. So now we will look at the code for the neural network definition.
104 | Remember last time we had a sequential with just one layer in it. Now we have three layers.
105 |
106 | ```python
107 | model = keras.Sequential([ keras.layers.Flatten(input_shape = (28, 28)),
108 | keras.layers.Dense(128, activation = tf.nn.relu),
109 | keras.layers.Dense(10, activation = tf.nn.softmax)
110 | ])
111 | ```
112 |
113 | The important things to look at are the first and the last layers.
114 | The last layer has 10 neurons in it because we have ten classes of clothing in the data set.
115 | They should always match. The first layer is a flatten layer with the input shaping 28 by 28.
116 | Now, if you remember our images are 28 by 28, so we’re specifying that this is the shape that we
117 | should expect the data to be in. Flatten takes this 28 by 28 square and turns it into a simple linear array.
118 | The interesting stuff happens in the middle layer, sometimes also called a hidden layer. This is a 128 neurons in it,
119 | and I’d like you to think about these as variables in a function. Maybe call them x1, x2 x3, etc.
120 | Now, there exists a rule that incorporates all of these that turns the 784 values of an ankle boot into the value nine,
121 | and similar for all of the other 70,000.
122 |
123 | 
124 |
A neural net layer
125 |
126 | So, what the neural net does is it figure out `w0` , `w1` , `w2` … `w n` such that `(x1 * w1) + (x2 * w2) ... (x128 * w128) = y`
127 |
128 | You’ll see that it’s doing something very, very similar to what we did earlier when we figured out `y = 2x — 1`. In that case the two,
129 | was the weight of `x`. So, I’m saying `y = w1 * x1`, etc.
130 | The important thing now is to get the code working, so you can see a classification scenario for yourself.
131 | You can also tune the neural network by adding, removing and changing layer size to see the impact.
132 |
133 | As we discussed earlier to finish this example and writing the complete code we will use Tensor Flow 2.x,
134 | before that we will explore few Google Colaboratory tips as that is what you might be using.
135 | However, you can also use Jupyter Notebooks preferably on your local environment.
136 |
137 | ## Colab Tips (OPTIONAL)
138 |
139 | * Map your Google Drive
140 |
141 | On Colab notebooks you can access your Google Drive as a network mapped drive in the Colab VM runtime.
142 |
143 | ```python
144 | #You can access to your Drive files using this path "/content
145 | # /gdrive/My Drive/"
146 |
147 | from google.colab import drive
148 | drive.mount('/content/gdrive')
149 | ```
150 |
151 | * Work with your files transparently in your computer
152 |
153 | You can sync a Google Drive folder in your computer. Along with the previous tip, your local files will be
154 | available locally in your Colab notebook.
155 |
156 | * Clean your root folder on Google Drive
157 |
158 | There’s some resources from Google that explains that having a lot of files in your root folder
159 | can affect the process of mapping the unit. If you have a lot of files in your root folder on Drive,
160 | create a new folder and move all of them there. I suppose that having a lot of folders on the root folder will
161 | have similar impact.
162 |
163 | * Hardware acceleration
164 |
165 | For some applications you might need a hardware accelerator like a GPU or a TPU.
166 | Let’s say you are building a CNN or so 1 epoch might be 90–100 seconds on a CPU but just 5–6 seconds on a
167 | GPU and in milliseconds on a TPU. So, this is definetely helpful. You can go to-
168 |
169 | ```
170 | Runtime > Change Runtime Type > Select your hardware accelerator
171 | ```
172 |
173 | * A fun feature
174 |
175 | This is called power level. Power level is an April fools joke feature that adds sparks and combos to cell editing.
176 | Access using-
177 |
178 | ```
179 | Tools > Settings > Miscellaneous > Select Power
180 | ```
181 |
182 | Example of high power
183 |
184 | 
185 |
Example of high power
186 |
187 | ## Walk through the notebook
188 |
189 | The notebook is availaible [here](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Blog-series/blob/master/Part%202-Computer%20Vision%20with%20TensorFlow/Computer_vision_examples_Notebook.ipynb). If you are using local development environment, download this notebook;
190 | if you are using Colab click the `open in colab` button. We will also see some excercises in this notebook.
191 |
192 | Import tensorflow 2.0 in Colab-
193 |
194 | ```python
195 | try:
196 | # %tensorflow_version only exists in Colab.
197 | %tensorflow_version 2.x
198 | except Exception:
199 | pass
200 |
201 | import tensorflow as tf
202 | ```
203 |
204 | First we use the above code to import TensorFlow 2.x,
205 | If you are using local development environment you do not need lines 1–5.
206 |
207 | Then, as discussed we use this code to get the data set.
208 |
209 | ```python
210 | fashion_mnist = keras.datasets.fashion_mnist
211 | (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
212 | ```
213 |
214 | We will now use matplotlib to view a sample image from the dataset.
215 |
216 | ```python
217 | import matplotlib.pyplot as plt
218 | plt.imshow(training_images[0])
219 | ```
220 |
221 | You can change the 0 to other values to get other images as you might have guessed.
222 | You’ll notice that all of the values in the number are between 0 and 255. If we are training a neural network,
223 | for various reasons it’s easier if we treat all values as between 0 and 1, a process called ‘normalizing’ and fortunately
224 | in Python it’s easy to normalize a list like this without looping. You do it like this:
225 |
226 | ```python
227 | training_images = training_images / 255.0
228 | test_images = test_images / 255.0
229 | ```
230 |
231 | Now in the next code block in the notebook we have defines the same neural net we earlier discussed about.
232 | Ok so you might have noticed a change we use `softmax` function. Softmax takes a set of values, and effectively picks
233 | the biggest one, so, for example, if the output of the last layer looks like `[0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05]`,
234 | it saves you from fishing through it looking for the biggest value, and turns it into `[0,0,0,0,1,0,0,0,0]` —
235 | The goal is to save a lot of coding!
236 |
237 | We can then try to fit the training images to the training labels. We’ll just do it for 10 epochs to be quick.
238 | We spend about 50 seconds training it over five epochs and we end up with a loss of about 0.205.
239 | That means it’s pretty accurate in guessing the relationship between the images and their labels.
240 | That’s not great, but considering it was done in just 50 seconds with a very basic neural network, it’s not bad either.
241 | But a better measure of performance can be seen by trying the test data. These are images that the network has not yet seen.
242 | You would expect performance to be worse, but if it’s much worse, you have a problem. As you can see, it’s about 0.32 loss,
243 | meaning it’s a little bit less accurate on the test set. It’s not great either, but we know we’re doing something right.
244 |
245 | I have some questions and excercises for you 8 in all and I recommend you to go through all of them,
246 | you will also be exploring the same example with more neurons and thinngs like that. So have fun coding.
247 |
248 | You just made a complete fashion fashion MNIST algorithm which can predict with a pretty
249 | good accuracy the images of fashion items.
250 |
251 | ## Callbacks (Very important)
252 |
253 | How can I stop training when I reach a point that I want to be at? What do I always have to hard code it to go for certain number of epochs? So in every epoch, you can callback to a code function, having checked the metrics. If they’re what you want to say, then you can cancel the training at that point.
254 |
255 | Callback code-
256 |
257 | ```python
258 | class myCallback(tf.keras.callbacks.Callback):
259 | def on_epoch_end(self, epoch, logs = {}):
260 | if logs.get('loss') < 0.7:
261 | print("\n Low loss so cancelling the training")
262 | self.model.stop_training = True
263 |
264 | ```
265 |
266 | It’s implemented as a separate class, but that can be in-line with your other code. It doesn’t need to be in a separate file. In it, we’ll implement the on_epoch_end function, which gets called by the callback whenever the epoch ends. It also sends a logs object which contains lots of great information about the current state of training. For example, the current loss is available in the logs, so we can query it for certain amount. For example, here I’m checking if the loss is less than 0.7 and canceling the training itself. Now that we have our callback, let’s return to the rest of the code, and there are two modifications that we need to make. First, we instantiate the class that we just created, we do that with this code.
267 |
268 | ```python
269 | callbacks = myCallback()
270 | ```
271 |
272 | Then, in my `model.fit`, I used the callbacks parameter and pass it this instance of the class.
273 |
274 | ```python
275 | model.fit(training_images, training_labels, epochs = 10, callbacks = [callbacks])
276 | ```
277 |
278 | And now we pass the callback object to the callback argument of the `model.fit()` .
279 |
280 | Use this notebook to explore more and see this code in action [here](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Blog-series/blob/master/Part%202-Computer%20Vision%20with%20TensorFlow/Callbacks_example_Notebook.ipynb). This notebook contains all the modifications we talked about.
281 |
282 | ## Excercise 2
283 |
284 | You learned how to do classificaiton using Fashion MNIST, a data set containing items of clothing. There’s another, similar dataset called MNIST which has items of handwriting — the digits 0 through 9.
285 |
286 | Write an MNIST classifier that trains to 99% accuracy or above, and does it without a fixed number of epochs — i.e. you should stop training once you reach that level of accuracy.
287 |
288 | Some notes:
289 |
290 | * It should succeed in less than 10 epochs, so it is okay to change epochs = to 10, but nothing larger
291 | * When it reaches 99% or greater it should print out the string “Reached 99% accuracy so cancelling training!”
292 |
293 | Use this code line to get MNIST handwriting data set:
294 |
295 | ```python
296 | mnist = tf.keras.datasets.mnist
297 | ```
298 |
299 | Here’s a Colab notebook with the question and some strater code already written — [here](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Blog-series/blob/master/Part%202-Computer%20Vision%20with%20TensorFlow/Excercise2_question.ipynb)
300 |
301 | ## My Solution
302 |
303 | Wonderful! 😃 , you just coded for a handwriting recognizer with a 99% accuracy (that’s good) in less than 10 epochs. Let explore my solution for this.
304 |
305 | Excercise 2 Solution-
306 |
307 | ```python
308 | def train_mnist():
309 | # Please write your code only where you are indicated.
310 | # please do not remove # model fitting inline comments.
311 |
312 | # YOUR CODE SHOULD START HERE
313 | class myCallback(tf.keras.callbacks.Callback):
314 | def on_epoch_end(self, epoch, logs={}):
315 | if(logs.get('acc')>0.99):
316 | print("/nReached 99% accuracy so cancelling training!")
317 | self.model.stop_training = True
318 | # YOUR CODE SHOULD END HERE
319 |
320 | mnist = tf.keras.datasets.mnist
321 |
322 | (x_train, y_train),(x_test, y_test) = mnist.load_data()
323 | # YOUR CODE SHOULD START HERE
324 | x_train, x_test = x_train / 255.0, x_test / 255.0
325 |
326 |
327 | callbacks = myCallback()
328 | # YOUR CODE SHOULD END HERE
329 | model = tf.keras.models.Sequential([
330 | # YOUR CODE SHOULD START HERE
331 | tf.keras.layers.Flatten(input_shape=(28, 28)),
332 | tf.keras.layers.Dense(512, activation=tf.nn.relu),
333 | tf.keras.layers.Dense(10, activation=tf.nn.softmax)
334 | # YOUR CODE SHOULD END HERE
335 | ])
336 |
337 | model.compile(optimizer='adam',
338 | loss='sparse_categorical_crossentropy',
339 | metrics=['accuracy'])
340 |
341 | # model fitting
342 | history = model.fit(# YOUR CODE SHOULD START HERE
343 | x_train,
344 | y_train,
345 | epochs=10,
346 | callbacks=[callbacks]
347 | # YOUR CODE SHOULD END HERE
348 | )
349 | # model fitting
350 | return history.epoch, history.history['acc'][-1]
351 | ```
352 |
353 | I will just go through the important parts.
354 |
355 | The callback class-
356 |
357 | ```python
358 | class myCallback(tf.keras.callbacks.Callback):
359 | def on_epoch_end(self, epoch, logs={}):
360 | if(logs.get('acc')>0.99):
361 | print("/nReached 99% accuracy so cancelling training!")
362 | self.model.stop_training = True
363 | ```
364 |
365 | The main neural net code-
366 |
367 | ```python
368 | model = tf.keras.models.Sequential([
369 | tf.keras.layers.Flatten(input_shape=(28, 28)),
370 | tf.keras.layers.Dense(512, activation=tf.nn.relu),
371 | tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
372 |
373 | model.compile(optimizer='adam',
374 | loss='sparse_categorical_crossentropy',
375 | metrics=['accuracy'])
376 |
377 | history = model.fit(x_train, y_train, epochs=10, callbacks=[callbacks])
378 | ```
379 |
380 | So, all you had to do was play around with the code and this gets done in just 5 epochs.
381 |
382 | The solution notebook is availaible [here](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Blog-series/blob/master/Part%202-Computer%20Vision%20with%20TensorFlow/Excercise2_solution.ipynb).
383 |
384 | ## About Me
385 |
386 | Hi everyone I am Rishit Dagli
387 |
388 | [Twitter](https://twitter.com/rishit_dagli)
389 |
390 | [Website](https://rishit.tech/)
391 |
392 | If you want to ask me some questions, report any mistake, suggest improvements, give feedback you are free to do so by emailing me at —
393 |
394 | * [rishit.dagli@gmail.com](mailto:rishit.dagli@gmail.com)
395 |
396 | * [hello@rishit.tech](mailto:hello@rishit.tech)
397 |
398 |
399 |
--------------------------------------------------------------------------------
/Part 3-Using Convolutional Neural Networks with TensorFlow/README.md:
--------------------------------------------------------------------------------
1 | # Using Convolutional Neural Networks with TensorFlow
2 |
3 | The same blog is availaible on Medium [here](https://medium.com/@rishit.dagli/using-convolutional-neural-networks-with-tensorflow-part-3-35de28a5621)
4 |
5 | 
6 | Source: Cognitiveclass.ai
7 |
8 | All the code used here is available in my GitHub repository
9 | [here](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Blog-series/).
10 |
11 | *****
12 |
13 | This is the third part of the series where I post about TensorFlow for Deep
14 | Learning and Machine Learning. In the earlier blog post you saw a basic Neural
15 | Network for Computer Vision. It did the job nicely, but it was a little naive in
16 | its approach. This time you’re going to improve on that using Convolutional
17 | Neural Networks(CNN). I believe in hands-on coding so we will have many
18 | exercises and demos which you can try yourself too. I would recommend you to
19 | play around with these exercises and change the hyper-parameters and experiment
20 | with the code. We will also be working with some real life data sets and apply
21 | the discussed algorithms on them too. If you have not read the previous article
22 | consider reading it once before you read this one
23 | [here](https://medium.com/@rishit.dagli/computer-vision-with-tensorflow-part-2-57e95cd0551).
24 |
25 | ### Introduction
26 |
27 | I think it’s really cool that you’re already able to implement a neural network
28 | to do this fashion classification task. It’s just amazing that large data sets
29 | like this are readily available to you which makes it really easy to learn. And
30 | in this case we saw with just a few lines of code, we were able to build a DNN,
31 | deep neural net that allowed you to do this classification of clothing and we
32 | got reasonable accuracy with it but it was a little bit of a naive algorithm
33 | that we used, right? We’re looking at each and every pixel in every image, but
34 | maybe there are ways that we can make it better but maybe looking at features of
35 | what makes a shoe a shoe and what makes a handbag a handbag. What do you think?
36 | You might think something like if I have a shoelace in the picture it could be a
37 | shoe and if there is a handle it may be a handbag.
38 |
39 | So, one of the ideas that make these neural networks work much better is to use
40 | convolutional neural networks, where instead of looking at every single pixel
41 | and say, getting the pixel values and then figuring out, “is this a shoe or is
42 | this a hand bag? I don’t know.” But instead you can look at a picture and say,
43 | “Ok, I see shoelaces and a sole.” Then, it’s probably shoe or say, “I see a
44 | handle and rectangular bag beneath that.” Probably a handbag. What’s really
45 | interesting about convolutions is that they sound very complicated but they’re
46 | actually quite straightforward. It is essentially just a filter that you pass
47 | over an image in the same way as if you’re doing some sharpening. If you have
48 | ever done image processing, it can spot features within the image just like we
49 | talked about. With the same paradigm of just data labels, we can let a neural
50 | network figure out for itself that it should look for shoe laces and soles or
51 | handles in bags and then just learn how to detect these things by itself. So we
52 | will also see how good or bad it works in comparison to our earlier approach for
53 | Fashion MNIST?
54 |
55 | So, now we will know about convolutional neural networks and get to use it to
56 | build a much better fashion classifier.
57 |
58 | *****
59 |
60 | ### What are Convolutions and Poolings
61 |
62 | In the DNN approach, in just a couple of minutes, you’re able to train it to
63 | classify with pretty high accuracy on the training set, but a little less on the
64 | test set. Now, one of the things that you would have seen when you looked at the
65 | images is that there’s a lot of wasted space in each image. While there are only
66 | 784 pixels, it will be interesting to see if there was a way that we could
67 | condense the image down to the important features that distinguish what makes it
68 | a shoe, or a handbag, or a shirt. That’s where convolutions come in. So, what’s
69 | convolution at all?
70 |
71 | 
72 | How filters work?
73 |
74 | If you have ever done any kind of image processing, it usually involves having a
75 | filter and passing that filter over the image in order to change the underlying
76 | image. The process works a little bit like this. For every pixel, take its
77 | value, and take a look at the value of its neighbors. If our filter is three by
78 | three, then we can take a look at the immediate neighbor, so that you have a
79 | corresponding 3 by 3 grid. Then to get the new value for the pixel, we simply
80 | multiply each neighbor by the corresponding value in the filter. So, for
81 | example, in this case, our pixel has the value 192, and its upper left neighbor
82 | has the value 0. The upper left value and the filter is -1, so we multiply 0 by
83 | -1. Then we would do the same for the upper neighbor. Its value is 64 and the
84 | corresponding filter value was 0, so we’d multiply those out.
85 |
86 | Repeat this for each neighbor and each corresponding filter value, and would
87 | then have the new pixel with the sum of each of the neighbor values multiplied
88 | by the corresponding filter value, and that’s a convolution. It’s really as
89 | simple as that. The idea here is that some convolutions will change the image in
90 | such a way that certain features in the image get emphasized.
91 |
92 | So, for example, if you look at this filter, then the vertical lines in the
93 | image really pop out. Don’t worry we will do a hands-on for this later.
94 |
95 | 
96 | A filter which pops out vertical lines
97 |
98 | With this filter, the horizontal lines pop out.
99 |
100 | 
101 | A filter which pops out horizontal lines
102 |
103 | Now, that’s a very basic introduction to what convolutions do, and when combined
104 | with something called pooling, they can become really powerful.
105 |
106 | Now what’s pooling then? pooling is a way of compressing an image. A quick and
107 | easy way to do this, is to go over the image of 4 pixels at a time, that is, the
108 | current pixel and its neighbors underneath and to the right of it.
109 |
110 | 
111 | a 4 x 4 pooling
112 |
113 | Of these 4, pick the biggest value and keep just that. So, for example, you can
114 | see it here. My 16 pixels on the left are turned into the four pixels on the
115 | right, by looking at them in 2 by 2 grids and picking the biggest value. This
116 | will preserve the features that were highlighted by the convolution, while
117 | simultaneously quartering the size of the image. We have the horizontal and
118 | vertical axes too.
119 |
120 | *****
121 |
122 | ### Coding for convolutions and max pooling
123 |
124 | These layers are available as
125 |
126 | * [Conv2D](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Conv2D) and
127 | * [MaxPooling2D](https://www.tensorflow.org/api_docs/python/tf/keras/layers/MaxPool2D?version=stable)
128 |
129 | in TensorFlow.
130 |
131 | We don’t have to do all the math for filtering and compressing, we simply define
132 | convolutional and pooling layers to do the job for us.
133 |
134 | So here’s our code from the earlier example, where we defined out a neural
135 | network to have an input layer in the shape of our data, and output layer in the
136 | shape of the number of categories we’re trying to define, and a hidden layer in
137 | the middle. The Flatten takes our square 28 by 28 images and turns them into a
138 | one dimensional array.
139 |
140 | model = tf.keras.models.Sequential([
141 |
142 | tf.keras.layers.Flatten(input_shape=(28, 28)),
143 | tf.keras.layers.Dense(128, activation = tf.nn.relu,
144 | tf.keras.layers.Dense(10, activation = tf.nn.softmax
145 |
146 | ])
147 |
148 | To add convolutions to this, you use code like this.
149 |
150 | model = tf.keras.models.Sequential([
151 |
152 | tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28, 28, 1)),
153 |
154 | tf.keras.layers.MaxPooling2D(2, 2),
155 |
156 | tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
157 |
158 | tf.keras.layers.MaxPooling2D(2,2),
159 |
160 | tf.keras.layers.Flatten(),
161 |
162 | tf.keras.layers.Dense(128, activation='relu'),
163 |
164 | tf.keras.layers.Dense(10, activation='softmax')
165 |
166 | ])
167 |
168 | You’ll see that the last three lines are the same, the `Flatten`, the `Dense`
169 | hidden layer with 128 neurons, and the `Dense` output layer with 10 neurons.
170 | What’s different is what has been added on top of this. Let’s take a look at
171 | this, line by line.
172 |
173 | tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28, 28, 1))
174 |
175 | Here we’re specifying the first convolution. We’re asking `keras` to generate 64
176 | filters for us. These filters are 3 by 3, their activation is `relu`, which
177 | means the negative values will be thrown way, and finally the input shape is as
178 | before, the 28 by 28. That extra 1 just means that we are tallying using a
179 | single byte for color depth. As we saw before our image is our gray scale, so we
180 | just use one byte. Now, of course, you might wonder what the 64 filters are.
181 | It’s a little beyond the scope of this blog to define them, but they for now you
182 | can understand that they are not random. They start with a set of known good
183 | filters in a similar way to the pattern fitting that you saw earlier, and the
184 | ones that work from that set are learned over time.
185 |
186 | tf.keras.layers.MaxPooling2D(2, 2)
187 |
188 | This next line of code will then create a pooling layer. It’s max-pooling
189 | because we’re going to take the maximum value. We’re saying it’s a two-by-two
190 | pool, so for every four pixels, the biggest one will survive as shown earlier.
191 | We then add another convolutional layer, and another max-pooling layer so that
192 | the network can learn another set of convolutions on top of the existing one,
193 | and then again, pool to reduce the size. So, by the time the image gets to the
194 | flatten to go into the dense layers, it’s already much smaller. It’s being
195 | quartered, and then quartered again. So, its content has been greatly
196 | simplified, the goal being that the convolutions will filter it to the features
197 | that determine the output.
198 |
199 | A really useful method on the model is the `model.summary` method. This allows
200 | you to inspect the layers of the model, and see the journey of the image through
201 | the convolutions, and here is the output.
202 |
203 | 
204 | Output of model.summary
205 |
206 | It’s a nice table showing us the layers, and some details about them including
207 | the output shape. It’s important to keep an eye on the output shape column. When
208 | you first look at this, it can be a little bit confusing and feel like a bug.
209 | After all, isn’t the data 28 by 28, so why is the output, 26 by 26? The key to
210 | this is remembering that the filter is a 3 by 3 filter. Consider what happens
211 | when you start scanning through an image starting on the top left. So, you can’t
212 | calculate the filter for the pixel in the top left, because it doesn’t have any
213 | neighbors above it or to its left. In a similar fashion, the next pixel to the
214 | right won’t work either because it doesn’t have any neighbors above it. So,
215 | logically, the first pixel that you can do calculations on is this one, because
216 | this one of course has all 8 neighbors that a three by 3 filter needs. This when
217 | you think about it, means that you can’t use a 1 pixel margin all around the
218 | image, so the output of the convolution will be 2 pixels smaller on `x`, and 2
219 | pixels smaller on `y`. If your filter is five-by-five for similar reasons, your
220 | output will be four smaller on `x`, and four smaller on `y`. So, that’s `y` with
221 | a three by three filter, our output from the 28 by 28 image, is now 26 by 26,
222 | we’ve removed that one pixel on `x` and `y`, and each of the borders.
223 |
224 | So, now our output gets reduced from 26 by 26, to 13 by 13. The convolutions
225 | will then operate on that, and of course, we lose the 1 pixel margin as before,
226 | so we’re down to 11 by 11, add another 2 by 2 max-pooling to have this rounding
227 | down, and went down, down to 5 by 5 images. So, now our dense neural network is
228 | the same as before, but it’s being fed with five-by-five images instead of 28 by
229 | 28 ones.
230 |
231 | But remember, it’s not just one compressed 5 by 5 image instead of the original
232 | 28 by 28, there are a number of convolutions per image that we specified, in
233 | this case 64. So, there are 64 new images of 5 by 5 that had been fed in.
234 | Flatten that out and you have 25 pixels times 64, which is 1600. So, you can see
235 | that the new flattened layer has 1,600 elements in it, as opposed to the 784
236 | that you had previously. This number is impacted by the parameters that you set
237 | when defining the convolutional 2D layers. Later when you experiment, you’ll see
238 | what the impact of setting what other values for the number of convolutions will
239 | be, and in particular, you can see what happens when you’re feeding less than
240 | 784 over all pixels in. Training should be faster, but is there a sweet spot
241 | where it’s more accurate?
242 |
243 | *****
244 |
245 | To know more about this, implement this on a real life data set and even
246 | visualize the journey of an image through a CNN please head on to the next blog.
247 |
248 | *****
249 |
250 | ### About Me
251 |
252 | Hi everyone I am Rishit Dagli
253 |
254 | [Twitter](https://twitter.com/rishit_dagli)
255 |
256 | [Website](https://rishit.tech/)
257 |
258 | If you want to ask me some questions, report any mistake, suggest improvements,
259 | give feedback you are free to do so by emailing me at —
260 |
261 | * [rishit.dagli@gmail.com](mailto:rishit.dagli@gmail.com)
262 | * [hello@rishit.tech](mailto:hello@rishit.tech)
263 |
--------------------------------------------------------------------------------
/Part 4-Extending what Convolutional Neural Nets can do/CNN_with_Fashion_MNIST_Notebook.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "CNN with Fashion MNIST Notebook.ipynb",
7 | "provenance": [],
8 | "collapsed_sections": [],
9 | "include_colab_link": true
10 | },
11 | "kernelspec": {
12 | "name": "python3",
13 | "display_name": "Python 3"
14 | },
15 | "accelerator": "GPU"
16 | },
17 | "cells": [
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {
21 | "id": "view-in-github",
22 | "colab_type": "text"
23 | },
24 | "source": [
25 | ""
26 | ]
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "metadata": {
31 | "id": "R6gHiH-I7uFa",
32 | "colab_type": "text"
33 | },
34 | "source": [
35 | "#Improving Computer Vision Accuracy using Convolutions\n",
36 | "\n",
37 | "In the previous lessons you saw how to do fashion recognition using a Deep Neural Network (DNN) containing three layers -- the input layer (in the shape of the data), the output layer (in the shape of the desired output) and a hidden layer. You experimented with the impact of different sized of hidden layer, number of training epochs etc on the final accuracy.\n",
38 | "\n",
39 | "For convenience, here's the entire code again. Run it and take a note of the test accuracy that is printed out at the end. "
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "metadata": {
45 | "id": "xcsRtq9OLorS",
46 | "colab_type": "code",
47 | "outputId": "44de9249-667e-419f-c46d-9b96257019c5",
48 | "colab": {
49 | "base_uri": "https://localhost:8080/",
50 | "height": 507
51 | }
52 | },
53 | "source": [
54 | "import tensorflow as tf\n",
55 | "mnist = tf.keras.datasets.fashion_mnist\n",
56 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()\n",
57 | "training_images=training_images / 255.0\n",
58 | "test_images=test_images / 255.0\n",
59 | "model = tf.keras.models.Sequential([\n",
60 | " tf.keras.layers.Flatten(),\n",
61 | " tf.keras.layers.Dense(128, activation=tf.nn.relu),\n",
62 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n",
63 | "])\n",
64 | "model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n",
65 | "model.fit(training_images, training_labels, epochs=5)\n",
66 | "\n",
67 | "test_loss = model.evaluate(test_images, test_labels)"
68 | ],
69 | "execution_count": 0,
70 | "outputs": [
71 | {
72 | "output_type": "display_data",
73 | "data": {
74 | "text/html": [
75 | "
\n",
76 | "The default version of TensorFlow in Colab will soon switch to TensorFlow 2.x. \n",
77 | "We recommend you upgrade now \n",
78 | "or ensure your notebook will continue to use TensorFlow 1.x via the %tensorflow_version 1.x magic:\n",
79 | "more info.
\n"
80 | ],
81 | "text/plain": [
82 | ""
83 | ]
84 | },
85 | "metadata": {
86 | "tags": []
87 | }
88 | },
89 | {
90 | "output_type": "stream",
91 | "text": [
92 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz\n",
93 | "32768/29515 [=================================] - 0s 0us/step\n",
94 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz\n",
95 | "26427392/26421880 [==============================] - 0s 0us/step\n",
96 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz\n",
97 | "8192/5148 [===============================================] - 0s 0us/step\n",
98 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz\n",
99 | "4423680/4422102 [==============================] - 0s 0us/step\n",
100 | "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/resource_variable_ops.py:1630: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.\n",
101 | "Instructions for updating:\n",
102 | "If using Keras pass *_constraint arguments to layers.\n",
103 | "Train on 60000 samples\n",
104 | "Epoch 1/5\n",
105 | "60000/60000 [==============================] - 5s 82us/sample - loss: 0.4985 - acc: 0.8256\n",
106 | "Epoch 2/5\n",
107 | "60000/60000 [==============================] - 3s 54us/sample - loss: 0.3719 - acc: 0.8663\n",
108 | "Epoch 3/5\n",
109 | "60000/60000 [==============================] - 3s 55us/sample - loss: 0.3368 - acc: 0.8766\n",
110 | "Epoch 4/5\n",
111 | "60000/60000 [==============================] - 3s 56us/sample - loss: 0.3152 - acc: 0.8840\n",
112 | "Epoch 5/5\n",
113 | "60000/60000 [==============================] - 3s 58us/sample - loss: 0.2965 - acc: 0.8905\n",
114 | "10000/10000 [==============================] - 0s 41us/sample - loss: 0.3447 - acc: 0.8786\n"
115 | ],
116 | "name": "stdout"
117 | }
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {
123 | "id": "zldEXSsF8Noz",
124 | "colab_type": "text"
125 | },
126 | "source": [
127 | "Your accuracy is probably about 89% on training and 87% on validation...not bad...But how do you make that even better? One way is to use something called Convolutions. I'm not going to details on Convolutions here, but the ultimate concept is that they narrow down the content of the image to focus on specific, distinct, details. \n",
128 | "\n",
129 | "If you've ever done image processing using a filter (like this: https://en.wikipedia.org/wiki/Kernel_(image_processing)) then convolutions will look very familiar.\n",
130 | "\n",
131 | "In short, you take an array (usually 3x3 or 5x5) and pass it over the image. By changing the underlying pixels based on the formula within that matrix, you can do things like edge detection. So, for example, if you look at the above link, you'll see a 3x3 that is defined for edge detection where the middle cell is 8, and all of its neighbors are -1. In this case, for each pixel, you would multiply its value by 8, then subtract the value of each neighbor. Do this for every pixel, and you'll end up with a new image that has the edges enhanced.\n",
132 | "\n",
133 | "This is perfect for computer vision, because often it's features that can get highlighted like this that distinguish one item for another, and the amount of information needed is then much less...because you'll just train on the highlighted features.\n",
134 | "\n",
135 | "That's the concept of Convolutional Neural Networks. Add some layers to do convolution before you have the dense layers, and then the information going to the dense layers is more focussed, and possibly more accurate.\n",
136 | "\n",
137 | "Run the below code -- this is the same neural network as earlier, but this time with Convolutional layers added first. It will take longer, but look at the impact on the accuracy:"
138 | ]
139 | },
140 | {
141 | "cell_type": "code",
142 | "metadata": {
143 | "id": "C0tFgT1MMKi6",
144 | "colab_type": "code",
145 | "outputId": "09ec210f-621d-4be3-d259-20e4b6b326e0",
146 | "colab": {
147 | "base_uri": "https://localhost:8080/",
148 | "height": 660
149 | }
150 | },
151 | "source": [
152 | "import tensorflow as tf\n",
153 | "print(tf.__version__)\n",
154 | "mnist = tf.keras.datasets.fashion_mnist\n",
155 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()\n",
156 | "training_images=training_images.reshape(60000, 28, 28, 1)\n",
157 | "training_images=training_images / 255.0\n",
158 | "test_images = test_images.reshape(10000, 28, 28, 1)\n",
159 | "test_images=test_images/255.0\n",
160 | "model = tf.keras.models.Sequential([\n",
161 | " tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28, 28, 1)),\n",
162 | " tf.keras.layers.MaxPooling2D(2, 2),\n",
163 | " tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n",
164 | " tf.keras.layers.MaxPooling2D(2,2),\n",
165 | " tf.keras.layers.Flatten(),\n",
166 | " tf.keras.layers.Dense(128, activation='relu'),\n",
167 | " tf.keras.layers.Dense(10, activation='softmax')\n",
168 | "])\n",
169 | "model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n",
170 | "model.summary()\n",
171 | "model.fit(training_images, training_labels, epochs=5)\n",
172 | "test_loss = model.evaluate(test_images, test_labels)\n"
173 | ],
174 | "execution_count": 0,
175 | "outputs": [
176 | {
177 | "output_type": "stream",
178 | "text": [
179 | "1.15.0\n",
180 | "Model: \"sequential_1\"\n",
181 | "_________________________________________________________________\n",
182 | "Layer (type) Output Shape Param # \n",
183 | "=================================================================\n",
184 | "conv2d (Conv2D) (None, 26, 26, 64) 640 \n",
185 | "_________________________________________________________________\n",
186 | "max_pooling2d (MaxPooling2D) (None, 13, 13, 64) 0 \n",
187 | "_________________________________________________________________\n",
188 | "conv2d_1 (Conv2D) (None, 11, 11, 64) 36928 \n",
189 | "_________________________________________________________________\n",
190 | "max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64) 0 \n",
191 | "_________________________________________________________________\n",
192 | "flatten_1 (Flatten) (None, 1600) 0 \n",
193 | "_________________________________________________________________\n",
194 | "dense_2 (Dense) (None, 128) 204928 \n",
195 | "_________________________________________________________________\n",
196 | "dense_3 (Dense) (None, 10) 1290 \n",
197 | "=================================================================\n",
198 | "Total params: 243,786\n",
199 | "Trainable params: 243,786\n",
200 | "Non-trainable params: 0\n",
201 | "_________________________________________________________________\n",
202 | "Train on 60000 samples\n",
203 | "Epoch 1/5\n",
204 | "60000/60000 [==============================] - 10s 161us/sample - loss: 0.4334 - acc: 0.8436\n",
205 | "Epoch 2/5\n",
206 | "60000/60000 [==============================] - 5s 85us/sample - loss: 0.2918 - acc: 0.8931\n",
207 | "Epoch 3/5\n",
208 | "60000/60000 [==============================] - 5s 85us/sample - loss: 0.2469 - acc: 0.9090\n",
209 | "Epoch 4/5\n",
210 | "60000/60000 [==============================] - 5s 85us/sample - loss: 0.2159 - acc: 0.9185\n",
211 | "Epoch 5/5\n",
212 | "60000/60000 [==============================] - 5s 85us/sample - loss: 0.1888 - acc: 0.9297\n",
213 | "10000/10000 [==============================] - 1s 50us/sample - loss: 0.2494 - acc: 0.9081\n"
214 | ],
215 | "name": "stdout"
216 | }
217 | ]
218 | },
219 | {
220 | "cell_type": "markdown",
221 | "metadata": {
222 | "id": "uRLfZ0jt-fQI",
223 | "colab_type": "text"
224 | },
225 | "source": [
226 | "It's likely gone up to about 93% on the training data and 91% on the validation data. \n",
227 | "\n",
228 | "That's significant, and a step in the right direction!\n",
229 | "\n",
230 | "Try running it for more epochs -- say about 20, and explore the results! But while the results might seem really good, the validation results may actually go down, due to something called 'overfitting' which will be discussed later. \n",
231 | "\n",
232 | "(In a nutshell, 'overfitting' occurs when the network learns the data from the training set really well, but it's too specialised to only that data, and as a result is less effective at seeing *other* data. For example, if all your life you only saw red shoes, then when you see a red shoe you would be very good at identifying it, but blue suade shoes might confuse you...and you know you should never mess with my blue suede shoes.)\n",
233 | "\n",
234 | "Then, look at the code again, and see, step by step how the Convolutions were built:"
235 | ]
236 | },
237 | {
238 | "cell_type": "markdown",
239 | "metadata": {
240 | "id": "RaLX5cgI_JDb",
241 | "colab_type": "text"
242 | },
243 | "source": [
244 | "Step 1 is to gather the data. You'll notice that there's a bit of a change here in that the training data needed to be reshaped. That's because the first convolution expects a single tensor containing everything, so instead of 60,000 28x28x1 items in a list, we have a single 4D list that is 60,000x28x28x1, and the same for the test images. If you don't do this, you'll get an error when training as the Convolutions do not recognize the shape. \n",
245 | "\n",
246 | "\n",
247 | "\n",
248 | "```\n",
249 | "import tensorflow as tf\n",
250 | "mnist = tf.keras.datasets.fashion_mnist\n",
251 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()\n",
252 | "training_images=training_images.reshape(60000, 28, 28, 1)\n",
253 | "training_images=training_images / 255.0\n",
254 | "test_images = test_images.reshape(10000, 28, 28, 1)\n",
255 | "test_images=test_images/255.0\n",
256 | "```\n",
257 | "\n"
258 | ]
259 | },
260 | {
261 | "cell_type": "markdown",
262 | "metadata": {
263 | "id": "SS_W_INc_kJQ",
264 | "colab_type": "text"
265 | },
266 | "source": [
267 | "Next is to define your model. Now instead of the input layer at the top, you're going to add a Convolution. The parameters are:\n",
268 | "\n",
269 | "1. The number of convolutions you want to generate. Purely arbitrary, but good to start with something in the order of 32\n",
270 | "2. The size of the Convolution, in this case a 3x3 grid\n",
271 | "3. The activation function to use -- in this case we'll use relu, which you might recall is the equivalent of returning x when x>0, else returning 0\n",
272 | "4. In the first layer, the shape of the input data.\n",
273 | "\n",
274 | "You'll follow the Convolution with a MaxPooling layer which is then designed to compress the image, while maintaining the content of the features that were highlighted by the convlution. By specifying (2,2) for the MaxPooling, the effect is to quarter the size of the image. Without going into too much detail here, the idea is that it creates a 2x2 array of pixels, and picks the biggest one, thus turning 4 pixels into 1. It repeats this across the image, and in so doing halves the number of horizontal, and halves the number of vertical pixels, effectively reducing the image by 25%.\n",
275 | "\n",
276 | "You can call model.summary() to see the size and shape of the network, and you'll notice that after every MaxPooling layer, the image size is reduced in this way. \n",
277 | "\n",
278 | "\n",
279 | "```\n",
280 | "model = tf.keras.models.Sequential([\n",
281 | " tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28, 28, 1)),\n",
282 | " tf.keras.layers.MaxPooling2D(2, 2),\n",
283 | "```\n",
284 | "\n"
285 | ]
286 | },
287 | {
288 | "cell_type": "markdown",
289 | "metadata": {
290 | "id": "RMorM6daADjA",
291 | "colab_type": "text"
292 | },
293 | "source": [
294 | "Add another convolution\n",
295 | "\n",
296 | "\n",
297 | "\n",
298 | "```\n",
299 | " tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n",
300 | " tf.keras.layers.MaxPooling2D(2,2)\n",
301 | "```\n",
302 | "\n"
303 | ]
304 | },
305 | {
306 | "cell_type": "markdown",
307 | "metadata": {
308 | "colab_type": "text",
309 | "id": "b1-x-kZF4_tC"
310 | },
311 | "source": [
312 | "Now flatten the output. After this you'll just have the same DNN structure as the non convolutional version\n",
313 | "\n",
314 | "```\n",
315 | " tf.keras.layers.Flatten(),\n",
316 | "```\n",
317 | "\n"
318 | ]
319 | },
320 | {
321 | "cell_type": "markdown",
322 | "metadata": {
323 | "id": "qPtqR23uASjX",
324 | "colab_type": "text"
325 | },
326 | "source": [
327 | "The same 128 dense layers, and 10 output layers as in the pre-convolution example:\n",
328 | "\n",
329 | "\n",
330 | "\n",
331 | "```\n",
332 | " tf.keras.layers.Dense(128, activation='relu'),\n",
333 | " tf.keras.layers.Dense(10, activation='softmax')\n",
334 | "])\n",
335 | "```\n",
336 | "\n"
337 | ]
338 | },
339 | {
340 | "cell_type": "markdown",
341 | "metadata": {
342 | "id": "C0GSsjUhAaSj",
343 | "colab_type": "text"
344 | },
345 | "source": [
346 | "Now compile the model, call the fit method to do the training, and evaluate the loss and accuracy from the test set.\n",
347 | "\n",
348 | "\n",
349 | "\n",
350 | "```\n",
351 | "model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n",
352 | "model.fit(training_images, training_labels, epochs=5)\n",
353 | "test_loss, test_acc = model.evaluate(test_images, test_labels)\n",
354 | "print(test_acc)\n",
355 | "```\n",
356 | "\n",
357 | "\n"
358 | ]
359 | },
360 | {
361 | "cell_type": "markdown",
362 | "metadata": {
363 | "id": "IXx_LX3SAlFs",
364 | "colab_type": "text"
365 | },
366 | "source": [
367 | "# Visualizing the Convolutions and Pooling\n",
368 | "\n",
369 | "This code will show us the convolutions graphically. The print (test_labels[;100]) shows us the first 100 labels in the test set, and you can see that the ones at index 0, index 23 and index 28 are all the same value (9). They're all shoes. Let's take a look at the result of running the convolution on each, and you'll begin to see common features between them emerge. Now, when the DNN is training on that data, it's working with a lot less, and it's perhaps finding a commonality between shoes based on this convolution/pooling combination."
370 | ]
371 | },
372 | {
373 | "cell_type": "code",
374 | "metadata": {
375 | "id": "f-6nX4QsOku6",
376 | "colab_type": "code",
377 | "outputId": "971d0afe-bc4f-4619-fd58-1bfb00a55c9f",
378 | "colab": {
379 | "base_uri": "https://localhost:8080/",
380 | "height": 72
381 | }
382 | },
383 | "source": [
384 | "print(test_labels[:100])"
385 | ],
386 | "execution_count": 0,
387 | "outputs": [
388 | {
389 | "output_type": "stream",
390 | "text": [
391 | "[9 2 1 1 6 1 4 6 5 7 4 5 7 3 4 1 2 4 8 0 2 5 7 9 1 4 6 0 9 3 8 8 3 3 8 0 7\n",
392 | " 5 7 9 6 1 3 7 6 7 2 1 2 2 4 4 5 8 2 2 8 4 8 0 7 7 8 5 1 1 2 3 9 8 7 0 2 6\n",
393 | " 2 3 1 2 8 4 1 8 5 9 5 0 3 2 0 6 5 3 6 7 1 8 0 1 4 2]\n"
394 | ],
395 | "name": "stdout"
396 | }
397 | ]
398 | },
399 | {
400 | "cell_type": "code",
401 | "metadata": {
402 | "id": "9FGsHhv6JvDx",
403 | "colab_type": "code",
404 | "outputId": "54d24dff-8cbe-4b2b-8c3b-96f81dd199d1",
405 | "colab": {
406 | "base_uri": "https://localhost:8080/",
407 | "height": 268
408 | }
409 | },
410 | "source": [
411 | "import matplotlib.pyplot as plt\n",
412 | "f, axarr = plt.subplots(3,4)\n",
413 | "FIRST_IMAGE=0\n",
414 | "SECOND_IMAGE=7\n",
415 | "THIRD_IMAGE=26\n",
416 | "CONVOLUTION_NUMBER = 1\n",
417 | "from tensorflow.keras import models\n",
418 | "layer_outputs = [layer.output for layer in model.layers]\n",
419 | "activation_model = tf.keras.models.Model(inputs = model.input, outputs = layer_outputs)\n",
420 | "for x in range(0,4):\n",
421 | " f1 = activation_model.predict(test_images[FIRST_IMAGE].reshape(1, 28, 28, 1))[x]\n",
422 | " axarr[0,x].imshow(f1[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')\n",
423 | " axarr[0,x].grid(False)\n",
424 | " f2 = activation_model.predict(test_images[SECOND_IMAGE].reshape(1, 28, 28, 1))[x]\n",
425 | " axarr[1,x].imshow(f2[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')\n",
426 | " axarr[1,x].grid(False)\n",
427 | " f3 = activation_model.predict(test_images[THIRD_IMAGE].reshape(1, 28, 28, 1))[x]\n",
428 | " axarr[2,x].imshow(f3[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')\n",
429 | " axarr[2,x].grid(False)"
430 | ],
431 | "execution_count": 0,
432 | "outputs": [
433 | {
434 | "output_type": "display_data",
435 | "data": {
436 | "image/png": "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\n1CtOBQv4rAAAAABJRU5ErkJggg==\n",
437 | "text/plain": [
438 | ""
439 | ]
440 | },
441 | "metadata": {
442 | "tags": []
443 | }
444 | }
445 | ]
446 | },
447 | {
448 | "cell_type": "markdown",
449 | "metadata": {
450 | "id": "8KVPZqgHo5Ux",
451 | "colab_type": "text"
452 | },
453 | "source": [
454 | "EXERCISES\n",
455 | "\n",
456 | "1. Try editing the convolutions. Change the 32s to either 16 or 64. What impact will this have on accuracy and/or training time.\n",
457 | "\n",
458 | "2. Remove the final Convolution. What impact will this have on accuracy or training time?\n",
459 | "\n",
460 | "3. How about adding more Convolutions? What impact do you think this will have? Experiment with it.\n",
461 | "\n",
462 | "4. Remove all Convolutions but the first. What impact do you think this will have? Experiment with it. \n",
463 | "\n",
464 | "5. In the previous lesson you implemented a callback to check on the loss function and to cancel training once it hit a certain amount. See if you can implement that here!"
465 | ]
466 | },
467 | {
468 | "cell_type": "code",
469 | "metadata": {
470 | "id": "ZpYRidBXpBPM",
471 | "colab_type": "code",
472 | "outputId": "5ed6ac8d-924f-4e86-872c-b366a83592c4",
473 | "colab": {
474 | "base_uri": "https://localhost:8080/",
475 | "height": 495
476 | }
477 | },
478 | "source": [
479 | "import tensorflow as tf\n",
480 | "print(tf.__version__)\n",
481 | "mnist = tf.keras.datasets.mnist\n",
482 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()\n",
483 | "training_images=training_images.reshape(60000, 28, 28, 1)\n",
484 | "training_images=training_images / 255.0\n",
485 | "test_images = test_images.reshape(10000, 28, 28, 1)\n",
486 | "test_images=test_images/255.0\n",
487 | "model = tf.keras.models.Sequential([\n",
488 | " tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28, 28, 1)),\n",
489 | " tf.keras.layers.MaxPooling2D(2, 2),\n",
490 | " tf.keras.layers.Flatten(),\n",
491 | " tf.keras.layers.Dense(128, activation='relu'),\n",
492 | " tf.keras.layers.Dense(10, activation='softmax')\n",
493 | "])\n",
494 | "model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n",
495 | "model.fit(training_images, training_labels, epochs=10)\n",
496 | "test_loss, test_acc = model.evaluate(test_images, test_labels)\n",
497 | "print(test_acc)"
498 | ],
499 | "execution_count": 0,
500 | "outputs": [
501 | {
502 | "output_type": "stream",
503 | "text": [
504 | "1.15.0\n",
505 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n",
506 | "11493376/11490434 [==============================] - 0s 0us/step\n",
507 | "Train on 60000 samples\n",
508 | "Epoch 1/10\n",
509 | "60000/60000 [==============================] - 4s 71us/sample - loss: 0.1483 - acc: 0.9557\n",
510 | "Epoch 2/10\n",
511 | "60000/60000 [==============================] - 4s 69us/sample - loss: 0.0498 - acc: 0.9851\n",
512 | "Epoch 3/10\n",
513 | "60000/60000 [==============================] - 4s 71us/sample - loss: 0.0320 - acc: 0.9897\n",
514 | "Epoch 4/10\n",
515 | "60000/60000 [==============================] - 4s 71us/sample - loss: 0.0206 - acc: 0.9935\n",
516 | "Epoch 5/10\n",
517 | "60000/60000 [==============================] - 4s 71us/sample - loss: 0.0134 - acc: 0.9956\n",
518 | "Epoch 6/10\n",
519 | "60000/60000 [==============================] - 4s 73us/sample - loss: 0.0103 - acc: 0.9968\n",
520 | "Epoch 7/10\n",
521 | "60000/60000 [==============================] - 4s 73us/sample - loss: 0.0072 - acc: 0.9976\n",
522 | "Epoch 8/10\n",
523 | "60000/60000 [==============================] - 4s 71us/sample - loss: 0.0053 - acc: 0.9984\n",
524 | "Epoch 9/10\n",
525 | "60000/60000 [==============================] - 4s 70us/sample - loss: 0.0051 - acc: 0.9983\n",
526 | "Epoch 10/10\n",
527 | "60000/60000 [==============================] - 4s 70us/sample - loss: 0.0053 - acc: 0.9984\n",
528 | "10000/10000 [==============================] - 0s 48us/sample - loss: 0.0593 - acc: 0.9864\n",
529 | "0.9864\n"
530 | ],
531 | "name": "stdout"
532 | }
533 | ]
534 | }
535 | ]
536 | }
--------------------------------------------------------------------------------
/Part 4-Extending what Convolutional Neural Nets can do/Excercise2_question.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "Excercise2 question.ipynb",
7 | "provenance": [],
8 | "include_colab_link": true
9 | },
10 | "kernelspec": {
11 | "name": "python3",
12 | "display_name": "Python 3"
13 | }
14 | },
15 | "cells": [
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {
19 | "id": "view-in-github",
20 | "colab_type": "text"
21 | },
22 | "source": [
23 | ""
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {
29 | "id": "I5tcbh0IWTmQ",
30 | "colab_type": "text"
31 | },
32 | "source": [
33 | "\n",
34 | "You learned how to do classificaiton using Fashion MNIST, a data set containing items of clothing. There's another, similar dataset called MNIST which has items of handwriting - the digits 0 through 9.\n",
35 | "Write an MNIST classifier that trains to 99% accuracy or above, and does it without a fixed number of epochs - i.e. you should stop training once you reach that level of accuracy.\n",
36 | "\n",
37 | "Some notes:\n",
38 | "\n",
39 | "1. It should succeed in less than 10 epochs, so it is okay to change epochs = to 10, but nothing larger\n",
40 | "2. When it reaches 99% or greater it should print out the string \"Reached 99% accuracy so cancelling training!\"\n",
41 | "\n",
42 | "Use this code line to get MNIST handwriting data set:\n",
43 | "\n",
44 | "```\n",
45 | "mnist = tf.keras.datasets.mnist\n",
46 | "```\n",
47 | "\n"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "metadata": {
53 | "id": "aXwpXnljWIji",
54 | "colab_type": "code",
55 | "colab": {}
56 | },
57 | "source": [
58 | "# YOUR CODE SHOULD START HERE\n",
59 | "# YOUR CODE SHOULD END HERE\n",
60 | "import tensorflow as tf\n",
61 | "mnist = tf.keras.datasets.mnist\n",
62 | "\n",
63 | "(x_train, y_train),(x_test, y_test) = mnist.load_data()\n",
64 | "# YOUR CODE SHOULD START HERE\n",
65 | "\n",
66 | "# YOUR CODE SHOULD END HERE\n",
67 | "model = tf.keras.models.Sequential([\n",
68 | "# YOUR CODE SHOULD START HERE\n",
69 | " \n",
70 | "# YOUR CODE SHOULD END HERE\n",
71 | "])\n",
72 | "\n",
73 | "model.compile(optimizer='adam',\n",
74 | " loss='sparse_categorical_crossentropy',\n",
75 | " metrics=['accuracy'])\n",
76 | "\n",
77 | "# YOUR CODE SHOULD START HERE\n",
78 | "# YOUR CODE SHOULD END HERE"
79 | ],
80 | "execution_count": 0,
81 | "outputs": []
82 | }
83 | ]
84 | }
--------------------------------------------------------------------------------
/Part 4-Extending what Convolutional Neural Nets can do/Excercise2_solution.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "Excercise2_solution.ipynb",
7 | "provenance": [],
8 | "authorship_tag": "ABX9TyMSE3HNT4DRkyfFTeuF+fhi",
9 | "include_colab_link": true
10 | },
11 | "kernelspec": {
12 | "name": "python3",
13 | "display_name": "Python 3"
14 | }
15 | },
16 | "cells": [
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {
20 | "id": "view-in-github",
21 | "colab_type": "text"
22 | },
23 | "source": [
24 | ""
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "metadata": {
30 | "id": "nyV34YajcGuP",
31 | "colab_type": "code",
32 | "colab": {}
33 | },
34 | "source": [
35 | "def train_mnist():\n",
36 | " # Please write your code only where you are indicated.\n",
37 | " # please do not remove # model fitting inline comments.\n",
38 | "\n",
39 | " # YOUR CODE SHOULD START HERE\n",
40 | " class myCallback(tf.keras.callbacks.Callback):\n",
41 | " def on_epoch_end(self, epoch, logs={}):\n",
42 | " if(logs.get('acc')>0.99):\n",
43 | " print(\"/nReached 99% accuracy so cancelling training!\")\n",
44 | " self.model.stop_training = True\n",
45 | " # YOUR CODE SHOULD END HERE\n",
46 | "\n",
47 | " mnist = tf.keras.datasets.mnist\n",
48 | "\n",
49 | " (x_train, y_train),(x_test, y_test) = mnist.load_data()\n",
50 | " # YOUR CODE SHOULD START HERE\n",
51 | " x_train, x_test = x_train / 255.0, x_test / 255.0\n",
52 | " \n",
53 | "\n",
54 | " callbacks = myCallback()\n",
55 | " # YOUR CODE SHOULD END HERE\n",
56 | " model = tf.keras.models.Sequential([\n",
57 | " # YOUR CODE SHOULD START HERE\n",
58 | " tf.keras.layers.Flatten(input_shape=(28, 28)),\n",
59 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n",
60 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n",
61 | " # YOUR CODE SHOULD END HERE\n",
62 | " ])\n",
63 | "\n",
64 | " model.compile(optimizer='adam',\n",
65 | " loss='sparse_categorical_crossentropy',\n",
66 | " metrics=['accuracy'])\n",
67 | " \n",
68 | " # model fitting\n",
69 | " history = model.fit(# YOUR CODE SHOULD START HERE\n",
70 | " x_train,\n",
71 | " y_train,\n",
72 | " epochs=10,\n",
73 | " callbacks=[callbacks]\n",
74 | " # YOUR CODE SHOULD END HERE\n",
75 | " )\n",
76 | " # model fitting\n",
77 | " return history.epoch, history.history['acc'][-1]"
78 | ],
79 | "execution_count": 0,
80 | "outputs": []
81 | }
82 | ]
83 | }
--------------------------------------------------------------------------------
/Part 4-Extending what Convolutional Neural Nets can do/README.md:
--------------------------------------------------------------------------------
1 | ### Extending what Convolutional Neural Nets can do
2 |
3 | The same blog is avaliaible on Medium [here](https://medium.com/@rishit.dagli/extending-what-convolutional-nets-can-do-251f3021529c)
4 |
5 | 
6 | Source: Cognitiveclass.ai
7 |
8 | ### Table of contents
9 |
10 | 1. [Get started with TensorFlow and Deep
11 | Learning](https://medium.com/@rishit.dagli/get-started-with-tensorflow-and-deep-learning-part-1-72c7d67f99fc)
12 | 1. [Computer Vision with
13 | TensorFlow](https://medium.com/@rishit.dagli/computer-vision-with-tensorflow-part-2-57e95cd0551)
14 | 1. [Using Convolutional Neural Networks with
15 | TensorFlow](https://medium.com/@rishit.dagli/using-convolutional-neural-networks-with-tensorflow-part-3-35de28a5621)
16 | 1. [Extending what Convolutional Neural Nets can
17 | do](https://medium.com/@rishit.dagli/extending-what-convolutional-nets-can-do-251f3021529c)
18 |
19 | All the code used here is available in my GitHub repository
20 | [here](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Blog-series/).
21 |
22 | *****
23 |
24 | This is the fourth part of the series where I post about TensorFlow for Deep
25 | Learning and Machine Learning. In the earlier blog post you saw a convolutional
26 | Neural Network for Computer Vision. It did the job pretty nicely. This time
27 | you’re going to improve your skills with some real life data sets and apply the
28 | discussed algorithms on them too. I believe in hands-on coding so we will have
29 | many exercises and demos which you can try yourself too. I would recommend you
30 | to play around with these exercises and change the hyper-parameters and
31 | experiment with the code. We will also be working. If you have not read the
32 | previous article consider reading it once before you read this one
33 | [here](https://medium.com/@rishit.dagli/computer-vision-with-tensorflow-part-2-57e95cd0551).
34 | This one is more like a continuation of that.
35 |
36 | *****
37 |
38 | ### Hands on with CNN
39 |
40 | You can find the notebook used by me
41 | [here](https://github.com/Rishit-dagli/Artificial-Intelligence_resources-and-notebooks/blob/master/CNN_with_Fashion_MNIST_Notebook.ipynb).
42 | Again, you can download the notebook if you are using a local environment and if
43 | you are using Colab, you can click on `opeen in colab` button.
44 |
45 | This is a really nice way to improve our image recognition performance. Let’s
46 | now look at it in action using a notebook. Here’s the same neural network that
47 | you used before for loading the set of images of clothing and then classifying
48 | them. By the end of epoch five, you can see the loss is around 0.34, meaning,
49 | your accuracy is pretty good on the training data.
50 |
51 | 
52 | Output with DNN
53 |
54 | It took just a few seconds to train, so that’s not bad. With the test data as
55 | before and as expected, the losses a little higher and thus, the accuracy is a
56 | little lower.
57 |
58 | So now, you can see the code that adds convolutions and pooling. We’re going to
59 | do 2 convolutional layers each with 64 convolutions, and each followed by a max
60 | pooling layer.
61 |
62 | You can see that we defined our convolutions to be three-by-three and our pools
63 | to be two-by-two. Let’s train. The first thing you’ll notice is that the
64 | training is much slower. For every image, 64 convolutions are being tried, and
65 | then the image is compressed and then another 64 convolutions, and then it’s
66 | compressed again, and then it’s passed through the DNN, and that’s for 60,000
67 | images that this is happening on each epoch. So it might take a few minutes
68 | instead of a few seconds. To remedy this what you can do is use a GPU. How to do
69 | that in Colab?
70 |
71 | All you need to do is Runtime > Change Runtime Type > GPU. A single layer would
72 | now take approximately 5–6 seconds.
73 |
74 | 
75 | Output with the Convolutions and max poolings
76 |
77 | Now that it’s done, you can see that the loss has improved a little it’s 0.25
78 | now. In this case, it’s brought our accuracy up a bit for both our test data and
79 | with our training data. That’s pretty cool, right?
80 |
81 | Now, this is a really fun visualization of the journey of an image through the
82 | convolutions. First, I’ll print out the first 100 test labels. The number 9 as
83 | we saw earlier is a shoe or boots. I picked out a few instances of this whether
84 | the zero, the 23rd and the 28th labels are all nine. So let’s take a look at
85 | their journey.
86 |
87 | 
88 | The visualization
89 |
90 | The Keras API gives us each convolution and each pooling and each dense, etc. as
91 | a layer. So with the layers API, I can take a look at each layer’s outputs, so
92 | I’ll create a list of each layer’s output. I can then treat each item in the
93 | layer as an individual activation model if I want to see the results of just
94 | that layer. Now, by looping through the layers, I can display the journey of the
95 | image through the first convolution and then the first pooling and then the
96 | second convolution and then the second pooling. Note how the size of the image
97 | is changing by looking at the axes. If I set the convolution number to one, we
98 | can see that it almost immediately detects the laces area as a common feature
99 | between the shoes.
100 |
101 | So, for example, if I change the third image to be one, which looks like a
102 | handbag, you’ll see that it also has a bright line near the bottom that could
103 | look like the soul of the shoes, but by the time it gets through the
104 | convolutions, that’s lost, and that area for the laces doesn’t even show up at
105 | all. So this convolution definitely helps me separate issue from a handbag.
106 | Again, if I said it’s a two, it appears to be trousers, but the feature that
107 | detected something that the shoes had in common fails again. Also, if I changed
108 | my third image back to that for shoe, but I tried a different convolution
109 | number, you’ll see that for convolution two, it didn’t really find any common
110 | features. To see commonality in a different image, try images two, three, and
111 | five. These all appear to be trousers. Convolutions two and four seem to detect
112 | this vertical feature as something they all have in common. If I again go to the
113 | list and find three labels that are the same, in this case six, I can see what
114 | they signify. When I run it, I can see that they appear to be shirts.
115 | Convolution four doesn’t do a whole lot, so let’s try five. We can kind of see
116 | that the color appears to light up in this case.
117 |
118 | There are some exercises at the bottom of the notebook check them out.
119 |
120 | *****
121 |
122 | ### How convolutions work, hands-on ?(OPTIONAL)
123 |
124 | We willcreate a little pooling algorithm, so you can visualize its impact.
125 | There’s a notebook that you can play with too, and I’ll step through that here.
126 | Here’s the notebook for playing with convolutions[
127 | here](https://github.com/Rishit-dagli/Artificial-Intelligence_resources-and-notebooks/blob/master/Convolutions_from_scratch.ipynb).
128 | It does use a few Python libraries that you may not be familiar with such as
129 | `cv2`. It also has `Matplotlib `that we used before. If you haven’t used them,
130 | they’re really quite intuitive for this task and they’re very very easy to
131 | learn. So first, we’ll set up our inputs and in particular, import the misc
132 | library from `SciPy`. Now, this is a nice shortcut for us because `misc.ascent`
133 | returns a nice image that we can play with, and we don’t have to worry about
134 | managing our own.
135 |
136 | `Matplotlib` contains the code for drawing an image and it will render it right
137 | in the browser with Colab. Here, we can see the ascent image from `SciPy`. Next
138 | up, we’ll take a copy of the image, and we’ll add it with our homemade
139 | convolutions, and we’ll create variables to keep track of the `x` and `y`
140 | dimensions of the image. So we can see here that it’s a 512 by 512 image. So
141 | now, let’s create a convolution as a three by three array. We’ll load it with
142 | values that are pretty good for detecting sharp edges first. Here’s where we’ll
143 | create the convolution.
144 |
145 | We then iterate over the image, leaving a one pixel margin. You’ll see that the
146 | loop starts at one and not zero, and it ends at size x minus one and size y
147 | minus one. In the loop, it will then calculate the convolution value by looking
148 | at the pixel and its neighbors, and then by multiplying them out by the values
149 | determined by the filter, before finally summing it all up.
150 |
151 | 
152 | Vertical line filter
153 |
154 | Let’s run it. It takes just a few seconds, so when it’s done, let’s draw the
155 | results. We can see that only certain features made it through the filter. I’ve
156 | provided a couple more filters, so let’s try them. This first one is really
157 | great at spotting vertical lines. So when I run it, and plot the results, we can
158 | see that the vertical lines in the image made it through. It’s really cool
159 | because they’re not just straight up and down, they are vertical in perspective
160 | within the perspective of the image itself. Similarly, this filter works well
161 | for horizontal lines. So when I run it, and then plot the results, we can see
162 | that a lot of the horizontal lines made it through. Now, let’s take a look at
163 | pooling, and in this case, Max pooling, which takes pixels in chunks of four and
164 | only passes through the biggest value. I run the code and then render the
165 | output. We can see that the features of the image are maintained, but look
166 | closely at the axes, and we can see that the size has been halved from the 500’s
167 | to the 250's.
168 |
169 | 
170 | With pooling
171 |
172 | *****
173 |
174 | ### Excercise 3
175 |
176 | Now you need to apply this to MNIST Handwrting recognition we will revisit that
177 | from last blog post. You need to improve MNIST to 99.8% accuracy or more using
178 | only a single convolutional layer and a single MaxPooling 2D. You should stop
179 | training once the accuracy goes above this amount. It should happen in less than
180 | 20 epochs, so it’s ok to hard code the number of epochs for training, but your
181 | training must end once it hits the above metric. If it doesn’t, then you’ll need
182 | to redesign your layers.
183 |
184 | When 99.8% accuracy has been hit, you should print out the string “Reached 99.8%
185 | accuracy so cancelling training!”. Yes this is just optional (You can also print
186 | out something like “I’m getting bored and won’t train any more” 🤣)
187 |
188 | The question notebook is available —
189 | [here](https://github.com/Rishit-dagli/Artificial-Intelligence_resources-and-notebooks/blob/master/Exercise_3_Question.ipynb)
190 |
191 | ### My Solution
192 |
193 | Wonderful! 😃 , you just coded for a handwriting recognizer with a 99.8%
194 | accuracy (that’s good) in less than 20 epochs. Let explore my solution for this.
195 |
196 | My solution
197 |
198 | The callback class (This is the simplest)
199 |
200 | class myCallback(tf.keras.callbacks.Callback):
201 |
202 | def on_epoch_end(self, epoch, logs={}):
203 |
204 | if(logs.get('acc')>0.998):
205 |
206 | print("/n Reached 99.8% accuracy so cancelling training!")
207 |
208 | self.model.stop_training = True
209 |
210 | The main CNN code
211 |
212 | training_images=training_images.reshape(60000, 28, 28, 1)
213 | test_images=test_images.reshape(10000, 28, 28, 1)
214 | training_images = training_images / 255.0
215 | test_images = test_images / 255.0
216 | # YOUR CODE ENDS HERE
217 |
218 | model = tf.keras.models.Sequential([
219 | # YOUR CODE STARTS HERE
220 | tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28, 28, 1)),
221 | tf.keras.layers.MaxPooling2D(2, 2),
222 | tf.keras.layers.Flatten(),
223 | tf.keras.layers.Dense(256, activation='relu'),
224 | tf.keras.layers.Dense(10, activation='softmax')
225 | # YOUR CODE ENDS HERE
226 | ])
227 |
228 | So, all you had to do was play around the code and get this done in just 7
229 | epochs.
230 |
231 | 
232 | My output
233 |
234 | The solution notebook is available
235 | [here](https://github.com/Rishit-dagli/Artificial-Intelligence_resources-and-notebooks/blob/master/Excercise_3_Solution.ipynb)
236 |
237 | I hope this was helpful for you and you learned about visualizing CNNs and
238 | applying them on a real life data set, you also created a handwritten number
239 | recognizer all by yourself with a wonderful accuracy. That’s pretty good
240 |
241 | *****
242 |
243 | ### About Me
244 |
245 | Hi everyone I am Rishit Dagli
246 |
247 | [Twitter](https://twitter.com/rishit_dagli)
248 |
249 | [Website](https://rishit.tech/)
250 |
251 | If you want to ask me some questions, report any mistake, suggest improvements,
252 | give feedback you are free to do so by emailing me at —
253 |
254 | * [rishit.dagli@gmail.com](mailto:rishit.dagli@gmail.com)
255 | * [hello@rishit.tech](mailto:hello@rishit.tech)
256 |
--------------------------------------------------------------------------------
/Part 5-Working with Complex Image data for CNNs/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Working with Complex Image data for CNNs
3 |
4 | The same blog is avaliaible on Medium [here](https://medium.com/@rishit.dagli/working-with-complex-image-data-for-cnns-187fb4526893)
5 |
6 | 
7 |
8 | ## Table of contents
9 |
10 | 1. [Get started with TensorFlow and Deep Learning](https://medium.com/@rishit.dagli/get-started-with-tensorflow-and-deep-learning-part-1-72c7d67f99fc)
11 |
12 | 2. [Computer Vision with TensorFlow](https://medium.com/@rishit.dagli/computer-vision-with-tensorflow-part-2-57e95cd0551)
13 |
14 | 3. [Using Convolutional Neural Networks with TensorFlow](https://medium.com/@rishit.dagli/using-convolutional-neural-networks-with-tensorflow-part-3-35de28a5621)
15 |
16 | 4. [Extending what Convolutional Neural Nets can do](https://medium.com/@rishit.dagli/extending-what-convolutional-nets-can-do-251f3021529c)
17 |
18 | 5. [Working with Complex Image data for CNNs](https://medium.com/@rishit.dagli/working-with-complex-image-data-for-cnns-187fb4526893)
19 |
20 | All the code used here is available in my GitHub repository [here](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Tutorials).
21 |
22 | This is the fifth part of the series where I post about TensorFlow for Deep Learning and Machine Learning. In the earlier blog post, you saw how you could apply a Convolutional Neural Network for Computer Vision with some real-life data sets. It did the job pretty nicely. This time you’re going to work with more complex data and do even more with the data. I believe in hands-on coding so we will have many exercises and demos which you can try yourself too. I would recommend you to play around with these exercises and change the hyper-parameters and experiment with the code. We will also be working. If you have not read the previous article consider reading it once before you read this one [here](https://medium.com/@rishit.dagli/extending-what-convolutional-nets-can-do-251f3021529c). This one is more like a continuation of that.
23 |
24 | ## Reading the Data
25 |
26 | In the previous blog post, we worked with MNIST data which was pretty simple, grayscaled 28 X 28 images, and the thing you want to classify is centered in the image. Real-life data is different, it has more complex images, your subject might be anywhere in the image not necessarily centered. Our dataset had very uniform images too. This time we’ll also work on a larger dataset.
27 | We’ll be using the [Cats vs Dogs dataset](https://www.kaggle.com/c/dogs-vs-cats) to try out these things for ourselves. TensorFlow has something called [ImageDataGenerator](https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator) which simplifies things for us and allows us to directly read the images and place them. So you would first have two directories called train and validation directory, each of the directories would have two subdirectories Cats and Dogs each of which would have the respective images and auto label them for us. Here’s how the directory structure looks-
28 |
29 | 
30 |
31 | Let’s now see this in code. The ImageDataGenerator is present in tensorflow.keras.preprocessing.image so first let’s go ahead and import it-
32 |
33 | from tensorflow.keras.preprocessing.image import ImageDataGenerator
34 |
35 | Once you do this you can now use the ImageDataGenerator -
36 |
37 | train_image_generator = ImageDataGenerator(rescale=1./255)
38 |
39 | train_data_gen = train_iamge_generator.flow_from_directory(
40 | batch_size=batch_size,
41 | directory=train_dir,
42 | shuffle=True,
43 | target_size=(IMG_HEIGHT,IMG_WIDTH)
44 | class_mode='binary')
45 |
46 | We first pass in rescale=1./255 to normalize the images, you can then call the flow_from_directory the method from that directory and its sub-directories. So in this case taking the above diagram as a reference, you would pass in the Training directory.
47 |
48 | Images in your data might be of different sizes to convert or resize them all into one size by the target_size . This is a very important step as all inputs to the neural network should be of the size. A nice thing about this code is that the images are resized for you as they’re loaded. So you don’t need to preprocess thousands of images on your file system you instead to do it in runtime.
49 |
50 | The images will be loaded for training and validation in batches where it’s more efficient than doing it one by one. You can specify this by the batch_size , there are a lot of factors to consider when specifying a batch size which we will not be discussing in this blog post. But you can experiment with different sizes to see the impact on the performance.
51 |
52 | This is a binary classifier that is it picks between two different things; cats and dogs so we specify that here by the class_mode.
53 |
54 | And that’s all you need to read your data and auto label them according to their directories and also do some processing in run time. SO let’s do the same for validation data too-
55 |
56 | validation_image_generator = ImageDataGenerator(rescale=1./255)
57 | val_data_gen = validation_imadata_generator.flow_from_directory(
58 | batch_size=batch_size,
59 | directory= validation_dir,
60 | shuffle=True,
61 | target_size=(IMG_HEIGHT,IMG_WIDTH)
62 | class_mode='binary')
63 |
64 | ## Training the model
65 |
66 | Another great thing about ImageDataGenerator is there is little or almost no change while building and training the model, so let's build a sample model for the dogs vs cats problem and then compile it.
67 |
68 | model = Sequential([
69 | Conv2D(16, (3,3), padding='same', activation='relu',
70 | input_shape=(IMG_HEIGHT, IMG_WIDTH ,3)),
71 | MaxPooling2D(2,2),
72 | Conv2D(32, (3,3), padding='same', activation='relu'),
73 | MaxPooling2D(2,2),
74 | Conv2D(64, (3,3), padding='same', activation='relu'),
75 | MaxPooling2D(2,2),
76 | Flatten(),
77 | Dense(512, activation='relu'),
78 | Dense(1, activation='sigmoid')])
79 |
80 | model.compile(optimizer='adam',
81 | loss='binary_crossentropy',
82 | metrics=['accuracy'])
83 |
84 | You can see that you don't have to do any changes while compiling your model to make it work with ImageDataGenerator , let’s get to the training part now.
85 |
86 | history = model.fit_generator(
87 | train_data_gen,
88 | steps_per_epoch=total_train//batch_size,
89 | epochs=epochs,
90 | validation_data=val_data_gen,
91 | validation_steps=total_val//batch_size
92 | )
93 |
94 | A difference you would see here is instead of passing the training data directly after loading it, I now pass the train_data_gen which reads the data from the disk using ImageDataGenerator and performs the transformations on it. And you can do the same with the validation data too.
95 |
96 | ## Trying out for yourself
97 |
98 | All the code we just talked about is implemented in [this notebook](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Tutorials/tree/master/Part%205-Working%20with%20Complex%20Image%20data%20for%C2%A0CNNs). The model we will build is not yet a perfect or suitable model and suffers from overfitting, we will see how we can tackle this problem in the next blog in this series.
99 |
100 | You can use the Open in Colab button to directly open the notebook in Colab or even download it and run it on your system.
101 |
102 | ## About Me
103 |
104 | Hi everyone I am Rishit Dagli
105 |
106 | [Twitter](https://twitter.com/rishit_dagli)
107 |
108 | [Website](https://rishit.tech/)
109 |
110 | If you want to ask me some questions, report any mistake, suggest improvements, give feedback you are free to do so by emailing me at —
111 |
112 | * [rishit.dagli@gmail.com](mailto:rishit.dagli@gmail.com)
113 |
114 | * [hello@rishit.tech](mailto:hello@rishit.tech)
115 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Deep-Learning-With-TensorFlow [](https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Fgithub.com%2FRishit-dagli%2FDeep-Learning-With-TensorFlow-Blog-series)
2 |
3 | [](https://colab.research.google.com/github/Rishit-dagli/Deep-Learning-With-TensorFlow)
4 | [](https://mybinder.org/v2/gh/Rishit-dagli/Deep-Learning-With-TensorFlow/master)
5 |
6 | [](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow-Blog-series/blob/master/LICENSE)
7 | [](https://github.com/Rishit-dagli)
8 | [](https://twitter.com/intent/follow?screen_name=rishit_dagli)
9 |
10 | Consider leaving a :star: if you like this series of tutorials.
11 |
12 | This repo gets you started with Deep Learning with TensorFlow. This will be all about about coding Machine Learning and Deep Learning algorithms. I believe in hands-on coding
13 | so we will have many exercises and demos which you can try yourself too. You would first have a blog to read to and have one or many Jupyter Notebooks which you can try and also
14 | have excercises which you can do. These blogs are also availaible as a blog series on [Medium](http://bit.ly/dlwithtf).
15 |
16 | > More parts coming soon!
17 |
18 | ## Table of Contents
19 |
20 | - [Getting started with TensorFlow and Deep Learning](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow/tree/master/Part%201-Getting%20started%20with%20TensorFlow%20and%20Deep%20Learning)
21 | - [Computer Vision with TensorFlow](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow/tree/master/Part%202-Computer%20Vision%20with%20TensorFlow)
22 | - [Using Convolutional Neural Networks with TensorFlow](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow/tree/master/Part%203-Using%20Convolutional%20Neural%20Networks%20with%20TensorFlow)
23 | - [Extending what Convolutional Neural Nets can do](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow/tree/master/Part%204-Extending%20what%20Convolutional%20Neural%20Nets%20can%20do)
24 | - [Working with Complex Image data for CNNs](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow/tree/master/Part%205-Working%20with%20Complex%20Image%20data%20for%C2%A0CNNs)
25 |
26 | ## Do you need any setup?
27 |
28 | No! You would not need any hardware or software setup to work your way around these tutorials, each of the notebooks have a button  which you can use to open it in [Google Colab](https://colab.research.google.com/) (We'll often refer to this as just Colab) right in your browser :rocket: . If you do not know about Google Colab head on to the [first part](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow/tree/master/Part%201-Getting%20started%20with%20TensorFlow%20and%20Deep%20Learning) which also gives an intro about Colab. If you are more comfortable with using [Binder](https://mybinder.org/) you can use this button [](https://mybinder.org/v2/gh/Rishit-dagli/Deep-Learning-With-TensorFlow/master) to open this repo in Binder.
29 |
30 | ## Why should you be learning this?
31 |
32 | To keep the tutorials concise and to-the-point I have not included this in the tutorials itself.
33 | If you are a newbie to Machine Learning you would most likely wonder why would you be interested in any of this? However, if you have worked with same other ML Framework or library and want to know about TensorFlow you can simply skip this section.
34 |
35 | Artificial Intelligence has revolutionized the way people think, learn, and work in almost every field. You most probably make more use of this than you would imagine. Think about games, the famous YouTube recommendation algorithm or Google Photos identifying faces or identifying if an image is a person or an animal (You will be making a similar program in [Part-5](https://github.com/Rishit-dagli/Deep-Learning-With-TensorFlow/tree/master/Part%205-Working%20with%20Complex%20Image%20data%20for%C2%A0CNNs) ) all powered by Machine Learning. In these tutorials you will be exploring more of the practical aspect of this :smiley: .
36 |
37 | To know more about where AI could be used give [this](https://hackernoon.com/10-reasons-why-you-should-learn-artificial-intelligence-5v6q30vo) blog by Ben Cryer a read.
38 |
--------------------------------------------------------------------------------