├── README.md └── SqueezeNet_v1.0 ├── deploy.prototxt ├── solver.prototxt ├── squeezenet ├── 1602.07360v2.pdf ├── GenerateMXNET.py ├── calc_accuracy.py ├── generate_data.sh ├── mxnet_predict_example.py ├── symbol_squeezenet.py ├── test_squeezenet.sh ├── train.py ├── train_model.py └── train_squeezenet.sh ├── squeezenet_v1.0.caffemodel └── train_val.prototxt /README.md: -------------------------------------------------------------------------------- 1 | 2 | The Caffe-compatible files that you are probably looking for: 3 | 4 | SqueezeNet_v1.0/train_val.prototxt #model architecture 5 | SqueezeNet_v1.0/solver.prototxt #additional training details (learning rate schedule, etc.) 6 | SqueezeNet_v1.0/squeezenet_v1.0.caffemodel #pretrained model parameters 7 | 8 | If you find SqueezeNet useful in your research, please consider citing the [SqueezeNet paper](http://arxiv.org/abs/1602.07360): 9 | 10 | @article{SqueezeNet, 11 | Author = {Forrest N. Iandola and Matthew W. Moskewicz and Khalid Ashraf and Song Han and William J. Dally and Kurt Keutzer}, 12 | Title = {SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <1MB model size}, 13 | Journal = {arXiv:1602.07360}, 14 | Year = {2016} 15 | } 16 | 17 | 18 | Helpful hints: 19 | 20 | 1. **Getting the SqueezeNet model:** `git clone `. 21 | In this repository, we include Caffe-compatible files for the model architecture, the solver configuration, and the pretrained model (4.8MB uncompressed). 22 | 23 | 2. **Batch size.** For the SqueezeNet model in our paper, we used a batch size of 1024. If implemented naively on a single GPU, this may result in running out of memory. An effective workaround is to use hierarchical batching (sometimes called "delayed batching"). Caffe supports hierarchical batching by doing `train_val.prototxt>batch_size` training samples concurrently in memory. After `solver.prototxt>iter_size` iterations, the gradients are summed and the model is updated. Mathematically, the batch size is `batch_size * iter_size`. In the included prototxt files, we have set `(batch_size=32, iter_size=32)`, but any combination of batch_size and iter_size that multiply to 1024 will produce eqivalent results. In fact, with the same random number generator seed, the model will be fully reproducable if trained multiple times. Finally, note that in Caffe `iter_size` is applied while training on the training set but not while testing on the test set. 24 | 25 | 3. **Implementing Fire modules.** In the paper, we describe the `expand` portion of the Fire layer as a collection of 1x1 and 3x3 filters. Caffe does not natively support a convolution layer that has multiple filter sizes. To work around this, we implement `expand1x1` and `expand3x3` layers and concatenate the results together in the channel dimension. 26 | 27 | -------------------------------------------------------------------------------- /SqueezeNet_v1.0/deploy.prototxt: -------------------------------------------------------------------------------- 1 | name: "SqueezeNet" 2 | input: "data" 3 | input_dim: 1 4 | input_dim: 3 5 | input_dim: 227 6 | input_dim: 227 7 | layer { 8 | name: "conv1" 9 | type: "Convolution" 10 | bottom: "data" 11 | top: "conv1" 12 | convolution_param { 13 | num_output: 96 14 | kernel_size: 7 15 | stride: 2 16 | weight_filler { 17 | type: "xavier" 18 | } 19 | } 20 | } 21 | layer { 22 | name: "relu_conv1" 23 | type: "ReLU" 24 | bottom: "conv1" 25 | top: "conv1" 26 | } 27 | layer { 28 | name: "pool1" 29 | type: "Pooling" 30 | bottom: "conv1" 31 | top: "pool1" 32 | pooling_param { 33 | pool: MAX 34 | kernel_size: 3 35 | stride: 2 36 | } 37 | } 38 | layer { 39 | name: "fire2/squeeze1x1" 40 | type: "Convolution" 41 | bottom: "pool1" 42 | top: "fire2/squeeze1x1" 43 | convolution_param { 44 | num_output: 16 45 | kernel_size: 1 46 | weight_filler { 47 | type: "xavier" 48 | } 49 | } 50 | } 51 | layer { 52 | name: "fire2/relu_squeeze1x1" 53 | type: "ReLU" 54 | bottom: "fire2/squeeze1x1" 55 | top: "fire2/squeeze1x1" 56 | } 57 | layer { 58 | name: "fire2/expand1x1" 59 | type: "Convolution" 60 | bottom: "fire2/squeeze1x1" 61 | top: "fire2/expand1x1" 62 | convolution_param { 63 | num_output: 64 64 | kernel_size: 1 65 | weight_filler { 66 | type: "xavier" 67 | } 68 | } 69 | } 70 | layer { 71 | name: "fire2/relu_expand1x1" 72 | type: "ReLU" 73 | bottom: "fire2/expand1x1" 74 | top: "fire2/expand1x1" 75 | } 76 | layer { 77 | name: "fire2/expand3x3" 78 | type: "Convolution" 79 | bottom: "fire2/squeeze1x1" 80 | top: "fire2/expand3x3" 81 | convolution_param { 82 | num_output: 64 83 | pad: 1 84 | kernel_size: 3 85 | weight_filler { 86 | type: "xavier" 87 | } 88 | } 89 | } 90 | layer { 91 | name: "fire2/relu_expand3x3" 92 | type: "ReLU" 93 | bottom: "fire2/expand3x3" 94 | top: "fire2/expand3x3" 95 | } 96 | layer { 97 | name: "fire2/concat" 98 | type: "Concat" 99 | bottom: "fire2/expand1x1" 100 | bottom: "fire2/expand3x3" 101 | top: "fire2/concat" 102 | } 103 | layer { 104 | name: "fire3/squeeze1x1" 105 | type: "Convolution" 106 | bottom: "fire2/concat" 107 | top: "fire3/squeeze1x1" 108 | convolution_param { 109 | num_output: 16 110 | kernel_size: 1 111 | weight_filler { 112 | type: "xavier" 113 | } 114 | } 115 | } 116 | layer { 117 | name: "fire3/relu_squeeze1x1" 118 | type: "ReLU" 119 | bottom: "fire3/squeeze1x1" 120 | top: "fire3/squeeze1x1" 121 | } 122 | layer { 123 | name: "fire3/expand1x1" 124 | type: "Convolution" 125 | bottom: "fire3/squeeze1x1" 126 | top: "fire3/expand1x1" 127 | convolution_param { 128 | num_output: 64 129 | kernel_size: 1 130 | weight_filler { 131 | type: "xavier" 132 | } 133 | } 134 | } 135 | layer { 136 | name: "fire3/relu_expand1x1" 137 | type: "ReLU" 138 | bottom: "fire3/expand1x1" 139 | top: "fire3/expand1x1" 140 | } 141 | layer { 142 | name: "fire3/expand3x3" 143 | type: "Convolution" 144 | bottom: "fire3/squeeze1x1" 145 | top: "fire3/expand3x3" 146 | convolution_param { 147 | num_output: 64 148 | pad: 1 149 | kernel_size: 3 150 | weight_filler { 151 | type: "xavier" 152 | } 153 | } 154 | } 155 | layer { 156 | name: "fire3/relu_expand3x3" 157 | type: "ReLU" 158 | bottom: "fire3/expand3x3" 159 | top: "fire3/expand3x3" 160 | } 161 | layer { 162 | name: "fire3/concat" 163 | type: "Concat" 164 | bottom: "fire3/expand1x1" 165 | bottom: "fire3/expand3x3" 166 | top: "fire3/concat" 167 | } 168 | layer { 169 | name: "fire4/squeeze1x1" 170 | type: "Convolution" 171 | bottom: "fire3/concat" 172 | top: "fire4/squeeze1x1" 173 | convolution_param { 174 | num_output: 32 175 | kernel_size: 1 176 | weight_filler { 177 | type: "xavier" 178 | } 179 | } 180 | } 181 | layer { 182 | name: "fire4/relu_squeeze1x1" 183 | type: "ReLU" 184 | bottom: "fire4/squeeze1x1" 185 | top: "fire4/squeeze1x1" 186 | } 187 | layer { 188 | name: "fire4/expand1x1" 189 | type: "Convolution" 190 | bottom: "fire4/squeeze1x1" 191 | top: "fire4/expand1x1" 192 | convolution_param { 193 | num_output: 128 194 | kernel_size: 1 195 | weight_filler { 196 | type: "xavier" 197 | } 198 | } 199 | } 200 | layer { 201 | name: "fire4/relu_expand1x1" 202 | type: "ReLU" 203 | bottom: "fire4/expand1x1" 204 | top: "fire4/expand1x1" 205 | } 206 | layer { 207 | name: "fire4/expand3x3" 208 | type: "Convolution" 209 | bottom: "fire4/squeeze1x1" 210 | top: "fire4/expand3x3" 211 | convolution_param { 212 | num_output: 128 213 | pad: 1 214 | kernel_size: 3 215 | weight_filler { 216 | type: "xavier" 217 | } 218 | } 219 | } 220 | layer { 221 | name: "fire4/relu_expand3x3" 222 | type: "ReLU" 223 | bottom: "fire4/expand3x3" 224 | top: "fire4/expand3x3" 225 | } 226 | layer { 227 | name: "fire4/concat" 228 | type: "Concat" 229 | bottom: "fire4/expand1x1" 230 | bottom: "fire4/expand3x3" 231 | top: "fire4/concat" 232 | } 233 | layer { 234 | name: "pool4" 235 | type: "Pooling" 236 | bottom: "fire4/concat" 237 | top: "pool4" 238 | pooling_param { 239 | pool: MAX 240 | kernel_size: 3 241 | stride: 2 242 | } 243 | } 244 | layer { 245 | name: "fire5/squeeze1x1" 246 | type: "Convolution" 247 | bottom: "pool4" 248 | top: "fire5/squeeze1x1" 249 | convolution_param { 250 | num_output: 32 251 | kernel_size: 1 252 | weight_filler { 253 | type: "xavier" 254 | } 255 | } 256 | } 257 | layer { 258 | name: "fire5/relu_squeeze1x1" 259 | type: "ReLU" 260 | bottom: "fire5/squeeze1x1" 261 | top: "fire5/squeeze1x1" 262 | } 263 | layer { 264 | name: "fire5/expand1x1" 265 | type: "Convolution" 266 | bottom: "fire5/squeeze1x1" 267 | top: "fire5/expand1x1" 268 | convolution_param { 269 | num_output: 128 270 | kernel_size: 1 271 | weight_filler { 272 | type: "xavier" 273 | } 274 | } 275 | } 276 | layer { 277 | name: "fire5/relu_expand1x1" 278 | type: "ReLU" 279 | bottom: "fire5/expand1x1" 280 | top: "fire5/expand1x1" 281 | } 282 | layer { 283 | name: "fire5/expand3x3" 284 | type: "Convolution" 285 | bottom: "fire5/squeeze1x1" 286 | top: "fire5/expand3x3" 287 | convolution_param { 288 | num_output: 128 289 | pad: 1 290 | kernel_size: 3 291 | weight_filler { 292 | type: "xavier" 293 | } 294 | } 295 | } 296 | layer { 297 | name: "fire5/relu_expand3x3" 298 | type: "ReLU" 299 | bottom: "fire5/expand3x3" 300 | top: "fire5/expand3x3" 301 | } 302 | layer { 303 | name: "fire5/concat" 304 | type: "Concat" 305 | bottom: "fire5/expand1x1" 306 | bottom: "fire5/expand3x3" 307 | top: "fire5/concat" 308 | } 309 | layer { 310 | name: "fire6/squeeze1x1" 311 | type: "Convolution" 312 | bottom: "fire5/concat" 313 | top: "fire6/squeeze1x1" 314 | convolution_param { 315 | num_output: 48 316 | kernel_size: 1 317 | weight_filler { 318 | type: "xavier" 319 | } 320 | } 321 | } 322 | layer { 323 | name: "fire6/relu_squeeze1x1" 324 | type: "ReLU" 325 | bottom: "fire6/squeeze1x1" 326 | top: "fire6/squeeze1x1" 327 | } 328 | layer { 329 | name: "fire6/expand1x1" 330 | type: "Convolution" 331 | bottom: "fire6/squeeze1x1" 332 | top: "fire6/expand1x1" 333 | convolution_param { 334 | num_output: 192 335 | kernel_size: 1 336 | weight_filler { 337 | type: "xavier" 338 | } 339 | } 340 | } 341 | layer { 342 | name: "fire6/relu_expand1x1" 343 | type: "ReLU" 344 | bottom: "fire6/expand1x1" 345 | top: "fire6/expand1x1" 346 | } 347 | layer { 348 | name: "fire6/expand3x3" 349 | type: "Convolution" 350 | bottom: "fire6/squeeze1x1" 351 | top: "fire6/expand3x3" 352 | convolution_param { 353 | num_output: 192 354 | pad: 1 355 | kernel_size: 3 356 | weight_filler { 357 | type: "xavier" 358 | } 359 | } 360 | } 361 | layer { 362 | name: "fire6/relu_expand3x3" 363 | type: "ReLU" 364 | bottom: "fire6/expand3x3" 365 | top: "fire6/expand3x3" 366 | } 367 | layer { 368 | name: "fire6/concat" 369 | type: "Concat" 370 | bottom: "fire6/expand1x1" 371 | bottom: "fire6/expand3x3" 372 | top: "fire6/concat" 373 | } 374 | layer { 375 | name: "fire7/squeeze1x1" 376 | type: "Convolution" 377 | bottom: "fire6/concat" 378 | top: "fire7/squeeze1x1" 379 | convolution_param { 380 | num_output: 48 381 | kernel_size: 1 382 | weight_filler { 383 | type: "xavier" 384 | } 385 | } 386 | } 387 | layer { 388 | name: "fire7/relu_squeeze1x1" 389 | type: "ReLU" 390 | bottom: "fire7/squeeze1x1" 391 | top: "fire7/squeeze1x1" 392 | } 393 | layer { 394 | name: "fire7/expand1x1" 395 | type: "Convolution" 396 | bottom: "fire7/squeeze1x1" 397 | top: "fire7/expand1x1" 398 | convolution_param { 399 | num_output: 192 400 | kernel_size: 1 401 | weight_filler { 402 | type: "xavier" 403 | } 404 | } 405 | } 406 | layer { 407 | name: "fire7/relu_expand1x1" 408 | type: "ReLU" 409 | bottom: "fire7/expand1x1" 410 | top: "fire7/expand1x1" 411 | } 412 | layer { 413 | name: "fire7/expand3x3" 414 | type: "Convolution" 415 | bottom: "fire7/squeeze1x1" 416 | top: "fire7/expand3x3" 417 | convolution_param { 418 | num_output: 192 419 | pad: 1 420 | kernel_size: 3 421 | weight_filler { 422 | type: "xavier" 423 | } 424 | } 425 | } 426 | layer { 427 | name: "fire7/relu_expand3x3" 428 | type: "ReLU" 429 | bottom: "fire7/expand3x3" 430 | top: "fire7/expand3x3" 431 | } 432 | layer { 433 | name: "fire7/concat" 434 | type: "Concat" 435 | bottom: "fire7/expand1x1" 436 | bottom: "fire7/expand3x3" 437 | top: "fire7/concat" 438 | } 439 | layer { 440 | name: "fire8/squeeze1x1" 441 | type: "Convolution" 442 | bottom: "fire7/concat" 443 | top: "fire8/squeeze1x1" 444 | convolution_param { 445 | num_output: 64 446 | kernel_size: 1 447 | weight_filler { 448 | type: "xavier" 449 | } 450 | } 451 | } 452 | layer { 453 | name: "fire8/relu_squeeze1x1" 454 | type: "ReLU" 455 | bottom: "fire8/squeeze1x1" 456 | top: "fire8/squeeze1x1" 457 | } 458 | layer { 459 | name: "fire8/expand1x1" 460 | type: "Convolution" 461 | bottom: "fire8/squeeze1x1" 462 | top: "fire8/expand1x1" 463 | convolution_param { 464 | num_output: 256 465 | kernel_size: 1 466 | weight_filler { 467 | type: "xavier" 468 | } 469 | } 470 | } 471 | layer { 472 | name: "fire8/relu_expand1x1" 473 | type: "ReLU" 474 | bottom: "fire8/expand1x1" 475 | top: "fire8/expand1x1" 476 | } 477 | layer { 478 | name: "fire8/expand3x3" 479 | type: "Convolution" 480 | bottom: "fire8/squeeze1x1" 481 | top: "fire8/expand3x3" 482 | convolution_param { 483 | num_output: 256 484 | pad: 1 485 | kernel_size: 3 486 | weight_filler { 487 | type: "xavier" 488 | } 489 | } 490 | } 491 | layer { 492 | name: "fire8/relu_expand3x3" 493 | type: "ReLU" 494 | bottom: "fire8/expand3x3" 495 | top: "fire8/expand3x3" 496 | } 497 | layer { 498 | name: "fire8/concat" 499 | type: "Concat" 500 | bottom: "fire8/expand1x1" 501 | bottom: "fire8/expand3x3" 502 | top: "fire8/concat" 503 | } 504 | layer { 505 | name: "pool8" 506 | type: "Pooling" 507 | bottom: "fire8/concat" 508 | top: "pool8" 509 | pooling_param { 510 | pool: MAX 511 | kernel_size: 3 512 | stride: 2 513 | } 514 | } 515 | layer { 516 | name: "fire9/squeeze1x1" 517 | type: "Convolution" 518 | bottom: "pool8" 519 | top: "fire9/squeeze1x1" 520 | convolution_param { 521 | num_output: 64 522 | kernel_size: 1 523 | weight_filler { 524 | type: "xavier" 525 | } 526 | } 527 | } 528 | layer { 529 | name: "fire9/relu_squeeze1x1" 530 | type: "ReLU" 531 | bottom: "fire9/squeeze1x1" 532 | top: "fire9/squeeze1x1" 533 | } 534 | layer { 535 | name: "fire9/expand1x1" 536 | type: "Convolution" 537 | bottom: "fire9/squeeze1x1" 538 | top: "fire9/expand1x1" 539 | convolution_param { 540 | num_output: 256 541 | kernel_size: 1 542 | weight_filler { 543 | type: "xavier" 544 | } 545 | } 546 | } 547 | layer { 548 | name: "fire9/relu_expand1x1" 549 | type: "ReLU" 550 | bottom: "fire9/expand1x1" 551 | top: "fire9/expand1x1" 552 | } 553 | layer { 554 | name: "fire9/expand3x3" 555 | type: "Convolution" 556 | bottom: "fire9/squeeze1x1" 557 | top: "fire9/expand3x3" 558 | convolution_param { 559 | num_output: 256 560 | pad: 1 561 | kernel_size: 3 562 | weight_filler { 563 | type: "xavier" 564 | } 565 | } 566 | } 567 | layer { 568 | name: "fire9/relu_expand3x3" 569 | type: "ReLU" 570 | bottom: "fire9/expand3x3" 571 | top: "fire9/expand3x3" 572 | } 573 | layer { 574 | name: "fire9/concat" 575 | type: "Concat" 576 | bottom: "fire9/expand1x1" 577 | bottom: "fire9/expand3x3" 578 | top: "fire9/concat" 579 | } 580 | layer { 581 | name: "drop9" 582 | type: "Dropout" 583 | bottom: "fire9/concat" 584 | top: "fire9/concat" 585 | dropout_param { 586 | dropout_ratio: 0.5 587 | } 588 | } 589 | layer { 590 | name: "conv10" 591 | type: "Convolution" 592 | bottom: "fire9/concat" 593 | top: "conv10" 594 | convolution_param { 595 | num_output: 1000 596 | pad: 1 597 | kernel_size: 1 598 | weight_filler { 599 | type: "gaussian" 600 | mean: 0.0 601 | std: 0.01 602 | } 603 | } 604 | } 605 | layer { 606 | name: "relu_conv10" 607 | type: "ReLU" 608 | bottom: "conv10" 609 | top: "conv10" 610 | } 611 | layer { 612 | name: "pool10" 613 | type: "Pooling" 614 | bottom: "conv10" 615 | top: "pool10" 616 | pooling_param { 617 | pool: AVE 618 | global_pooling: true 619 | } 620 | } 621 | 622 | layer { 623 | bottom: "pool10" 624 | top: "prob" 625 | name: "prob" 626 | type: "Softmax" 627 | } 628 | 629 | -------------------------------------------------------------------------------- /SqueezeNet_v1.0/solver.prototxt: -------------------------------------------------------------------------------- 1 | # please cite: 2 | # @article{SqueezeNet, 3 | # Author = {Forrest N. Iandola and Matthew W. Moskewicz and Khalid Ashraf and Song Han and William J. Dally and Kurt Keutzer}, 4 | # Title = {SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <1MB model size}, 5 | # Journal = {arXiv:1602.07360}, 6 | # Year = {2016} 7 | # } 8 | 9 | test_iter: 2000 #not subject to iter_size 10 | test_interval: 1000 11 | base_lr: 0.08 12 | display: 40 13 | max_iter: 85000 14 | iter_size: 32 #global batch size = batch_size * iter_size 15 | lr_policy: "poly" 16 | power: 0.5 17 | momentum: 0.9 18 | weight_decay: 0.0002 19 | snapshot: 1000 20 | snapshot_prefix: "train" 21 | solver_mode: GPU 22 | random_seed: 42 23 | net: "train_val.prototxt" #we typically do `cd SqueezeNet_v1.0; caffe train ` 24 | test_initialization: false 25 | average_loss: 40 26 | -------------------------------------------------------------------------------- /SqueezeNet_v1.0/squeezenet/1602.07360v2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hariag/SqueezeNet/3ae4e4f38dfba19460346f99ebce37e7be288569/SqueezeNet_v1.0/squeezenet/1602.07360v2.pdf -------------------------------------------------------------------------------- /SqueezeNet_v1.0/squeezenet/GenerateMXNET.py: -------------------------------------------------------------------------------- 1 | #! /bin/python 2 | import os, sys, time 3 | import random 4 | import shutil 5 | 6 | def CheckPathOrFail(path, isFile=True): 7 | if os.path.exists(path): 8 | if isFile: 9 | if os.path.isfile(path): 10 | return True 11 | else: 12 | print("path %s not a valid file, exit"%path) 13 | exit(1) 14 | if not isFile: 15 | if os.path.isdir(path): 16 | return True 17 | else: 18 | print("path %s not a valid folder, exit"%path) 19 | exit(1) 20 | 21 | def getTimestampStr(): 22 | return str(int(time.time())) 23 | 24 | def CreateImageTree(dataPath, dataFilePath): 25 | os.system("tree -i -f %s |grep \".jpg\|.png\|.bmp\" > %s"%(dataPath, dataFilePath)) 26 | 27 | def GetImageListFromFile(fileName): 28 | f=open(fileName,"rb") 29 | lines = [line.strip() for line in f.readlines()] 30 | return lines 31 | 32 | def GetClassNameFromImageList(imageList, dataPath): 33 | classList=[] 34 | for image in imageList: 35 | className=image.replace(dataPath,"").split("/")[3] 36 | classList.append(className) 37 | return list(set(classList)) 38 | 39 | def SplitImageFileListIntoTrainAndVal(imageFileList, classNameList, ratio=0.8, countFilter=0, limits=None): 40 | trainSet=[] 41 | valSet=[] 42 | labelSet=[] 43 | labelId = 0 44 | index =0 45 | for className in classNameList: 46 | searchKey="/"+className+"/" 47 | currentClassList =[] 48 | for image in imageFileList: 49 | if image.find(searchKey)>=0: 50 | currentClassList.append(image) 51 | if len(currentClassList)4: 111 | shape = int(sys.argv[4]) 112 | if len(sys.argv) >5: 113 | ratio = float(sys.argv[5]) 114 | if len(sys.argv) >6: 115 | countFilter = int(sys.argv[6]) 116 | if len(sys.argv) >7: 117 | limits = int(sys.argv[7]) 118 | ################################################################## 119 | 120 | dataFilePath = "./data.txt" 121 | labelsFilePath = "./labels.txt" 122 | trainFilePath = "./train.txt" 123 | valFilePath = "./val.txt" 124 | 125 | CreateImageTree(dataPath, dataFilePath) 126 | imageFileList = GetImageListFromFile(dataFilePath) 127 | # remove dataPath in beginning 128 | imageFileList = [image.replace(os.path.abspath(dataPath),"") for image in imageFileList] 129 | classNameList = GetClassNameFromImageList(imageFileList, dataPath) 130 | trainSet, valSet, labelSet = SplitImageFileListIntoTrainAndVal(imageFileList, classNameList, ratio, countFilter, limits) 131 | random.shuffle (trainSet) 132 | WriteDownToFile(trainSet, trainFilePath) 133 | WriteDownToFile(valSet, valFilePath) 134 | WriteDownToFile(labelSet, labelsFilePath) 135 | 136 | 137 | ################################################################## 138 | im2rec = os.path.join(MXNETHome, "bin/im2rec") 139 | command = "%s %s %s %s resize=%s"%(im2rec, trainFilePath, dataPath, trainPath, shape) 140 | print command 141 | os.system(command) 142 | 143 | command = "%s %s %s %s resize=%s"%(im2rec, valFilePath, dataPath, valPath, shape) 144 | print command 145 | os.system(command) 146 | 147 | end = time.time() 148 | print ("Time Elapsed: %.3fs."%(end-start)) 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /SqueezeNet_v1.0/squeezenet/calc_accuracy.py: -------------------------------------------------------------------------------- 1 | import os, sys, time 2 | 3 | lines = [line.strip() for line in open(sys.argv[1],"r").readlines()] 4 | correct=0 5 | for line in lines: 6 | truth=line.split("/")[6] 7 | predict=line.split(" ")[3] 8 | if truth==predict: 9 | correct+=1 10 | print "accuracy=%s"%(float(correct)/len(lines)) 11 | -------------------------------------------------------------------------------- /SqueezeNet_v1.0/squeezenet/generate_data.sh: -------------------------------------------------------------------------------- 1 | python GenerateMXNET.py /media/haria/data/data/vgg_face/ train.rec test.rec 227 0.8 2 | -------------------------------------------------------------------------------- /SqueezeNet_v1.0/squeezenet/mxnet_predict_example.py: -------------------------------------------------------------------------------- 1 | import sys, os, time 2 | import subprocess 3 | import threading 4 | curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) 5 | sys.path.append("~/mxnet/amalgamation/python/") 6 | sys.path.append("~/mxnet/python/") 7 | 8 | from mxnet_predict import Predictor, load_ndarray_file 9 | import mxnet as mx 10 | import logging 11 | import numpy as np 12 | from skimage import io, transform 13 | # Load the pre-trained model 14 | prefix = "./face-0" 15 | num_round = 125 16 | batch_size = 20 17 | if len(sys.argv) >2: 18 | num_round = int(sys.argv[2]) 19 | symbol_file = "%s-symbol.json" % prefix 20 | param_file = "%s-%s.params" % (prefix,str(num_round).zfill(4)) 21 | predictor = Predictor(open(symbol_file).read(), open(param_file).read(), {'data':(batch_size , 3, 224, 224)},'gpu',0) 22 | mean_img = load_ndarray_file(open("./mean.bin").read())["mean_img"] 23 | 24 | synset = [l.strip() for l in open('./labels.txt').readlines()] 25 | 26 | def PreprocessImage(batchs, index, path, show_img=False): 27 | # load image 28 | img = io.imread(path) 29 | #print("Original Image Shape: ", img.shape) 30 | # we crop image from center 31 | short_egde = min(img.shape[:2]) 32 | yy = int((img.shape[0] - short_egde) / 2) 33 | xx = int((img.shape[1] - short_egde) / 2) 34 | crop_img = img[yy : yy + short_egde, xx : xx + short_egde] 35 | # resize to 224, 224 36 | resized_img = transform.resize(crop_img, (224, 224)) 37 | if show_img: 38 | io.imshow(resized_img) 39 | # convert to numpy.ndarray 40 | sample = np.asarray(resized_img) * 255 41 | # swap axes to make image from (224, 224, 3) to (3, 224, 224) 42 | sample = np.swapaxes(sample, 0, 2) 43 | sample = np.swapaxes(sample, 1, 2) 44 | 45 | # sub mean 46 | normed_img = sample - mean_img 47 | normed_img.resize(1, 3, 224, 224) 48 | 49 | batchs[index] = normed_img 50 | 51 | 52 | if __name__=="__main__": 53 | imageList=[] 54 | if len(sys.argv) >1: 55 | folder=sys.argv[1] 56 | if os.path.isdir(folder): 57 | items= subprocess.check_output("tree -i -f %s|grep \.jpg"%folder,shell=True).strip().split("\n") 58 | imageList.extend(items) 59 | else: 60 | if os.path.exists(folder): 61 | # its a image actually 62 | imageList.append(folder) 63 | 64 | iters = len(imageList)/batch_size 65 | if len(imageList)%batch_size >0: 66 | iters+=1 67 | for it in range(iters): 68 | 69 | # Get preprocessed batch (single image batch) 70 | batchs=np.ndarray(shape=[batch_size , 3, 224, 224]) 71 | threads = [] 72 | 73 | for index in range(batch_size): 74 | if it*batch_size+index