├── .gitattributes
├── .gitignore
├── ImageClassification.sln
├── ImageClassification
├── App.config
├── Form1.Designer.cs
├── Form1.cs
├── Form1.resx
├── ImageClassification.csproj
└── Program.cs
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # =========================
18 | # Operating System Files
19 | # =========================
20 |
21 | # OSX
22 | # =========================
23 |
24 | .DS_Store
25 | .AppleDouble
26 | .LSOverride
27 |
28 | # Icon must end with two \r
29 | Icon
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear on external disk
35 | .Spotlight-V100
36 | .Trashes
37 |
38 | # Directories potentially created on remote AFP share
39 | .AppleDB
40 | .AppleDesktop
41 | Network Trash Folder
42 | Temporary Items
43 | .apdisk
44 |
--------------------------------------------------------------------------------
/ImageClassification.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Express 2013 for Windows Desktop
4 | VisualStudioVersion = 12.0.30723.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageClassification", "ImageClassification\ImageClassification.csproj", "{5C540CBB-8A89-43A4-9AB9-88BAE54F8BBA}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {5C540CBB-8A89-43A4-9AB9-88BAE54F8BBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {5C540CBB-8A89-43A4-9AB9-88BAE54F8BBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {5C540CBB-8A89-43A4-9AB9-88BAE54F8BBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {5C540CBB-8A89-43A4-9AB9-88BAE54F8BBA}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/ImageClassification/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ImageClassification/Form1.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ImageClassification
2 | {
3 | partial class Form1
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
32 | this.pictureBox1 = new System.Windows.Forms.PictureBox();
33 | this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
34 | this.closeButton = new System.Windows.Forms.Button();
35 | this.button2 = new System.Windows.Forms.Button();
36 | this.button3 = new System.Windows.Forms.Button();
37 | this.button4 = new System.Windows.Forms.Button();
38 | this.loadButton = new System.Windows.Forms.Button();
39 | this.saveButton = new System.Windows.Forms.Button();
40 | this.getDataButton = new System.Windows.Forms.Button();
41 | this.label1 = new System.Windows.Forms.Label();
42 | this.listBox1 = new System.Windows.Forms.ListBox();
43 | this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
44 | this.reconstructButton = new System.Windows.Forms.Button();
45 | this.generateInput = new System.Windows.Forms.Button();
46 | this.textBox1 = new System.Windows.Forms.TextBox();
47 | this.label3 = new System.Windows.Forms.Label();
48 | this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
49 | this.label4 = new System.Windows.Forms.Label();
50 | this.label5 = new System.Windows.Forms.Label();
51 | this.label2 = new System.Windows.Forms.Label();
52 | this.txtUnsupervised = new System.Windows.Forms.TextBox();
53 | this.txtSupervised = new System.Windows.Forms.TextBox();
54 | this.txtCategories = new System.Windows.Forms.TextBox();
55 | this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
56 | this.colorDialog1 = new System.Windows.Forms.ColorDialog();
57 | this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
58 | this.openFileDialog2 = new System.Windows.Forms.OpenFileDialog();
59 | this.tableLayoutPanel1.SuspendLayout();
60 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
61 | this.flowLayoutPanel1.SuspendLayout();
62 | this.flowLayoutPanel3.SuspendLayout();
63 | this.tableLayoutPanel2.SuspendLayout();
64 | this.SuspendLayout();
65 | //
66 | // tableLayoutPanel1
67 | //
68 | this.tableLayoutPanel1.ColumnCount = 2;
69 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
70 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
71 | this.tableLayoutPanel1.Controls.Add(this.pictureBox1, 0, 0);
72 | this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 1, 1);
73 | this.tableLayoutPanel1.Controls.Add(this.label1, 1, 0);
74 | this.tableLayoutPanel1.Controls.Add(this.listBox1, 0, 2);
75 | this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel3, 0, 1);
76 | this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 1, 2);
77 | this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
78 | this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
79 | this.tableLayoutPanel1.Name = "tableLayoutPanel1";
80 | this.tableLayoutPanel1.RowCount = 3;
81 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 60F));
82 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
83 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
84 | this.tableLayoutPanel1.Size = new System.Drawing.Size(684, 447);
85 | this.tableLayoutPanel1.TabIndex = 0;
86 | //
87 | // pictureBox1
88 | //
89 | this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
90 | this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
91 | this.pictureBox1.Location = new System.Drawing.Point(3, 3);
92 | this.pictureBox1.Name = "pictureBox1";
93 | this.pictureBox1.Size = new System.Drawing.Size(336, 262);
94 | this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
95 | this.pictureBox1.TabIndex = 0;
96 | this.pictureBox1.TabStop = false;
97 | //
98 | // flowLayoutPanel1
99 | //
100 | this.flowLayoutPanel1.Controls.Add(this.closeButton);
101 | this.flowLayoutPanel1.Controls.Add(this.button2);
102 | this.flowLayoutPanel1.Controls.Add(this.button3);
103 | this.flowLayoutPanel1.Controls.Add(this.button4);
104 | this.flowLayoutPanel1.Controls.Add(this.loadButton);
105 | this.flowLayoutPanel1.Controls.Add(this.saveButton);
106 | this.flowLayoutPanel1.Controls.Add(this.getDataButton);
107 | this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
108 | this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
109 | this.flowLayoutPanel1.Location = new System.Drawing.Point(345, 271);
110 | this.flowLayoutPanel1.Name = "flowLayoutPanel1";
111 | this.flowLayoutPanel1.Size = new System.Drawing.Size(336, 83);
112 | this.flowLayoutPanel1.TabIndex = 2;
113 | //
114 | // closeButton
115 | //
116 | this.closeButton.AutoSize = true;
117 | this.closeButton.Location = new System.Drawing.Point(258, 3);
118 | this.closeButton.Name = "closeButton";
119 | this.closeButton.Size = new System.Drawing.Size(75, 23);
120 | this.closeButton.TabIndex = 0;
121 | this.closeButton.Text = "Close";
122 | this.closeButton.UseVisualStyleBackColor = true;
123 | this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
124 | //
125 | // button2
126 | //
127 | this.button2.AutoSize = true;
128 | this.button2.Location = new System.Drawing.Point(167, 3);
129 | this.button2.Name = "button2";
130 | this.button2.Size = new System.Drawing.Size(85, 23);
131 | this.button2.TabIndex = 1;
132 | this.button2.Text = "Choose Image";
133 | this.button2.UseVisualStyleBackColor = true;
134 | this.button2.Click += new System.EventHandler(this.chooseImage_Click);
135 | //
136 | // button3
137 | //
138 | this.button3.AutoSize = true;
139 | this.button3.Location = new System.Drawing.Point(86, 3);
140 | this.button3.Name = "button3";
141 | this.button3.Size = new System.Drawing.Size(75, 23);
142 | this.button3.TabIndex = 2;
143 | this.button3.Text = "Classify";
144 | this.button3.UseVisualStyleBackColor = true;
145 | this.button3.Click += new System.EventHandler(this.Classify);
146 | //
147 | // button4
148 | //
149 | this.button4.AutoSize = true;
150 | this.button4.Location = new System.Drawing.Point(5, 3);
151 | this.button4.Name = "button4";
152 | this.button4.Size = new System.Drawing.Size(75, 23);
153 | this.button4.TabIndex = 3;
154 | this.button4.Text = "Train";
155 | this.button4.UseVisualStyleBackColor = true;
156 | this.button4.Click += new System.EventHandler(this.train_Click);
157 | //
158 | // loadButton
159 | //
160 | this.loadButton.Location = new System.Drawing.Point(258, 32);
161 | this.loadButton.Name = "loadButton";
162 | this.loadButton.Size = new System.Drawing.Size(75, 23);
163 | this.loadButton.TabIndex = 4;
164 | this.loadButton.Text = "Load DBN";
165 | this.loadButton.UseVisualStyleBackColor = true;
166 | this.loadButton.Click += new System.EventHandler(this.loadButton_Clicked);
167 | //
168 | // saveButton
169 | //
170 | this.saveButton.Location = new System.Drawing.Point(177, 32);
171 | this.saveButton.Name = "saveButton";
172 | this.saveButton.Size = new System.Drawing.Size(75, 23);
173 | this.saveButton.TabIndex = 5;
174 | this.saveButton.Text = "Save DBN";
175 | this.saveButton.UseVisualStyleBackColor = true;
176 | this.saveButton.Click += new System.EventHandler(this.saveButton_Clicked);
177 | //
178 | // getDataButton
179 | //
180 | this.getDataButton.Location = new System.Drawing.Point(96, 32);
181 | this.getDataButton.Name = "getDataButton";
182 | this.getDataButton.Size = new System.Drawing.Size(75, 23);
183 | this.getDataButton.TabIndex = 6;
184 | this.getDataButton.Text = "Get Data";
185 | this.getDataButton.UseVisualStyleBackColor = true;
186 | this.getDataButton.Click += new System.EventHandler(this.getDataButton_Clicked);
187 | //
188 | // label1
189 | //
190 | this.label1.AutoSize = true;
191 | this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
192 | this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
193 | this.label1.Location = new System.Drawing.Point(345, 0);
194 | this.label1.Name = "label1";
195 | this.label1.Size = new System.Drawing.Size(336, 268);
196 | this.label1.TabIndex = 3;
197 | this.label1.Text = "Click \'Train\' first to train the DBN!";
198 | //
199 | // listBox1
200 | //
201 | this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill;
202 | this.listBox1.FormattingEnabled = true;
203 | this.listBox1.Location = new System.Drawing.Point(3, 360);
204 | this.listBox1.Name = "listBox1";
205 | this.listBox1.Size = new System.Drawing.Size(336, 84);
206 | this.listBox1.TabIndex = 5;
207 | //
208 | // flowLayoutPanel3
209 | //
210 | this.flowLayoutPanel3.Controls.Add(this.reconstructButton);
211 | this.flowLayoutPanel3.Controls.Add(this.generateInput);
212 | this.flowLayoutPanel3.Controls.Add(this.textBox1);
213 | this.flowLayoutPanel3.Controls.Add(this.label3);
214 | this.flowLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
215 | this.flowLayoutPanel3.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
216 | this.flowLayoutPanel3.Location = new System.Drawing.Point(3, 271);
217 | this.flowLayoutPanel3.Name = "flowLayoutPanel3";
218 | this.flowLayoutPanel3.Size = new System.Drawing.Size(336, 83);
219 | this.flowLayoutPanel3.TabIndex = 7;
220 | //
221 | // reconstructButton
222 | //
223 | this.reconstructButton.Location = new System.Drawing.Point(3, 3);
224 | this.reconstructButton.Name = "reconstructButton";
225 | this.reconstructButton.Size = new System.Drawing.Size(75, 23);
226 | this.reconstructButton.TabIndex = 4;
227 | this.reconstructButton.Text = "Reconstruct";
228 | this.reconstructButton.UseVisualStyleBackColor = true;
229 | this.reconstructButton.Click += new System.EventHandler(this.reconstructButton_Click);
230 | //
231 | // generateInput
232 | //
233 | this.generateInput.Location = new System.Drawing.Point(3, 32);
234 | this.generateInput.Name = "generateInput";
235 | this.generateInput.Size = new System.Drawing.Size(75, 23);
236 | this.generateInput.TabIndex = 5;
237 | this.generateInput.Text = "Generate Input";
238 | this.generateInput.UseVisualStyleBackColor = true;
239 | this.generateInput.Click += new System.EventHandler(this.generateInputButton_Clicked);
240 | //
241 | // textBox1
242 | //
243 | this.textBox1.Location = new System.Drawing.Point(84, 3);
244 | this.textBox1.Name = "textBox1";
245 | this.textBox1.Size = new System.Drawing.Size(100, 20);
246 | this.textBox1.TabIndex = 1;
247 | //
248 | // label3
249 | //
250 | this.label3.AutoSize = true;
251 | this.label3.Location = new System.Drawing.Point(84, 26);
252 | this.label3.Name = "label3";
253 | this.label3.Size = new System.Drawing.Size(151, 13);
254 | this.label3.TabIndex = 0;
255 | this.label3.Text = "Enter \",\" here";
256 | //
257 | // tableLayoutPanel2
258 | //
259 | this.tableLayoutPanel2.ColumnCount = 2;
260 | this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
261 | this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
262 | this.tableLayoutPanel2.Controls.Add(this.label4, 0, 1);
263 | this.tableLayoutPanel2.Controls.Add(this.label5, 0, 2);
264 | this.tableLayoutPanel2.Controls.Add(this.label2, 0, 0);
265 | this.tableLayoutPanel2.Controls.Add(this.txtUnsupervised, 1, 0);
266 | this.tableLayoutPanel2.Controls.Add(this.txtSupervised, 1, 1);
267 | this.tableLayoutPanel2.Controls.Add(this.txtCategories, 1, 2);
268 | this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
269 | this.tableLayoutPanel2.Location = new System.Drawing.Point(345, 360);
270 | this.tableLayoutPanel2.Name = "tableLayoutPanel2";
271 | this.tableLayoutPanel2.RowCount = 3;
272 | this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
273 | this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
274 | this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
275 | this.tableLayoutPanel2.Size = new System.Drawing.Size(336, 84);
276 | this.tableLayoutPanel2.TabIndex = 8;
277 | //
278 | // label4
279 | //
280 | this.label4.AutoSize = true;
281 | this.label4.Location = new System.Drawing.Point(3, 28);
282 | this.label4.Name = "label4";
283 | this.label4.Size = new System.Drawing.Size(99, 13);
284 | this.label4.TabIndex = 1;
285 | this.label4.Text = "Supervised Epochs";
286 | this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
287 | //
288 | // label5
289 | //
290 | this.label5.AutoSize = true;
291 | this.label5.Location = new System.Drawing.Point(3, 56);
292 | this.label5.Name = "label5";
293 | this.label5.Size = new System.Drawing.Size(159, 13);
294 | this.label5.TabIndex = 2;
295 | this.label5.Text = "Number of Categories to Classify";
296 | //
297 | // label2
298 | //
299 | this.label2.AutoSize = true;
300 | this.label2.Location = new System.Drawing.Point(3, 0);
301 | this.label2.Name = "label2";
302 | this.label2.Size = new System.Drawing.Size(111, 13);
303 | this.label2.TabIndex = 0;
304 | this.label2.Text = "Unsupervised Epochs";
305 | this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
306 | //
307 | // txtUnsupervised
308 | //
309 | this.txtUnsupervised.Location = new System.Drawing.Point(171, 3);
310 | this.txtUnsupervised.Name = "txtUnsupervised";
311 | this.txtUnsupervised.Size = new System.Drawing.Size(100, 20);
312 | this.txtUnsupervised.TabIndex = 3;
313 | this.txtUnsupervised.TextChanged += new System.EventHandler(this.txtUnsupervised_Changed);
314 | //
315 | // txtSupervised
316 | //
317 | this.txtSupervised.Location = new System.Drawing.Point(171, 31);
318 | this.txtSupervised.Name = "txtSupervised";
319 | this.txtSupervised.Size = new System.Drawing.Size(100, 20);
320 | this.txtSupervised.TabIndex = 4;
321 | this.txtSupervised.TextChanged += new System.EventHandler(this.txtSupervised_Changed);
322 | //
323 | // txtCategories
324 | //
325 | this.txtCategories.Enabled = false;
326 | this.txtCategories.Location = new System.Drawing.Point(171, 59);
327 | this.txtCategories.Name = "txtCategories";
328 | this.txtCategories.Size = new System.Drawing.Size(100, 20);
329 | this.txtCategories.TabIndex = 5;
330 | //
331 | // openFileDialog1
332 | //
333 | this.openFileDialog1.FileName = "openFileDialog1";
334 | this.openFileDialog1.Filter = "JPEG Files (*.jpg)|*.jpg|PNG Files (*.png)|*.png|BMP Files (*.bmp)|*.bmp|All file" +
335 | "s (*.*)|*.*";
336 | this.openFileDialog1.Title = "Select an Image";
337 | //
338 | // saveFileDialog1
339 | //
340 | this.saveFileDialog1.Filter = "DBN Files|*.dbn";
341 | this.saveFileDialog1.Title = "Save DBN";
342 | //
343 | // openFileDialog2
344 | //
345 | this.openFileDialog2.Filter = "DBN Files|*.dbn";
346 | this.openFileDialog2.Title = "Load DBN";
347 | //
348 | // Form1
349 | //
350 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
351 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
352 | this.ClientSize = new System.Drawing.Size(684, 447);
353 | this.Controls.Add(this.tableLayoutPanel1);
354 | this.Name = "Form1";
355 | this.Text = "Deep Net Image Classifier";
356 | this.Load += new System.EventHandler(this.Form1_Load);
357 | this.tableLayoutPanel1.ResumeLayout(false);
358 | this.tableLayoutPanel1.PerformLayout();
359 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
360 | this.flowLayoutPanel1.ResumeLayout(false);
361 | this.flowLayoutPanel1.PerformLayout();
362 | this.flowLayoutPanel3.ResumeLayout(false);
363 | this.flowLayoutPanel3.PerformLayout();
364 | this.tableLayoutPanel2.ResumeLayout(false);
365 | this.tableLayoutPanel2.PerformLayout();
366 | this.ResumeLayout(false);
367 |
368 | }
369 |
370 | #endregion
371 |
372 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
373 | private System.Windows.Forms.PictureBox pictureBox1;
374 | private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
375 | private System.Windows.Forms.Button closeButton;
376 | private System.Windows.Forms.Button button2;
377 | private System.Windows.Forms.Button button3;
378 | private System.Windows.Forms.Button button4;
379 | private System.Windows.Forms.OpenFileDialog openFileDialog1;
380 | private System.Windows.Forms.ColorDialog colorDialog1;
381 | private System.Windows.Forms.Label label1;
382 | private System.Windows.Forms.Button reconstructButton;
383 | private System.Windows.Forms.ListBox listBox1;
384 | private System.Windows.Forms.Button loadButton;
385 | private System.Windows.Forms.Button saveButton;
386 | private System.Windows.Forms.SaveFileDialog saveFileDialog1;
387 | private System.Windows.Forms.OpenFileDialog openFileDialog2;
388 | private System.Windows.Forms.Label label3;
389 | private System.Windows.Forms.TextBox textBox1;
390 | private System.Windows.Forms.Button getDataButton;
391 | private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3;
392 | private System.Windows.Forms.Button generateInput;
393 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
394 | private System.Windows.Forms.Label label4;
395 | private System.Windows.Forms.Label label5;
396 | private System.Windows.Forms.Label label2;
397 | private System.Windows.Forms.TextBox txtUnsupervised;
398 | private System.Windows.Forms.TextBox txtSupervised;
399 | private System.Windows.Forms.TextBox txtCategories;
400 | }
401 | }
402 |
403 |
--------------------------------------------------------------------------------
/ImageClassification/Form1.cs:
--------------------------------------------------------------------------------
1 | using Accord.Imaging.Converters;
2 | using Accord.Math;
3 | using Accord.Neuro;
4 | using Accord.Neuro.ActivationFunctions;
5 | using Accord.Neuro.Learning;
6 | using Accord.Neuro.Networks;
7 | using Accord.Statistics;
8 | using AForge.Neuro.Learning;
9 | using System;
10 | using System.Collections.Generic;
11 | using System.ComponentModel;
12 | using System.Data;
13 | using System.Diagnostics;
14 | using System.Drawing;
15 | using System.IO;
16 | using System.Linq;
17 | using System.Text;
18 | using System.Threading.Tasks;
19 | using System.Windows.Forms;
20 |
21 | namespace ImageClassification
22 | {
23 | public partial class Form1 : Form
24 | {
25 | private static string PREFIX = "../../data/101_ObjectCategories";
26 | private static int NUM_CATEGORIES = 5; // can be up to 101
27 | private static int UNSUPERVISED_EPOCHS = 200; // originally 200
28 | private static int SUPERVISED_EPOCHS = 300; // originally 500
29 | private static int NUM_EXAMPLES = 30; // must be <= 31
30 | private static int NUM_TRAIN = 20; // must be < NUM_EXAMPLES to have something to test
31 | private static int WIDTH = 30; // standard width for images used here
32 | private static int HEIGHT = 20; // standard height for images used here
33 | private static int[] LAYERS = new int[] { 600, 400, NUM_CATEGORIES, NUM_CATEGORIES }; // architecture of the net
34 |
35 | private static ImageToArray _itoa = new ImageToArray(min: 0, max: 1);
36 | private static ArrayToImage _atoi = new ArrayToImage(WIDTH, HEIGHT, min: 0.0, max: 1.0);
37 | private DeepBeliefNetwork _network;
38 | private Bitmap _imageToClassify;
39 | private string[] _categories;
40 |
41 | public Form1()
42 | {
43 | InitializeComponent();
44 |
45 | UpdateLayerDescription();
46 | txtUnsupervised.Text = UNSUPERVISED_EPOCHS.ToString();
47 | txtSupervised.Text = SUPERVISED_EPOCHS.ToString();
48 | txtCategories.Text = NUM_CATEGORIES.ToString();
49 | }
50 |
51 | private void UpdateLayerDescription(){
52 | label3.Text += "\n";
53 | for (int i = 0; i < LAYERS.Length; i++)
54 | {
55 | label3.Text += "Layer " + i + " has " + LAYERS[i] + " neurons.\n";
56 | }
57 | label3.Refresh();
58 | }
59 |
60 | private void Form1_Load(object sender, EventArgs e)
61 | {
62 |
63 | }
64 |
65 | private void closeButton_Click(object sender, EventArgs e)
66 | {
67 | this.Close();
68 | }
69 |
70 | private void txtUnsupervised_Changed(object sender, EventArgs e)
71 | {
72 | UNSUPERVISED_EPOCHS = int.Parse(txtUnsupervised.Text);
73 | UpdateLayerDescription();
74 | }
75 |
76 | private void txtSupervised_Changed(object sender, EventArgs e)
77 | {
78 | SUPERVISED_EPOCHS = int.Parse(txtSupervised.Text);
79 | UpdateLayerDescription();
80 | }
81 |
82 | private void txtCategories_Changed(object sender, EventArgs e)
83 | {
84 | NUM_CATEGORIES = int.Parse(txtCategories.Text);
85 | // TODO: need to update LAYERS
86 | UpdateLayerDescription();
87 | }
88 |
89 | private void Classify(object sender, EventArgs e)
90 | {
91 | if (_imageToClassify == null)
92 | {
93 | label1.Text = "You didn't choose an image!\n";
94 | label1.Refresh();
95 | return;
96 | }
97 |
98 | double[] input;
99 | _itoa.Convert(_imageToClassify, out input);
100 | double[] output = _network.Compute(input);
101 | label1.Text = "Prediction: " + _categories[GetResult(output)];
102 | label1.Refresh();
103 | }
104 |
105 | private void Recall(bool reconstruct)
106 | {
107 | string[] sp = textBox1.Text.Split(',');
108 | if (sp.Length != 2) {
109 | label1.Text = "You need to enter ,!";
110 | label1.Refresh();
111 | return;
112 | }
113 | try
114 | {
115 | int neuron = int.Parse(sp[0]);
116 | int layer = int.Parse(sp[1]);
117 | string c = (layer == LAYERS.Length - 1) ? listBox1.Items[neuron].ToString() : "(not a category)";
118 |
119 | double[] a = (reconstruct) ? new double[LAYERS[layer]] : new double[NUM_CATEGORIES];
120 | a[neuron] = 1;
121 |
122 | double[] r = (reconstruct) ? _network.Reconstruct(a, layer) : _network.GenerateInput(a);
123 | Bitmap bm;
124 | _atoi.Convert(r, out bm);
125 |
126 | label1.Text = "Reconstructing " + c + ", length of reconstruction: " + r.Length;
127 | label1.Refresh();
128 |
129 | pictureBox1.Image = bm;
130 | pictureBox1.Refresh();
131 | }
132 | catch (Exception ex)
133 | {
134 | label1.Text = ex.Message + "\n" + ex.StackTrace + "\n";
135 | label1.Text += "Reconstruction input params invalid. neuron should be < size of layer.";
136 | label1.Refresh();
137 | }
138 | }
139 |
140 | private void reconstructButton_Click(object sender, EventArgs e)
141 | {
142 | Recall(true);
143 | }
144 |
145 | private void generateInputButton_Clicked(object sender, EventArgs e)
146 | {
147 | Recall(false);
148 | }
149 |
150 | private void getDataButton_Clicked(object sender, EventArgs e)
151 | {
152 | double[][] inputs;
153 | double[][] outputs;
154 | double[][] testInputs;
155 | double[][] testOutputs;
156 | GetData(out inputs, out outputs, out testInputs, out testOutputs);
157 | }
158 |
159 | private void train_Click(object sender, EventArgs e)
160 | {
161 | double[][] inputs;
162 | double[][] outputs;
163 | double[][] testInputs;
164 | double[][] testOutputs;
165 | GetData(out inputs, out outputs, out testInputs, out testOutputs);
166 |
167 | Stopwatch sw = Stopwatch.StartNew();
168 |
169 | // Setup the deep belief network and initialize with random weights.
170 | _network = new DeepBeliefNetwork(inputs.First().Length, LAYERS);
171 | new GaussianWeights(_network, 0.1).Randomize();
172 | _network.UpdateVisibleWeights();
173 |
174 | // Setup the learning algorithm.
175 | DeepBeliefNetworkLearning teacher = new DeepBeliefNetworkLearning(_network)
176 | {
177 | Algorithm = (h, v, i) => new ContrastiveDivergenceLearning(h, v)
178 | {
179 | LearningRate = 0.1,
180 | Momentum = 0.5,
181 | Decay = 0.001,
182 | }
183 | };
184 |
185 | // Setup batches of input for learning.
186 | int batchCount = Math.Max(1, inputs.Length / 100);
187 | // Create mini-batches to speed learning.
188 | int[] groups = Accord.Statistics.Tools.RandomGroups(inputs.Length, batchCount);
189 | double[][][] batches = inputs.Subgroups(groups);
190 | // Learning data for the specified layer.
191 | double[][][] layerData;
192 |
193 | // Unsupervised learning on each hidden layer, except for the output layer.
194 | for (int layerIndex = 0; layerIndex < _network.Machines.Count - 1; layerIndex++)
195 | {
196 | teacher.LayerIndex = layerIndex;
197 | layerData = teacher.GetLayerInput(batches);
198 | for (int i = 0; i < UNSUPERVISED_EPOCHS; i++)
199 | {
200 | double error = teacher.RunEpoch(layerData) / inputs.Length;
201 | if (i % 10 == 0)
202 | {
203 | label1.Text = "Layer: " + layerIndex + " Epoch: " + i + ", Error: " + error;
204 | label1.Refresh();
205 | }
206 | }
207 | }
208 |
209 | // Supervised learning on entire network, to provide output classification.
210 | var teacher2 = new BackPropagationLearning(_network)
211 | {
212 | LearningRate = 0.1,
213 | Momentum = 0.5
214 | };
215 |
216 | // Run supervised learning.
217 | for (int i = 0; i < SUPERVISED_EPOCHS; i++)
218 | {
219 | double error = teacher2.RunEpoch(inputs, outputs) / inputs.Length;
220 | if (i % 10 == 0)
221 | {
222 | label1.Text = "Supervised: " + i + ", Error = " + error;
223 | label1.Refresh();
224 | }
225 | }
226 |
227 | // Test the resulting accuracy.
228 | label1.Text = "";
229 | int correct = 0;
230 | for (int i = 0; i < testInputs.Length; i++)
231 | {
232 | double[] outputValues = _network.Compute(testInputs[i]);
233 | int y = GetResult(outputValues);
234 | int t = GetResult(testOutputs[i]);
235 | label1.Text += "predicted: " + y + " actual: " + t + "\n";
236 | label1.Refresh();
237 | if (y == t)
238 | {
239 | correct++;
240 | }
241 | }
242 | sw.Stop();
243 |
244 | label1.Text = "Correct " + correct + "/" + testInputs.Length + ", " + Math.Round(((double)correct / (double)testInputs.Length * 100), 2) + "%";
245 | label1.Text += "\nElapsed train+test time: " + sw.Elapsed;
246 | label1.Refresh();
247 | }
248 |
249 | int GetResult(double[] output)
250 | {
251 | return output.ToList().IndexOf(output.Max());
252 | }
253 |
254 | private void chooseImage_Click(object sender, EventArgs e)
255 | {
256 | // Show the Open File dialog. If the user clicks OK, load the
257 | // picture that the user chose.
258 | if (openFileDialog1.ShowDialog() == DialogResult.OK)
259 | {
260 | //double[] array;
261 | Bitmap image = (Bitmap)Bitmap.FromFile(openFileDialog1.FileName, true);
262 | _imageToClassify = ShrinkImage(image);
263 | // itoa.Convert(image, out array);
264 |
265 | //Bitmap im2;
266 | //atoi.Convert(array, out im2);
267 |
268 | //ImageBox.Show(array, image.Width, image.Height, PictureBoxSizeMode.Zoom);
269 | pictureBox1.Load(openFileDialog1.FileName);
270 | //pictureBox1.Image = im2;
271 | //pictureBox1.Refresh();
272 | }
273 | }
274 |
275 | private void saveButton_Clicked(object sender, EventArgs e)
276 | {
277 | if (saveFileDialog1.ShowDialog() == DialogResult.OK)
278 | {
279 | Stream st;
280 | if ((st = saveFileDialog1.OpenFile()) != null)
281 | {
282 | _network.Save(st);
283 | st.Close();
284 | }
285 | }
286 | }
287 |
288 | private void loadButton_Clicked(object sender, EventArgs e)
289 | {
290 | if (openFileDialog2.ShowDialog() == DialogResult.OK)
291 | {
292 | _network = DeepBeliefNetwork.Load(openFileDialog2.FileName);
293 | }
294 | }
295 |
296 | static Bitmap ShrinkImage(Bitmap bmp)
297 | {
298 | Bitmap bmp2 = new Bitmap(WIDTH, HEIGHT);
299 | Graphics g = Graphics.FromImage(bmp2);
300 | g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
301 | g.DrawImage(bmp, 0, 0, bmp2.Width, bmp2.Height);
302 | g.Dispose();
303 | return bmp2;
304 | }
305 |
306 | void GetData(out double[][] r_inputs, out double[][] r_outputs, out double[][] test_inputs, out double[][] test_outputs)
307 | {
308 | //ImageToArray conv = new ImageToArray(min: 0, max: 1);
309 |
310 | List inputs = new List();
311 | List outputs = new List();
312 | List t_inputs = new List();
313 | List t_outputs = new List();
314 | List cat_idx = new List();
315 | List short_cats = new List();
316 |
317 | string prefix = PREFIX;
318 | string[] categories = Directory.GetDirectories(prefix);
319 | int min = 10000;
320 | double[] input;
321 | label1.Text = "";
322 | for (int i = 0; i < NUM_CATEGORIES; i++)
323 | {
324 | string c = categories[i];
325 | cat_idx.Add(c);
326 |
327 | string[] split = c.Split('\\');
328 | short_cats.Add(split.Last());
329 | string[] files = Directory.GetFiles(c, "*.jpg");
330 | label1.Text += c + " => " + files.Length + " files.\n";
331 | label1.Refresh();
332 | if (files.Length < min) min = files.Length;
333 |
334 | int added = 0;
335 | foreach (string f in files)
336 | {
337 | Bitmap image = (Bitmap)Bitmap.FromFile(f, true);
338 | if (image.Width < 300 || image.Height < 180) continue;
339 |
340 | // crop the image
341 | image = image.Clone(new Rectangle(0, 0, 300, Math.Min(180,200)), image.PixelFormat);
342 |
343 | // downsample the image to save memory
344 | Bitmap small_image = ShrinkImage(image);
345 | image.Dispose();
346 |
347 | _itoa.Convert(small_image, out input);
348 | small_image.Dispose();
349 |
350 | //Console.WriteLine("Length of input: " + input.Length);
351 |
352 | double[] output = new double[NUM_CATEGORIES];
353 | output[i] = 1;
354 |
355 | added++;
356 |
357 | if (added <= NUM_TRAIN)
358 | {
359 | inputs.Add(input);
360 | outputs.Add(output);
361 | }
362 | else
363 | {
364 | t_inputs.Add(input);
365 | t_outputs.Add(output);
366 | }
367 | if (added >= NUM_EXAMPLES) break;
368 | }
369 | }
370 | label1.Text += "Number of categories: " + categories.Length + " min files: " + min + " number of short cats: " + short_cats.Count();
371 |
372 | listBox1.Items.Clear();
373 | for (int i = 0; i < short_cats.Count; i++)
374 | listBox1.Items.Add(short_cats[i] + ", " + i);
375 |
376 | _categories = short_cats.ToArray();
377 | r_inputs = inputs.ToArray();
378 | r_outputs = outputs.ToArray();
379 | test_inputs = t_inputs.ToArray();
380 | test_outputs = t_outputs.ToArray();
381 | }
382 | }
383 | }
384 |
--------------------------------------------------------------------------------
/ImageClassification/Form1.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 | 157, 17
125 |
126 |
127 | 278, 17
128 |
129 |
130 | 414, 17
131 |
132 |
133 | 54
134 |
135 |
--------------------------------------------------------------------------------
/ImageClassification/ImageClassification.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {5C540CBB-8A89-43A4-9AB9-88BAE54F8BBA}
8 | WinExe
9 | Properties
10 | ImageClassification
11 | ImageClassification
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | False
42 | ..\..\..\..\..\..\..\Program Files (x86)\AForge.NET\Framework\Release\AForge.Imaging.dll
43 |
44 |
45 | False
46 | ..\..\..\..\..\..\..\Program Files (x86)\AForge.NET\Framework\Release\AForge.Neuro.dll
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | Form
62 |
63 |
64 | Form1.cs
65 |
66 |
67 |
68 |
69 | Form1.cs
70 |
71 |
72 | ResXFileCodeGenerator
73 | Resources.Designer.cs
74 | Designer
75 |
76 |
77 | True
78 | Resources.resx
79 |
80 |
81 | SettingsSingleFileGenerator
82 | Settings.Designer.cs
83 |
84 |
85 | True
86 | Settings.settings
87 | True
88 |
89 |
90 |
91 |
92 |
93 |
94 |
101 |
--------------------------------------------------------------------------------
/ImageClassification/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 |
7 | namespace ImageClassification
8 | {
9 | static class Program
10 | {
11 | ///
12 | /// The main entry point for the application.
13 | ///
14 | [STAThread]
15 | static void Main()
16 | {
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new Form1());
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | image-classification-dbn
2 | ========================
3 |
4 | Image classification using a Deep Belief Network with multiple layers of Restricted Boltzmann Machines.
5 |
6 | Written in C# and uses the Accord.NET machine learning library.
7 |
8 | Lazily threw together some code to create a deep net where weights are initialized via unsupervised training in the hidden layers and then trained further using backpropagation.
9 |
10 | The data is included, I used Caltech 101.
11 |
12 | There are a handful of parameters you can configure. Number of epochs you can control through the UI, but the rest, which would affect the architecture of the net, I leave in the code. They are all in one place though (member variables of the main class) so they should be easy to change.
13 |
14 | - Number of categories - I set it to 5 currently, but it can go up to all 101 categories. Will take much longer to train all 101.
15 | - Number of examples - To balance the labels used for training I make it so that you can only use up to 31 samples (the min number of images for a category).
16 | - Number of training samples - Should be something less than total number of examples, so there is something to test on.
17 | - Width and height - By default I downsample the image by 10 in both directions. This sped up training a reasonable amount for development purposes, but you could increase this later given you have the computational power to do so. Also, it would help greatly with reconstructing images later to see what the network has learned.
18 | - Layers - Define the architecture of the network by specifying how many neurons are in each layer. There must be NUM_CATEGORIES in the last layer.
19 |
20 | Performance:
21 | - Despite downsampling the image by 10x10, we still get very good performance. With only 2 categories I consistently achieve a perfect score on the test set. With 5 categories I get > 80% and with 10 categories I get > 66%, which are all significantly better than randomly guessing, which would give 1/N.
22 |
23 | Usage:
24 | - Training: Click the train button.
25 | - Prediction: Click "choose image" to choose a test image (should be approx. 3x2 aspect ratio, and obviously the object should be something similar compared to that seen in the data). Then click the "Classify" button.
26 | - "Get Data" was more for debugging purposes, it just loads up the data and produces the categories in the lower left list box.
27 | - Because training takes so long, I provide you with the "Save DBN" and "Load DBN" buttons to save and load a trained DBN.
28 | - To reconstruct an image given a label, or by activating a particular neuron, enter the neuron index and layer index beside the "reconstruct" button and then click the button. Accord.NET also lets you probabilistically generate inputs given an output, so I included a button for that too. You still have to enter neuron and layer but it only uses the neuron.
29 | - Of course, reconstructing something from a hidden layer there are actually 2^H possible reconstructions where H=number of nodes in the layer. Another thing that could be done is to randomly reconstruct an image for a layer given a random choice of the 2^H activations. This might lead to more meaningful pictures.
30 |
--------------------------------------------------------------------------------