Wednesday, June 15, 2016

"Becoming a Social Developer" at NDC Oslo

I had a really amazing time at NDC Oslo last week. And I also did a brand new session using a new technique. I'll have to say that I'm happy with the way that things came out, even though I had some apprehensions about the talk.

So let's do a quick review of "Becoming a Social Developer" from NDC Oslo.

[Update: You can watch a recording of the presentation here: Becoming a Social Developer - Jeremy Clark]

A New Technique
I tried something completely new to me: hand-drawn slides. This is something that I first picked up from talking to David Neal (@reverentgeek) at That Conference last August. He recommended Dan Roam's book Show and Tell (Jeremy's review), and I found it to be a very interesting read.

The first thing that stuck out is that Roam describes several "storylines" for presentations. When looking through these, I saw that "The Drama" would be a good storyline for this particular talk. In fact, I got out my portable white board and drew up the outline:


Since this talk is basically me telling a bunch of stories (and no code at all!), I figured that I needed something interesting going on the screen, so I took another bit of advice from David and Roam and decided to hand-draw my slides.

I spent *a lot* of time on this -- trying to figure out what to write, what to draw, and how much stuff I needed to fill in a full hour. I ended up with 125 slides (YIKES!).

Here are a few samples:

Force Field
May I join you?
Fear!
What a dork!

As you can see, my drawing skills aren't all that great. I think I'll go back and redraw a few of the slides if I give this talk again, but overall, I'm happy with the result.

If you're really curious, you can download the presentation slides (warning, 125 page PDF file): Slides for Becoming a Social Developer at NDC Oslo.

The Apprehension
I was a bit apprehensive about giving this talk as a conference session. I have written articles on it (Becoming a Social Developer & On Being a Social Developer), talked about it on .NET Rocks (Episode 1187), had plenty of hallway conversations, and even had a chance to share it before the keynote at a couple of events (including Live! 360 and Code PaLOUsa).

And back when I originally drew my outline (in October 2015), I was planning it as a full conference session. But the more I thought about it, the less interested I thought people would be. It's a soft topic, and these are hard to do at a technical conference. And to make things more difficult, this would need to be toward the front of the conference to be most useful. I figured that few people would want to start off a conference by attending a soft topic -- that's when you want to dive headlong into the tech; soft topics are good when your head is full and you need a break.

However, I was very surprised with the turnout at NDC Oslo. The room was decently filled (I'm really bad at estimating numbers, so I won't try). I had the first time slot after the opening keynote. The good news is since Troy Hunt gave the keynote, I knew that everyone would be awake.

The Talk
Several people live-tweeted the talk. A big thanks to those folks. Plus, I got to spend some time with them during the rest of the week (another way to meet new friends).



To see all the activity from the talk reinforced that I'm not alone in having these feelings and fears when attending developer events.

So, thank you to my friends David Neal (@reverentgeek), Sabine Bendixen (@SabineBendixen & @getNextIT), Erika Carlson (@eacarlson), Pavneet Singh Saund (@pavsaund), and Daniel Gaszewski (@DanielGaszewski).

The Results
I was very happy with the results. Several people came up to me to talk after the session, and a couple of the speakers even mentioned me in their talks later in the week.

I also know of several people who actively used the tips that I presented. It was really great to see this tweet come through on the last day of the conference:
Fortunately I had a chance to talk to Daniel in person about his experiences, and I'm hoping to share more of them in the future.

In addition, the topic was featured in the NDC Oslo opening day re-cap video:



Review
Based on the response and the successes that people had meeting new people, I'm really encouraged to keep sharing this message. And although I had a bit of apprehension about the session itself, things went very well (much better than I expected): there was a good turnout, I managed to get my stories in the right order, and the timing worked out pretty close to perfectly.

I'm really looking forward to the video of the presentation. Once it's posted, I'll be sure to pass it along.

[Update: You can watch a recording of the presentation here: Becoming a Social Developer - Jeremy Clark]

And today, something interesting happened...
In my presentation, I mentioned how I have become a person who makes connections between other developers (something that is definitely not part of my nature). In particular, I talked about how I was able to connect Maggie Pint (who has an interest in date/time challenges) with Matt Johnson (who I refer to as "Mr. DateTime").

Today, Maggie announced that she has a new challenge ahead of her:
And she blames me for helping get it started:

I'm really glad I could get the ball rolling in the right direction. I made the connection, but it was Maggie who did all the work. She continued the conversation with Matt, she got involved with open source projects and the surrounding community, and ultimately that work led to her getting a new opportunity.

You Never Know...
You never know which of these relationships turn into something bigger, and you never know which relationships may change your life.
If you want to continue the conversation and join the movement, head over to Becoming a Social Developer, sign up for the newsletter, and send in your stories.

Happy Coding!

Oh, and I lied, there was some code in the presentation...


Monday, June 13, 2016

Exploring the Digit Recognizer with F#

I haven't worked on my functional programming for a while. At NDC Oslo, I spent a bit of time with the functional folks, and I was reminded of what a great community is represented by those leaders. They are people who are curious about the world around them, who like to explore and try new things, and who love to share what they know with other people.

It inspired me to go back to a bit of my coding practice and do some more experimentation. I took some code that was written in C# and replaced it with F# code and then worked on some optimization. This let me explore the dataset and find some interesting results regarding accuracy based on the size of the training set and the algorithm used.

Previous Code
So, back in June 2014, I first did some exploration into a machine learning problem: recognizing hand-written digits. I wasn't up to the challenge at that point, so I just figured out a way to display the data (represented by a string of values from 0 to 255 that represent the "lightness" of a pixel). You can read about that here: Coding Practice: Displaying Bitmaps from Pixel Data.

This gave me an output like this:

The Original Digit Display
Then a few months ago (in April), I added the machine learning code that I got from Mathias Brandewinder's book Machine Learning Projects for .NET Developers.

This let me see the original bitmaps next to the prediction from the machine learning algorithm. You can read more about the process here: More Fun with Machine Learning: Recognizing Digits.

Here's the result of that:

Digit Display with Predictions (C# Code)

This is great because I get to see a side-by-side comparison of the hand-written digit and what the computer thinks it is.

But this was all C# code (taken from Mathias' book). I wanted to use the F# code here.

Integrating the F# Code
So, I had the F# code (also from Mathias' book). But there were a couple of challenges since I haven't worked extensively with F# projects.

If you'd like to take a look at the code, go to the GitHub project: jeremybytes/digit-display and take a look at the FSharpRecognizer branch. This project has taken on a life of its own, so I'll probably be re-organizing things in a bit.

The first is that the code that I had was in a script file. This is great for running interactively in the REPL. But it wouldn't work for what I needed. I needed a .NET library that I could call from my WPF application.

The other thing is that the original code ran the machine learning algorithm against an entire set of data so that it could get an accuracy percentage at the end. I needed to run the algorithm against one image at a time so that I could associate the prediction with the image.

The first thing I did was create an F# library in my solution. I copied the script file (.fsx) that I had and created a new F# file (.fs) from it.


I had to make some changes to the top of the file to get things to work. This was new to me since I hadn't done this before, but I managed to get a working solution.

Here's the top of the file:

Top of the F# Library File

The first thing I had to do was create a module. The way I figured this out was from Visual Studio telling me that I needed to have a module:


So, I declared a module.

Next, I needed to update where I got my data. The original script was using a hard-coded path, but I wanted to get that value from configuration (since that's what I was doing with the C# code). With a little hunting, I found "FSharp.Configuration" that let me do just that.

This gives us an AppSettings type provider (type providers are *extremely* useful in F#). The code is pretty simple:

Getting the File from Configuration

Now I had the data pointed at the right files.

The last thing that I really needed to do was create a function that would work with an individual bitmap image (or technically an integer array that represented that bitmap image). This was some new code that I needed to write.

I took a couple different shots at this, first using the "Observation" object from the original script. That contains both the integer array, plus a value that represents the actual digit. I didn't have the actual digit here since I was using a different data set (the original script used the training data with *does* have the actual digit).

This wasn't all that difficult since I had the original script code I could copy from:

A New Prediction Function

The "evaluate" method takes the classifier (our algorithm) and runs it against all of the data values. The important bit is right in the middle where it calls "classifer x.Pixels". This creates a prediction (and then it compares it to the actual value in the test data).

So, I just pulled that one piece out and created the "predict" method. This would now return a single prediction (a string) based on a single integer array.

Using the Code
Once I had this, I could go to my WPF project and replace the code that called into the C# library with calls to the F# library.

Here's the snippet of code to do that:

Using the F# Code in the C# Application

Since the data comes from a text file and is represented by a list of comma-separated integer values, I first had to do some parsing.

The first line takes that entire string and "Split"s it on the commas. This will give us an array of strings. Then the "Select" does a conversion to turn those string values (such as "50", "240", etc.) into integers. The result is an enumeration of integer values. The final method "ToArray" turns it into the integer array that we need for our function.

This syntax takes a bit of getting used to. But I've found that I've become more and more comfortable with this over the years, and I've started to prefer a fluent syntax (where we "dot" methods together) to pipe the output of one function into the input of another.

This is actually a sign that I should jump into functional programming more. The syntax in F# is a bit cleaner than the "dot" syntax that we use in C#.

After getting the integer array, we can run the "predict" function that we just created. All we have to do is pass in the integer array and the classifier that we want to use. In this case, we're using the "manhattanClassifier" -- this was copied from the script file into the F# file with no changes.

I won't lie. It took me a while to figure out the right syntax for everything here. It was the first time that I was calling F# code from a C# application.

Success!
When I did this, I got a successful output. I was able to display the bitmap side-by-side with the prediction coming from the F# library.

But...
(Everyone I know has a big but...)
The application was *SLOW*. The code with the C# library would load up 1000 records in about 3 minutes. The F# library took 3 times that long.

I figured that I would need to do some optimization. For one thing, I wasn't sure how the F# code was behaving. I was using the "manhattanClassifier" inside of a loop. I was pretty sure that the functions behind this method ran for each loop iteration. This meant loading the training set and other things like that.

I really wanted to simply change the loop that I had from a "foreach" to a "Parallel.ForEach". But that wouldn't work with the existing code. The problem is that I was creating the UI elements (the bitmap image and the text block with the predicted number) inside of the loop. So those really needed to be on the UI thread in order to work.

So, I ended up leaving this code alone for a while.

Optimization - Step 1
At NDC Oslo, I showed the code that I had to Mathias, and he worked with me to figure out where the bottleneck was in the code. When you're optimizing, you first have to figure out where the biggest problem is.

Based on stepping through the code, he suggested that we optimize the code that calculates the distance between the pixels (the so called Manhattan distance). Here's the original code:

Original F# Manhattan Distance Calculation

This function is applied between the pixels of our bitmap and the pixels of all of the data in our training file. So this gets run *a lot*.

Mathias actually suggested that we go a bit non-functional by using mutable data. This would run a bit faster:

Optimized F# Manhattan Distance Calculation

Instead of piping the data through a map function and then summing the values, we created a mutable total object that would be updated along the way.

This seems counter-intuitive to how I felt we *should* be doing things. But sometimes optimization leads us to these types of choices. I'm glad that Mathias was there to recommend this because I never would have thought of this on my own.

With this change in place, the F# code was now just as fast as the C# code. That really makes sense since the C# code is using the doing the same thing. Here's a snippet of the C# code for comparison:

C# Manhattan Distance Calculation

By looking at these 2 blocks of code, it makes sense that these would run at the same speed -- they are doing the same thing.

So I had successfully swapped out the F# code for the C# code and had the same performance in the application. But I knew that I could eke out some more performance by parallelizing things a bit.

Optimization - Step 2
The working application had one big flaw (which is a flaw that I had with the C# code as well). When the application was running, it would go into a "Not Responding" state while the data was loading up. That's because everything was happening on the UI thread. So everything was blocked until the process was complete.

This is never a good experience.

In addition, when I looked at the Task Manager, I saw that only 25% of my CPU was being used by the application (meaning, I was only using 1 of the 4 cores available on my machine).

Time to figure out how to run the calculations in parallel.

I really wanted to use the Parallel.ForEach, even if I had to move my code around a bit. But I couldn't figure out a good way to do that while still keeping things on the appropriate threads. I wanted the "predict" method to run on another thread, but I needed all of the UI element creation and interaction to happen on the UI thread.

So I went to my experience with Task. I knew that I could easily create a Task that would run on a different thread. And then I could create a continuation that ran on the UI thread. (For more information, check out my videos and articles for "I'll Get Back to You: Task, Await, and Asynchronous Methods".)

I extracted out the code that creates the UI elements into a separate method. This was originally inside the foreach loop that iterated over the data:

Creating the UI Elements

Everything in this method should run on the UI thread. To manage that, I created a task and a continuation inside the foreach loop:

Getting Tasks on the Right Threads

The first Task will run the "predict" method on a separate thread. This will keep our UI thread clear during the long processing parts.

After that, we have a continuation that calls the "CreateUIElements" method that we have above. This method will get called after the original task complete. But more importantly, since we have "TaskScheduler.FromCurrentSynchronizationContext()", this will run the "CreateUIElements" method on the UI thread of our application.

This keeps our UI elements on the UI thread and everything else on separate threads.

The Results
The result of creating the tasks is that we now use all 4 cores of my machine, and we can get CPU usage up to 100%.

In addition, our application no longer goes into a "Not Responding" state. Instead, we see the results get gradually added to the list box in our UI as the processes complete. It's not completely smooth. I think the UI thread is still getting starved a bit by the other activity, so sometimes there are pauses and then a bunch of elements get added to the UI at the same time. But the overall effect is good.

FASTER!

As we can see, this loads up the data in 1 minute, 16 seconds. This is about 3 times faster than before (it's not 4 times faster because there's some overhead for the tasks, threading, scheduling, etc.).

As a reminder, you can get the code from the GitHub project: jeremybytes/digit-display and take a look at the FSharpRecognizer branch.

More to Come
I was really excited to get the F# code working in this application. This makes me feel like I can integrate F# code into my existing applications without too much trouble. But this also opened up a lot of possibilities for more exploration.

1. Different Classifiers
In addition to the classifier that uses that Manhattan distance calculation, the F# code has a classifier that uses Euclidean distance. In the script examples that Mathias shows, the Euclidean classifier is more accurate. Now I can swap between the Manhattan classifier and Euclidean classifier to see what the actual output looks like. I'm curious to see if the Euclidean classifier simply reduces the number of errors made by the Manhattan classifier or if it makes completely different errors.

I've already done a bit of this experimentation, so look forward to an article on that soon.

2. Speed - Training Set
The Euclidean classifier is a bit slower than the Manhattan classifier -- the calculation uses a power instead of absolute subtraction. This code runs quite a bit more slowly than the code from Mathias' book, and that's because I'm using a different training set. Mathias uses a portion of the training set provided by Kaggle, but I'm using the entire 40,000 records as the training set. This significantly slows down the predictions.

I've experimented with different size training sets (which affect both performance and accuracy). So the results of that will be coming soon, too.

3. Speed - Prediction
As another way of speeding things up, Mathias suggested that there may be a way to optimize the predictions (such as short-circuiting if a value gets too high). This will require a bit more thought.

4. Speed - Reloading
Finally, I'm pretty sure that the training data is getting reloaded each time I call the "predict" function. When this code is being used in a script, it's really easy to only run part of the script so that the data only gets loaded once. But because I'm calling this in a library, I think it gets run each time. This doesn't appear to be terribly slow, but eliminating duplicate work is always a good idea.

[Update: After some more experimentation, I found that the training data is *not* being reloaded each time.]

So there's still quite a bit of work to do on this application.

Wrap Up
This process has reminded me of how much I like functional programming. I really need to do the deep dive that I've been threatening to do for the last 2 years. The good news is that I've got some downtime after the next few weeks. I think I'll use that time to go full-bore into the functional world. I've spent enough time sitting on the edge; it's time to dive in.

Happy Coding!

Sunday, May 29, 2016

June 2016 Speaking Engagements

June is set to be a pretty busy month. Everything coming up is brand new to me, so I'm looking forward to new places, new people, and new experiences.

Monday - Friday, June 6 - 10, 2016
NDC Oslo
Oslo, Norway
Conference Site (hey, look, I'm on the front page)
My Speaker Page
o Becoming a Social Developer
o Learn the Lingo: Design Patterns

I'm really looking forward to NDC Oslo. First, Oslo! Second, I've heard really great things about this conference from both attendees and speakers. Third, I get to talk for a full session about "Becoming a Social Developer". There will be a few familiar faces (which is nice), but there will be lots of new people to meet.

Wednesday, June 15, 2016
Irvine Programming Meetup
Irvine, CA
Meetup Link
o DI Why? Getting a Grip on Dependency Injection

This is a brand new group that started just last month. I love to see the developer community expand, and I'm looking forward to talking to a new group of folks. Plus, I get to talk about one of my favorite topics: dependency injection.

Tuesday, June 21, 2016
Kansas City .NET User Group
Mission, KS
Meetup Link
o Unit Testing Makes Me Faster: Convincing Your Boss, Your Co-Workers, and Yourself

I love talking about unit testing -- it's been a huge help to me as a developer. This will be my first time talking in Kansas, and I'm looking forward to speaking in a new venue and meeting a bunch of new people.

Wednesday - Friday, June 22 - 24, 2016
KC/DC 2016
Kansas City, MO
Conference Site
My Speaker Page
o I'll Get Back to You: Task, Await, and Asynchronous Methods
o IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces

I've heard some really great things about KC/DC, and I'm really looking forward to my first opportunity to speak and attend. This will be my first time speaking in Missouri, and I'm looking forward to seeing some familiar faces and a lot of new ones.

A Look Back
I had a great time speaking at Agile San Diego a few weeks ago. We got some great conversations going about the benefits of unit testing. And it was great to interact with folks who had roles other than developer.

A couple weeks back, I went to Visual Studio LIVE! in Austin, TX. I had a really great time. As usual, I managed to meet lots of great people, and it was really nice to keep running into the same folks over and over throughout the week. I started some good relationships with folks from around the country, and I expect that those relationships will continue.

I spoke on the last day of the conference, and I presented 3 sessions. It was a ton of fun, and I used pretty much all of my energy that day. But it was worth it. I got some good feedback from folks who found it useful.
Finally, I had a chance to give a multi-day workshop for a group of folks in San Diego. Take a look at the workshops that I currently have available, and feel free to contact me if you'd like to book one of these or a custom workshop for your team.

A Look Ahead
I've got some more exciting stuff coming up that isn't quite ready to announce, so stay tuned for that.

I'm also really excited to see that Desert Code Camp is coming back in October. This has been an awesome event in the past, and I've really missed it while it's been on hiatus. If you're in the southwest, be sure to hold the weekend. It will be well worth it.

Hopefully I'll see you at an upcoming event. If you see me, be sure to stop by and say "Hi!"

Happy Coding!

Monday, May 2, 2016

Don't Be Afraid to Show What You Don't Know

For some reason, there's a fear of showing weakness in our industry. But the truth is that we can't know everything - there's just too much technology out there.

I've been using my banjo as a learning tool (and a teaching tool). That really wasn't the plan when I first got it, but that's how things have turned out.


I've had my banjo for over a year now, so I really can't use the excuse of it being "new" anymore. I am getting a lot better (close to competent). And the continuous improvement is really what I'm looking for.
I've found more and more opportunities for me to learn something new by showing what I *don't* know.
Showing What I Don't Know
A couple weeks ago, I was at the Utah Code Camp, and I ended up having lunch with Joe Dean (LinkedIn). We had a great conversation. Joe has a background in music, and he's just getting started with a career producing video games.

I had my banjo with me, and Joe asked if I would play for him. This is a first; I think he's been the only one brave enough to actually ask me to play. I showed him a few things that I had learned, including the progression from my first banjo book: Bluegrass Banjo for the Complete Ignoramus by Wayne Erbsen (Amazon link).

I also played some of the songs that I was working on (a couple that I'm pretty good at and a couple that I'm still learning).

Joe is a guitar instructor, and he gave me some affirmation and some advice (this is always a great combination). First he commented on the way that I held the instrument -- he said that I wouldn't cause myself injury by the way I held it. That was great to know since I don't have an instructor and I've just been learning on my own through various sources.

Next he gave me some great advice on learning to play faster (which is something that I'd like to do). He recommended that I get a metronome app and slowly ramp up the speed. He said to start somewhere comfortable (like 120 beats per minute). Then to get faster, up it by 6 bpm and get comfortable with that. By going step by step it will make the progress easier. He said that people who try to speed up too quickly often just get frustrated. (And I can understand that.)

It was really great to talk to Joe (and this was just another unexpected conversation from a developer event that turned into something awesome). And I'm very thankful that he was so willing to share.

A Found Opportunity
So this opportunity to learn from someone who was well-versed in a particular field came up because I wasn't afraid to show what I *don't* know.

When starting something new (whether music or the latest JavaScript framework), we aren't instantly awesome, and that's okay. Don't be afraid to show what you don't know. That will give you the opportunity to learn from someone who is farther along the path.
And be sure to help out those that are on the path behind you.
It's great to be able to help someone over a problem that you have struggled with yourself. This is how we all get better together.

Still Making Progress
And in case you're wondering, I am still making progress. Here's a recording from the Central California .NET User Group in Fresno from a couple weeks ago.


If you'd like to see the rest of the presentation, you can watch it on YouTube: JeremyBytes Live.
Keep moving forward.
Don't be afraid to show what you don't know.
Don't be afraid to ask questions.
Help those who are on the path behind you.
Happy Coding!

Sunday, May 1, 2016

May 2016 Speaking Engagements

I have a couple of events scheduled for May. And they look to be really great events.

Thursday, May 12, 2016
Agile SD
San Diego, CA
Website
All the Details (Flyer)
o Unit Testing Makes Me Faster: Convincing Your Boss, Your Co-Workers, and Yourself

This is my first time visiting Agile SD. It will be great to meet a new group of folks (and I'll hopefully see some familiar faces as well). Be sure to stop by if you're in the area.

Mon-Thu, May 16-19, 2016
Visual Studio LIVE!
Austin, TX
Website
o Clean Code: Homicidal Maniacs Read Code, Too!
o DI Why? Getting a Grip on Dependency Injection
o Unit Testing Makes Me Faster: Convincing Your Boss, Your Co-Workers, and Yourself

Visual Studio LIVE! is a great event. This is an event that I used to attend when I was a corporate developer, and it really helped me get up to speed on technologies that became very useful in my career. I'm very excited to be a part of it now.

It's not too late to sign up. You can use code AUSPK07 to save $400 on a 4-Day Conference pass. And you'll have plenty of time to talk to me, I'll be around all week.

A Look Back
I had a really great time in April. I got to visit the San Diego .NET User Group, which is probably my most-visited group. One awesome experience happened before things got started. During the networking time, things were pretty quiet in the auditorium. So I gave my 5 minute version of "Becoming a Social Developer" and the importance of talking to other developers. And it worked! People started talking to their neighbors a few seats over or in the next row. It was great to see the group pick it up so quickly. Some people just need a nudge and permission to talk to others. Keep it up!

I also got to go to the Utah Code Camp in Salt Lake City. I had a ton of great experiences there, including some conversations that I'll be writing about later. Thanks to everyone for the great feedback from my presentations where I got to talk about Dependency Injection and Lambda Expressions -- two of my favorite topics.

A bit more locally, I spoke at Agile SoCal in Irvine, CA. This was my first time at this group, and it was great to interact with a different group of folks. Similar to my experiences at the Agile Open conference, fewer developers than most groups that I speak at. And it's great to get some different perspectives.

Finally, I took a drive up to Fresno to speak at the Central California .NET User Group. We had a great time making Task and Await a bit more understandable. After the meeting was over, I had some great conversations with folks who wanted to hang out for a bit longer.

I recorded the presentation from the event. You can watch it on YouTube: JeremyBytes Live! - I'll Get Back To You: Task, Await, and Asynchronous Methods in C#

Or watch it here:


Coming Up
June is looking to be really busy. I'll be going to Norway for NDC Oslo, heading to Kansas for the Kansas City .NET User Group, and on to KCDC in Kansas City, MO.

Other exciting stuff happening, too. I'll be posting updates on that once I've got more information.

As always, check my homepage to get the latest schedule: JeremyBytes.com. And I hope to see you at an upcoming event!

Happy Coding!

Thursday, April 28, 2016

More Fun with Machine Learning - Recognizing Digits

I've been interested in machine learning for a long time, but I've been moving very slowly. I got curious recently and decided to put two of my projects together to see what would happen.

Back in June 2014, I came across a machine learning competition to recognize hand-written digits. I wasn't up for the machine-learning parts, but I did write a program to figure out how to display the datasets: Coding Practice: Displaying Bitmaps from Pixel Data


Then in July 2015, I got really excited about Mathias Brandewinder's book Machine Learning Projects for .NET Developers -- mainly because Chapter 1 was all about recognizing hand-written digits using this same training set:


I went through the code, first with the C# sample and then with F#. And working through the process step-by-step was very helpful. Ultimately, the result of this, though, was an accuracy percentage. The initial evaluator that used Manhattan Distance came out with an accuracy of 93.4%.

Then Mathias goes on to show other algorithms that get that accuracy much closer.

A Visual Display of Accuracy
Fast forward to a couple weeks ago: I got it into my head that I should combine these two things. Rather than just showing an accuracy percentage, why don't I display what the computer thinks the digit is next to the bitmap of the digit itself?

And that's exactly what I did.

You can get the code from GitHub. I put it into the same "digit-display" project that I used previously, but I added a new branch to hold the combined code: GitHub: jeremybytes/digit-display - Recognizer Branch.

Just a note: if you download and run the code as it is right now, it takes about 3 minutes to process 1,000 records. I'm working on improving the speed, but I'm just happy to get the results right now.

Here's the output:


This is a *large* image, so you might want to click on it to see the full size (non-blurry) version.

Before analyzing the results, let's take a look at how I modified the code.

The Original Project
The original project had a WPF application and a separate project that loaded the data (which is a string of pixel brightness values) and turned them into bitmaps.


The New Project
I added the C# code from Mathias' book in a separate project (named "Recognizer"):


I know I should be using the F# code here, but most of that is in a script. Future steps will be for me to put that F# code into a library that I can bring in to this solution.

Updates to the WPF Application
I took the path of least resistance to get this to work. In my WPF application, I have most of the code in the code-behind of the MainWindow.

I added a new method that would initialize the digit recognizer (GitHub: MainWindow.xaml.cs):


This uses the "BasicClassifier" (as described in Mathias' book). I load up the data from the "training" set and use that to train the classifier.

In the previous code, I loaded up data from the training set to display. But I changed the code a bit to display the "test" set.

The difference between the "training" set and the "test" set is that the training set has a field that tells what the hand-written digit is supposed to be. This lets gives our classifier both the bitmap data and the expected output.

The "test" set only has the bitmap data. It does not have a field that tells what the number is supposed to be. Instead, we'll use our eyes to pick out the wrong ones.

In the App.config file, we have both files referenced so we can load them in the right places:


Displaying the Digits
In the old code, I created an Image control and loaded it into a WPF wrap panel. In the new code, I add the Image, and then I add a TextBlock that holds the result of our classifier.


The "imageString.Split..." code takes our original input (which is a string of comma-separated values) and turns it into an integer array -- the format needed by our classifier.

Then we pass that to the "classifier.Predict()" method, and it gives us back the recognized digit.

And that gives us the output (again, it takes about 3 minutes to process 1,000 records):


Analyzing the Results
This is where things get interesting. Now we (as humans) can look through the results to find the pairs of numbers that do not match. Here are just a few.



When looking through the numbers that are wrong, it's easy to see why the classifier made the choice that it did. There are similarities in shapes. And these similarities are easy to see when looking at all the numbers the classifier got *right*.

My next steps are to convert this to use the F# code for the machine learning bits and also figure out how to speed things up -- probably by parallelizing a bunch of the code.

Humans are Awesome
Looking at the hand-written digits compared to the numbers predicted by the classifier really gives me an appreciation for how difficult this problem really is.

As a human, I have no trouble interpreting the hand-written digits (except for a couple that are really ambiguous). And it's interesting to think about the things that go on in our brains that allow us to recognize things so quickly -- without conscious analysis. It all happens in a moment without having to think about it.

Before you leave, scan through the results to see how it gets some "hard" ones right, and some "easy" ones wrong. Our brains are pretty amazing:

Click for full-size image
Teaching a computer how to do that is pretty impressive. And honestly, I'm surprised that such a simple algorithm (remember, this is the "step 1" algorithm that we're using here) can get the accuracy as high as it does. This really taught me that we should start out simple and only get more complex as we need to.

And it also gives us a lot of new places to explore.

Happy Coding!

Monday, April 25, 2016

Integrating NUnit into Visual Studio -- Update for NUnit 3

Overview: This article talks about using the NUnit Test Adapter to integrate the NUnit test runner with the Visual Studio Test Explorer. In particular, we need to ensure that we're using the right Test Adapter package for the version of NUnit that we're using.

I like using the Visual Studio Test Explorer. This is integrated into my environment, and I can always undock the window and move it to a different monitor. In particular, I love this button:


This is the "Run Tests After Build" button (it's currently only available in the expensive version of Visual Studio). When this button is toggled down, impacted unit tests are automatically run every time I build. This gives me immediate feedback when I break something.

Integrating NUnit with the Test Adapter
I've started using NUnit more and more (check out the "Why NUnit?" articles here: http://www.jeremybytes.com/Demos.aspx#UTMMF). In addition to the NUnit framework, there is also a Test Adapter package available from NuGet that integrates the NUnit test runner with the Visual Studio test explorer.

I've been using this functionality for quite some time now: Integrating NUnit into Visual Studio Test Explorer.

The problem is that we've had a bit of a version mis-match between NUnit and the Test Adapter since NUnit 3 came out last November. The good news is that last week (April 19th, 2016), the Test Adapter that's compatible with NUnit 3 finally hit release.

NUnit Version 3 and the NUnit3TestAdapter
To use NUnit and the Test Adapter with a particular project in Visual Studio, we just need to use NuGet to grab the appropriate packages. But we need to pay attention to the packages that we're pulling.

For NUnit 3, we want the following 2 packages:


Since we're using Nunit version 3 (specifically v3.2.1), we need to use the "NUnit3TestAdapter" package.

Note: This is a completely different package from the old test adapter. It is not merely the old package with a new version.

NUnit Version 2 and the NUnitTestAdapter
If you're still using NUnit version 2, we need to use a completely different test adapter package:


Here, we have NUnit version 2 (specifically v2.6.4), so we need to use the "NUnitTestAdapter" package.

Note: This is a different package from the new test adapter.

Wrap Up
The moral of the story is that we need to be careful about the packages that we pull down when using NUnit.

When using NUnit 3, we need to use the NUnit3TestAdapter package.
When using NUnit 2, we need to use the NUnitTestAdapter package.

Even though the NUnit framework packages are the same (with different versions), the test adapter packages are different packages. If we get a mismatch, then we won't see our tests in the test explorer.

But when we get the right packages together, things work great. We get to see our tests inside Visual Studio, and we can interact with them easily in the integrated environment.

Happy Coding!