├── .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 | --------------------------------------------------------------------------------