├── requirements.txt ├── caffe ├── modeldef │ ├── labels.txt │ ├── mean.binaryproto │ ├── AlexNet │ │ ├── solver.prototxt │ │ ├── solver_without_BN.prototxt │ │ └── deploy.prototxt │ ├── GoogleNet │ │ └── solver.prototxt │ ├── ShuffleNet │ │ └── solver.prototxt │ ├── SqueezeNet │ │ └── solver.prototxt │ ├── VGG16 │ │ └── solver.prototxt │ ├── VGG19 │ │ └── solver.prototxt │ ├── MobileNet │ │ └── solver.prototxt │ ├── ResNet50 │ │ └── solver.prototxt │ ├── ResNet101 │ │ └── solver.prototxt │ ├── MnasNet │ │ ├── solver.prototxt │ │ └── train.log.test │ ├── BN-GoogleNet │ │ └── solver.prototxt │ └── readme.md ├── test_acc.png ├── train_loss.png ├── evaluation.sh ├── train.bat ├── plot.sh ├── solver.prototxt ├── clean.bat ├── classification.bat ├── train.sh ├── train.log.test ├── cpp │ ├── LenetClassifier.h │ ├── LenetClassifier.cpp │ └── evaluation.cpp ├── oneclick.sh ├── oneclick.bat ├── util │ ├── plotlog.py │ └── preprocess.py ├── caffe.pyproj ├── cpp4caffe │ └── evaluation.cpp ├── convert2lmdb.py ├── train.log.train └── train.py ├── tensorflow ├── labels.txt ├── categories.txt ├── rose.jpg ├── convert.sh ├── build.sh ├── ncs.sh ├── convertdataset.py ├── run_ncs.py ├── tf.pyproj ├── train.sh └── train_layers.py ├── web ├── .gitignore ├── uploads │ └── README.md ├── requirements.txt ├── Dockerfile ├── templates │ ├── index.html │ └── base.html ├── static │ ├── css │ │ └── main.css │ └── js │ │ └── main.js ├── app.py └── README.md ├── pytorch ├── datasets │ ├── __init__.py │ └── dogcat.py ├── train.sh ├── utils │ ├── __init__.py │ ├── config.py │ ├── focalloss.py │ ├── util.py │ └── visualize.py ├── requirements.txt ├── .gitignore ├── build.sh ├── models │ ├── __init__.py │ ├── resnet.py │ ├── ShuffleNet.py │ ├── squeezenet.py │ ├── mnasnet.py │ ├── alexnet.py │ ├── mrnet.py │ ├── MobileNetV2.py │ └── se_resnext.py ├── README.md ├── CMakeLists.txt ├── cpp │ └── example.cpp ├── demo.py ├── test.py └── train.py ├── Keras ├── model.png ├── keras.pyproj ├── filtererrors.py ├── keras2tf.py └── train.py ├── paddle ├── utils │ ├── .DS_Store │ ├── __init__.py │ ├── dist_utils.py │ └── train.py ├── run.sh ├── models │ ├── __init__.py │ ├── vgg.py │ ├── darknet.py │ ├── model_libs.py │ ├── squeezenet.py │ ├── fast_imagenet.py │ ├── resnext101_wsl.py │ ├── alexnet.py │ └── resnet_vc.py └── build_model.py ├── .gitignore ├── Kaggle.sln └── README.md /requirements.txt: -------------------------------------------------------------------------------- 1 | paddlepaddle -------------------------------------------------------------------------------- /caffe/modeldef/labels.txt: -------------------------------------------------------------------------------- 1 | 0 cat 2 | 1 dog -------------------------------------------------------------------------------- /tensorflow/labels.txt: -------------------------------------------------------------------------------- 1 | 0:cat 2 | 1:dog 3 | -------------------------------------------------------------------------------- /tensorflow/categories.txt: -------------------------------------------------------------------------------- 1 | 0:cat 2 | 1:dog 3 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | data/ 2 | uploads/*.png 3 | models/*.h5 -------------------------------------------------------------------------------- /pytorch/datasets/__init__.py: -------------------------------------------------------------------------------- 1 | from .dogcat import DogCat -------------------------------------------------------------------------------- /pytorch/train.sh: -------------------------------------------------------------------------------- 1 | python3 train.py --num_workers=$(nproc) -------------------------------------------------------------------------------- /pytorch/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .visualize import Visualizer -------------------------------------------------------------------------------- /Keras/model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UPCCV/cat-vs-dog/HEAD/Keras/model.png -------------------------------------------------------------------------------- /caffe/test_acc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UPCCV/cat-vs-dog/HEAD/caffe/test_acc.png -------------------------------------------------------------------------------- /pytorch/requirements.txt: -------------------------------------------------------------------------------- 1 | torch 2 | torchvision 3 | torchnet 4 | torchsummary 5 | tqdm -------------------------------------------------------------------------------- /caffe/train_loss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UPCCV/cat-vs-dog/HEAD/caffe/train_loss.png -------------------------------------------------------------------------------- /tensorflow/rose.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UPCCV/cat-vs-dog/HEAD/tensorflow/rose.jpg -------------------------------------------------------------------------------- /web/uploads/README.md: -------------------------------------------------------------------------------- 1 | The image uploaded by the user will be stored here for classification. -------------------------------------------------------------------------------- /paddle/utils/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UPCCV/cat-vs-dog/HEAD/paddle/utils/.DS_Store -------------------------------------------------------------------------------- /web/requirements.txt: -------------------------------------------------------------------------------- 1 | Werkzeug 2 | Flask 3 | numpy 4 | Keras 5 | gevent 6 | pillow 7 | h5py 8 | tensorflow -------------------------------------------------------------------------------- /pytorch/.gitignore: -------------------------------------------------------------------------------- 1 | log 2 | logs 3 | data 4 | checkpoints 5 | output 6 | *.pyc 7 | config.ini 8 | job.sh 9 | run.sh -------------------------------------------------------------------------------- /caffe/modeldef/mean.binaryproto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UPCCV/cat-vs-dog/HEAD/caffe/modeldef/mean.binaryproto -------------------------------------------------------------------------------- /caffe/evaluation.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | EVAL_ITER=1000 4 | cd util 5 | python "evaluation.py" --iter=$EVAL_ITER 6 | cd .. -------------------------------------------------------------------------------- /caffe/train.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set CAFFE_DIR=D:/CNN/caffe 3 | "%CAFFE_DIR%/build/tools/caffe" train --solver="solver.prototxt" 4 | pause -------------------------------------------------------------------------------- /pytorch/build.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | if [ ! -d build ] ; then 3 | mkdir build 4 | fi 5 | cd build 6 | cmake -DCMAKE_PREFIX_PATH=~/CNN/libtorch .. 7 | make -j4 8 | ./example-app ../data/5.jpg -------------------------------------------------------------------------------- /tensorflow/convert.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cd ~/models/research/slim 3 | DATA_DIR=/media/yanyu/1882684582682A08/CNN/Kaggle/data 4 | python download_and_convert_data.py --dataset_name=catdogs --dataset_dir="${DATA_DIR}" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/* 2 | .vscode/ 3 | data/ 4 | bak 5 | caffe/lmdb 6 | caffe/trainedmodels 7 | web/uploads/*.jpg 8 | Keras/logs/* 9 | Keras/errors/* 10 | tensorflow/graph 11 | tensorflow/models/ 12 | *.h5 13 | *.npy 14 | *.pyc 15 | *.caffemodel -------------------------------------------------------------------------------- /caffe/plot.sh: -------------------------------------------------------------------------------- 1 | caffe_dir=~/CNN/caffe 2 | python ${caffe_dir}/tools/extra/parse_log.py train.log ./ 3 | python ${caffe_dir}/tools/extra/plot_training_log.py 0 test_acc.png train.log 4 | python ${caffe_dir}/tools/extra/plot_training_log.py 6 train_loss.png train.log -------------------------------------------------------------------------------- /pytorch/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .alexnet import AlexNet 2 | from .resnet import ResNet 3 | from .squeezenet import SqueezeNet 4 | from .mnasnet import MnasNet 5 | from .mrnet import MRNet 6 | from .MobileNetV2 import mobilenetv2_19 7 | from .se_resnext import * 8 | from .ShuffleNet import * -------------------------------------------------------------------------------- /caffe/modeldef/AlexNet/solver.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/AlexNet/train_val.prototxt" 2 | test_iter: 25 3 | test_interval: 1000 4 | base_lr: 0.01 5 | lr_policy: "poly" 6 | display: 100 7 | max_iter: 100000 8 | power: 1 9 | momentum: 0.9 10 | weight_decay: 0.0005 11 | snapshot: 10000 12 | snapshot_prefix: "trainedmodels/AlexNet" 13 | solver_mode: GPU 14 | -------------------------------------------------------------------------------- /caffe/modeldef/GoogleNet/solver.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/GoogleNet/train_val_img.prototxt" 2 | test_iter: 250 3 | test_interval: 500 4 | display: 100 5 | base_lr: 0.001 6 | lr_policy: "step" 7 | stepsize: 10000 8 | gamma: 0.1 9 | momentum: 0.9 10 | weight_decay: 1e-05 11 | max_iter: 40000 12 | snapshot: 10000 13 | snapshot_prefix: "trainedmodels/GoogelNet" 14 | solver_mode: GPU -------------------------------------------------------------------------------- /caffe/modeldef/ShuffleNet/solver.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/ShuffleNet/train_val.prototxt" 2 | test_iter: 100 3 | test_interval: 500 4 | display: 100 5 | base_lr: 0.01 6 | lr_policy: "poly" 7 | power: 1.0 8 | max_iter: 100000 9 | momentum: 0.9 10 | weight_decay: 0.0001 11 | snapshot: 10000 12 | snapshot_prefix: "trainedmodels/shuffluenet" 13 | solver_mode: GPU 14 | iter_size: 4 -------------------------------------------------------------------------------- /caffe/modeldef/AlexNet/solver_without_BN.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/AlexNet/train_val_BN.prototxt" 2 | test_iter: 25 3 | test_interval: 500 4 | base_lr: 0.0001 5 | lr_policy: "step" 6 | gamma: 0.1 7 | stepsize: 4000 8 | display: 100 9 | max_iter: 10000 10 | momentum: 0.9 11 | weight_decay: 0.0005 12 | snapshot: 1000 13 | snapshot_prefix: "trainedmodels/AlexNet" 14 | solver_mode: GPU -------------------------------------------------------------------------------- /caffe/modeldef/SqueezeNet/solver.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/SqueezeNet/train_val.prototxt" 2 | test_iter: 79 3 | test_interval: 313 4 | base_lr: 0.005 5 | display: 39 6 | max_iter: 9390 7 | lr_policy: "poly" 8 | power: 1.0 9 | momentum: 0.9 10 | weight_decay: 5e-05 11 | snapshot: 313 12 | solver_mode: GPU 13 | solver_type: SGD 14 | iter_size: 4 15 | snapshot_prefix: "trainedmodels/SqueezeNet" -------------------------------------------------------------------------------- /caffe/modeldef/VGG16/solver.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/VGG16/train_val.prototxt" 2 | 3 | test_iter: 209 4 | test_interval: 500 5 | momentum: 0.9 6 | weight_decay: 0.0005 7 | base_lr: 0.001 8 | lr_policy: "step" 9 | gamma: 0.1 10 | stepsize: 10000 11 | max_iter: 40000 12 | display: 100 13 | snapshot: 5000 14 | solver_mode: GPU 15 | snapshot_prefix: "trainedmodels/VGG16" 16 | 17 | iter_size: 8 -------------------------------------------------------------------------------- /caffe/modeldef/VGG19/solver.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/VGG19/train_val.prototxt" 2 | 3 | test_iter: 250 4 | test_interval: 500 5 | momentum: 0.9 6 | weight_decay: 0.0001 7 | base_lr: 0.001 8 | lr_policy: "step" 9 | gamma: 0.1 10 | stepsize: 10000 11 | max_iter: 40000 12 | display: 100 13 | snapshot: 10000 14 | solver_mode: GPU 15 | snapshot_prefix: "trainedmodels/VGG19" 16 | 17 | iter_size: 8 -------------------------------------------------------------------------------- /caffe/modeldef/MobileNet/solver.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/MobileNet/train_val.prototxt" 2 | #test_initialization: false 3 | test_iter: 100 4 | test_interval: 500 5 | display: 100 6 | #average_loss: 20 7 | base_lr: 0.1 8 | lr_policy: "poly" 9 | power: 1.0 10 | max_iter: 50000 11 | momentum: 0.9 12 | weight_decay: 0.0001 13 | snapshot: 5000 14 | solver_mode: GPU 15 | snapshot_prefix: "trainedmodels/MobileNet" -------------------------------------------------------------------------------- /caffe/solver.prototxt: -------------------------------------------------------------------------------- 1 | train_net: "train.prototxt" 2 | test_net: "val.prototxt" 3 | test_iter: 156 4 | test_interval: 10000 5 | base_lr: 0.009999999776482582 6 | display: 100 7 | max_iter: 500000 8 | lr_policy: "poly" 9 | gamma: 0.8999999761581421 10 | power: 1.0 11 | momentum: 0.8999999761581421 12 | weight_decay: 0.0005000000237487257 13 | stepsize: 50000 14 | snapshot: 10000 15 | snapshot_prefix: "trainedmodels/" 16 | solver_mode: GPU 17 | -------------------------------------------------------------------------------- /caffe/clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set dirs2del="./,cpp4caffe" 3 | :DEL_LOOP 4 | for /f "Tokens=1,* Delims=," %%a in (%dirs2del%) do ( 5 | echo clearing %%a 6 | if exist "%%a\x64" rd "%%a\x64" /s /q 7 | if exist "%%a\Release" rd "%%a\Release" /s /q 8 | if exist "%%a\Debug" rd "%%a\Debug" /s /q 9 | if exist "%%a\*.exp" del "%%a\*.exp" /f /s /q 10 | if exist "%%a\*.pdb" del "%%a\*.pdb" /f /s /q 11 | set dirs2del="%%b" 12 | goto DEL_LOOP 13 | ) 14 | pause -------------------------------------------------------------------------------- /caffe/modeldef/ResNet50/solver.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/ResNet50/train_val.prototxt" 2 | iter_size: 4 3 | test_iter: 5000 4 | test_interval: 1000 5 | test_initialization: false 6 | display: 100 7 | base_lr: 0.01 8 | lr_policy: "multistep" 9 | stepvalue: 10000 10 | stepvalue: 20000 11 | gamma: 0.1 12 | max_iter: 40000 13 | momentum: 0.9 14 | weight_decay: 0.0001 15 | snapshot: 10000 16 | snapshot_prefix: "trainedmodels/ResNet50" 17 | solver_mode: GPU -------------------------------------------------------------------------------- /caffe/modeldef/ResNet101/solver.prototxt: -------------------------------------------------------------------------------- 1 | net: "modeldef/ResNet101/train_val.prototxt" 2 | test_iter: 625 3 | test_interval: 1000 4 | #test_initialization: true 5 | display: 100 6 | #average_loss: 3000 7 | base_lr: 0.01 8 | lr_policy: "step" 9 | iter_size: 8 10 | stepsize: 10000 11 | gamma: 0.1 12 | max_iter: 40000 13 | momentum: 0.9 14 | weight_decay: 0.0001 15 | snapshot: 10000 16 | snapshot_prefix: "trainedmodels/ResNet101" 17 | solver_mode: GPU 18 | -------------------------------------------------------------------------------- /tensorflow/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd ~/CNN/tensorflow 4 | bazel build tensorflow/examples/label_image/... 5 | 6 | cd ~/models 7 | bazel build tensorflow/python/tools:freeze_graph 8 | bazel build tensorflow/tools/graph_transforms:summarize_graph 9 | bazel build tensorflow/tools/graph_transforms:transform_graph 10 | bazel build tensorflow/tools/quantization:quantize_graph 11 | bazel build tensorflow/contrib/util:convert_graphdef_memmapped_format -------------------------------------------------------------------------------- /web/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | # Install Python. 4 | RUN \ 5 | apt-get update && \ 6 | apt-get install -y python python-dev python-pip python-virtualenv && \ 7 | rm -rf /var/lib/apt/lists/* 8 | 9 | WORKDIR app 10 | 11 | # reqs from file, to speed up dev iteration 12 | RUN pip install Werkzeug Flask numpy Keras gevent pillow h5py tensorflow 13 | 14 | COPY . . 15 | 16 | RUN pip install -r requirements.txt 17 | 18 | ENTRYPOINT [ "python" , "app.py"] -------------------------------------------------------------------------------- /caffe/classification.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set CAFFE_DIR=.. 3 | set eval_iter=10000 4 | set DATA="D:/OCR/traffic-sign" 5 | set imagepath=%DATA%/test/00000/00017_00000.png 6 | set trainedmodel=trainedmodels/lenet_iter_%eval_iter%.caffemodel 7 | ::set trainedmodel=platere996.caffemodel 8 | echo %imagepath% %eval_iter% 9 | "%CAFFE_DIR%/build/examples/cpp_classification/classification" "modeldef/deploy.prototxt" "%trainedmodel%" "modeldef/mean.binaryproto" "modeldef/labels.txt" "%imagepath%" 10 | 11 | pause -------------------------------------------------------------------------------- /caffe/modeldef/MnasNet/solver.prototxt: -------------------------------------------------------------------------------- 1 | train_net: "modeldef/MnasNet/train.prototxt" 2 | test_net: "modeldef/MnasNet/test.prototxt" 3 | test_iter: 25 4 | test_interval: 500 5 | base_lr: 0.01 6 | display: 100 7 | max_iter: 64000 8 | lr_policy: "multistep" 9 | gamma: 0.1 10 | momentum: 0.9 11 | weight_decay: 0.0005 12 | stepsize: 20000 13 | snapshot: 1000 14 | snapshot_prefix:"trainedmodels/MnasNet" 15 | solver_mode: GPU 16 | random_seed: 831486 17 | stepvalue: 32000 18 | stepvalue: 48000 19 | stepvalue: 60000 20 | iter_size: 8 21 | type: "Nesterov" 22 | -------------------------------------------------------------------------------- /caffe/train.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | RESUME=0 4 | TOOLS=~/CNN/caffe/build/tools 5 | MODEL=AlexNet 6 | 7 | #compute mean 8 | if [ ! -f "modeldef/mean.binaryproto" ]; then 9 | $TOOLS/compute_image_mean lmdb/train_lmdb modeldef/mean.binaryproto 10 | fi 11 | 12 | if [ $RESUME -eq 1 ]; then 13 | echo "Resume from $resumemodel" 14 | $TOOLS/caffe train --solver=modeldef/${MODEL}/solver.prototxt --weights="$resumemodel" 2>&1 | tee train.log 15 | else 16 | echo "Start Training" 17 | $TOOLS/caffe train --solver=modeldef/${MODEL}/solver.prototxt 2>&1 | tee train.log 18 | fi 19 | echo "Training Done" -------------------------------------------------------------------------------- /caffe/train.log.test: -------------------------------------------------------------------------------- 1 | #Iters Seconds TestAccuracy TestLoss 2 | 0 0.013903 0 0.693129 3 | 1000 4132.983190 0.993 0.0160433 4 | 2000 8142.512269 0.9928 0.0168141 5 | 3000 12155.322233 0.993 0.020271 6 | 4000 16174.269980 0.9934 0.0230172 7 | 5000 20195.494127 0.9938 0.0239159 8 | 6000 24218.831902 0.9932 0.0242739 9 | 7000 28240.889021 0.9936 0.0226499 10 | 8000 32265.638428 0.9936 0.0241045 11 | 9000 36289.293120 0.9934 0.0234792 12 | 10000 40316.188819 0.9936 0.0257581 13 | 11000 44341.659358 0.9936 0.0270077 14 | 12000 48366.411736 0.9936 0.0255049 15 | -------------------------------------------------------------------------------- /pytorch/README.md: -------------------------------------------------------------------------------- 1 | # PyTorch 实践指南 2 | 3 | 本文是文章[PyTorch实践指南](https://zhuanlan.zhihu.com/p/29024978)配套代码,请参照[知乎专栏原文](https://zhuanlan.zhihu.com/p/29024978)或者[对应的markdown文件](PyTorch实战指南.md)更好的了解而文件组织和代码细节, 本项目增加了配置文件,日志功能以及断点续训的能力. 4 | 5 | ## 数据下载 6 | - 从[kaggle比赛官网](https://www.kaggle.com/c/dogs-vs-cats/data) 下载所需的数据;或者直接从此下载[训练集](http://pytorch-1252820389.file.myqcloud.com/data/dogcat/train.zip)和[测试集](http://pytorch-1252820389.file.myqcloud.com/data/dogcat/test1.zip) 7 | - 解压并把训练集和测试集分别放在一个文件夹中 8 | 9 | ## 安装 10 | - PyTorch : 可按照[PyTorch官网](http://pytorch.org)的指南,根据自己的平台安装指定的版本 11 | - 安装指定依赖: 12 | 13 | ``` 14 | pip3 install -r requirements.txt 15 | ``` 16 | 17 | ## 训练 18 | 19 | ``` 20 | ./train.sh 21 | ``` 22 | 23 | ## 测试 24 | 25 | ``` 26 | python3 test.py 27 | ``` -------------------------------------------------------------------------------- /pytorch/models/resnet.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from torch import nn 3 | import torchvision.models as models 4 | 5 | class ResNet(nn.Module): 6 | def __init__(self,num_classes=2): 7 | super(ResNet,self).__init__() 8 | self.model_name = "ResNet" 9 | model = models.resnet50(pretrained=True) 10 | for param in model.parameters(): 11 | param.requires_grad = False 12 | model.fc = nn.Linear(model.fc.in_features,num_classes) 13 | self.model = model 14 | 15 | def forward(self,x): 16 | return self.model(x) 17 | 18 | if __name__=="__main__": 19 | net = ResNet() 20 | device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") 21 | net.to(device) 22 | from torchsummary import summary 23 | print(summary(net,(3,224,224))) -------------------------------------------------------------------------------- /pytorch/models/ShuffleNet.py: -------------------------------------------------------------------------------- 1 | from torch import nn 2 | import torchvision.models as models 3 | import torch 4 | 5 | class ShuffleNet(nn.Module): 6 | def __init__(self,num_classes=2): 7 | super(ShuffleNet,self).__init__() 8 | self.model_name = "ShuffleNet" 9 | model = models.shufflenet_v2_x0_5(pretrained=True) 10 | for param in model.parameters(): 11 | param.requires_grad = False 12 | model.fc = nn.Linear(model.fc.in_features,num_classes) 13 | self.model = model 14 | def forward(self,x): 15 | return self.model(x) 16 | 17 | if __name__=="__main__": 18 | net = ShuffleNet() 19 | device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") 20 | net.to(device) 21 | from torchsummary import summary 22 | print(summary(net,(3,224,224))) -------------------------------------------------------------------------------- /pytorch/models/squeezenet.py: -------------------------------------------------------------------------------- 1 | from torch import nn 2 | import torchvision.models as models 3 | import torch 4 | 5 | class SqueezeNet(nn.Module): 6 | def __init__(self,num_classes=2): 7 | super(SqueezeNet,self).__init__() 8 | self.model_name = "SqueezeNet" 9 | model = models.squeezenet1_0(pretrained=True) 10 | for param in model.parameters(): 11 | param.requires_grad = False 12 | model.classifier[-3] = nn.Conv2d(model.classifier[-3].in_channels,num_classes,kernel_size=1) 13 | self.model = model 14 | def forward(self,x): 15 | return self.model(x) 16 | 17 | if __name__=="__main__": 18 | net = SqueezeNet() 19 | device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") 20 | net.to(device) 21 | from torchsummary import summary 22 | print(summary(net,(3,224,224))) -------------------------------------------------------------------------------- /pytorch/models/mnasnet.py: -------------------------------------------------------------------------------- 1 | from torch import nn 2 | import torchvision.models as models 3 | import torch 4 | class MnasNet(nn.Module): 5 | def __init__(self,num_classes=2): 6 | super(MnasNet,self).__init__() 7 | self.model_name = "MnasNet" 8 | model = models.mnasnet0_5(pretrained=True) 9 | for param in model.parameters(): 10 | param.requires_grad = True 11 | model.classifier[-1] = nn.Linear(model.classifier[-1].in_features,num_classes) 12 | model.num_classes=num_classes 13 | self.model = model 14 | 15 | def forward(self,x): 16 | return self.model(x) 17 | 18 | if __name__=="__main__": 19 | net = MnasNet() 20 | device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") 21 | net.to(device) 22 | from torchsummary import summary 23 | print(summary(net,(3,224,224))) -------------------------------------------------------------------------------- /caffe/cpp/LenetClassifier.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "string" 3 | #include "opencv2/opencv.hpp" 4 | #include 5 | using namespace cv::dnn; 6 | using namespace std; 7 | const string caffeplatedir = "../"; 8 | const string model_file = caffeplatedir + "/modeldef/deploy.prototxt"; 9 | const string trained_file = caffeplatedir + "/plate996.caffemodel"; 10 | const string mean_file = caffeplatedir + "/modeldef/mean.binaryproto"; 11 | 12 | class CLenetClassifier 13 | { 14 | public: 15 | static CLenetClassifier*getInstance() 16 | { 17 | static CLenetClassifier instance; 18 | return &instance; 19 | } 20 | std::pairpredict(const cv::Mat &img); 21 | bool load(cv::String modelTxt = model_file, cv::String modelBin = trained_file); 22 | private: 23 | bool bloaded = false; 24 | Net _net; 25 | cv::Scalar _mean; 26 | CLenetClassifier() { 27 | } 28 | }; -------------------------------------------------------------------------------- /tensorflow/ncs.sh: -------------------------------------------------------------------------------- 1 | 2 | MODELS_DIR=~/models/research/slim 3 | TENSORFLOW_DIR=~/CNN/tensorflow 4 | 5 | MODEL_NAME=inception_v3 6 | 7 | cd ${MODELS_DIR} 8 | 9 | 10 | if [ -f ${MODEL_NAME}_inf_graph.pb ] 11 | then 12 | echo ${MODEL_NAME}_inf_graph.pb "laready exists" 13 | python export_inference_graph.py --alsologtostderr --model_name=${MODEL_NAME} --batch_size=1 --dataset_name=imagenet --image_size=299 --output_file=${MODEL_NAME}_inf_graph.pb 14 | fi 15 | 16 | if [ -f frozen_${MODEL_NAME}.pb ] 17 | then 18 | echo frozen_${MODEL_NAME}.pb "laready exists" 19 | ${TENSORFLOW_DIR}/bazel-bin/tensorflow/python/tools/freeze_graph --input_graph=${MODEL_NAME}_inf_graph.pb --input_binary=true --input_checkpoint=${MODEL_NAME}/${MODEL_NAME}.ckpt --output_graph=frozen_${MODEL_NAME}.pb --output_node_name=InceptionV3/Predictions/Reshape_1 20 | fi 21 | mvNCCompile -s 12 frozen_${MODEL_NAME}.pb -in=input -on=InceptionV3/Predictions/Reshape_1 -------------------------------------------------------------------------------- /web/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} {% block content %} 2 | 3 |

Image Classifier

4 | 5 |
6 |
7 | 10 | 11 |
12 | 13 | 22 | 23 | 24 | 25 |

26 | 27 |

28 | 29 |
30 | 31 | {% endblock %} -------------------------------------------------------------------------------- /caffe/modeldef/BN-GoogleNet/solver.prototxt: -------------------------------------------------------------------------------- 1 | # the definition of neural network model 2 | net: "modeldef/BN-GoogleNet/train_val.prototxt" 3 | # test_iter is related to batch_size in test layer, test_iter * batch_size = the number of test data 4 | test_iter: 250 5 | # carry out test once every 5 training iterations 6 | test_interval:500 7 | # exclude test phase when test_initialization = false 8 | # test_initialization: false 9 | # display information once every 10 training iterations 10 | display: 100 11 | # 12 | average_loss: 40 13 | # the initial learning rate 14 | base_lr: 0.001 15 | lr_policy: "poly" 16 | stepsize: 10000 17 | gamma: 0.96 18 | # The max number of iterations 19 | max_iter: 10001 20 | power: 1.0 21 | momentum: 0.9 22 | # weight decay item, in case of overfitting 23 | weight_decay: 0.0002 24 | # save once every 50 training iterations 25 | snapshot: 10000 26 | # save path 27 | snapshot_prefix: "inception-v2" 28 | solver_mode: GPU 29 | -------------------------------------------------------------------------------- /pytorch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0 FATAL_ERROR) 2 | 3 | project(example-app) 4 | find_package(Torch REQUIRED) 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}") 6 | 7 | find_package(OpenCV REQUIRED) 8 | add_executable(example-app cpp/example.cpp) 9 | set_property(TARGET example-app PROPERTY CXX_STANDARD 14) 10 | target_link_libraries(example-app ${TORCH_LIBRARIES} ${OpenCV_LIBS}) 11 | # The following code block is suggested to be used on Windows. 12 | # According to https://github.com/pytorch/pytorch/issues/25457, 13 | # the DLLs need to be copied to avoid memory errors. 14 | if (MSVC) 15 | file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll") 16 | add_custom_command(TARGET example-app 17 | POST_BUILD 18 | COMMAND ${CMAKE_COMMAND} -E copy_if_different 19 | ${TORCH_DLLS} 20 | $) 21 | endif (MSVC) -------------------------------------------------------------------------------- /caffe/cpp/LenetClassifier.cpp: -------------------------------------------------------------------------------- 1 | #include "LenetClassifier.h" 2 | std::pairCLenetClassifier::predict(const cv::Mat &img) 3 | { 4 | std::pairp; 5 | if (!bloaded) 6 | { 7 | load(); 8 | } 9 | else 10 | { 11 | cv::Mat input; 12 | cv::resize(img, input, cv::Size(20, 20)); 13 | cv::Mat inputBlob = blobFromImage(input);// , 255.0f, cv::Size(20, 20), _mean, false); 14 | cv::Mat prob; 15 | _net.setInput(inputBlob, "data"); 16 | prob = _net.forward("prob"); 17 | cv::Mat probMat = prob.reshape(1, 1); 18 | cv::Point classNumber; 19 | cv::minMaxLoc(probMat, NULL, &p.second, NULL, &classNumber); 20 | p.first = classNumber.x; 21 | } 22 | 23 | return p; 24 | } 25 | 26 | bool CLenetClassifier::load(cv::String modelTxt, cv::String modelBin) 27 | { 28 | _net = cv::dnn::readNetFromCaffe(modelTxt, modelBin); 29 | // _mean = cv::Scalar(66, 66, 66); 30 | bloaded = !_net.empty(); 31 | return bloaded; 32 | } -------------------------------------------------------------------------------- /pytorch/models/alexnet.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from torch import nn 3 | import torchvision.models as models 4 | 5 | class AlexNet(nn.Module): 6 | def __init__(self,num_classes=2): 7 | super(AlexNet,self).__init__() 8 | self.model_name = "AlexNet" 9 | model = models.alexnet(pretrained=True) 10 | for param in model.parameters(): 11 | param.requires_grad = False 12 | model.classifier[-1] = nn.Linear(model.classifier[-1].in_features,num_classes) 13 | self.model = model 14 | 15 | def forward(self,x): 16 | return self.model(x) 17 | 18 | if __name__=="__main__": 19 | net = AlexNet() 20 | device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") 21 | net.to(device) 22 | from torchsummary import summary 23 | <<<<<<< HEAD 24 | print(summary(net,(3,224,224))) 25 | ======= 26 | print(summary(net,(3,224,224))) 27 | >>>>>>> df55394a74005d3d1b17654c1b4d31c41d4e2bb6 28 | -------------------------------------------------------------------------------- /paddle/utils/__init__.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | from .optimizer import cosine_decay, lr_warmup, cosine_decay_with_warmup, exponential_decay_with_warmup, Optimizer, create_optimizer 15 | from .utility import add_arguments, print_arguments, parse_args, check_gpu, check_args, check_version, init_model, save_model, create_data_loader, print_info, best_strategy_compiled, init_model, save_model, ExponentialMovingAverage 16 | -------------------------------------------------------------------------------- /caffe/oneclick.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | TOOLS=/home/yanyu/CNN/caffe/build/tools 4 | DATA=../ 5 | TRAIN_DATA_ROOT=$DATA/ 6 | VAL_DATA_ROOT=$DATA/ 7 | EXAMPLE=lmdb 8 | RESIZE=true 9 | rm lmdb -r 10 | mkdir lmdb 11 | if $RESIZE;then 12 | RESIZE_HEIGHT=256 13 | RESIZE_WIDTH=256 14 | else 15 | RESIZE_HEIGHT=256 16 | RESIZE_WIDTH=256 17 | fi 18 | 19 | echo "Creating train lmdb..." 20 | 21 | GLOG_logtostderr=1 $TOOLS/convert_imageset \ 22 | --resize_height=$RESIZE_HEIGHT \ 23 | --resize_width=$RESIZE_WIDTH \ 24 | --shuffle \ 25 | $TRAIN_DATA_ROOT \ 26 | util/train.txt \ 27 | $EXAMPLE/train_lmdb 28 | 29 | echo "Creating val lmdb..." 30 | 31 | GLOG_logtostderr=1 $TOOLS/convert_imageset \ 32 | --resize_height=$RESIZE_HEIGHT \ 33 | --resize_width=$RESIZE_WIDTH \ 34 | --shuffle \ 35 | $VAL_DATA_ROOT \ 36 | util/val.txt \ 37 | $EXAMPLE/val_lmdb 38 | 39 | echo "Start compute mean." 40 | 41 | "$TOOLS/compute_image_mean" "lmdb/train_lmdb" "modeldef/mean.binaryproto" 42 | 43 | echo "Start Training" 44 | $TOOLS/caffe train --solver=modeldef/AlexNet/solver.prototxt 45 | echo "Training Done" 46 | -------------------------------------------------------------------------------- /web/static/css/main.css: -------------------------------------------------------------------------------- 1 | .img-preview { 2 | width: 256px; 3 | height: 256px; 4 | position: relative; 5 | border: 5px solid #F8F8F8; 6 | box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1); 7 | margin-top: 1em; 8 | margin-bottom: 1em; 9 | } 10 | 11 | .img-preview>div { 12 | width: 100%; 13 | height: 100%; 14 | background-size: 256px 256px; 15 | background-repeat: no-repeat; 16 | background-position: center; 17 | } 18 | 19 | input[type="file"] { 20 | display: none; 21 | } 22 | 23 | .upload-label{ 24 | display: inline-block; 25 | padding: 12px 30px; 26 | background: #39D2B4; 27 | color: #fff; 28 | font-size: 1em; 29 | transition: all .4s; 30 | cursor: pointer; 31 | } 32 | 33 | .upload-label:hover{ 34 | background: #34495E; 35 | color: #39D2B4; 36 | } 37 | 38 | .loader { 39 | border: 8px solid #f3f3f3; /* Light grey */ 40 | border-top: 8px solid #3498db; /* Blue */ 41 | border-radius: 50%; 42 | width: 50px; 43 | height: 50px; 44 | animation: spin 1s linear infinite; 45 | } 46 | 47 | @keyframes spin { 48 | 0% { transform: rotate(0deg); } 49 | 100% { transform: rotate(360deg); } 50 | } -------------------------------------------------------------------------------- /caffe/oneclick.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set CAFFE_DIR=D:/CNN/caffe 3 | set DATA="../" 4 | set REISZE_DIM=256 5 | set converttool=%CAFFE_DIR%/build/tools/convert_imageset 6 | set finetunemodel=modeldef/bvlc_alexnet.caffemodel 7 | if exist "lmdb/train_lmdb" (set regenlmdb=0) else (set regenlmdb=1) 8 | ::set regenlmdb=1 9 | 10 | if %regenlmdb% equ 1 goto regeneratelmdb 11 | 12 | goto train 13 | :regeneratelmdb 14 | echo "Creating train lmdb..." 15 | del "lmdb/train_lmdb\*.*" /f /s /q 16 | del "lmdb/val_lmdb\*.*" /f /s /q 17 | rd /s /q "lmdb/train_lmdb" 18 | rd /s /q "lmdb/val_lmdb" 19 | rd /s /q lmdb 20 | mkdir lmdb 21 | "%converttool%" --resize_height=%REISZE_DIM% --resize_width=%REISZE_DIM% --shuffle "%DATA%" "util/train.txt" "lmdb/train_lmdb" 22 | echo "Creating val lmdb..." 23 | "%converttool%" --resize_height=%REISZE_DIM% --resize_width=%REISZE_DIM% --shuffle "%DATA%" "util/val.txt" "lmdb/val_lmdb" 24 | 25 | echo "Computing mean:" 26 | "%CAFFE_DIR%/build/tools/compute_image_mean" "lmdb/train_lmdb" "modeldef/mean.binaryproto" 27 | 28 | :train 29 | if exist %finetunemodel% (set extra_cmd="--weights=%finetunemodel%") 30 | "%CAFFE_DIR%/build/tools/caffe" train --solver=modeldef/MobileNet/solver.prototxt %extra_cmd% 31 | echo "Done" 32 | pause -------------------------------------------------------------------------------- /caffe/modeldef/readme.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: BAIR/BVLC AlexNet Model 3 | caffemodel: bvlc_alexnet.caffemodel 4 | caffemodel_url: http://dl.caffe.berkeleyvision.org/bvlc_alexnet.caffemodel 5 | license: unrestricted 6 | sha1: 9116a64c0fbe4459d18f4bb6b56d647b63920377 7 | caffe_commit: 709dc15af4a06bebda027c1eb2b3f3e3375d5077 8 | --- 9 | 10 | This model is a replication of the model described in the [AlexNet](http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks) publication. 11 | 12 | Differences: 13 | - not training with the relighting data-augmentation; 14 | - initializing non-zero biases to 0.1 instead of 1 (found necessary for training, as initialization to 1 gave flat loss). 15 | 16 | The bundled model is the iteration 360,000 snapshot. 17 | The best validation performance during training was iteration 358,000 with validation accuracy 57.258% and loss 1.83948. 18 | This model obtains a top-1 accuracy 57.1% and a top-5 accuracy 80.2% on the validation set, using just the center crop. 19 | (Using the average of 10 crops, (4 + 1 center) * 2 mirror, should obtain a bit higher accuracy.) 20 | 21 | This model was trained by Evan Shelhamer @shelhamer 22 | 23 | ## License 24 | 25 | This model is released for unrestricted use. 26 | -------------------------------------------------------------------------------- /web/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AI Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 22 |
23 |
{% block content %}{% endblock %}
24 |
25 | 26 | 27 |
28 | 29 |
30 | 31 | -------------------------------------------------------------------------------- /tensorflow/convertdataset.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tensorflow as tf 3 | from PIL import Image 4 | from tqdm import tqdm 5 | 6 | def _int64_feature(value): 7 | return tf.train.Feature(int64_list=tf.train.Int64List(value=[value])) 8 | 9 | def _bytes_feature(value): 10 | return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value])) 11 | 12 | def convert2tfrecords(imgdir="train",args=None): 13 | recordfilename=imgdir+".tfrecords" 14 | writer= tf.python_io.TFRecordWriter(recordfilename) 15 | files=os.listdir(imgdir) 16 | labels={} 17 | for file in tqdm(files): 18 | filepath=imgdir+"/"+file 19 | cls=file.split(".")[0] 20 | if cls in labels: 21 | label=labels[cls] 22 | else: 23 | labels[cls]=len(labels) 24 | label=labels[cls] 25 | img=Image.open(filepath) 26 | #img= img.resize(args.resize) 27 | example=tf.train.Example(features=tf.train.Features(feature={ 28 | "filepath":_bytes_feature(bytes(filepath, encoding = "utf8")), 29 | "height":_int64_feature(img.height), 30 | "width":_int64_feature(img.width), 31 | "label":_int64_feature(label), 32 | "image_raw":_bytes_feature(img.tobytes()) 33 | })) 34 | writer.write(example.SerializeToString()) 35 | writer.close() 36 | 37 | if __name__=="__main__": 38 | convert2tfrecords() -------------------------------------------------------------------------------- /pytorch/utils/config.py: -------------------------------------------------------------------------------- 1 | # coding:utf8 2 | import warnings 3 | import torch 4 | import logging 5 | class DefaultConfig(object): 6 | env = 'default' # visdom 环境 7 | vis_port = 8097 # visdom 端口 8 | model = 'SqueezeNet' # 使用的模型,名字必须与models/__init__.py中的名字一致 9 | 10 | train_data_root = 'data/dogcat/train/' # 训练集存放路径 11 | test_data_root = 'data/dogcat/test1' # 测试集存放路径 12 | load_model_path = None # 加载预训练的模型的路径,为None代表不加载 13 | 14 | batch_size = 32 # batch size 15 | use_gpu = True # user GPU or not 16 | num_workers = 40 # how many workers for loading data 17 | print_freq = 100 # print info every N batch 18 | result_file = 'result.csv' 19 | 20 | max_epoch = 10000 21 | lr = 0.001 # initial learning rate 22 | lr_decay = 0.5 # when val_loss increase, lr = lr*lr_decay 23 | weight_decay = 0e-5 # 损失函数 24 | device = torch.device('cpu') 25 | dataset = "DogCat" 26 | 27 | def parse(self, kwargs): 28 | for k, v in kwargs.items(): 29 | if not hasattr(self, k): 30 | warnings.warn("Warning: opt has not attribut %s" % k) 31 | setattr(self, k, v) 32 | self.device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu') 33 | for k, v in self.__class__.__dict__.items(): 34 | if not k.startswith('_'): 35 | logging.info(str(k)+":"+str(getattr(self, k))) 36 | 37 | opt = DefaultConfig() -------------------------------------------------------------------------------- /Kaggle.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "tf", "tensorflow\tf.pyproj", "{02C4E36D-42E7-4886-A13D-D02AEA028759}" 7 | EndProject 8 | Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "caffe", "caffe\caffe.pyproj", "{55AFC290-61F1-4F32-BBF6-B89E0906EF01}" 9 | EndProject 10 | Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "keras", "Keras\keras.pyproj", "{66E55EA6-E9FE-41E2-9648-0894CADA2385}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {02C4E36D-42E7-4886-A13D-D02AEA028759}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {02C4E36D-42E7-4886-A13D-D02AEA028759}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {55AFC290-61F1-4F32-BBF6-B89E0906EF01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {55AFC290-61F1-4F32-BBF6-B89E0906EF01}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {66E55EA6-E9FE-41E2-9648-0894CADA2385}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {66E55EA6-E9FE-41E2-9648-0894CADA2385}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /pytorch/utils/focalloss.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | import torch.nn.functional as F 4 | from torch.autograd import Variable 5 | 6 | class FocalLoss(nn.Module): 7 | def __init__(self, gamma=0, alpha=None, size_average=True): 8 | super(FocalLoss, self).__init__() 9 | self.gamma = gamma 10 | self.alpha = alpha 11 | if isinstance(alpha,(float,int)): self.alpha = torch.Tensor([alpha,1-alpha]) 12 | if isinstance(alpha,list): self.alpha = torch.Tensor(alpha) 13 | self.size_average = size_average 14 | 15 | def forward(self, input, target): 16 | if input.dim()>2: 17 | input = input.view(input.size(0),input.size(1),-1) # N,C,H,W => N,C,H*W 18 | input = input.transpose(1,2) # N,C,H*W => N,H*W,C 19 | input = input.contiguous().view(-1,input.size(2)) # N,H*W,C => N*H*W,C 20 | target = target.view(-1,1) 21 | 22 | logpt = F.log_softmax(input, dim=1) 23 | logpt = logpt.gather(1,target) 24 | logpt = logpt.view(-1) 25 | pt = Variable(logpt.data.exp()) 26 | 27 | if self.alpha is not None: 28 | if self.alpha.type()!=input.data.type(): 29 | self.alpha = self.alpha.type_as(input.data) 30 | at = self.alpha.gather(0,target.data.view(-1)) 31 | logpt = logpt * Variable(at) 32 | 33 | loss = -1 * (1-pt)**self.gamma * logpt 34 | if self.size_average: return loss.mean() 35 | else: return loss.sum() -------------------------------------------------------------------------------- /pytorch/cpp/example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "mrutil.h" 5 | 6 | //https://pytorch.org/tutorials/advanced/cpp_export.html 7 | std::string CLASSES[] = {"cat","dog"}; 8 | 9 | int main(int argc, const char* argv[]) { 10 | auto module = torch::jit::load("../mnasnet_dogcat.pt"); 11 | std::string imgpath = "../data/1.jpg"; 12 | if(argc > 1){ 13 | imgpath = argv[1]; 14 | } 15 | auto image = cv::imread(imgpath); 16 | if(image.data == NULL){ 17 | std::cout << imgpath << " cannot read" << std::endl; 18 | return -1; 19 | } 20 | cv::Mat image_transfomed; 21 | cv::resize(image, image_transfomed, cv::Size(224, 224)); 22 | cv::cvtColor(image_transfomed, image_transfomed, cv::COLOR_BGR2RGB); 23 | torch::Tensor tensor_image = torch::from_blob(image_transfomed.data, {image_transfomed.rows, image_transfomed.cols,3},torch::kByte); 24 | tensor_image = tensor_image.permute({2,0,1}); 25 | tensor_image = tensor_image.toType(torch::kFloat); 26 | tensor_image = tensor_image.div(255); 27 | tensor_image = tensor_image.unsqueeze(0); 28 | at::Tensor output = module.forward({tensor_image}).toTensor(); 29 | auto max_result = output.max(1,true); 30 | auto max_index = std::get<1>(max_result).item(); 31 | auto score = std::get<0>(max_result).item(); 32 | std::string display=CLASSES[int(max_index)]+tostring(score); 33 | cv::putText(image, display, cv::Point(100, 50), 1, 1,cv::Scalar(0, 0, 255)); 34 | cv::imshow("image", image); 35 | cv::waitKey(0); 36 | //cv::imwrite("./result.jpg", image); 37 | } -------------------------------------------------------------------------------- /pytorch/utils/util.py: -------------------------------------------------------------------------------- 1 | import os 2 | import torch 3 | import argparse 4 | 5 | def accuracy(y_pred, y_actual, topk=(1, )): 6 | """Computes the precision@k for the specified values of k""" 7 | maxk = max(topk) 8 | batch_size = y_actual.size(0) 9 | 10 | _, pred = y_pred.topk(maxk, 1, True, True) 11 | pred = pred.t() 12 | correct = pred.eq(y_actual.view(1, -1).expand_as(pred)) 13 | 14 | res = [] 15 | for k in topk: 16 | correct_k = correct[:k].view(-1).float().sum(0) 17 | res.append(correct_k.mul_(100.0 / batch_size)) 18 | 19 | return res 20 | 21 | def get_lastest_model(modeldir="output",prefix="MnasNet"): 22 | files = os.listdir(modeldir) 23 | if len(files)==0: 24 | return None 25 | files = list(filter(lambda x: x.startswith(prefix),files)) 26 | files.sort(key=lambda fn:os.path.getmtime(modeldir + "/" + fn)) 27 | if len(files) > 0: 28 | lastest = os.path.join(modeldir,files[-1]) 29 | else: 30 | lastest = None 31 | return lastest 32 | 33 | def get_args(): 34 | parser = argparse.ArgumentParser(description=__doc__) 35 | parser.add_argument("--model",type=str,default="ShuffleNet",choices=["MRNet","AlexNet","ResNet50","SqueezeNet","MnasNet","ShuffleNet"]) 36 | parser.add_argument("--batch_size",type=int,default=64) 37 | parser.add_argument("--num_workers",type=int,default=40) 38 | parser.add_argument("--load_model_path",type=str,default=None) 39 | # for demo 40 | parser.add_argument("--image_dir",type=str,default="data/dogcat/test1") 41 | parser.add_argument("--image_path",type=str,default="data/dogcat/test1/1.jpg") 42 | return parser.parse_args() 43 | 44 | if __name__=="__main__": 45 | print(get_lastest_model()) -------------------------------------------------------------------------------- /web/static/js/main.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | // Init 3 | $('.image-section').hide(); 4 | $('.loader').hide(); 5 | $('#result').hide(); 6 | 7 | // Upload Preview 8 | function readURL(input) { 9 | if (input.files && input.files[0]) { 10 | var reader = new FileReader(); 11 | reader.onload = function (e) { 12 | $('#imagePreview').css('background-image', 'url(' + e.target.result + ')'); 13 | $('#imagePreview').hide(); 14 | $('#imagePreview').fadeIn(650); 15 | } 16 | reader.readAsDataURL(input.files[0]); 17 | } 18 | } 19 | $("#imageUpload").change(function () { 20 | $('.image-section').show(); 21 | $('#btn-predict').show(); 22 | $('#result').text(''); 23 | $('#result').hide(); 24 | readURL(this); 25 | }); 26 | 27 | // Predict 28 | $('#btn-predict').click(function () { 29 | var form_data = new FormData($('#upload-file')[0]); 30 | 31 | // Show loading animation 32 | $(this).hide(); 33 | $('.loader').show(); 34 | 35 | // Make prediction by calling api /predict 36 | $.ajax({ 37 | type: 'POST', 38 | url: '/predict', 39 | data: form_data, 40 | contentType: false, 41 | cache: false, 42 | processData: false, 43 | async: true, 44 | success: function (data) { 45 | // Get and display the result 46 | $('.loader').hide(); 47 | $('#result').fadeIn(600); 48 | $('#result').text(' Result: ' + data); 49 | console.log('Success!'); 50 | }, 51 | }); 52 | }); 53 | 54 | }); 55 | -------------------------------------------------------------------------------- /pytorch/models/mrnet.py: -------------------------------------------------------------------------------- 1 | from torch import nn 2 | import torch 3 | import math 4 | import torch.nn.functional as F 5 | class MRNet(nn.Module): 6 | 7 | def __init__(self, num_classes = 2): 8 | super(MRNet,self).__init__() 9 | self.model_name = "MRNet" 10 | self.conv1 = nn.Conv2d(3,6,3) 11 | self.conv2 = nn.Conv2d(self.conv1.out_channels,16,3) 12 | self.conv3 = nn.Conv2d(self.conv2.out_channels,24,3) 13 | self.conv4 = nn.Conv2d(self.conv3.out_channels,32,3) 14 | self.conv5 = nn.Conv2d(self.conv4.out_channels,64,3) 15 | self.conv6 = nn.Conv2d(self.conv5.out_channels,128,3) 16 | self.fc = nn.Linear(self.conv6.out_channels,num_classes) 17 | 18 | def forward(self,x): 19 | x = F.max_pool2d(F.relu(self.conv1(x)),2) 20 | x = F.max_pool2d(F.relu(self.conv2(x)),2) 21 | x = F.max_pool2d(F.relu(self.conv3(x)),2) 22 | x = F.max_pool2d(F.relu(self.conv4(x)),2) 23 | x = F.max_pool2d(F.relu(self.conv5(x)),2) 24 | x = F.max_pool2d(F.relu(self.conv6(x)),2) 25 | x = x.view(-1,self.num_flat_features(x)) 26 | x = self.fc(x) 27 | return x 28 | 29 | def num_flat_features(self,x): 30 | size = x.size()[1:] 31 | num_features = 1 32 | for s in size: 33 | num_features*=s 34 | return num_features 35 | 36 | if __name__=="__main__": 37 | net = MRNet() 38 | device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") 39 | net.to(device) 40 | from torchsummary import summary 41 | print(summary(net,(3,224,224))) 42 | <<<<<<< HEAD 43 | dummy_input = torch.rand(1,3,224,224).to(device) 44 | ======= 45 | dummy_input = torch.rand(1,3,224,224).to(device) 46 | >>>>>>> df55394a74005d3d1b17654c1b4d31c41d4e2bb6 47 | -------------------------------------------------------------------------------- /paddle/run.sh: -------------------------------------------------------------------------------- 1 | #Hyperparameters config 2 | export CUDA_VISIBLE_DEVICES=6 3 | export LD_LIBRARY_PATH=/home/ar/gongyanhe/libs/cuda/lib64/:$LD_LIBRARY_PATH 4 | export FLAGS_fraction_of_gpu_memory_to_use=0.9 5 | 6 | #AlexNet: 7 | #python train.py \ 8 | --model=AlexNet \ 9 | --batch_size=256 \ 10 | --total_images=20000 \ 11 | --class_dim=2 \ 12 | --image_shape=3,224,224 \ 13 | --model_save_dir=output/ \ 14 | --with_mem_opt=False \ 15 | --lr_strategy=piecewise_decay \ 16 | --num_epochs=120 \ 17 | --lr=0.01 \ 18 | >log_AlexNet.txt 2>&1 & 19 | 20 | #VGG11: 21 | #python train.py \ 22 | # --model=VGG11 \ 23 | # --batch_size=512 \ 24 | # --total_images=1281167 \ 25 | # --class_dim=1000 \ 26 | # --image_shape=3,224,224 \ 27 | # --model_save_dir=output/ \ 28 | # --with_mem_opt=False \ 29 | # --lr_strategy=piecewise_decay \ 30 | # --num_epochs=120 \ 31 | # --lr=0.1 32 | 33 | 34 | #Mnasnet: 35 | # python train.py \ 36 | # --model=Mnasnet \ 37 | # --batch_size=32 \ 38 | # --total_images=20000 \ 39 | # --class_dim=2 \ 40 | # --image_shape=3,224,224 \ 41 | # --model_save_dir=output/ \ 42 | # --with_mem_opt=False \ 43 | # --lr_strategy=piecewise_decay \ 44 | # --num_epochs=120 \ 45 | # --lr=0.1 \ 46 | #>log_Mnasnet.txt 2>&1 & 47 | 48 | 49 | #ResNet50: 50 | #python train.py \ 51 | # --model=ResNet50 \ 52 | # --batch_size=256 \ 53 | # --total_images=1281167 \ 54 | # --class_dim=1000 \ 55 | # --image_shape=3,224,224 \ 56 | # --model_save_dir=output/ \ 57 | # --with_mem_opt=False \ 58 | # --lr_strategy=piecewise_decay \ 59 | # --num_epochs=120 \ 60 | # --lr=0.1 61 | 62 | #ResNet101: 63 | #python train.py \ 64 | # --model=ResNet101 \ 65 | # --batch_size=256 \ 66 | # --total_images=1281167 \ 67 | # --class_dim=1000 \ 68 | # --image_shape=3,224,224 \ 69 | # --model_save_dir=output/ \ 70 | # --with_mem_opt=False \ 71 | # --lr_strategy=piecewise_decay \ 72 | # --num_epochs=120 \ 73 | # --lr=0.1 74 | 75 | -------------------------------------------------------------------------------- /caffe/util/plotlog.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | import math 6 | import re 7 | import pylab 8 | from pylab import figure, show, legend 9 | from mpl_toolkits.axes_grid1 import host_subplot 10 | 11 | def get_last_logpath(logdir): 12 | return 13 | 14 | def plot_logtxt(logpath): 15 | # read the log file 16 | fp = open(logpath, 'r') 17 | 18 | train_iterations = [] 19 | train_loss = [] 20 | test_iterations = [] 21 | test_accuracy = [] 22 | 23 | for ln in fp: 24 | # get train_iterations and train_loss 25 | if '] Iteration ' in ln and 'loss = ' in ln: 26 | arr = re.findall(r'ion \b\d+\b,',ln) 27 | train_iterations.append(int(arr[0].strip(',')[4:])) 28 | train_loss.append(float(ln.strip().split(' = ')[-1])) 29 | # get test_iteraitions 30 | if '] Iteration' in ln and 'Testing net (#0)' in ln: 31 | arr = re.findall(r'ion \b\d+\b,',ln) 32 | test_iterations.append(int(arr[0].strip(',')[4:])) 33 | # get test_accuracy 34 | if '#2:' in ln and 'loss/top-5' in ln: 35 | test_accuracy.append(float(ln.strip().split(' = ')[-1])) 36 | 37 | fp.close() 38 | 39 | host = host_subplot(111) 40 | plt.subplots_adjust(right=0.8) # ajust the right boundary of the plot window 41 | par1 = host.twinx() 42 | # set labels 43 | host.set_xlabel("iterations") 44 | host.set_ylabel("log loss") 45 | par1.set_ylabel("validation accuracy") 46 | 47 | # plot curves 48 | p1, = host.plot(train_iterations, train_loss, label="training log loss") 49 | p2, = par1.plot(test_iterations, test_accuracy, label="validation accuracy") 50 | 51 | # set location of the legend, 52 | # 1->rightup corner, 2->leftup corner, 3->leftdown corner 53 | # 4->rightdown corner, 5->rightmid ... 54 | host.legend(loc=5) 55 | 56 | # set label color 57 | host.axis["left"].label.set_color(p1.get_color()) 58 | par1.axis["right"].label.set_color(p2.get_color()) 59 | # set the range of x axis of host and y axis of par1 60 | host.set_xlim([-1500, 160000]) 61 | par1.set_ylim([0., 1.05]) 62 | 63 | plt.draw() 64 | plt.show() 65 | 66 | if __name__=="__main__": 67 | plot_logtxt(get_last_logpath()) -------------------------------------------------------------------------------- /pytorch/demo.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | import torch 4 | import torchvision.models as models 5 | import cv2 6 | from PIL import Image 7 | import numpy as np 8 | from torchvision import transforms 9 | from tqdm import tqdm 10 | import models 11 | from utils.util import get_args,get_lastest_model 12 | 13 | CLASSES=['cat','dog'] 14 | 15 | transformsImage = transforms.Compose([ 16 | transforms.ToPILImage(), 17 | transforms.Resize(224), 18 | transforms.CenterCrop(224), 19 | transforms.ToTensor(), 20 | transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) 21 | ]) 22 | 23 | def test_image(model, device, imgpath): 24 | img = cv2.imread(imgpath) 25 | #img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_CUBIC) 26 | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 27 | image = transformsImage(img).unsqueeze(0) 28 | outputs = model(image.to(device)) 29 | _, index = torch.max(outputs, 1) 30 | percentage = torch.nn.functional.softmax(outputs, dim=1)[0] * 100 31 | print(imgpath,CLASSES[index[0]], percentage[index[0]].item()) 32 | 33 | def test_dir(model, device, dir): 34 | files = os.listdir(dir) 35 | for file in tqdm(files): 36 | imgpath = dir+'/'+file 37 | test_image(model,device, imgpath) 38 | def export_model(model): 39 | example = torch.rand(1, 3, 224, 224) 40 | traced_script_module = torch.jit.trace(model, example) 41 | output = traced_script_module(torch.ones(1, 3, 224, 224)) 42 | traced_script_module.save("./mnasnet_dogcat.pt") 43 | 44 | @torch.no_grad() 45 | def demo(): 46 | args = get_args() 47 | model = getattr(models,args.model)() 48 | if not args.load_model_path: 49 | args.load_model_path = get_lastest_model() 50 | if not args.load_model_path: 51 | print("No pretrained model found") 52 | return 53 | model.load_state_dict(torch.load(args.load_model_path,map_location=torch.device('cpu'))) 54 | device = torch.device('cpu') 55 | if torch.cuda.is_available(): 56 | device = torch.device('cuda') 57 | model.to(device) 58 | model.eval() 59 | #export_model(model) 60 | test_image(model, device, args.image_path) 61 | #test_dir(model, device, args.image_dir) 62 | 63 | if __name__=="__main__": 64 | demo() -------------------------------------------------------------------------------- /pytorch/test.py: -------------------------------------------------------------------------------- 1 | #coding=utf8 2 | 3 | import os 4 | import cv2 5 | import torch 6 | from torch.utils.data import DataLoader 7 | from torchnet import meter 8 | from tqdm import tqdm 9 | from config import opt 10 | import datasets 11 | import models 12 | from utils.util import accuracy,get_lastest_model,get_args 13 | 14 | CLASSES=['cat','dog'] 15 | 16 | @torch.no_grad() 17 | def test(args): 18 | new_config ={"model":args.model,"num_workers":args.num_workers, 19 | "batch_size":args.batch_size,"load_model_path":args.load_model_path} 20 | opt.parse(new_config) 21 | if not args.load_model_path: 22 | args.load_model_path = get_lastest_model() 23 | if not args.load_model_path: 24 | print("No pretrained model found") 25 | return 26 | # step1: configure model 27 | model = getattr(models, opt.model)() 28 | model.load_state_dict(torch.load(args.load_model_path)) 29 | model.to(opt.device) 30 | dataset = getattr(datasets,opt.dataset) 31 | val_data = dataset(opt.train_data_root,train=False) 32 | val_dataloader = DataLoader(val_data,opt.batch_size, 33 | shuffle=False,num_workers=opt.num_workers) 34 | model.eval() 35 | confusion_matrix = meter.ConfusionMeter(2) 36 | 37 | for _, (val_input, label) in enumerate(tqdm(val_dataloader)): 38 | val_input = val_input.to(opt.device) 39 | score = model(val_input) 40 | confusion_matrix.add(score.detach().squeeze(), label.type(torch.LongTensor)) 41 | cm_value = confusion_matrix.value() 42 | accuracy = 100. * (cm_value[0][0] + cm_value[1][1]) / (cm_value.sum()) 43 | print("Acc:{acc}".format(acc=accuracy)) 44 | print("confusion matrix:{val_cm}".format(val_cm = str(cm_value))) 45 | 46 | def test_loader(): 47 | dataset = getattr(datasets,opt.dataset) 48 | train_data = dataset(opt.train_data_root,train=False) 49 | dataloader = DataLoader(train_data,opt.batch_size, 50 | shuffle=True,num_workers=0) 51 | for _, (val_input, label) in enumerate(dataloader): 52 | for i in range(len(val_input.numpy())): 53 | img = val_input.numpy()[i].transpose(1,2,0).copy() 54 | cv2.putText(img,CLASSES[label[i].item()],(0,40),3,1,(0,0,255)) 55 | cv2.imshow("img",img) 56 | cv2.waitKey() 57 | 58 | if __name__=='__main__': 59 | args = get_args() 60 | test(args) 61 | #test_loader() -------------------------------------------------------------------------------- /pytorch/datasets/dogcat.py: -------------------------------------------------------------------------------- 1 | # coding:utf8 2 | import os 3 | from PIL import Image 4 | from torch.utils import data 5 | import numpy as np 6 | from torchvision import transforms as T 7 | import logging 8 | 9 | class DogCat(data.Dataset): 10 | 11 | def __init__(self, root, transforms=None, train=True, test=False): 12 | self.classes = 2 13 | self.test = test 14 | imgs = [os.path.join(root, img) for img in os.listdir(root)] 15 | 16 | # test1: data/test1/8973.jpg 17 | # train: data/train/cat.10004.jpg 18 | if self.test: 19 | imgs = sorted(imgs, key=lambda x: int(x.split('.')[-2].split('/')[-1])) 20 | else: 21 | imgs = sorted(imgs, key=lambda x: int(x.split('.')[-2])) 22 | 23 | imgs_num = len(imgs) 24 | 25 | if self.test: 26 | self.imgs = imgs 27 | elif train: 28 | self.imgs = imgs[:int(0.9 * imgs_num)] 29 | else: 30 | self.imgs = imgs[int(0.9 * imgs_num):] 31 | logging.info("Loading "+str(len(self.imgs))+" images from "+root) 32 | if transforms is None: 33 | normalize = T.Normalize(mean=[0.485, 0.456, 0.406], 34 | std=[0.229, 0.224, 0.225]) 35 | 36 | if self.test or not train: 37 | self.transforms = T.Compose([ 38 | T.Resize(224), 39 | T.CenterCrop(224), 40 | T.ToTensor(), 41 | normalize 42 | ]) 43 | else: 44 | self.transforms = T.Compose([ 45 | T.RandomRotation(30), 46 | T.Resize(256), 47 | T.RandomResizedCrop(224), 48 | T.RandomHorizontalFlip(), 49 | T.ColorJitter(brightness=0.2,contrast=0.3,hue=0.5), 50 | T.ToTensor(), 51 | normalize 52 | ]) 53 | 54 | def __getitem__(self, index): 55 | img_path = self.imgs[index] 56 | if self.test: 57 | label = int(self.imgs[index].split('.')[-2].split('/')[-1]) 58 | else: 59 | label = 1 if 'dog' in img_path.split('/')[-1] else 0 60 | data = Image.open(img_path) 61 | data = self.transforms(data) 62 | return data, label 63 | 64 | def __len__(self): 65 | return len(self.imgs) -------------------------------------------------------------------------------- /caffe/caffe.pyproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | 2.0 6 | {55afc290-61f1-4f32-bbf6-b89e0906ef01} 7 | . 8 | util\preprocess.py 9 | 10 | 11 | . 12 | . 13 | Kaggle 14 | Kaggle 15 | 16 | 17 | true 18 | false 19 | 20 | 21 | true 22 | false 23 | 24 | 25 | 10.0 26 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets 27 | 28 | 29 | 30 | Code 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /tensorflow/run_ncs.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | # Copyright(c) 2017 Intel Corporation. 4 | # License: MIT See LICENSE file in root directory. 5 | 6 | import sys 7 | sys.path.insert(0, "/home/yanyu/ncappzoo/ncapi2_shim") 8 | import mvnc_simple_api as mvnc 9 | import numpy 10 | import cv2 11 | 12 | path_to_networks = './' 13 | path_to_images = './' 14 | graph_filename = 'graph' 15 | image_filename = "rose.jpg"#path_to_images + 'nps_electric_guitar.png' 16 | 17 | #mvnc.SetGlobalOption(mvnc.GlobalOption.LOGLEVEL, 2) 18 | devices = mvnc.EnumerateDevices() 19 | if len(devices) == 0: 20 | print('No devices found') 21 | quit() 22 | 23 | device = mvnc.Device(devices[0]) 24 | device.OpenDevice() 25 | 26 | #Load graph 27 | with open(path_to_networks + graph_filename, mode='rb') as f: 28 | graphfile = f.read() 29 | 30 | #Load preprocessing data 31 | mean = 128 32 | std = 1.0/128.0 33 | 34 | #Load categories 35 | categories = [] 36 | with open(path_to_networks + 'categories.txt', 'r') as f: 37 | for line in f: 38 | cat = line.split('\n')[0] 39 | if cat != 'classes': 40 | categories.append(cat) 41 | f.close() 42 | print('Number of categories:', len(categories)) 43 | 44 | #Load image size 45 | with open(path_to_networks + 'inputsize.txt', 'r') as f: 46 | reqsize = int(f.readline().split('\n')[0]) 47 | 48 | graph = device.AllocateGraph(graphfile) 49 | 50 | img = cv2.imread(image_filename).astype(numpy.float32) 51 | dx,dy,dz= img.shape 52 | delta=float(abs(dy-dx)) 53 | if dx > dy: #crop the x dimension 54 | img=img[int(0.5*delta):dx-int(0.5*delta),0:dy] 55 | else: 56 | img=img[0:dx,int(0.5*delta):dy-int(0.5*delta)] 57 | img = cv2.resize(img, (reqsize, reqsize)) 58 | 59 | img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB) 60 | 61 | for i in range(3): 62 | img[:,:,i] = (img[:,:,i] - mean) * std 63 | 64 | print('Start download to NCS...') 65 | graph.LoadTensor(img.astype(numpy.float16), 'user object') 66 | output, userobj = graph.GetResult() 67 | 68 | top_inds = output.argsort()[::-1] 69 | #print(top_inds) 70 | print(output) 71 | print(''.join(['*' for i in range(79)])) 72 | print('inception-v3 on NCS') 73 | print(''.join(['*' for i in range(79)])) 74 | for i in range(2): 75 | print(i) 76 | print(top_inds[i], categories[top_inds[i]], output[top_inds[i]]) 77 | 78 | print(''.join(['*' for i in range(79)])) 79 | graph.DeallocateGraph() 80 | device.CloseDevice() 81 | print('Finished') 82 | -------------------------------------------------------------------------------- /caffe/cpp4caffe/evaluation.cpp: -------------------------------------------------------------------------------- 1 | #define REG_USE_CNN 1 2 | #pragma warning(disable:4996) 3 | #include "mrutil.h" 4 | #include "cnnpredictor.h" 5 | const string errordir = caffeplatedir + "error"; 6 | const string platedatadir = caffeplatedir+"data"; 7 | 8 | void cleardir(const string dir) 9 | { 10 | vectorfiles=getAllFilesinDir(dir); 11 | for (int i = 0; i < files.size(); i++) 12 | { 13 | string filepath = dir + "/" + files[i]; 14 | remove(filepath.c_str()); 15 | } 16 | } 17 | 18 | void clearerror(const string dir) 19 | { 20 | vectorsubdirs=getAllSubdirs(dir); 21 | for (int i = 0; i < subdirs.size(); i++) 22 | { 23 | string subdir = dir + "/" + subdirs[i]; 24 | cleardir(subdir); 25 | } 26 | } 27 | 28 | int evaluation() 29 | { 30 | string line; 31 | string label; 32 | int rightcount = 0, errorcount = 0, total = 0; 33 | if (!exist(errordir.c_str())) 34 | { 35 | cout << "Error dir not exist" << endl; 36 | _mkdir(errordir.c_str()); 37 | } 38 | clearerror(errordir); 39 | vectorsubdirs=getAllSubdirs(platedatadir); 40 | for (auto sub : subdirs) 41 | { 42 | string subdir = platedatadir + "/" + sub; 43 | vectorfiles=getAllFilesinDir(subdir); 44 | for (auto file : files) 45 | { 46 | string fileapth = subdir + "/" + file; 47 | cv::Mat img = cv::imread(fileapth); 48 | auto ret = split(CnnPredictor::getInstance()->predict(img), " ")[1]; 49 | if (ret == sub) 50 | rightcount++; 51 | else 52 | { 53 | errorcount++; 54 | string errorlabeldir = errordir; 55 | errorlabeldir = errorlabeldir + "/" + sub; 56 | if (!exist(errorlabeldir.c_str())) 57 | { 58 | _mkdir(errorlabeldir.c_str()); 59 | } 60 | string errorfilepath = errorlabeldir + "/" + file.substr(0,file.size()-4) + "_" + sub + "_" + ret + ".png"; 61 | cout << sub + "/" + file.substr(0, file.size() - 4) + ":" + ret << endl; 62 | imshow("error", img); 63 | imwrite(errorfilepath, img); 64 | cv::waitKey(1); 65 | } 66 | total++; 67 | } 68 | } 69 | cout << "acc:" << rightcount << "/" << total << endl; 70 | cout << rightcount*1.0 / total << endl; 71 | return 0; 72 | } 73 | 74 | int main(int argc,char*argv[]) 75 | { 76 | if (argc==1) 77 | evaluation(); 78 | else 79 | { 80 | cv::Mat img = cv::imread(argv[1]); 81 | cout << CnnPredictor::getInstance()->predict(img) << endl; 82 | } 83 | return 0; 84 | } -------------------------------------------------------------------------------- /Keras/keras.pyproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | 2.0 6 | {66e55ea6-e9fe-41e2-9648-0894cada2385} 7 | . 8 | filtererrors.py 9 | 10 | 11 | . 12 | . 13 | Kaggle 14 | Kaggle 15 | {9a7a9026-48c1-4688-9d5d-e5699d47d074} 16 | 3.5 17 | 18 | 19 | true 20 | false 21 | 22 | 23 | true 24 | false 25 | 26 | 27 | 28 | 29 | 30 | 31 | Code 32 | 33 | 34 | 35 | 36 | 37 | 10.0 38 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets 39 | 40 | 41 | 42 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /pytorch/utils/visualize.py: -------------------------------------------------------------------------------- 1 | # coding:utf8 2 | import visdom 3 | import time 4 | import numpy as np 5 | 6 | 7 | class Visualizer(object): 8 | """ 9 | 封装了visdom的基本操作,但是你仍然可以通过`self.vis.function` 10 | 调用原生的visdom接口 11 | """ 12 | 13 | def __init__(self, env='default', **kwargs): 14 | self.vis = visdom.Visdom(env=env,use_incoming_socket=False, **kwargs) 15 | 16 | # 画的第几个数,相当于横座标 17 | # 保存(’loss',23) 即loss的第23个点 18 | self.index = {} 19 | self.log_text = '' 20 | 21 | def reinit(self, env='default', **kwargs): 22 | """ 23 | 修改visdom的配置 24 | """ 25 | self.vis = visdom.Visdom(env=env, **kwargs) 26 | return self 27 | 28 | def plot_many(self, d): 29 | """ 30 | 一次plot多个 31 | @params d: dict (name,value) i.e. ('loss',0.11) 32 | """ 33 | for k, v in d.items(): 34 | self.plot(k, v) 35 | 36 | def img_many(self, d): 37 | for k, v in d.items(): 38 | self.img(k, v) 39 | 40 | def plot(self, name, y, **kwargs): 41 | """ 42 | self.plot('loss',1.00) 43 | """ 44 | x = self.index.get(name, 0) 45 | self.vis.line(Y=np.array([y]), X=np.array([x]), 46 | win=name, 47 | opts=dict(title=name), 48 | update=None if x == 0 else 'append', 49 | **kwargs 50 | ) 51 | self.index[name] = x + 1 52 | 53 | def img(self, name, img_, **kwargs): 54 | """ 55 | self.img('input_img',t.Tensor(64,64)) 56 | self.img('input_imgs',t.Tensor(3,64,64)) 57 | self.img('input_imgs',t.Tensor(100,1,64,64)) 58 | self.img('input_imgs',t.Tensor(100,3,64,64),nrows=10) 59 | 60 | !!!don‘t ~~self.img('input_imgs',t.Tensor(100,64,64),nrows=10)~~!!! 61 | """ 62 | self.vis.images(img_.cpu().numpy(), 63 | win=name, 64 | opts=dict(title=name), 65 | **kwargs 66 | ) 67 | 68 | def log(self, info, win='log_text'): 69 | """ 70 | self.log({'loss':1,'lr':0.0001}) 71 | """ 72 | 73 | self.log_text += ('[{time}] {info}
'.format( 74 | time=time.strftime('%m%d_%H%M%S'), 75 | info=info)) 76 | self.vis.text(self.log_text, win) 77 | 78 | def __getattr__(self, name): 79 | return getattr(self.vis, name) 80 | -------------------------------------------------------------------------------- /caffe/util/preprocess.py: -------------------------------------------------------------------------------- 1 | import os,argparse,random,shutil 2 | from random import shuffle 3 | 4 | def get_files_by_category(args,set): 5 | datadir=args.datadir#+"/"+set 6 | print("loading data from "+datadir+":") 7 | file=open("util/"+set+".txt","w"); 8 | categoryfile=open("modeldef/labels.txt",'w') 9 | subdirs=os.listdir(datadir) 10 | classindex=0 11 | paths=[] 12 | categorys=[] 13 | for subdir in subdirs: 14 | if(os.path.isdir(datadir+"/"+subdir)): 15 | categorys.append(str(classindex)+" "+subdir) 16 | files=os.listdir(datadir+"/"+subdir) 17 | files=[file for file in files] 18 | random.shuffle(files) 19 | print(subdir,len(files)) 20 | for f in files: 21 | paths.append(subdir+"/"+f+" "+str(classindex)+"\n") 22 | classindex=classindex+1 23 | for category in categorys: 24 | if category==categorys[1]: 25 | categoryfile.write(category) 26 | else: 27 | categoryfile.write(category+"\n") 28 | random.shuffle(paths) 29 | print("writing to "+set+".txt") 30 | for path in paths: 31 | file.write(path) 32 | print(len(paths)) 33 | 34 | def get_datasets(args): 35 | sets=["train","val"] 36 | for set in sets: 37 | get_files_by_category(args,set) 38 | print("generate_txt4lmdb Done") 39 | 40 | def get_files(args): 41 | datadir=args.datadir 42 | files=os.listdir(datadir) 43 | lines=[] 44 | for file in files: 45 | items=file.split(".") 46 | path=file#"data/train/"+ 47 | if items[0]=="cat": 48 | line=path+" 0" 49 | else: 50 | line=path+" 1" 51 | lines.append(line) 52 | shuffle(lines) 53 | with open("util/train.txt","w") as ftrain: 54 | with open("util/val.txt","w") as fval: 55 | for i in range(len(lines)): 56 | line=lines[i] 57 | if i<0.8*len(lines): 58 | ftrain.write(line+"\n") 59 | else: 60 | fval.write(line+"\n") 61 | def get_args(): 62 | parser = argparse.ArgumentParser() 63 | parser.add_argument("--datadir",default="../data/train",help="Directory of images to classify") 64 | #parser.add_argument("--set",default="train",help="set") 65 | args = parser.parse_args() 66 | return args 67 | 68 | if __name__=="__main__": 69 | args=get_args() 70 | #get_datasets(args) 71 | get_files(args) -------------------------------------------------------------------------------- /tensorflow/tf.pyproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | 2.0 6 | 02c4e36d-42e7-4886-a13d-d02aea028759 7 | . 8 | multigpu_train.py 9 | 10 | 11 | . 12 | . 13 | Kaggle 14 | Kaggle 15 | {9a7a9026-48c1-4688-9d5d-e5699d47d074} 16 | 3.5 17 | 18 | 19 | true 20 | false 21 | 22 | 23 | true 24 | false 25 | 26 | 27 | 28 | Code 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 10.0 39 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets 40 | 41 | 42 | 43 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /caffe/convert2lmdb.py: -------------------------------------------------------------------------------- 1 | import os 2 | import lmdb 3 | import caffe 4 | import numpy as np 5 | import cv2 6 | import random 7 | from tqdm import tqdm 8 | import shutil 9 | 10 | new_width=256 11 | new_height=256 12 | 13 | def image2lmdb(split="train",dataroot="../data/train"): 14 | if not os.path.exists("lmdb"): 15 | os.makedirs("lmdb") 16 | lmdb_dir = "lmdb/"+split+"_lmdb" 17 | if os.path.exists(lmdb_dir): 18 | shutil.rmtree(lmdb_dir) 19 | txtpath="util/"+split+".txt" 20 | map_size = 10000000000 21 | db = lmdb.open(lmdb_dir,map_size=map_size) 22 | with db.begin(write=True) as txn: 23 | with open(txtpath) as f: 24 | lines = f.readlines() 25 | if split=="train": 26 | random.shuffle(lines) 27 | for i,line in enumerate(tqdm(lines)): 28 | items = line.split(" ") 29 | if len(items)==2: 30 | filename = items[0] 31 | label = items[1] 32 | datum = caffe.proto.caffe_pb2.Datum() 33 | img = cv2.imread(dataroot+"/"+filename) 34 | if img is None: 35 | print(filename + ' cannot read') 36 | continue 37 | img = cv2.resize(img,(new_width,new_height)) 38 | datum.channels = img.shape[2] 39 | datum.height = img.shape[0] 40 | datum.width = img.shape[1] 41 | datum.data = img.tobytes() 42 | datum.label = int(label) 43 | str_id = '{:08}'.format(i) 44 | txn.put(str_id.encode('ascii'),datum.SerializeToString()) 45 | 46 | def lmdb2image(split="train",show=True,togt=False): 47 | db = lmdb.open("lmdb/"+split+"_lmdb") 48 | txn = db.begin() 49 | cursor = txn.cursor() 50 | for key, value in tqdm(cursor): 51 | datum = caffe.proto.caffe_pb2.Datum() 52 | datum.ParseFromString(value) 53 | img = np.fromstring(datum.data,dtype=np.uint8) 54 | img = img.reshape(datum.channels,datum.height,datum.width).transpose(1,2,0).copy() 55 | label = datum.label 56 | cv2.putText(img,key,(0,20),1,1,(255,0,0)) 57 | cv2.putText(img,str(label),(0,40),3,1,(0,0,255)) 58 | if show: 59 | cv2.imshow("img",img) 60 | cv2.waitKey() 61 | if togt: 62 | cv2.imwrite("gt/"+key,img) 63 | 64 | def main(): 65 | image2lmdb() 66 | image2lmdb("val") 67 | #lmdb2image() 68 | 69 | if __name__=="__main__": 70 | main() -------------------------------------------------------------------------------- /web/app.py: -------------------------------------------------------------------------------- 1 | from __future__ import division, print_function 2 | # coding=utf-8 3 | import sys 4 | import os 5 | import glob 6 | import re 7 | import numpy as np 8 | 9 | # Keras 10 | from keras.applications.imagenet_utils import preprocess_input, decode_predictions 11 | from keras.models import load_model 12 | from keras.preprocessing import image 13 | 14 | # Flask utils 15 | from flask import Flask, redirect, url_for, request, render_template 16 | from werkzeug.utils import secure_filename 17 | from gevent.pywsgi import WSGIServer 18 | 19 | # Define a flask app 20 | app = Flask(__name__) 21 | 22 | class_list=['cat','dog'] 23 | 24 | # Load your trained model 25 | model = load_model("../Keras/model.h5") 26 | # model._make_predict_function() # Necessary 27 | # print('Model loaded. Start serving...') 28 | 29 | # You can also use pretrained model from Keras 30 | # Check https://keras.io/applications/ 31 | from keras.applications.resnet50 import ResNet50 32 | #model = ResNet50(weights='imagenet') 33 | print('Model loaded. Check http://127.0.0.1:5000/') 34 | 35 | 36 | def model_predict(img_path, model): 37 | img = image.load_img(img_path, target_size=(224, 224)) 38 | 39 | # Preprocessing the image 40 | x = image.img_to_array(img) 41 | # x = np.true_divide(x, 255) 42 | x = np.expand_dims(x, axis=0) 43 | 44 | # Be careful how your trained model deals with the input 45 | # otherwise, it won't make correct prediction! 46 | x = preprocess_input(x, mode='caffe') 47 | 48 | preds = model.predict(x) 49 | return preds 50 | 51 | 52 | @app.route('/', methods=['GET']) 53 | def index(): 54 | # Main page 55 | return render_template('index.html') 56 | 57 | 58 | @app.route('/predict', methods=['GET', 'POST']) 59 | def upload(): 60 | if request.method == 'POST': 61 | # Get the file from post request 62 | f = request.files['file'] 63 | 64 | # Save the file to ./uploads 65 | basepath = os.path.dirname(__file__) 66 | file_path = os.path.join( 67 | basepath, 'uploads', secure_filename(f.filename)) 68 | f.save(file_path) 69 | 70 | # Make prediction 71 | preds = model_predict(file_path, model) 72 | 73 | # Process your result for human 74 | pred_class = (int)(preds.argmax(axis=-1)) # Simple argmax 75 | #pred_class = decode_predictions(preds, top=1) # ImageNet Decode 76 | #result = str(pred_class[0][0][1]) # Convert to string 77 | result=class_list[pred_class]+":"+str(preds[0][pred_class]) 78 | #print(result) 79 | return result 80 | return None 81 | 82 | 83 | if __name__ == '__main__': 84 | # app.run(port=5002, debug=True) 85 | 86 | # Serve the app with gevent 87 | http_server = WSGIServer(('', 5000), app) 88 | http_server.serve_forever() 89 | -------------------------------------------------------------------------------- /caffe/cpp/evaluation.cpp: -------------------------------------------------------------------------------- 1 | #include "mrdir.h" 2 | #include "mrutil.h" 3 | #include "mropencv.h" 4 | #include "LenetClassifier.h" 5 | using namespace std; 6 | const string errordir = caffeplatedir + "/error"; 7 | const string platedatadir = caffeplatedir + "/data"; 8 | 9 | void cleardir(const string dir) 10 | { 11 | vectorfiles=getAllFilesinDir(dir); 12 | for (int i = 0; i < files.size(); i++) 13 | { 14 | string filepath = dir + "/" + files[i]; 15 | remove(filepath.c_str()); 16 | } 17 | } 18 | 19 | void clearerror(const string dir) 20 | { 21 | cout << "clearing" << dir << endl; 22 | vectorsubdirs=getAllSubdirs(dir); 23 | for (int i = 0; i < subdirs.size(); i++) 24 | { 25 | string subdir = dir + "/" + subdirs[i]; 26 | cout << subdirs[i]<subdirs=getAllSubdirs(platedatadir); 44 | for (auto sub : subdirs) 45 | { 46 | string subdir = platedatadir + "/" + sub; 47 | vectorfiles=getAllFilesinDir(subdir); 48 | for (auto file : files) 49 | { 50 | string fileapth = subdir + "/" + file; 51 | cv::Mat img = cv::imread(fileapth); 52 | auto ret=CLenetClassifier::getInstance()->predict(img).first; 53 | if (ret == string2int(sub)) 54 | rightcount++; 55 | else 56 | { 57 | cout << sub + "/" + file.substr(0, file.size() - 4) + ":" + int2string(ret) << endl; 58 | errorcount++; 59 | string errorlabeldir = errordir; 60 | errorlabeldir = errorlabeldir + "/" + sub; 61 | if (!EXISTS(errorlabeldir.c_str())) 62 | { 63 | MKDIR(errorlabeldir.c_str()); 64 | } 65 | string errorfilepath = errorlabeldir + "/" + file.substr(0,file.size()-4) + "_" + sub + "_" + int2string(ret) + ".png"; 66 | imshow("error", img); 67 | imwrite(errorfilepath, img); 68 | cv::waitKey(1); 69 | } 70 | total++; 71 | } 72 | } 73 | cout << "acc:" << rightcount << "/" << total << endl; 74 | cout << rightcount*1.0 / total << endl; 75 | return 0; 76 | } 77 | 78 | int testimg(const std::string imgpath = "img/0.jpg") 79 | { 80 | cv::Mat img = imread(imgpath); 81 | TickMeter tm; 82 | tm.start(); 83 | auto p = CLenetClassifier::getInstance()->predict(img); 84 | tm.stop(); 85 | std::cout << p.first << std::endl;// " " << p.second << endl; 86 | std::cout << tm.getTimeMilli() << "ms" << std::endl; 87 | return 0; 88 | } 89 | 90 | int testdir(const std::string dir = "img") 91 | { 92 | auto files = getAllFilesinDir(dir); 93 | for (int i = 0; i < files.size(); i++) 94 | { 95 | std::string imgpath = dir + "/" + files[i]; 96 | std::cout << files[i] << ":"; 97 | testimg(imgpath); 98 | } 99 | return 0; 100 | } 101 | 102 | int main(int argc,char*argv[]) 103 | { 104 | if (argc==1) 105 | evaluation(); 106 | else 107 | { 108 | testimg(); 109 | testdir(); 110 | } 111 | return 0; 112 | } -------------------------------------------------------------------------------- /Keras/filtererrors.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import os,shutil 3 | import tensorflow as tf 4 | 5 | tf.app.flags.DEFINE_string('train_dir', '../data/train2', 'The directory of train dataset.') 6 | 7 | FLAGS = tf.app.flags.FLAGS 8 | 9 | dst_dir="errors" 10 | # 无法识别的四种类型,需要从训练集中删去 11 | no_cat_or_dog = ["dog.1773", "cat.11184", "cat.4338", "cat.10712", "dog.10747", 12 | "dog.10237", "dog.10801", "cat.5418", "cat.5351", "dog.2614", 13 | "dog.4367", "dog.5604", "dog.8736", "dog.9517", "dog.11299"] 14 | both_cat_and_dog = ["cat.5583", "cat.3822", "cat.9250", "cat.10863", "cat.4688", 15 | "cat.11724", "cat.11222", "cat.10266", "cat.9444", "cat.7920", 16 | "cat.7194", "cat.5355", "cat.724", "dog.2461", "dog.8507"] 17 | hard_to_recognition = ["cat.6402", "cat.6987", "dog.11083", "cat.12499", "cat.2753", 18 | "dog.669", "cat.2150", "dog.5490", "cat.12493", "cat.7703", 19 | "dog.3430", "cat.2433", "cat.3250", "dog.4386", "dog.12223", 20 | "cat.9770", "cat.9626", "cat.6649", "cat.5324", "cat.335", 21 | "cat.10029", "dog.1835", "dog.3322", "dog.3524", "dog.6921", 22 | "dog.7413", "dog.10939", "dog.11248"] 23 | too_abstract_image = ["dog.8898", "dog.1895", "dog.4690", "dog.1308", "dog.10190", 24 | "dog.10161"] 25 | 26 | # 标注反了,需要修改标注 27 | label_reverse = ["cat.4085", "cat.12272", "dog.2877", "dog.4334", "dog.10401", "dog.10797", 28 | "dog.11731"] 29 | 30 | cat_index = 12500 31 | dog_index = 12500 32 | 33 | def mklink(): 34 | train_dir="../data/train" 35 | files=os.listdir(train_dir) 36 | train_cat=filter(lambda x:x[:3]=="cat",files) 37 | train_dog=filter(lambda x:x[:3]=="dog",files) 38 | for file in train_cat: 39 | #os.syslink(train_dir+"/"+file,"train2/cat/"+file) 40 | shutil.copyfile(train_dir+"/"+file,"../data/train2/cat/"+file) 41 | for file in train_dog: 42 | #os.syslink(train_dir+"/"+file,"train2/dog/"+file) 43 | shutil.copyfile(train_dir+"/"+file,"../data/train2/dog/"+file) 44 | 45 | def mv_image_in_list(name_list): 46 | for name in name_list: 47 | cls=name.split(".")[0] 48 | path = os.path.join(FLAGS.train_dir, cls,name + ".jpg") 49 | dst_path=dst_dir+"/"+name + ".jpg" 50 | if os.path.exists(path): 51 | shutil.move(path,dst_path) 52 | 53 | def change_label_in_list(name_list): 54 | global cat_index 55 | global dog_index 56 | for name in name_list: 57 | cls=name.split(".")[0] 58 | path = os.path.join(FLAGS.train_dir,cls, name + ".jpg") 59 | if os.path.exists(path): 60 | if "cat" in name: 61 | new_name = "dog." + str(dog_index) 62 | dog_index += 1 63 | else: 64 | new_name = "cat." + str(cat_index) 65 | cat_index += 1 66 | new_path = os.path.join(FLAGS.train_dir,new_name.split(".")[0],new_name + ".jpg") 67 | os.rename(path, new_path) 68 | 69 | if __name__=="__main__": 70 | mklink() 71 | if not os.path.exists(dst_dir): 72 | os.makedirs(dst_dir) 73 | #mv_image_in_list(no_cat_or_dog) 74 | #mv_image_in_list(both_cat_and_dog) 75 | #mv_image_in_list(hard_to_recognition) 76 | #mv_image_in_list(too_abstract_image) 77 | change_label_in_list(label_reverse) -------------------------------------------------------------------------------- /paddle/utils/dist_utils.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | 15 | from __future__ import absolute_import 16 | from __future__ import division 17 | from __future__ import print_function 18 | import os 19 | import paddle.fluid as fluid 20 | 21 | 22 | def nccl2_prepare(args, startup_prog, main_prog): 23 | config = fluid.DistributeTranspilerConfig() 24 | config.mode = "nccl2" 25 | t = fluid.DistributeTranspiler(config=config) 26 | 27 | envs = args.dist_env 28 | 29 | t.transpile( 30 | envs["trainer_id"], 31 | trainers=','.join(envs["trainer_endpoints"]), 32 | current_endpoint=envs["current_endpoint"], 33 | startup_program=startup_prog, 34 | program=main_prog) 35 | 36 | 37 | def pserver_prepare(args, train_prog, startup_prog): 38 | config = fluid.DistributeTranspilerConfig() 39 | config.slice_var_up = args.split_var 40 | t = fluid.DistributeTranspiler(config=config) 41 | envs = args.dist_env 42 | training_role = envs["training_role"] 43 | 44 | t.transpile( 45 | envs["trainer_id"], 46 | program=train_prog, 47 | pservers=envs["pserver_endpoints"], 48 | trainers=envs["num_trainers"], 49 | sync_mode=not args.async_mode, 50 | startup_program=startup_prog) 51 | if training_role == "PSERVER": 52 | pserver_program = t.get_pserver_program(envs["current_endpoint"]) 53 | pserver_startup_program = t.get_startup_program( 54 | envs["current_endpoint"], 55 | pserver_program, 56 | startup_program=startup_prog) 57 | return pserver_program, pserver_startup_program 58 | elif training_role == "TRAINER": 59 | train_program = t.get_trainer_program() 60 | return train_program, startup_prog 61 | else: 62 | raise ValueError( 63 | 'PADDLE_TRAINING_ROLE environment variable must be either TRAINER or PSERVER' 64 | ) 65 | 66 | 67 | def nccl2_prepare_paddle(trainer_id, startup_prog, main_prog): 68 | config = fluid.DistributeTranspilerConfig() 69 | config.mode = "nccl2" 70 | t = fluid.DistributeTranspiler(config=config) 71 | t.transpile( 72 | trainer_id, 73 | trainers=os.environ.get('PADDLE_TRAINER_ENDPOINTS'), 74 | current_endpoint=os.environ.get('PADDLE_CURRENT_ENDPOINT'), 75 | startup_program=startup_prog, 76 | program=main_prog) 77 | 78 | 79 | def prepare_for_multi_process(exe, build_strategy, train_prog): 80 | # prepare for multi-process 81 | trainer_id = int(os.environ.get('PADDLE_TRAINER_ID', 0)) 82 | num_trainers = int(os.environ.get('PADDLE_TRAINERS_NUM', 1)) 83 | if num_trainers < 2: return 84 | print("PADDLE_TRAINERS_NUM", num_trainers) 85 | print("PADDLE_TRAINER_ID", trainer_id) 86 | build_strategy.num_trainers = num_trainers 87 | build_strategy.trainer_id = trainer_id 88 | # NOTE(zcd): use multi processes to train the model, 89 | # and each process use one GPU card. 90 | startup_prog = fluid.Program() 91 | nccl2_prepare_paddle(trainer_id, startup_prog, train_prog) 92 | # the startup_prog are run two times, but it doesn't matter. 93 | exe.run(startup_prog) 94 | -------------------------------------------------------------------------------- /paddle/models/__init__.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | 15 | from .alexnet import AlexNet 16 | from .mobilenet_v1 import MobileNetV1_x0_25, MobileNetV1_x0_5, MobileNetV1_x1_0, MobileNetV1_x0_75, MobileNetV1 17 | from .mobilenet_v2 import MobileNetV2_x0_25, MobileNetV2_x0_5, MobileNetV2_x0_75, MobileNetV2_x1_0, MobileNetV2_x1_5, MobileNetV2_x2_0, MobileNetV2 18 | from .mobilenet_v3 import MobileNetV3_small_x0_25, MobileNetV3_small_x0_5, MobileNetV3_small_x0_75, MobileNetV3_small_x1_0, MobileNetV3_small_x1_25, MobileNetV3_large_x0_25, MobileNetV3_large_x0_5, MobileNetV3_large_x0_75, MobileNetV3_large_x1_0, MobileNetV3_large_x1_25 19 | from .googlenet import GoogLeNet 20 | from .vgg import VGG11, VGG13, VGG16, VGG19 21 | from .resnet import ResNet18, ResNet34, ResNet50, ResNet101, ResNet152 22 | from .resnet_vc import ResNet50_vc, ResNet101_vc, ResNet152_vc 23 | from .resnet_vd import ResNet18_vd, ResNet34_vd, ResNet50_vd, ResNet101_vd, ResNet152_vd, ResNet200_vd 24 | from .resnext import ResNeXt50_64x4d, ResNeXt101_64x4d, ResNeXt152_64x4d, ResNeXt50_32x4d, ResNeXt101_32x4d, ResNeXt152_32x4d 25 | from .resnext_vd import ResNeXt50_vd_64x4d, ResNeXt101_vd_64x4d, ResNeXt152_vd_64x4d, ResNeXt50_vd_32x4d, ResNeXt101_vd_32x4d, ResNeXt152_vd_32x4d 26 | from .inception_v4 import InceptionV4 27 | from .se_resnet_vd import SE_ResNet18_vd, SE_ResNet34_vd, SE_ResNet50_vd, SE_ResNet101_vd, SE_ResNet152_vd, SE_ResNet200_vd 28 | from .se_resnext import SE_ResNeXt50_32x4d, SE_ResNeXt101_32x4d, SE_ResNeXt152_32x4d 29 | from .se_resnext_vd import SE_ResNeXt50_vd_32x4d, SE_ResNeXt101_vd_32x4d, SENet154_vd 30 | from .dpn import DPN68, DPN92, DPN98, DPN107, DPN131 31 | from .shufflenet_v2_swish import ShuffleNetV2_swish, ShuffleNetV2_x0_5_swish, ShuffleNetV2_x1_0_swish, ShuffleNetV2_x1_5_swish, ShuffleNetV2_x2_0_swish 32 | from .shufflenet_v2 import ShuffleNetV2_x0_25, ShuffleNetV2_x0_33, ShuffleNetV2_x0_5, ShuffleNetV2_x1_0, ShuffleNetV2_x1_5, ShuffleNetV2_x2_0, ShuffleNetV2 33 | from .fast_imagenet import FastImageNet 34 | from .xception import Xception41, Xception65, Xception71 35 | from .xception_deeplab import Xception41_deeplab, Xception65_deeplab, Xception71_deeplab 36 | from .densenet import DenseNet121, DenseNet161, DenseNet169, DenseNet201, DenseNet264 37 | from .squeezenet import SqueezeNet1_0, SqueezeNet1_1 38 | from .darknet import DarkNet53 39 | from .resnext101_wsl import ResNeXt101_32x8d_wsl, ResNeXt101_32x16d_wsl, ResNeXt101_32x32d_wsl, ResNeXt101_32x48d_wsl, Fix_ResNeXt101_32x48d_wsl 40 | from .efficientnet import EfficientNet, EfficientNetB0, EfficientNetB1, EfficientNetB2, EfficientNetB3, EfficientNetB4, EfficientNetB5, EfficientNetB6, EfficientNetB7 41 | from .res2net import Res2Net50_48w_2s, Res2Net50_26w_4s, Res2Net50_14w_8s, Res2Net50_26w_6s, Res2Net50_26w_8s, Res2Net101_26w_4s, Res2Net152_26w_4s 42 | from .res2net_vd import Res2Net50_vd_48w_2s, Res2Net50_vd_26w_4s, Res2Net50_vd_14w_8s, Res2Net50_vd_26w_6s, Res2Net50_vd_26w_8s, Res2Net101_vd_26w_4s, Res2Net152_vd_26w_4s, Res2Net200_vd_26w_4s 43 | from .hrnet import HRNet_W18_C, HRNet_W30_C, HRNet_W32_C, HRNet_W40_C, HRNet_W44_C, HRNet_W48_C, HRNet_W60_C, HRNet_W64_C, SE_HRNet_W18_C, SE_HRNet_W30_C, SE_HRNet_W32_C, SE_HRNet_W40_C, SE_HRNet_W44_C, SE_HRNet_W48_C, SE_HRNet_W60_C, SE_HRNet_W64_C 44 | -------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | # Deploy Keras Model with Flask as Web App in 10 Minutes 2 | 3 | [![](https://img.shields.io/badge/python-2.7%2C%203.5%2B-green.svg)]() 4 | [![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](http://perso.crans.org/besson/LICENSE.html) 5 | 6 | > A pretty and customizable web app to deploy your DL model with ease 7 | 8 | ------------------ 9 | 10 | ## Getting started in 10 minutes 11 | 12 | - Clone this repo 13 | - Install requirements 14 | - Run the script 15 | - Check http://localhost:5000 16 | - Done! :tada: 17 | 18 | :point_down:Screenshot: 19 | 20 |

21 | 22 |

23 | 24 | ------------------ 25 | 26 | ## Docker Installation 27 | 28 | Build the image 29 | 30 | ```shell 31 | cd keras-flask-deploy-webapp 32 | docker build -t keras_flask . 33 | docker run -e MODEL_PATH=models/your_model.h5 -p 5000:5000 34 | ``` 35 | 36 | You can mount your model into the container. 37 | 38 | ```shell 39 | docker run -e MODEL_PATH=/mnt/models/your_model.h5 -v volume-name:/mnt/models -p 5000:5000 keras_flask 40 | ``` 41 | 42 | 43 | ## Local Installation 44 | 45 | ### Clone the repo 46 | ```shell 47 | $ git clone https://github.com/mtobeiyf/keras-flask-deploy-webapp.git 48 | ``` 49 | 50 | ### Install requirements 51 | 52 | ```shell 53 | $ pip install -r requirements.txt 54 | ``` 55 | 56 | Make sure you have the following installed: 57 | - tensorflow 58 | - keras 59 | - flask 60 | - pillow 61 | - h5py 62 | - gevent 63 | 64 | ### Run with Python 65 | 66 | Python 2.7 or 3.5+ are supported and tested. 67 | 68 | ```shell 69 | $ python app.py 70 | ``` 71 | 72 | ### Play 73 | 74 | Open http://localhost:5000 and have fun. :smiley: 75 | 76 |

77 | 78 |

79 | 80 | ------------------ 81 | 82 | ## Customization 83 | 84 | ### Use your own model 85 | 86 | Place your trained `.h5` file saved by `model.save()` under models directory. 87 | 88 | Check the [commented code](https://github.com/mtobeiyf/keras-flask-deploy-webapp/blob/master/app.py#L25) in app.py. 89 | 90 | 91 | ### Use other pre-trained model 92 | 93 | See [Keras applications](https://keras.io/applications/) for more available models such as DenseNet, MobilNet, NASNet, etc. 94 | 95 | Check [this section](https://github.com/mtobeiyf/keras-flask-deploy-webapp/blob/master/app.py#L25) in app.py. 96 | 97 | ### UI Modification 98 | 99 | Modify files in `templates` and `static` directory. 100 | 101 | `index.html` for the UI and `main.js` for all the behaviors 102 | 103 | ## Deployment 104 | 105 | To deploy it for public use, you need to have a public **linux server**. 106 | 107 | ### Run the app 108 | 109 | Run the script and hide it in background with `tmux` or `screen`. 110 | ``` 111 | $ python app.py 112 | ``` 113 | 114 | You can also use gunicorn instead of gevent 115 | ``` 116 | $ gunicorn -b 127.0.0.1:5000 app:app 117 | ``` 118 | 119 | More deployment options, check [here](http://flask.pocoo.org/docs/0.12/deploying/wsgi-standalone/) 120 | 121 | ### Set up Nginx 122 | 123 | To redirect the traffic to your local app. 124 | Configure your Nginx `.conf` file. 125 | ``` 126 | server { 127 | listen 80; 128 | 129 | client_max_body_size 20M; 130 | 131 | location / { 132 | proxy_pass http://127.0.0.1:5000; 133 | } 134 | } 135 | ``` 136 | 137 | ## More resources 138 | 139 | Check Siraj's ["How to Deploy a Keras Model to Production"](https://youtu.be/f6Bf3gl4hWY) video. The corresponding [repo](https://github.com/llSourcell/how_to_deploy_a_keras_model_to_production). 140 | 141 | [Building a simple Keras + deep learning REST API](https://blog.keras.io/building-a-simple-keras-deep-learning-rest-api.html) 142 | -------------------------------------------------------------------------------- /tensorflow/train.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #DATASET_NAME= 3 | export CUDA_VISIBLE_DEVICES=0 4 | cd ~/models/research/slim 5 | TENSORFLOW_DIR=~/CNN/tensorflow 6 | #DATASET_NAME=catdogs 7 | DATASET_NAME=flowers 8 | DATASET_DIR=/home/yanyu/data/${DATASET_NAME} 9 | MODEL_NAME=inception_v3 10 | #resnet_v1_50 11 | #resnet_v1_50 12 | #mobilenet_v1 13 | #inception_v4 14 | #inception_v3 15 | CHECKPOINT_PATH=${MODEL_NAME}/${MODEL_NAME}.ckpt 16 | TRAIN_DIR=/tmp/${DATASET_NAME}-models/${MODEL_NAME} 17 | STEPS=1000 18 | 19 | #prepare data 20 | #DATA_DIR=/media/yanyu/1882684582682A08/CNN/Kaggle/data 21 | #python download_and_convert_data.py --dataset_name=${DATASET_NAME} --dataset_dir="${DATA_DIR}" 22 | 23 | #train model 24 | #python train_image_classifier.py --train_dir=${TRAIN_DIR} --dataset_dir=${DATASET_DIR} --dataset_name=${DATASET_NAME} --dataset_split_name=train --model_name=${MODEL_NAME} --max_number_of_steps=${STEPS} --checkpoint_path=${CHECKPOINT_PATH} --checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits --trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits 25 | 26 | #eval model 27 | #python eval_image_classifier.py --checkpoint_path=${TRAIN_DIR} --eval_dir=models/${DATASET_NAME}/ --dataset_name=${DATASET_NAME} --dataset_split_name=validation --dataset_dir=${DATASET_DIR} --model_name=${MODEL_NAME} 28 | 29 | #Generating inference graph 30 | if [ -f ${MODEL_NAME}_inf_graph.pb ] 31 | then 32 | echo "Inference model already exists." 33 | else 34 | python export_inference_graph.py --alsologtostderr --model_name=${MODEL_NAME} --output_file=${MODEL_NAME}_inf_graph.pb --dataset_dir=${DATASET_DIR} --dataset_name=${DATASET_NAME} 35 | fi 36 | #Get output nodes 37 | #${TENSORFLOW_DIR}/bazel-bin/tensorflow/tools/graph_transforms/summarize_graph --in_graph=${MODEL_NAME}_inf_graph.pb 38 | #freeze_gprah 39 | if [ -f frozen_${MODEL_NAME}.pb ] 40 | then 41 | echo "Freezon model already exists." 42 | else 43 | ${TENSORFLOW_DIR}/bazel-bin/tensorflow/python/tools/freeze_graph --input_graph=${MODEL_NAME}_inf_graph.pb --input_checkpoint=${TRAIN_DIR}/model.ckpt-${STEPS} --input_binary=true --output_graph=frozen_${MODEL_NAME}.pb --output_node_names=InceptionV3/Predictions/Reshape_1 44 | fi 45 | 46 | #test model 47 | ${TENSORFLOW_DIR}/bazel-bin/tensorflow/examples/label_image/label_image --image=rose.jpg --input_layer=input --output_layer=InceptionV3/Predictions/Reshape_1 --graph=frozen_${MODEL_NAME}.pb --labels=/home/yanyu/data/flowers/labels.txt --input_mean=0 --input_std=255 48 | 49 | exit 50 | #To tflite 51 | #${TENSORFLOW_DIR}/bazel-bin/tensorflow/contrib/lite/toco/toco --input_file=frozen_${MODEL_NAME}.pb --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --output_file=${MODEL_NAME}.lite --inference_type=FLOAT --input_type=FLOAT --input_arrays=input --output_arrays=InceptionV3/Predictions/Reshape_1 --input_shapes=1,299,299,3 52 | 53 | #${TENSORFLOW_DIR}/bazel-bin/tensorflow/contrib/lite/examples/label_image/label_image -i rose.jpg -l /home/yanyu/data/flowers/labels.txt -m ${MODEL_NAME}.lite -a 0 -c 1 -s 255 54 | #optimized_graph 55 | if [ -f optimized_graph.pb ] 56 | then 57 | echo "optimized_graph exists" 58 | else 59 | #${TENSORFLOW_DIR}/bazel-bin/tensorflow/python/tools/optimize_for_inference --input=frozen_${MODEL_NAME}.pb --output=optimized_graph.pb --input_names=input --output_names=InceptionV1/Predictions/Reshape_1 60 | fi 61 | #quantize 62 | if [ -f quantized_graph.pb ] 63 | then 64 | echo "quantized_graph exists" 65 | else 66 | #${TENSORFLOW_DIR}/bazel-bin/tensorflow/tools/quantization/quantize_graph --input=optimized_graph.pb --output_node_names=InceptionV3/Predictions/Reshape_1 --output=quantized_graph.pb --mode=eightbit 67 | fi 68 | if [ -f quantized_graph.pb ] 69 | then 70 | #${TENSORFLOW_DIR}/bazel-bin/tensorflow/examples/label_image/label_image --image=rose.jpg --input_layer=input --output_layer=InceptionV3/Predictions/Reshape_1 --graph=quantized_graph.pb --labels=/home/yanyu/data/flowers/labels.txt --input_mean=0 --input_std=255 71 | fi -------------------------------------------------------------------------------- /paddle/models/vgg.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | 15 | from __future__ import absolute_import 16 | from __future__ import division 17 | from __future__ import print_function 18 | 19 | import paddle 20 | import paddle.fluid as fluid 21 | 22 | __all__ = ["VGGNet", "VGG11", "VGG13", "VGG16", "VGG19"] 23 | 24 | 25 | class VGGNet(): 26 | def __init__(self, layers=16): 27 | self.layers = layers 28 | 29 | def net(self, input, class_dim=1000): 30 | layers = self.layers 31 | vgg_spec = { 32 | 11: ([1, 1, 2, 2, 2]), 33 | 13: ([2, 2, 2, 2, 2]), 34 | 16: ([2, 2, 3, 3, 3]), 35 | 19: ([2, 2, 4, 4, 4]) 36 | } 37 | assert layers in vgg_spec.keys(), \ 38 | "supported layers are {} but input layer is {}".format(vgg_spec.keys(), layers) 39 | 40 | nums = vgg_spec[layers] 41 | conv1 = self.conv_block(input, 64, nums[0], name="conv1_") 42 | conv2 = self.conv_block(conv1, 128, nums[1], name="conv2_") 43 | conv3 = self.conv_block(conv2, 256, nums[2], name="conv3_") 44 | conv4 = self.conv_block(conv3, 512, nums[3], name="conv4_") 45 | conv5 = self.conv_block(conv4, 512, nums[4], name="conv5_") 46 | 47 | fc_dim = 4096 48 | fc_name = ["fc6", "fc7", "fc8"] 49 | fc1 = fluid.layers.fc( 50 | input=conv5, 51 | size=fc_dim, 52 | act='relu', 53 | param_attr=fluid.param_attr.ParamAttr(name=fc_name[0] + "_weights"), 54 | bias_attr=fluid.param_attr.ParamAttr(name=fc_name[0] + "_offset")) 55 | fc1 = fluid.layers.dropout(x=fc1, dropout_prob=0.5) 56 | fc2 = fluid.layers.fc( 57 | input=fc1, 58 | size=fc_dim, 59 | act='relu', 60 | param_attr=fluid.param_attr.ParamAttr(name=fc_name[1] + "_weights"), 61 | bias_attr=fluid.param_attr.ParamAttr(name=fc_name[1] + "_offset")) 62 | fc2 = fluid.layers.dropout(x=fc2, dropout_prob=0.5) 63 | out = fluid.layers.fc( 64 | input=fc2, 65 | size=class_dim, 66 | param_attr=fluid.param_attr.ParamAttr(name=fc_name[2] + "_weights"), 67 | bias_attr=fluid.param_attr.ParamAttr(name=fc_name[2] + "_offset")) 68 | 69 | return out 70 | 71 | def conv_block(self, input, num_filter, groups, name=None): 72 | conv = input 73 | for i in range(groups): 74 | conv = fluid.layers.conv2d( 75 | input=conv, 76 | num_filters=num_filter, 77 | filter_size=3, 78 | stride=1, 79 | padding=1, 80 | act='relu', 81 | param_attr=fluid.param_attr.ParamAttr( 82 | name=name + str(i + 1) + "_weights"), 83 | bias_attr=False) 84 | return fluid.layers.pool2d( 85 | input=conv, pool_size=2, pool_type='max', pool_stride=2) 86 | 87 | 88 | def VGG11(): 89 | model = VGGNet(layers=11) 90 | return model 91 | 92 | 93 | def VGG13(): 94 | model = VGGNet(layers=13) 95 | return model 96 | 97 | 98 | def VGG16(): 99 | model = VGGNet(layers=16) 100 | return model 101 | 102 | 103 | def VGG19(): 104 | model = VGGNet(layers=19) 105 | return model 106 | -------------------------------------------------------------------------------- /Keras/keras2tf.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import keras,os 3 | import tensorflow as tf 4 | import numpy as np 5 | from keras import backend as K 6 | from keras.models import load_model 7 | from keras.preprocessing import image 8 | from tensorflow.python.framework import graph_io 9 | from keras.backend.tensorflow_backend import set_session 10 | 11 | config = tf.ConfigProto() 12 | config.gpu_options.allow_growth=True 13 | set_session(tf.Session(config=config)) 14 | 15 | cls_list = ['cats', 'dogs'] 16 | 17 | #h5_model_path="model.h5" 18 | #inputnode_name="conv2d_1_input:0" 19 | #outputnode_name="activation_4/Softmax:0" 20 | 21 | h5_model_path="model97.18.h5"#99.98.h5 22 | inputnode_name="input_1:0" 23 | outputnode_name="dense_2/Softmax:0" 24 | 25 | pb_model_name="model.pb" 26 | 27 | tf_model_path="./model/ckpt" 28 | 29 | def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True): 30 | from tensorflow.python.framework.graph_util import convert_variables_to_constants 31 | graph = session.graph 32 | with graph.as_default(): 33 | freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or [])) 34 | output_names = output_names or [] 35 | output_names += [v.op.name for v in tf.global_variables()] 36 | input_graph_def = graph.as_graph_def() 37 | if clear_devices: 38 | for node in input_graph_def.node: 39 | node.device = "" 40 | frozen_graph = convert_variables_to_constants(session, input_graph_def, 41 | output_names, freeze_var_names) 42 | return frozen_graph 43 | 44 | 45 | def keras2pb(): 46 | K.set_learning_phase(0) 47 | net_model = load_model(h5_model_path) 48 | sess = K.get_session() 49 | frozen_graph = freeze_session(K.get_session(), output_names=[net_model.output.op.name]) 50 | graph_io.write_graph(frozen_graph,"./", pb_model_name, as_text=False) 51 | 52 | def keras_to_tf(): 53 | K.set_learning_phase(0) 54 | net_model = load_model(h5_model_path) 55 | saver = tf.train.Saver() 56 | with K.get_session() as sess: 57 | K.set_learning_phase(0) 58 | saver.save(sess, tf_model_path) 59 | return True 60 | 61 | def tf_to_graph(tf_model_path, model_in, model_out, graph_path): 62 | os.system('mvNCCompile {0}.meta -in {1} -on {2} -o {3}'.format(tf_model_path, model_in, model_out, graph_path)) 63 | return True 64 | 65 | def keras_to_graph(): 66 | keras_to_tf() 67 | tf_to_graph(tf_model_path, "input_1", "dense_2/Softmax", "graph") 68 | 69 | 70 | def loadpb_test(imgpath="../data/train/cat.0.jpg"): 71 | with tf.Graph().as_default(): 72 | output_graph_def = tf.GraphDef() 73 | 74 | # 打开.pb模型 75 | with open(pb_model_name, "rb") as f: 76 | output_graph_def.ParseFromString(f.read()) 77 | tensors = tf.import_graph_def(output_graph_def, name="") 78 | print("tensors:",tensors) 79 | 80 | # 在一个session中去run一个前向 81 | with tf.Session() as sess: 82 | init = tf.global_variables_initializer() 83 | sess.run(init) 84 | 85 | op = sess.graph.get_operations() 86 | 87 | # 打印图中有的操作 88 | for i,m in enumerate(op): 89 | print('op{}:'.format(i),m.values()) 90 | 91 | #input_x = sess.graph.get_tensor_by_name("") # 具体名称看上一段代码的input.name 92 | input_x = sess.graph.get_tensor_by_name(inputnode_name) 93 | #print("input_X:",input_x) 94 | 95 | #out_softmax = sess.graph.get_tensor_by_name("") # 具体名称看上一段代码的output.name 96 | out_softmax = sess.graph.get_tensor_by_name(outputnode_name) 97 | #print("Output:",out_softmax) 98 | img=image.load_img(imgpath, target_size=(224,224)) 99 | x = image.img_to_array(img) 100 | x = keras.applications.resnet50.preprocess_input(x) 101 | x = np.expand_dims(x, axis=0) 102 | pred= sess.run(out_softmax,feed_dict={input_x: x}) 103 | print(pred) 104 | for i in range(len(pred[0])): 105 | print(' {:.3f} {}'.format(pred[0][i], cls_list[i])) 106 | 107 | if __name__=="__main__": 108 | keras2pb() 109 | loadpb_test() 110 | #keras_to_graph() -------------------------------------------------------------------------------- /paddle/models/darknet.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | from __future__ import absolute_import 15 | from __future__ import division 16 | from __future__ import print_function 17 | 18 | import paddle.fluid as fluid 19 | from paddle.fluid.param_attr import ParamAttr 20 | import math 21 | __all__ = ["DarkNet53"] 22 | 23 | 24 | class DarkNet53(): 25 | def __init__(self): 26 | 27 | pass 28 | 29 | def net(self, input, class_dim=1000): 30 | DarkNet_cfg = {53: ([1, 2, 8, 8, 4], self.basicblock)} 31 | stages, block_func = DarkNet_cfg[53] 32 | stages = stages[0:5] 33 | conv1 = self.conv_bn_layer( 34 | input, 35 | ch_out=32, 36 | filter_size=3, 37 | stride=1, 38 | padding=1, 39 | name="yolo_input") 40 | conv = self.downsample( 41 | conv1, ch_out=conv1.shape[1] * 2, name="yolo_input.downsample") 42 | 43 | for i, stage in enumerate(stages): 44 | conv = self.layer_warp( 45 | block_func, conv, 32 * (2**i), stage, name="stage.{}".format(i)) 46 | if i < len(stages) - 1: # do not downsaple in the last stage 47 | conv = self.downsample( 48 | conv, 49 | ch_out=conv.shape[1] * 2, 50 | name="stage.{}.downsample".format(i)) 51 | pool = fluid.layers.pool2d( 52 | input=conv, pool_type='avg', global_pooling=True) 53 | stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0) 54 | out = fluid.layers.fc( 55 | input=pool, 56 | size=class_dim, 57 | param_attr=ParamAttr( 58 | initializer=fluid.initializer.Uniform(-stdv, stdv), 59 | name='fc_weights'), 60 | bias_attr=ParamAttr(name='fc_offset')) 61 | return out 62 | 63 | def conv_bn_layer(self, 64 | input, 65 | ch_out, 66 | filter_size, 67 | stride, 68 | padding, 69 | name=None): 70 | conv = fluid.layers.conv2d( 71 | input=input, 72 | num_filters=ch_out, 73 | filter_size=filter_size, 74 | stride=stride, 75 | padding=padding, 76 | act=None, 77 | param_attr=ParamAttr(name=name + ".conv.weights"), 78 | bias_attr=False) 79 | 80 | bn_name = name + ".bn" 81 | out = fluid.layers.batch_norm( 82 | input=conv, 83 | act='relu', 84 | param_attr=ParamAttr(name=bn_name + '.scale'), 85 | bias_attr=ParamAttr(name=bn_name + '.offset'), 86 | moving_mean_name=bn_name + '.mean', 87 | moving_variance_name=bn_name + '.var') 88 | return out 89 | 90 | def downsample(self, 91 | input, 92 | ch_out, 93 | filter_size=3, 94 | stride=2, 95 | padding=1, 96 | name=None): 97 | return self.conv_bn_layer( 98 | input, 99 | ch_out=ch_out, 100 | filter_size=filter_size, 101 | stride=stride, 102 | padding=padding, 103 | name=name) 104 | 105 | def basicblock(self, input, ch_out, name=None): 106 | conv1 = self.conv_bn_layer(input, ch_out, 1, 1, 0, name=name + ".0") 107 | conv2 = self.conv_bn_layer(conv1, ch_out * 2, 3, 1, 1, name=name + ".1") 108 | out = fluid.layers.elementwise_add(x=input, y=conv2, act=None) 109 | return out 110 | 111 | def layer_warp(self, block_func, input, ch_out, count, name=None): 112 | res_out = block_func(input, ch_out, name='{}.0'.format(name)) 113 | for j in range(1, count): 114 | res_out = block_func(res_out, ch_out, name='{}.{}'.format(name, j)) 115 | return res_out 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cats vs dogs 猫狗大战 主流平台实现 2 | 3 | This is the solution of Kaggle cats vs dogs by caffe,tensorflow and keras. 4 | 5 | 猫狗大战是深度学习应用于计算机视觉的一个典型案例,源于[Kaggle比赛](https://www.kaggle.com/c/dogs-vs-cats),它一共有25000张训练图片(猫和狗各12500张)![](https://i.imgur.com/v7E4fut.jpg) 6 | 7 | 现在已经有很多针对各个框架下的实现,但存在以下几个问题: 8 | 9 | 1.描述简单,未提供完整解决方案及测试结果 10 | 11 | 2.实现复杂,代码长时间未做更新,以致新版本的库无法使用 12 | 13 | 3.架构设计不合理,没有可扩展性,需要改动很多代码才能用于新的任务 14 | 15 | 本项目针对以上这些问题,提供了caffe、tensorflow和keras等主流平台的实现,给出全流程解决方案,可以无缝切换到自己的task。 16 | 17 | 18 | ## 数据下载和结构安排 19 | 20 | 下载本项目后新建data子文件夹 21 | 22 | 23 | git clone https://github.com/imistyrain/cat-vs-dog 24 | mkdir data 25 | 26 | 然后去[Kaggle下载页面](https://www.kaggle.com/c/dogs-vs-cats/data)下载,解压train.zip到data文件夹,文件结构组织为: 27 | ![](https://i.imgur.com/NpdKPKs.jpg) 28 | 29 | ## 数据清洗 30 | 31 | 官网下载的数据存在异常数据,大致可分为图中无目标(15张),猫狗都有(15张),卡通图(6张),难以区分(28张)和标注反了(7张)等几大类. 32 | 33 | cd Keras 34 | python filtererrors.py 35 | 36 | ![](https://i.imgur.com/BqpIVsh.jpg) 37 | 38 | 经过这个过程处理后图片数量由25000张缩减到24936张. 39 | 40 | ## caffe 41 | 42 | 首先安装caffe,网上已有很多相关教程,数不赘述。 43 | 44 | 然后生成用于训练和验证的文件名列表,可通过 45 | 46 | cd caffe/util 47 | python preprocess.py 48 | 49 | 完成,代码执行后会在util文件夹下生成train.txt和val.txt,里面包含了用于训练和验证的文件名列表及其对应的标签 50 | 51 | 开始训练, 52 | 53 | sh train.sh 54 | 55 | 调整需要使用的模型及其对应的参数,一键完成训练. 56 | 57 | 目前能够达到的精度如下: 58 | 59 | 60 | Name| Acc. test | finetuned Acc. test. | Train time | Forward pass time | On disk model size | Year | Paper 61 | ------------------ | --- | --- | --- | --- | --- | --- | --- 62 | AlexNet | 95.62% | 98.26% | **35m** | **3.01 ms** | 227.5Mb | 2012 | [link](http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf) 63 | SqeezeNet v1.1 | 96.20% | 99.44% | ~2h | 3.91 ms| **2.9Mb** | 2016 | [link](http://arxiv.org/pdf/1602.07360v3.pdf) 64 | GoogLeNet | 94.62% | **99.58%** | 50m | 11.73 ms | 41.3Mb | 2014 | [link](http://www.cs.unc.edu/~wliu/papers/GoogLeNet.pdf) 65 | BN-GoogleNet | |99.36% | 66 | VGG-16 | 97.17% | 99.40% | 5h20m | 15.41 ms | 537.1Mb | 2014 | [link](http://arxiv.org/pdf/1409.1556.pdf) 67 | VGG-19 | **97.46%** | 99.50% | 25h50m | 19.23 ms | 558.3Mb | 2014 | [link](http://arxiv.org/pdf/1409.1556.pdf) 68 | Network-In-Network | 93.65% | 98.49% | ~2h | 3.17 ms | 26.3Mb | 2014 | [link](http://arxiv.org/pdf/1312.4400v3.pdf) 69 | ResNet-50 | 96.10% | 99.52% | 18h | 24.91 ms | 94.3Mb | 2015 | [link](https://arxiv.org/pdf/1512.03385.pdf) 70 | ResNet-101 | 96.39% | 99.48% | 1d 20h | 40.95 ms | 170.5Mb | 2015 | [link](https://arxiv.org/pdf/1512.03385.pdf) 71 | MobileNet | 97.22% | 97.8% 72 | ShuffleNet | 93.70 |98.70% | 73 | 74 | 训练采用的GPU为1080Ti. 75 | 76 | 部署参考cpp4caffe项目,这是一个C++工程. 77 | 78 | 79 | ## tensorflow 80 | 81 | tensorflow使用预训练的VGG19进行微调,精度为96%+ 82 | 83 | python train_vgg19.py 84 | 85 | 如果有多块GPU,可以使用 86 | 87 | python multigpu_train.py 88 | 89 | 加速训练 90 | 91 | 如果配备了Intel的计算棒,可以将其转换为graph格式,然后运行 92 | 93 | sh build.sh #编译所必须的程式 94 | sh train.sh #训练和导出模型 95 | sh ncs.sh #转换为计算棒需要的格式 96 | python run_ncs.py #在计算棒上测试 97 | 98 | ## keras 99 | 100 | keras需要先把猫和狗的图片分到两个不同的文件夹下,这可以通过train.py中的mklink函数完成. 101 | 102 | ![](https://i.imgur.com/lQXG8vC.jpg) 103 | 104 | python train.py #训练模型 105 | python keras2tf.py #转换为tnsorflow格式 106 | 107 | 经测试所能达到的精度如下: 108 | 109 | 110 | Model | Size | Accuracy 111 | --- | --- | --- 112 | VGG16 | 528MB | 113 | ResNet50 | 99MB | 99.78% 114 | InceptionV3 | 92MB | 115 | Xception | 88MB | 116 | InceptionResNetV2 | 215MB | 117 | 118 | ![](https://i.imgur.com/xn47OvN.jpg) 119 | 120 | ## web by flask 121 | 122 | python app.py 123 | 124 | 打开浏览器,输入网址http://localhost:5000/ 125 | 126 | 点击Choose...选择要识别的文件上传即可,稍等片刻即可得到结果 127 | 128 | 129 | ![](https://i.imgur.com/wBA6uuh.jpg) 130 | 131 | ![](https://i.imgur.com/plU8eue.jpg) 132 | 133 | ## 参考 134 | 135 | [基于TensorFlow的Cats vs. Dogs(猫狗大战)实现和详解](https://blog.csdn.net/qq_16137569/article/details/72802387) 136 | 137 | [kaggle-dogs-vs-cats-solution](https://github.com/mrgloom/kaggle-dogs-vs-cats-solution) 138 | 139 | [Cat_or_dog-kaggle-vgg19-tensorflow](https://github.com/2012013382/Cat_or_dog-kaggle-vgg19-tensorflow) 140 | 141 | [keras-cats-dogs-tutorial](https://github.com/jkjung-avt/keras-cats-dogs-tutorial) 142 | 143 | [利用resnet 做kaggle猫狗大战图像识别,秒上98准确率](https://blog.csdn.net/shizhengxin123/article/details/72473245) 144 | 145 | [keras-cats-dogs-tutorial](https://github.com/jkjung-avt/keras-cats-dogs-tutorial) 146 | 147 | [Building powerful image classification models using very little data](https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html) 148 | 149 | [基于Android和微信小程序端的猫狗图像分类](https://github.com/wlkdb/dogs_vs_cats) -------------------------------------------------------------------------------- /paddle/build_model.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | import paddle 15 | import paddle.fluid as fluid 16 | import utils.utility as utility 17 | 18 | 19 | def _calc_label_smoothing_loss(softmax_out, label, class_dim, epsilon): 20 | """Calculate label smoothing loss 21 | 22 | Returns: 23 | label smoothing loss 24 | 25 | """ 26 | 27 | label_one_hot = fluid.layers.one_hot(input=label, depth=class_dim) 28 | smooth_label = fluid.layers.label_smooth( 29 | label=label_one_hot, epsilon=epsilon, dtype="float32") 30 | loss = fluid.layers.cross_entropy( 31 | input=softmax_out, label=smooth_label, soft_label=True) 32 | return loss 33 | 34 | 35 | def _basic_model(data, model, args, is_train): 36 | image = data[0] 37 | label = data[1] 38 | 39 | net_out = model.net(input=image, class_dim=args.class_dim) 40 | softmax_out = fluid.layers.softmax(net_out, use_cudnn=False) 41 | 42 | if is_train and args.use_label_smoothing: 43 | cost = _calc_label_smoothing_loss(softmax_out, label, args.class_dim, 44 | args.label_smoothing_epsilon) 45 | 46 | else: 47 | cost = fluid.layers.cross_entropy(input=softmax_out, label=label) 48 | 49 | avg_cost = fluid.layers.mean(cost) 50 | acc_top1 = fluid.layers.accuracy(input=softmax_out, label=label, k=1) 51 | acc_top5 = fluid.layers.accuracy(input=softmax_out, label=label, k=2) 52 | return [avg_cost, acc_top1, acc_top5] 53 | 54 | 55 | def _googlenet_model(data, model, args, is_train): 56 | """GoogLeNet model output, include avg_cost, acc_top1 and acc_top5 57 | 58 | Returns: 59 | GoogLeNet model output 60 | 61 | """ 62 | image = data[0] 63 | label = data[1] 64 | 65 | out0, out1, out2 = model.net(input=image, class_dim=args.class_dim) 66 | cost0 = fluid.layers.cross_entropy(input=out0, label=label) 67 | cost1 = fluid.layers.cross_entropy(input=out1, label=label) 68 | cost2 = fluid.layers.cross_entropy(input=out2, label=label) 69 | 70 | avg_cost0 = fluid.layers.mean(x=cost0) 71 | avg_cost1 = fluid.layers.mean(x=cost1) 72 | avg_cost2 = fluid.layers.mean(x=cost2) 73 | 74 | avg_cost = avg_cost0 + 0.3 * avg_cost1 + 0.3 * avg_cost2 75 | acc_top1 = fluid.layers.accuracy(input=out0, label=label, k=1) 76 | acc_top5 = fluid.layers.accuracy(input=out0, label=label, k=5) 77 | 78 | return [avg_cost, acc_top1, acc_top5] 79 | 80 | 81 | def _mixup_model(data, model, args, is_train): 82 | """output of Mixup processing network, include avg_cost 83 | """ 84 | image = data[0] 85 | y_a = data[1] 86 | y_b = data[2] 87 | lam = data[3] 88 | 89 | net_out = model.net(input=image, class_dim=args.class_dim) 90 | softmax_out = fluid.layers.softmax(net_out, use_cudnn=False) 91 | if not args.use_label_smoothing: 92 | loss_a = fluid.layers.cross_entropy(input=softmax_out, label=y_a) 93 | loss_b = fluid.layers.cross_entropy(input=softmax_out, label=y_b) 94 | else: 95 | loss_a = _calc_label_smoothing_loss(softmax_out, y_a, args.class_dim, 96 | args.label_smoothing_epsilon) 97 | loss_b = _calc_label_smoothing_loss(softmax_out, y_b, args.class_dim, 98 | args.label_smoothing_epsilon) 99 | 100 | loss_a_mean = fluid.layers.mean(x=loss_a) 101 | loss_b_mean = fluid.layers.mean(x=loss_b) 102 | cost = lam * loss_a_mean + (1 - lam) * loss_b_mean 103 | avg_cost = fluid.layers.mean(x=cost) 104 | return [avg_cost] 105 | 106 | 107 | def create_model(model, args, is_train): 108 | """Create model, include basic model, googlenet model and mixup model 109 | """ 110 | data_loader, data = utility.create_data_loader(is_train, args) 111 | 112 | if args.model == "GoogLeNet": 113 | loss_out = _googlenet_model(data, model, args, is_train) 114 | else: 115 | if args.use_mixup and is_train: 116 | loss_out = _mixup_model(data, model, args, is_train) 117 | else: 118 | loss_out = _basic_model(data, model, args, is_train) 119 | return data_loader, loss_out 120 | -------------------------------------------------------------------------------- /caffe/modeldef/MnasNet/train.log.test: -------------------------------------------------------------------------------- 1 | NumIters,Seconds,LearningRate,acc 2 | 0.0,0.749585,0.01,0.484 3 | 500.0,523.970585,0.01,0.484 4 | 1000.0,1047.664786,0.01,0.588 5 | 1500.0,1574.033254,0.01,0.58 6 | 2000.0,2101.70435,0.01,0.568 7 | 2500.0,2625.167406,0.01,0.708 8 | 3000.0,3148.61503,0.01,0.624 9 | 3500.0,3672.09823,0.01,0.676 10 | 4000.0,4195.905825,0.01,0.684 11 | 4500.0,4719.527696,0.01,0.656 12 | 5000.0,5243.342638,0.01,0.66 13 | 5500.0,5766.743312,0.01,0.736 14 | 6000.0,6290.180223,0.01,0.772 15 | 6500.0,6813.570203,0.01,0.716 16 | 7000.0,7337.00859,0.01,0.792 17 | 7500.0,7860.437608,0.01,0.8 18 | 8000.0,8383.642662,0.01,0.768 19 | 8500.0,8906.806314,0.01,0.824 20 | 9000.0,9430.330282,0.01,0.78 21 | 9500.0,9953.552892,0.01,0.88 22 | 10000.0,10476.855036,0.01,0.856 23 | 10500.0,10999.991718,0.01,0.804 24 | 11000.0,11523.444188,0.01,0.864 25 | 11500.0,12046.695719,0.01,0.84 26 | 12000.0,12570.630433,0.01,0.888 27 | 12500.0,13093.502408,0.01,0.848 28 | 13000.0,13616.783622,0.01,0.868 29 | 13500.0,14139.981549,0.01,0.884 30 | 14000.0,14663.330023,0.01,0.848 31 | 14500.0,15186.392585,0.01,0.844 32 | 15000.0,15710.168503,0.01,0.924 33 | 15500.0,16233.679278,0.01,0.868 34 | 16000.0,16757.014259,0.01,0.884 35 | 16500.0,17280.6738,0.01,0.832 36 | 17000.0,17805.025629,0.01,0.912 37 | 17500.0,18328.823445,0.01,0.92 38 | 18000.0,18853.060481,0.01,0.9 39 | 18500.0,19376.763165,0.01,0.884 40 | 19000.0,19900.114468,0.01,0.904 41 | 19500.0,20423.720253,0.01,0.9 42 | 20000.0,20947.238243,0.01,0.928 43 | 20500.0,21470.711158,0.01,0.904 44 | 21000.0,21994.416218,0.01,0.908 45 | 21500.0,22517.865899,0.01,0.9 46 | 22000.0,23041.545676,0.01,0.928 47 | 22500.0,23564.48208,0.01,0.908 48 | 23000.0,24088.128114,0.01,0.868 49 | 23500.0,24611.541142,0.01,0.884 50 | 24000.0,25135.271994,0.01,0.92 51 | 24500.0,25658.507954,0.01,0.896 52 | 25000.0,26181.877614,0.01,0.924 53 | 25500.0,26705.157655,0.01,0.92 54 | 26000.0,27228.874212,0.01,0.94 55 | 26500.0,27752.096667,0.01,0.896 56 | 27000.0,28275.656001,0.01,0.936 57 | 27500.0,28799.020576,0.01,0.956 58 | 28000.0,29322.836986,0.01,0.92 59 | 28500.0,29846.314429,0.01,0.892 60 | 29000.0,30369.971298,0.01,0.912 61 | 29500.0,30893.369706,0.01,0.924 62 | 30000.0,31417.229579,0.01,0.944 63 | 30500.0,31940.80166,0.01,0.96 64 | 31000.0,32464.494853,0.01,0.92 65 | 31500.0,32987.839898,0.01,0.924 66 | 32000.0,33511.928152,0.01,0.92 67 | 32500.0,34035.410006,0.001,0.94 68 | 33000.0,34559.216189,0.001,0.928 69 | 33500.0,35082.625463,0.001,0.952 70 | 34000.0,35606.334388,0.001,0.928 71 | 34500.0,36129.585353,0.001,0.936 72 | 35000.0,36652.990301,0.001,0.952 73 | 35500.0,37176.170869,0.001,0.948 74 | 36000.0,37699.788703,0.001,0.94 75 | 36500.0,38223.023338,0.001,0.96 76 | 37000.0,38746.418698,0.001,0.952 77 | 37500.0,39269.740262,0.001,0.956 78 | 38000.0,39793.653525,0.001,0.964 79 | 38500.0,40317.378399,0.001,0.952 80 | 39000.0,40840.952321,0.001,0.968 81 | 39500.0,41364.322867,0.001,0.96 82 | 40000.0,41888.145729,0.001,0.972 83 | 40500.0,42411.432621,0.001,0.968 84 | 41000.0,42935.049978,0.001,0.976 85 | 41500.0,43458.402106,0.001,0.972 86 | 42000.0,43982.103017,0.001,0.972 87 | 42500.0,44505.361088,0.001,0.948 88 | 43000.0,45029.260585,0.001,0.94 89 | 43500.0,45552.677554,0.001,0.952 90 | 44000.0,46076.190076,0.001,0.944 91 | 44500.0,46599.790861,0.001,0.96 92 | 45000.0,47123.601447,0.001,0.968 93 | 45500.0,47646.933941,0.001,0.948 94 | 46000.0,48170.584886,0.001,0.952 95 | 46500.0,48694.320238,0.001,0.964 96 | 47000.0,49218.142526,0.001,0.96 97 | 47500.0,49741.838588,0.001,0.96 98 | 48000.0,50265.592926,0.001,0.968 99 | 48500.0,50789.116575,0.0001,0.944 100 | 49000.0,51312.664988,0.0001,0.96 101 | 49500.0,51835.955506,0.0001,0.964 102 | 50000.0,52359.369914,0.0001,0.968 103 | 50500.0,52882.766273,0.0001,0.964 104 | 51000.0,53406.425207,0.0001,0.96 105 | 51500.0,53929.939446,0.0001,0.964 106 | 52000.0,54453.832481,0.0001,0.964 107 | 52500.0,54976.870065,0.0001,0.952 108 | 53000.0,55500.57911,0.0001,0.94 109 | 53500.0,56023.960796,0.0001,0.956 110 | 54000.0,56547.835487,0.0001,0.94 111 | 54500.0,57071.384292,0.0001,0.944 112 | 55000.0,57594.911736,0.0001,0.964 113 | 55500.0,58118.27475,0.0001,0.952 114 | 56000.0,58642.203391,0.0001,0.948 115 | 56500.0,59165.760987,0.0001,0.964 116 | 57000.0,59689.548874,0.0001,0.956 117 | 57500.0,60213.10187,0.0001,0.968 118 | 58000.0,60736.948421,0.0001,0.964 119 | 58500.0,61260.439636,0.0001,0.944 120 | 59000.0,61783.767176,0.0001,0.96 121 | 59500.0,62307.051121,0.0001,0.964 122 | 60000.0,62830.715736,0.0001,0.972 123 | 60500.0,63353.990179,1e-05,0.964 124 | 61000.0,63877.525766,1e-05,0.96 125 | 61500.0,64400.87641,1e-05,0.964 126 | 62000.0,64924.432677,1e-05,0.964 127 | 62500.0,65447.799723,1e-05,0.948 128 | 63000.0,65971.538632,1e-05,0.94 129 | 63500.0,66494.895864,1e-05,0.952 130 | 64000.0,67018.696963,1e-05,0.94 131 | -------------------------------------------------------------------------------- /pytorch/models/MobileNetV2.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | import math 4 | 5 | __all__ = ['MobileNetV2', 'mobilenetv2_19'] 6 | 7 | class Bottleneck(nn.Module): 8 | 9 | def __init__(self, inplanes, planes, stride=1, downsample=None, expansion=1): 10 | super(Bottleneck, self).__init__() 11 | self.conv1 = nn.Conv2d(inplanes, inplanes*expansion, kernel_size=1, bias=False) 12 | self.bn1 = nn.BatchNorm2d(inplanes*expansion) 13 | self.conv2 = nn.Conv2d(inplanes*expansion, inplanes*expansion, kernel_size=3, stride=stride, 14 | padding=1, bias=False, groups=inplanes*expansion) 15 | self.bn2 = nn.BatchNorm2d(inplanes*expansion) 16 | self.conv3 = nn.Conv2d(inplanes*expansion, planes, kernel_size=1, bias=False) 17 | self.bn3 = nn.BatchNorm2d(planes) 18 | self.relu = nn.ReLU(inplace=True) 19 | self.downsample = downsample 20 | self.stride = stride 21 | 22 | def forward(self, x): 23 | residual = x 24 | 25 | out = self.conv1(x) 26 | out = self.bn1(out) 27 | out = self.relu(out) 28 | 29 | out = self.conv2(out) 30 | out = self.bn2(out) 31 | out = self.relu(out) 32 | 33 | out = self.conv3(out) 34 | out = self.bn3(out) 35 | 36 | if self.downsample is not None: 37 | residual = self.downsample(x) 38 | 39 | out += residual 40 | out = self.relu(out) 41 | 42 | return out 43 | 44 | 45 | class MobileNetV2(nn.Module): 46 | 47 | def __init__(self, block, layers, num_classes=1000): 48 | self.inplanes = 32 49 | super(MobileNetV2, self).__init__() 50 | self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1, bias=False) 51 | self.bn1 = nn.BatchNorm2d(32) 52 | self.relu = nn.ReLU(inplace=True) 53 | self.layer1 = self._make_layer(block, 16, layers[0], stride=1, expansion = 1) 54 | self.layer2 = self._make_layer(block, 24, layers[1], stride=2, expansion = 6) 55 | self.layer3 = self._make_layer(block, 32, layers[2], stride=2, expansion = 6) 56 | self.layer4 = self._make_layer(block, 64, layers[3], stride=2, expansion = 6) 57 | self.layer5 = self._make_layer(block, 96, layers[4], stride=1, expansion = 6) 58 | self.layer6 = self._make_layer(block, 160, layers[5], stride=2, expansion = 6) 59 | self.layer7 = self._make_layer(block, 320, layers[6], stride=1, expansion = 6) 60 | self.conv8 = nn.Conv2d(320, 1280, kernel_size=1, stride=1, bias=False) 61 | self.avgpool = nn.AvgPool2d(7, stride=1) 62 | self.conv9 = nn.Conv2d(1280,num_classes, kernel_size=1, stride=1, bias=False) 63 | 64 | for m in self.modules(): 65 | if isinstance(m, nn.Conv2d): 66 | n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels 67 | m.weight.data.normal_(0, math.sqrt(2. / n)) 68 | elif isinstance(m, nn.BatchNorm2d): 69 | m.weight.data.fill_(1) 70 | m.bias.data.zero_() 71 | 72 | def _make_layer(self, block, planes, blocks, stride, expansion): 73 | 74 | downsample = nn.Sequential( 75 | nn.Conv2d(self.inplanes, planes, 76 | kernel_size=1, stride=stride, bias=False), 77 | nn.BatchNorm2d(planes), 78 | ) 79 | 80 | layers = [] 81 | layers.append(block(self.inplanes, planes, stride=stride, downsample=downsample, expansion=expansion)) 82 | self.inplanes = planes 83 | for i in range(1, blocks): 84 | layers.append(block(self.inplanes, planes, expansion=expansion)) 85 | 86 | return nn.Sequential(*layers) 87 | 88 | def forward(self, x): 89 | x = self.conv1(x) 90 | x = self.bn1(x) 91 | x = self.relu(x) 92 | 93 | x = self.layer1(x) 94 | x = self.layer2(x) 95 | x = self.layer3(x) 96 | x = self.layer4(x) 97 | x = self.layer5(x) 98 | x = self.layer6(x) 99 | x = self.layer7(x) 100 | 101 | x = self.conv8(x) 102 | x = self.avgpool(x) 103 | x = self.conv9(x) 104 | x = x.view(x.size(0),-1) 105 | 106 | return x 107 | 108 | 109 | def mobilenetv2_19(**kwargs): 110 | """Constructs a MobileNetV2-19 model. 111 | """ 112 | model = MobileNetV2(Bottleneck, [1, 2, 3, 4, 3, 3, 1], **kwargs) 113 | return model 114 | 115 | def mobilenetv2_5(**kwargs): 116 | """Constructs a MobileNetV2-19 model. 117 | """ 118 | model = MobileNetV2(Bottleneck, [1, 1,1,1,1,1,1], **kwargs) 119 | return model 120 | 121 | if __name__=="__main__": 122 | net = mobilenetv2_5(num_classes=2) 123 | device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") 124 | net.to(device) 125 | from torchsummary import summary 126 | print(summary(net,(3,224,224))) -------------------------------------------------------------------------------- /paddle/models/model_libs.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | 15 | from __future__ import absolute_import 16 | from __future__ import division 17 | from __future__ import print_function 18 | import paddle 19 | import paddle.fluid as fluid 20 | import contextlib 21 | 22 | bn_regularizer = fluid.regularizer.L2DecayRegularizer(regularization_coeff=0.0) 23 | name_scope = "" 24 | 25 | @contextlib.contextmanager 26 | def scope(name): 27 | global name_scope 28 | bk = name_scope 29 | name_scope = name_scope + name + '/' 30 | yield 31 | name_scope = bk 32 | 33 | def max_pool(input, kernel, stride, padding): 34 | data = fluid.layers.pool2d(input, pool_size=kernel, pool_type='max', 35 | pool_stride=stride, pool_padding=padding) 36 | return data 37 | 38 | def group_norm(input, G, eps=1e-5, param_attr=None, bias_attr=None): 39 | N, C, H, W = input.shape 40 | if C % G != 0: 41 | # print "group can not divide channle:", C, G 42 | for d in range(10): 43 | for t in [d, -d]: 44 | if G + t <= 0: continue 45 | if C % (G + t) == 0: 46 | G = G + t 47 | break 48 | if C % G == 0: 49 | # print "use group size:", G 50 | break 51 | assert C % G == 0 52 | x = fluid.layers.group_norm( 53 | input, 54 | groups=G, 55 | param_attr=param_attr, 56 | bias_attr=bias_attr, 57 | name=name_scope + 'group_norm') 58 | return x 59 | 60 | def bn(*args, **kargs): 61 | with scope('BatchNorm'): 62 | return fluid.layers.batch_norm( 63 | *args, 64 | epsilon=1e-3, 65 | momentum=0.99, 66 | param_attr=fluid.ParamAttr( 67 | name=name_scope + 'gamma', regularizer=bn_regularizer), 68 | bias_attr=fluid.ParamAttr( 69 | name=name_scope + 'beta', regularizer=bn_regularizer), 70 | moving_mean_name=name_scope + 'moving_mean', 71 | moving_variance_name=name_scope + 'moving_variance', 72 | **kargs) 73 | 74 | def bn_relu(data): 75 | return fluid.layers.relu(bn(data)) 76 | 77 | def relu(data): 78 | return fluid.layers.relu(data) 79 | 80 | def conv(*args, **kargs): 81 | kargs['param_attr'] = name_scope + 'weights' 82 | if 'bias_attr' in kargs and kargs['bias_attr']: 83 | kargs['bias_attr'] = fluid.ParamAttr( 84 | name=name_scope + 'biases', 85 | regularizer=None, 86 | initializer=fluid.initializer.ConstantInitializer(value=0.0)) 87 | else: 88 | kargs['bias_attr'] = False 89 | return fluid.layers.conv2d(*args, **kargs) 90 | 91 | def deconv(*args, **kargs): 92 | kargs['param_attr'] = name_scope + 'weights' 93 | if 'bias_attr' in kargs and kargs['bias_attr']: 94 | kargs['bias_attr'] = name_scope + 'biases' 95 | else: 96 | kargs['bias_attr'] = False 97 | return fluid.layers.conv2d_transpose(*args, **kargs) 98 | 99 | def seperate_conv(input, channel, stride, filter, dilation=1, act=None): 100 | param_attr = fluid.ParamAttr( 101 | name=name_scope + 'weights', 102 | regularizer=fluid.regularizer.L2DecayRegularizer( 103 | regularization_coeff=0.0), 104 | initializer=fluid.initializer.TruncatedNormal(loc=0.0, scale=0.33)) 105 | with scope('depthwise'): 106 | input = conv( 107 | input, 108 | input.shape[1], 109 | filter, 110 | stride, 111 | groups=input.shape[1], 112 | padding=(filter // 2) * dilation, 113 | dilation=dilation, 114 | use_cudnn=False, 115 | param_attr=param_attr) 116 | input = bn(input) 117 | if act: input = act(input) 118 | 119 | param_attr = fluid.ParamAttr( 120 | name=name_scope + 'weights', 121 | regularizer=None, 122 | initializer=fluid.initializer.TruncatedNormal(loc=0.0, scale=0.06)) 123 | with scope('pointwise'): 124 | input = conv(input, channel, 1, 1, groups=1, padding=0, 125 | param_attr=param_attr) 126 | input = bn(input) 127 | if act: input = act(input) 128 | return input 129 | -------------------------------------------------------------------------------- /caffe/modeldef/AlexNet/deploy.prototxt: -------------------------------------------------------------------------------- 1 | name: "AlexNet" 2 | layer { 3 | name: "data" 4 | type: "Input" 5 | top: "data" 6 | input_param { shape: { dim: 10 dim: 3 dim: 227 dim: 227 } } 7 | } 8 | layer { 9 | name: "conv1" 10 | type: "Convolution" 11 | bottom: "data" 12 | top: "conv1" 13 | param { 14 | lr_mult: 1 15 | decay_mult: 1 16 | } 17 | param { 18 | lr_mult: 2 19 | decay_mult: 0 20 | } 21 | convolution_param { 22 | num_output: 96 23 | kernel_size: 11 24 | stride: 4 25 | } 26 | } 27 | layer { 28 | name: "relu1" 29 | type: "ReLU" 30 | bottom: "conv1" 31 | top: "conv1" 32 | } 33 | layer { 34 | name: "norm1" 35 | type: "LRN" 36 | bottom: "conv1" 37 | top: "norm1" 38 | lrn_param { 39 | local_size: 5 40 | alpha: 0.0001 41 | beta: 0.75 42 | } 43 | } 44 | layer { 45 | name: "pool1" 46 | type: "Pooling" 47 | bottom: "norm1" 48 | top: "pool1" 49 | pooling_param { 50 | pool: MAX 51 | kernel_size: 3 52 | stride: 2 53 | } 54 | } 55 | layer { 56 | name: "conv2" 57 | type: "Convolution" 58 | bottom: "pool1" 59 | top: "conv2" 60 | param { 61 | lr_mult: 1 62 | decay_mult: 1 63 | } 64 | param { 65 | lr_mult: 2 66 | decay_mult: 0 67 | } 68 | convolution_param { 69 | num_output: 256 70 | pad: 2 71 | kernel_size: 5 72 | group: 2 73 | } 74 | } 75 | layer { 76 | name: "relu2" 77 | type: "ReLU" 78 | bottom: "conv2" 79 | top: "conv2" 80 | } 81 | layer { 82 | name: "norm2" 83 | type: "LRN" 84 | bottom: "conv2" 85 | top: "norm2" 86 | lrn_param { 87 | local_size: 5 88 | alpha: 0.0001 89 | beta: 0.75 90 | } 91 | } 92 | layer { 93 | name: "pool2" 94 | type: "Pooling" 95 | bottom: "norm2" 96 | top: "pool2" 97 | pooling_param { 98 | pool: MAX 99 | kernel_size: 3 100 | stride: 2 101 | } 102 | } 103 | layer { 104 | name: "conv3" 105 | type: "Convolution" 106 | bottom: "pool2" 107 | top: "conv3" 108 | param { 109 | lr_mult: 1 110 | decay_mult: 1 111 | } 112 | param { 113 | lr_mult: 2 114 | decay_mult: 0 115 | } 116 | convolution_param { 117 | num_output: 384 118 | pad: 1 119 | kernel_size: 3 120 | } 121 | } 122 | layer { 123 | name: "relu3" 124 | type: "ReLU" 125 | bottom: "conv3" 126 | top: "conv3" 127 | } 128 | layer { 129 | name: "conv4" 130 | type: "Convolution" 131 | bottom: "conv3" 132 | top: "conv4" 133 | param { 134 | lr_mult: 1 135 | decay_mult: 1 136 | } 137 | param { 138 | lr_mult: 2 139 | decay_mult: 0 140 | } 141 | convolution_param { 142 | num_output: 384 143 | pad: 1 144 | kernel_size: 3 145 | group: 2 146 | } 147 | } 148 | layer { 149 | name: "relu4" 150 | type: "ReLU" 151 | bottom: "conv4" 152 | top: "conv4" 153 | } 154 | layer { 155 | name: "conv5" 156 | type: "Convolution" 157 | bottom: "conv4" 158 | top: "conv5" 159 | param { 160 | lr_mult: 1 161 | decay_mult: 1 162 | } 163 | param { 164 | lr_mult: 2 165 | decay_mult: 0 166 | } 167 | convolution_param { 168 | num_output: 256 169 | pad: 1 170 | kernel_size: 3 171 | group: 2 172 | } 173 | } 174 | layer { 175 | name: "relu5" 176 | type: "ReLU" 177 | bottom: "conv5" 178 | top: "conv5" 179 | } 180 | layer { 181 | name: "pool5" 182 | type: "Pooling" 183 | bottom: "conv5" 184 | top: "pool5" 185 | pooling_param { 186 | pool: MAX 187 | kernel_size: 3 188 | stride: 2 189 | } 190 | } 191 | layer { 192 | name: "fc6" 193 | type: "InnerProduct" 194 | bottom: "pool5" 195 | top: "fc6" 196 | param { 197 | lr_mult: 1 198 | decay_mult: 1 199 | } 200 | param { 201 | lr_mult: 2 202 | decay_mult: 0 203 | } 204 | inner_product_param { 205 | num_output: 4096 206 | } 207 | } 208 | layer { 209 | name: "relu6" 210 | type: "ReLU" 211 | bottom: "fc6" 212 | top: "fc6" 213 | } 214 | layer { 215 | name: "drop6" 216 | type: "Dropout" 217 | bottom: "fc6" 218 | top: "fc6" 219 | dropout_param { 220 | dropout_ratio: 0.5 221 | } 222 | } 223 | layer { 224 | name: "fc7" 225 | type: "InnerProduct" 226 | bottom: "fc6" 227 | top: "fc7" 228 | param { 229 | lr_mult: 1 230 | decay_mult: 1 231 | } 232 | param { 233 | lr_mult: 2 234 | decay_mult: 0 235 | } 236 | inner_product_param { 237 | num_output: 4096 238 | } 239 | } 240 | layer { 241 | name: "relu7" 242 | type: "ReLU" 243 | bottom: "fc7" 244 | top: "fc7" 245 | } 246 | layer { 247 | name: "drop7" 248 | type: "Dropout" 249 | bottom: "fc7" 250 | top: "fc7" 251 | dropout_param { 252 | dropout_ratio: 0.5 253 | } 254 | } 255 | layer { 256 | name: "fc8" 257 | type: "InnerProduct" 258 | bottom: "fc7" 259 | top: "fc8" 260 | param { 261 | lr_mult: 1 262 | decay_mult: 1 263 | } 264 | param { 265 | lr_mult: 2 266 | decay_mult: 0 267 | } 268 | inner_product_param { 269 | num_output: 2 270 | } 271 | } 272 | layer { 273 | name: "prob" 274 | type: "Softmax" 275 | bottom: "fc8" 276 | top: "prob" 277 | } 278 | -------------------------------------------------------------------------------- /pytorch/models/se_resnext.py: -------------------------------------------------------------------------------- 1 | ''' 2 | New for ResNeXt: 3 | 1. Wider bottleneck 4 | 2. Add group for conv2 5 | ''' 6 | 7 | import torch.nn as nn 8 | import math 9 | 10 | __all__ = ['SE_ResNeXt', 'se_resnext_50', 'se_resnext_101', 'se_resnext_152'] 11 | 12 | 13 | class Bottleneck(nn.Module): 14 | expansion = 4 15 | 16 | def __init__(self, inplanes, planes, stride=1, downsample=None, num_group=32): 17 | super(Bottleneck, self).__init__() 18 | self.conv1 = nn.Conv2d(inplanes, planes*2, kernel_size=1, bias=False) 19 | self.bn1 = nn.BatchNorm2d(planes*2) 20 | self.conv2 = nn.Conv2d(planes*2, planes*2, kernel_size=3, stride=stride, 21 | padding=1, bias=False, groups=num_group) 22 | self.bn2 = nn.BatchNorm2d(planes*2) 23 | self.conv3 = nn.Conv2d(planes*2, planes * 4, kernel_size=1, bias=False) 24 | self.bn3 = nn.BatchNorm2d(planes * 4) 25 | self.relu = nn.ReLU(inplace=True) 26 | self.downsample = downsample 27 | self.stride = stride 28 | 29 | if planes == 64: 30 | self.globalAvgPool = nn.AvgPool2d(56, stride=1) 31 | elif planes == 128: 32 | self.globalAvgPool = nn.AvgPool2d(28, stride=1) 33 | elif planes == 256: 34 | self.globalAvgPool = nn.AvgPool2d(14, stride=1) 35 | elif planes == 512: 36 | self.globalAvgPool = nn.AvgPool2d(7, stride=1) 37 | self.fc1 = nn.Linear(in_features=planes * 4, out_features=round(planes / 4)) 38 | self.fc2 = nn.Linear(in_features=round(planes / 4), out_features=planes * 4) 39 | self.sigmoid = nn.Sigmoid() 40 | 41 | def forward(self, x): 42 | residual = x 43 | 44 | out = self.conv1(x) 45 | out = self.bn1(out) 46 | out = self.relu(out) 47 | 48 | out = self.conv2(out) 49 | out = self.bn2(out) 50 | out = self.relu(out) 51 | 52 | out = self.conv3(out) 53 | out = self.bn3(out) 54 | 55 | if self.downsample is not None: 56 | residual = self.downsample(x) 57 | 58 | original_out = out 59 | out = self.globalAvgPool(out) 60 | out = out.view(out.size(0), -1) 61 | out = self.fc1(out) 62 | out = self.relu(out) 63 | out = self.fc2(out) 64 | out = self.sigmoid(out) 65 | out = out.view(out.size(0), out.size(1), 1, 1) 66 | out = out * original_out 67 | 68 | out += residual 69 | out = self.relu(out) 70 | 71 | return out 72 | 73 | 74 | class SE_ResNeXt(nn.Module): 75 | 76 | def __init__(self, block, layers, num_classes=1000, num_group=32): 77 | self.inplanes = 64 78 | super(SE_ResNeXt, self).__init__() 79 | self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, 80 | bias=False) 81 | self.bn1 = nn.BatchNorm2d(64) 82 | self.relu = nn.ReLU(inplace=True) 83 | self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) 84 | self.layer1 = self._make_layer(block, 64, layers[0], num_group) 85 | self.layer2 = self._make_layer(block, 128, layers[1], num_group, stride=2) 86 | self.layer3 = self._make_layer(block, 256, layers[2], num_group, stride=2) 87 | self.layer4 = self._make_layer(block, 512, layers[3], num_group, stride=2) 88 | self.avgpool = nn.AvgPool2d(7, stride=1) 89 | self.fc = nn.Linear(512 * block.expansion, num_classes) 90 | 91 | for m in self.modules(): 92 | if isinstance(m, nn.Conv2d): 93 | n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels 94 | m.weight.data.normal_(0, math.sqrt(2. / n)) 95 | elif isinstance(m, nn.BatchNorm2d): 96 | m.weight.data.fill_(1) 97 | m.bias.data.zero_() 98 | 99 | def _make_layer(self, block, planes, blocks, num_group, stride=1): 100 | downsample = None 101 | if stride != 1 or self.inplanes != planes * block.expansion: 102 | downsample = nn.Sequential( 103 | nn.Conv2d(self.inplanes, planes * block.expansion, 104 | kernel_size=1, stride=stride, bias=False), 105 | nn.BatchNorm2d(planes * block.expansion), 106 | ) 107 | 108 | layers = [] 109 | layers.append(block(self.inplanes, planes, stride, downsample, num_group=num_group)) 110 | self.inplanes = planes * block.expansion 111 | for i in range(1, blocks): 112 | layers.append(block(self.inplanes, planes, num_group=num_group)) 113 | 114 | return nn.Sequential(*layers) 115 | 116 | def forward(self, x): 117 | x = self.conv1(x) 118 | x = self.bn1(x) 119 | x = self.relu(x) 120 | x = self.maxpool(x) 121 | 122 | x = self.layer1(x) 123 | x = self.layer2(x) 124 | x = self.layer3(x) 125 | x = self.layer4(x) 126 | 127 | x = self.avgpool(x) 128 | x = x.view(x.size(0), -1) 129 | x = self.fc(x) 130 | 131 | return x 132 | 133 | def se_resnext_50(**kwargs): 134 | """Constructs a ResNeXt-50 model. 135 | """ 136 | model = SE_ResNeXt(Bottleneck, [3, 4, 6, 3], **kwargs) 137 | return model 138 | 139 | 140 | def se_resnext_101(**kwargs): 141 | """Constructs a ResNeXt-101 model. 142 | """ 143 | model = SE_ResNeXt(Bottleneck, [3, 4, 23, 3], **kwargs) 144 | return model 145 | 146 | 147 | def se_resnext_152(**kwargs): 148 | """Constructs a ResNeXt-152 model. 149 | """ 150 | model = SE_ResNeXt(Bottleneck, [3, 8, 36, 3], **kwargs) 151 | return model -------------------------------------------------------------------------------- /Keras/train.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import os,glob,shutil,keras 3 | import numpy as np 4 | from keras.models import * 5 | from keras.layers import * 6 | from keras.applications import * 7 | from keras.preprocessing.image import * 8 | from keras.utils import plot_model 9 | from keras.optimizers import SGD 10 | from keras.preprocessing import image 11 | 12 | num_classes=2 13 | cls_list = ['cats', 'dogs'] 14 | IMAGE_SIZE = (256, 256) 15 | CROP_LENGTH = 224 16 | 17 | MODEL_WEIGHTS="model.h5" 18 | 19 | import tensorflow as tf 20 | from keras.backend.tensorflow_backend import set_session 21 | config = tf.ConfigProto() 22 | config.gpu_options.allow_growth=True 23 | set_session(tf.Session(config=config)) 24 | 25 | def random_crop(img, random_crop_size): 26 | # Note: image_data_format is 'channel_last' 27 | assert img.shape[2] == 3 28 | height, width = img.shape[0], img.shape[1] 29 | dy, dx = random_crop_size 30 | x = np.random.randint(0, width - dx + 1) 31 | y = np.random.randint(0, height - dy + 1) 32 | return img[y:(y+dy), x:(x+dx), :] 33 | def crop_generator(batches, crop_length): 34 | ''' 35 | Take as input a Keras ImageGen (Iterator) and generate random 36 | crops from the image batches generated by the original iterator 37 | ''' 38 | while True: 39 | batch_x, batch_y = next(batches) 40 | batch_crops = np.zeros((batch_x.shape[0], crop_length, crop_length, 3)) 41 | for i in range(batch_x.shape[0]): 42 | batch_crops[i] = random_crop(batch_x[i], (crop_length, crop_length)) 43 | yield (batch_crops, batch_y) 44 | 45 | def simple_net(): 46 | model=Sequential() 47 | model.add(Convolution2D(4,5,5,input_shape=(224,224,3))) 48 | model.add(Activation("relu")) 49 | model.add(MaxPooling2D(pool_size=(2,2))) 50 | model.add(Convolution2D(8,3,3)) 51 | model.add(Activation("relu")) 52 | model.add(MaxPooling2D(pool_size=(2,2))) 53 | model.add(Flatten()) 54 | model.add(Dense(128)) 55 | model.add(Activation("relu")) 56 | #model.add(Dropout(0.5)) 57 | model.add(Dense(num_classes)) 58 | model.add(Activation("softmax")) 59 | return model 60 | 61 | def get_model(): 62 | input_tensor = Input(shape=(224, 224, 3)) 63 | #base_model = keras.applications.resnet50.ResNet50(input_tensor=input_tensor,weights='imagenet', include_top=False) 64 | #base_model =keras.applications.vgg19.VGG19(input_tensor=input_tensor,weights='imagenet', include_top=False) 65 | #base_model = InceptionResNetV2(input_shape=(229,229,3),weights='imagenet', include_top=False) 66 | base_model =keras.applications.mobilenet.MobileNet(input_shape=(224,224,3),weights='imagenet', include_top=False) 67 | x = base_model.output 68 | x = GlobalAveragePooling2D()(x) 69 | x = Dense(1024, activation='relu')(x) 70 | predictions = Dense(num_classes, activation='softmax')(x) 71 | model = Model(inputs=base_model.input, outputs=predictions) 72 | return model 73 | 74 | def train(): 75 | #model=simple_net() 76 | model=get_model() 77 | #for layer in model.layers[:25]: 78 | #layer.trainable = False 79 | sgd = SGD(lr=0.0001, decay=1e-6, momentum=0.9) 80 | #sgd=rmsprop' 81 | model.compile(optimizer=sgd,loss='categorical_crossentropy', metrics=['accuracy']) 82 | train_datagen=ImageDataGenerator( 83 | preprocessing_function=keras.applications.resnet50.preprocess_input, 84 | rotation_range=40, 85 | width_shift_range=0.2, 86 | height_shift_range=0.2, 87 | shear_range=0.2, 88 | zoom_range=0.2, 89 | channel_shift_range=10, 90 | horizontal_flip=True, 91 | fill_mode='nearest') 92 | train_generator=train_datagen.flow_from_directory("../data/train2",target_size=(224,224),batch_size=32) 93 | print(train_generator.class_indices) 94 | #json_string = model.to_json() 95 | #open('model.json','w').write(json_string) 96 | earlystop=keras.callbacks.EarlyStopping(monitor='val_loss', patience=20, verbose=1, mode='auto') 97 | checkpoints=keras.callbacks.ModelCheckpoint(MODEL_WEIGHTS, monitor='acc', save_best_only=True) 98 | tensorboard=keras.callbacks.TensorBoard(log_dir='logs', histogram_freq=0, write_graph=True, write_images=False, embeddings_freq=0,embeddings_layer_names=None, embeddings_metadata=None) 99 | callbacks = [earlystop,checkpoints,tensorboard] 100 | model.fit_generator(train_generator,callbacks = callbacks,samples_per_epoch=25000,nb_epoch=100) 101 | 102 | #model.save_weights(MODEL_WEIGHTS) 103 | model.save(MODEL_WEIGHTS) 104 | 105 | def evaluate(): 106 | #model = model_from_json(open('model.json').read()) 107 | #model.load_weights(MODEL_WEIGHTS) 108 | model=load_model(MODEL_WEIGHTS) 109 | sgd = SGD(lr=0.0001, decay=1e-6, momentum=0.9) 110 | model.compile(optimizer=sgd,loss='categorical_crossentropy', metrics=['accuracy']) 111 | test_datagen=ImageDataGenerator(preprocessing_function=preprocess_input) 112 | validation_generator=test_datagen.flow_from_directory("../data/train2",target_size=(224,224),batch_size=50) 113 | score=model.evaluate_generator(validation_generator,5000) 114 | print(score[1]) 115 | plot_model(model,to_file="model.png") 116 | 117 | def test_one_image(imgpath="../data/train/cat.0.jpg"): 118 | net = load_model(MODEL_WEIGHTS) 119 | img=image.load_img(imgpath, target_size=(224,224)) 120 | x = image.img_to_array(img) 121 | x = preprocess_input(x) 122 | x = np.expand_dims(x, axis=0) 123 | pred = net.predict(x)[0] 124 | top_inds = pred.argsort()[::-1][:] 125 | for i in top_inds: 126 | print(' {:.3f} {}'.format(pred[i], cls_list[i])) 127 | 128 | if __name__=="__main__": 129 | train() 130 | evaluate() 131 | test_one_image() -------------------------------------------------------------------------------- /paddle/models/squeezenet.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | from __future__ import absolute_import 15 | from __future__ import division 16 | from __future__ import print_function 17 | 18 | import paddle 19 | import paddle.fluid as fluid 20 | import math 21 | from paddle.fluid.param_attr import ParamAttr 22 | 23 | __all__ = ["SqueezeNet", "SqueezeNet1_0", "SqueezeNet1_1"] 24 | 25 | 26 | class SqueezeNet(): 27 | def __init__(self, version='1.0'): 28 | self.version = version 29 | 30 | def net(self, input, class_dim=1000): 31 | version = self.version 32 | assert version in ['1.0', '1.1'], \ 33 | "supported version are {} but input version is {}".format(['1.0', '1.1'], version) 34 | if version == '1.0': 35 | conv = fluid.layers.conv2d( 36 | input, 37 | num_filters=96, 38 | filter_size=7, 39 | stride=2, 40 | act='relu', 41 | param_attr=fluid.param_attr.ParamAttr(name="conv1_weights"), 42 | bias_attr=ParamAttr(name='conv1_offset')) 43 | conv = fluid.layers.pool2d( 44 | conv, pool_size=3, pool_stride=2, pool_type='max') 45 | conv = self.make_fire(conv, 16, 64, 64, name='fire2') 46 | conv = self.make_fire(conv, 16, 64, 64, name='fire3') 47 | conv = self.make_fire(conv, 32, 128, 128, name='fire4') 48 | conv = fluid.layers.pool2d( 49 | conv, pool_size=3, pool_stride=2, pool_type='max') 50 | conv = self.make_fire(conv, 32, 128, 128, name='fire5') 51 | conv = self.make_fire(conv, 48, 192, 192, name='fire6') 52 | conv = self.make_fire(conv, 48, 192, 192, name='fire7') 53 | conv = self.make_fire(conv, 64, 256, 256, name='fire8') 54 | conv = fluid.layers.pool2d( 55 | conv, pool_size=3, pool_stride=2, pool_type='max') 56 | conv = self.make_fire(conv, 64, 256, 256, name='fire9') 57 | else: 58 | conv = fluid.layers.conv2d( 59 | input, 60 | num_filters=64, 61 | filter_size=3, 62 | stride=2, 63 | padding=1, 64 | act='relu', 65 | param_attr=fluid.param_attr.ParamAttr(name="conv1_weights"), 66 | bias_attr=ParamAttr(name='conv1_offset')) 67 | conv = fluid.layers.pool2d( 68 | conv, pool_size=3, pool_stride=2, pool_type='max') 69 | conv = self.make_fire(conv, 16, 64, 64, name='fire2') 70 | conv = self.make_fire(conv, 16, 64, 64, name='fire3') 71 | conv = fluid.layers.pool2d( 72 | conv, pool_size=3, pool_stride=2, pool_type='max') 73 | conv = self.make_fire(conv, 32, 128, 128, name='fire4') 74 | conv = self.make_fire(conv, 32, 128, 128, name='fire5') 75 | conv = fluid.layers.pool2d( 76 | conv, pool_size=3, pool_stride=2, pool_type='max') 77 | conv = self.make_fire(conv, 48, 192, 192, name='fire6') 78 | conv = self.make_fire(conv, 48, 192, 192, name='fire7') 79 | conv = self.make_fire(conv, 64, 256, 256, name='fire8') 80 | conv = self.make_fire(conv, 64, 256, 256, name='fire9') 81 | conv = fluid.layers.dropout(conv, dropout_prob=0.5) 82 | conv = fluid.layers.conv2d( 83 | conv, 84 | num_filters=class_dim, 85 | filter_size=1, 86 | act='relu', 87 | param_attr=fluid.param_attr.ParamAttr(name="conv10_weights"), 88 | bias_attr=ParamAttr(name='conv10_offset')) 89 | conv = fluid.layers.pool2d(conv, pool_type='avg', global_pooling=True) 90 | out = fluid.layers.flatten(conv) 91 | return out 92 | 93 | def make_fire_conv(self, 94 | input, 95 | num_filters, 96 | filter_size, 97 | padding=0, 98 | name=None): 99 | conv = fluid.layers.conv2d( 100 | input, 101 | num_filters=num_filters, 102 | filter_size=filter_size, 103 | padding=padding, 104 | act='relu', 105 | param_attr=fluid.param_attr.ParamAttr(name=name + "_weights"), 106 | bias_attr=ParamAttr(name=name + '_offset')) 107 | return conv 108 | 109 | def make_fire(self, 110 | input, 111 | squeeze_channels, 112 | expand1x1_channels, 113 | expand3x3_channels, 114 | name=None): 115 | conv = self.make_fire_conv( 116 | input, squeeze_channels, 1, name=name + '_squeeze1x1') 117 | conv_path1 = self.make_fire_conv( 118 | conv, expand1x1_channels, 1, name=name + '_expand1x1') 119 | conv_path2 = self.make_fire_conv( 120 | conv, expand3x3_channels, 3, 1, name=name + '_expand3x3') 121 | out = fluid.layers.concat([conv_path1, conv_path2], axis=1) 122 | return out 123 | 124 | 125 | def SqueezeNet1_0(): 126 | model = SqueezeNet(version='1.0') 127 | return model 128 | 129 | 130 | def SqueezeNet1_1(): 131 | model = SqueezeNet(version='1.1') 132 | return model 133 | -------------------------------------------------------------------------------- /pytorch/train.py: -------------------------------------------------------------------------------- 1 | #coding=utf8 2 | 3 | import os 4 | import time 5 | import torch 6 | from torch.utils.data import DataLoader 7 | from torchnet import meter 8 | import sys 9 | if sys.stderr.isatty(): 10 | from tqdm import tqdm 11 | else: 12 | def tqdm(iterable,**kwargs): 13 | return iterable 14 | import logging 15 | import datasets 16 | import models 17 | from utils.util import accuracy,get_lastest_model,get_args 18 | from utils.config import opt 19 | from utils.focalloss import FocalLoss 20 | 21 | def create_logger(logdir="output"): 22 | time_str = time.strftime('%Y%m%d-%H%M%S') 23 | log_file = '{}/{}.log'.format(logdir, time_str) 24 | head = '%(asctime)-15s %(message)s' 25 | logging.basicConfig(filename=str(log_file), 26 | format=head) 27 | logger = logging.getLogger() 28 | logger.setLevel(logging.INFO) 29 | console = logging.StreamHandler() 30 | logging.getLogger('').addHandler(console) 31 | 32 | def train(args): 33 | # step0: parse config 34 | best_acc = 0 35 | new_config ={"model":args.model,"num_workers":args.num_workers, 36 | "batch_size":args.batch_size,"load_model_path":args.load_model_path} 37 | opt.parse(new_config) 38 | # step1:model 39 | model = getattr(models,opt.model)() 40 | 41 | # step2: data 42 | dataset = getattr(datasets,opt.dataset) 43 | train_data = dataset(opt.train_data_root,train=True) 44 | val_data = dataset(opt.train_data_root,train=False) 45 | train_dataloader = DataLoader(train_data,opt.batch_size,pin_memory=True, 46 | shuffle=True,num_workers=opt.num_workers) 47 | val_dataloader = DataLoader(val_data,opt.batch_size,pin_memory=True, 48 | shuffle=False,num_workers=opt.num_workers) 49 | # step3: criterion and optimizer 50 | #criterion = torch.nn.CrossEntropyLoss() 51 | criterion = FocalLoss(gamma=2.0) 52 | lr = opt.lr 53 | optimizer = torch.optim.Adam(model.parameters(),opt.lr,weight_decay=opt.weight_decay) 54 | # step4: meters 55 | loss_meter = meter.AverageValueMeter() 56 | acc_meter = meter.AverageValueMeter() 57 | confusion_matrix = meter.ConfusionMeter(2) 58 | previous_loss = 1e10 59 | if opt.load_model_path is None: 60 | opt.load_model_path = get_lastest_model(prefix=opt.model) 61 | if torch.cuda.device_count() > 1: 62 | model = torch.nn.DataParallel(model).cuda() 63 | else: 64 | model.to(opt.device) 65 | if opt.load_model_path: 66 | model.load_state_dict(torch.load(opt.load_model_path)) 67 | model.eval() 68 | _,best_acc = val(model,val_dataloader) 69 | logging.info("Resuming from "+opt.load_model_path+" with acc: "+str(best_acc)) 70 | prefix = 'output/' + opt.model 71 | # train 72 | for epoch in range(opt.max_epoch): 73 | model.train() 74 | loss_meter.reset() 75 | acc_meter.reset() 76 | confusion_matrix.reset() 77 | nIters = len(train_dataloader) 78 | pbar = tqdm(train_dataloader) 79 | start = time.time() 80 | for iter,(data,label) in enumerate(pbar): 81 | # train model 82 | input = data.to(opt.device) 83 | target = label.to(opt.device) 84 | optimizer.zero_grad() 85 | y_pred = model(input) 86 | loss = criterion(y_pred,target) 87 | prec1 = accuracy(y_pred.data, target) 88 | loss.backward() 89 | optimizer.step() 90 | # meters update 91 | loss_meter.add(loss.item()) 92 | acc_meter.add(prec1[0].item()) 93 | confusion_matrix.add(y_pred.detach(), target.detach()) 94 | if sys.stderr.isatty(): 95 | log_str = "{epoch}: Loss:{loss.val:.5f} Acc:{acc.val:.3f}".format(epoch=epoch,loss=loss_meter, acc=acc_meter) 96 | pbar.set_description(log_str) 97 | else: 98 | if iter%opt.print_freq == 0: 99 | log_str = "{iter}/{len}: Loss:{loss.val:.5f} Acc:{acc.val:.3f}".format(iter=iter,len=nIters,loss=loss_meter, acc=acc_meter) 100 | logging.info(log_str) 101 | logging.info(log_str) 102 | # validate and visualize 103 | end = time.time() 104 | if not sys.stderr.isatty(): 105 | logging.info(str(epoch)+": time "+str(end-start)+"s") 106 | val_cm,val_accuracy = val(model,val_dataloader) 107 | if val_accuracy > best_acc: 108 | best_acc =val_accuracy 109 | #name = time.strftime(prefix + '_%m%d_%H:%M:%S.pth') 110 | name = prefix+"_best.pth" 111 | torch.save(model.state_dict(),name) 112 | torch.save(model.state_dict(),prefix+"_last.pth") 113 | logging.info("Val {epoch}: Loss: {loss},Acc: {acc},lr: {lr}".format(epoch = epoch,acc=val_accuracy,loss = loss_meter.value()[0],lr=lr)) 114 | #logging.info("confusion_matrix:{val_cm}".format(val_cm = str(val_cm.value()))) 115 | # update learning rate 116 | if loss_meter.value()[0] > previous_loss: 117 | if lr > 1e-5: 118 | lr = lr * opt.lr_decay 119 | for param_group in optimizer.param_groups: 120 | param_group['lr'] = lr 121 | previous_loss = loss_meter.value()[0] 122 | 123 | @torch.no_grad() 124 | def val(model,dataloader): 125 | model.eval() 126 | confusion_matrix = meter.ConfusionMeter(2) 127 | for _, (val_input, label) in enumerate(tqdm(dataloader)): 128 | val_input = val_input.to(opt.device) 129 | score = model(val_input) 130 | confusion_matrix.add(score.detach().squeeze(), label.type(torch.LongTensor)) 131 | model.train() 132 | cm_value = confusion_matrix.value() 133 | accuracy = 100. * (cm_value[0][0] + cm_value[1][1]) / (cm_value.sum()) 134 | return confusion_matrix, accuracy 135 | 136 | if __name__=='__main__': 137 | args = get_args() 138 | create_logger() 139 | train(args) -------------------------------------------------------------------------------- /caffe/train.log.train: -------------------------------------------------------------------------------- 1 | #Iters Seconds TrainingLoss LearningRate 2 | 0 128.707545 0.207944 0.001 3 | 100 531.526072 0.00734167 0.000998 4 | 200 935.546270 0.00577467 0.000996 5 | 300 1339.451370 0.00476937 0.000994 6 | 400 1744.057585 0.00360522 0.000992 7 | 500 2148.161692 0.00331815 0.00099 8 | 600 2552.447581 0.00264361 0.000988 9 | 700 2957.336443 0.00222616 0.000986 10 | 800 3357.875937 0.00199788 0.000984 11 | 900 3747.405716 0.00184631 0.000982 12 | 1000 4258.913830 0.00148022 0.00098 13 | 1100 4647.392951 0.00165132 0.000978 14 | 1200 5036.337496 0.00141518 0.000976 15 | 1300 5425.089469 0.00104237 0.000974 16 | 1400 5813.676566 0.0011131 0.000972 17 | 1500 6202.071298 0.00111943 0.00097 18 | 1600 6590.460978 0.000846201 0.000968 19 | 1700 6978.972174 0.00070779 0.000966 20 | 1800 7368.047624 0.000604928 0.000964 21 | 1900 7757.213002 0.000733411 0.000962 22 | 2000 8268.279903 0.000487605 0.00096 23 | 2100 8656.614989 0.000641727 0.000958 24 | 2200 9045.640864 0.00054042 0.000956 25 | 2300 9434.644392 0.000473452 0.000954 26 | 2400 9823.683603 0.000529016 0.000952 27 | 2500 10212.686712 0.000383601 0.00095 28 | 2600 10601.691694 0.000397162 0.000948 29 | 2700 10990.825758 0.000418407 0.000946 30 | 2800 11380.178519 0.000281086 0.000944 31 | 2900 11769.648252 0.000495138 0.000942 32 | 3000 12281.209301 0.000238458 0.00094 33 | 3100 12670.034248 0.000204873 0.000938 34 | 3200 13059.678045 0.00022498 0.000936 35 | 3300 13449.526943 0.000182944 0.000934 36 | 3400 13839.381901 0.000191846 0.000932 37 | 3500 14229.144351 0.000201615 0.00093 38 | 3600 14618.965172 0.000204642 0.000928 39 | 3700 15008.746835 0.000338437 0.000926 40 | 3800 15398.532430 0.000210623 0.000924 41 | 3900 15788.336766 0.00019219 0.000922 42 | 4000 16300.037130 0.000225967 0.00092 43 | 4100 16689.185524 0.000222127 0.000918 44 | 4200 17079.248662 0.00022216 0.000916 45 | 4300 17469.258370 0.00015979 0.000914 46 | 4400 17859.306414 0.00015184 0.000912 47 | 4500 18249.404409 0.000114636 0.00091 48 | 4600 18639.545395 0.00013049 0.000908 49 | 4700 19029.737618 0.000120191 0.000906 50 | 4800 19419.833122 9.16823e-05 0.000904 51 | 4900 19809.595039 0.000130726 0.000902 52 | 5000 20321.251829 0.000169349 0.0009 53 | 5100 20710.641013 0.000145302 0.000898 54 | 5200 21100.846724 0.000223651 0.000896 55 | 5300 21491.319202 0.000142776 0.000894 56 | 5400 21881.807407 0.000115842 0.000892 57 | 5500 22272.281977 9.79749e-05 0.00089 58 | 5600 22662.738211 0.000150094 0.000888 59 | 5700 23052.910811 8.5967e-05 0.000886 60 | 5800 23442.938817 9.10171e-05 0.000884 61 | 5900 23832.869458 0.000108508 0.000882 62 | 6000 24344.787761 0.00013235 0.00088 63 | 6100 24734.258443 9.28495e-05 0.000878 64 | 6200 25124.382688 7.74297e-05 0.000876 65 | 6300 25514.350800 0.000110515 0.000874 66 | 6400 25904.145001 0.000126948 0.000872 67 | 6500 26293.987164 9.33633e-05 0.00087 68 | 6600 26683.802537 8.12628e-05 0.000868 69 | 6700 27073.825574 9.87202e-05 0.000866 70 | 6800 27464.040091 0.000111372 0.000864 71 | 6900 27854.354229 0.000158584 0.000862 72 | 7000 28366.564559 6.8329e-05 0.00086 73 | 7100 28756.208557 0.000196225 0.000858 74 | 7200 29146.702558 0.000149348 0.000856 75 | 7300 29537.122694 7.58981e-05 0.000854 76 | 7400 29927.637482 9.72298e-05 0.000852 77 | 7500 30318.185047 0.000134634 0.00085 78 | 7600 30708.653398 9.17249e-05 0.000848 79 | 7700 31099.125469 8.14752e-05 0.000846 80 | 7800 31489.157912 8.82677e-05 0.000844 81 | 7900 31879.343746 0.000103531 0.000842 82 | 8000 32391.377078 7.10496e-05 0.00084 83 | 8100 32780.843044 6.52493e-05 0.000838 84 | 8200 33170.998568 5.77724e-05 0.000836 85 | 8300 33561.093049 4.53542e-05 0.000834 86 | 8400 33951.180470 7.20276e-05 0.000832 87 | 8500 34341.858468 0.000103479 0.00083 88 | 8600 34732.068238 7.3347e-05 0.000828 89 | 8700 35122.379502 9.1043e-05 0.000826 90 | 8800 35512.607007 9.55755e-05 0.000824 91 | 8900 35902.826833 9.16302e-05 0.000822 92 | 9000 36416.014349 6.96384e-05 0.00082 93 | 9100 36805.633890 0.000148021 0.000818 94 | 9200 37196.066458 8.91928e-05 0.000816 95 | 9300 37586.445049 0.000101818 0.000814 96 | 9400 37976.788463 5.94084e-05 0.000812 97 | 9500 38367.091054 3.02173e-05 0.00081 98 | 9600 38757.325578 3.52849e-05 0.000808 99 | 9700 39147.926599 8.33069e-05 0.000806 100 | 9800 39538.511754 7.3808e-05 0.000804 101 | 9900 39929.135290 5.61798e-05 0.000802 102 | 10000 40442.411458 7.92375e-05 0.0008 103 | 10100 40832.160958 5.60651e-05 0.000798 104 | 10200 41222.738306 6.864e-05 0.000796 105 | 10300 41613.258858 5.90914e-05 0.000794 106 | 10400 42003.637758 8.46881e-05 0.000792 107 | 10500 42393.906044 4.61814e-05 0.00079 108 | 10600 42784.190521 7.44847e-05 0.000788 109 | 10700 43174.274502 8.31144e-05 0.000786 110 | 10800 43564.703860 3.69356e-05 0.000784 111 | 10900 43955.139415 4.87604e-05 0.000782 112 | 11000 44467.464859 8.33216e-05 0.00078 113 | 11100 44856.960682 5.78786e-05 0.000778 114 | 11200 45247.472517 6.00201e-05 0.000776 115 | 11300 45638.000040 7.20907e-05 0.000774 116 | 11400 46028.520978 5.86137e-05 0.000772 117 | 11500 46419.200794 7.22182e-05 0.00077 118 | 11600 46810.011144 6.30896e-05 0.000768 119 | 11700 47200.645911 9.50733e-05 0.000766 120 | 11800 47590.893127 5.65552e-05 0.000764 121 | 11900 47980.724575 0.000101099 0.000762 122 | 12000 48492.212785 4.65551e-05 0.00076 123 | 12100 48880.405412 4.75503e-05 0.000758 124 | 12200 49269.047340 7.66901e-05 0.000756 125 | 12300 49657.599890 7.44664e-05 0.000754 126 | 12400 50046.162751 6.05919e-05 0.000752 127 | 12500 50434.598759 8.28917e-05 0.00075 128 | 12600 50823.592237 6.98615e-05 0.000748 129 | 12700 51212.410756 0.000124488 0.000746 130 | 12800 51601.341435 7.31572e-05 0.000744 131 | -------------------------------------------------------------------------------- /paddle/models/fast_imagenet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import 16 | from __future__ import division 17 | from __future__ import print_function 18 | 19 | import functools 20 | import numpy as np 21 | import time 22 | import os 23 | import math 24 | 25 | import paddle 26 | import paddle.fluid as fluid 27 | import paddle.fluid.profiler as profiler 28 | import utils 29 | 30 | __all__ = ["FastImageNet"] 31 | 32 | 33 | class FastImageNet(): 34 | def __init__(self, layers=50, is_train=True): 35 | self.layers = layers 36 | self.is_train = is_train 37 | 38 | def net(self, input, class_dim=1000, img_size=224, is_train=True): 39 | layers = self.layers 40 | supported_layers = [50, 101, 152] 41 | assert layers in supported_layers, \ 42 | "supported layers are {} but input layer is {}".format(supported_layers, layers) 43 | 44 | if layers == 50: 45 | depth = [3, 4, 6, 3] 46 | elif layers == 101: 47 | depth = [3, 4, 23, 3] 48 | elif layers == 152: 49 | depth = [3, 8, 36, 3] 50 | num_filters = [64, 128, 256, 512] 51 | 52 | conv = self.conv_bn_layer( 53 | input=input, num_filters=64, filter_size=7, stride=2, act='relu') 54 | conv = fluid.layers.pool2d( 55 | input=conv, 56 | pool_size=3, 57 | pool_stride=2, 58 | pool_padding=1, 59 | pool_type='max') 60 | 61 | for block in range(len(depth)): 62 | for i in range(depth[block]): 63 | conv = self.bottleneck_block( 64 | input=conv, 65 | num_filters=num_filters[block], 66 | stride=2 if i == 0 and block != 0 else 1) 67 | pool_size = int(img_size / 32) 68 | pool = fluid.layers.pool2d( 69 | input=conv, pool_type='avg', global_pooling=True) 70 | out = fluid.layers.fc( 71 | input=pool, 72 | size=class_dim, 73 | act=None, 74 | param_attr=fluid.param_attr.ParamAttr( 75 | initializer=fluid.initializer.NormalInitializer(0.0, 0.01), 76 | regularizer=fluid.regularizer.L2Decay(1e-4)), 77 | bias_attr=fluid.ParamAttr( 78 | regularizer=fluid.regularizer.L2Decay(1e-4))) 79 | return out 80 | 81 | def conv_bn_layer(self, 82 | input, 83 | num_filters, 84 | filter_size, 85 | stride=1, 86 | groups=1, 87 | act=None, 88 | bn_init_value=1.0): 89 | conv = fluid.layers.conv2d( 90 | input=input, 91 | num_filters=num_filters, 92 | filter_size=filter_size, 93 | stride=stride, 94 | padding=(filter_size - 1) // 2, 95 | groups=groups, 96 | act=None, 97 | bias_attr=False, 98 | param_attr=fluid.ParamAttr( 99 | regularizer=fluid.regularizer.L2Decay(1e-4))) 100 | return fluid.layers.batch_norm( 101 | input=conv, 102 | act=act, 103 | is_test=not self.is_train, 104 | param_attr=fluid.param_attr.ParamAttr( 105 | initializer=fluid.initializer.Constant(bn_init_value), 106 | regularizer=None)) 107 | 108 | def shortcut(self, input, ch_out, stride): 109 | ch_in = input.shape[1] 110 | if ch_in != ch_out or stride != 1: 111 | return self.conv_bn_layer(input, ch_out, 1, stride) 112 | else: 113 | return input 114 | 115 | def bottleneck_block(self, input, num_filters, stride): 116 | conv0 = self.conv_bn_layer( 117 | input=input, num_filters=num_filters, filter_size=1, act='relu') 118 | conv1 = self.conv_bn_layer( 119 | input=conv0, 120 | num_filters=num_filters, 121 | filter_size=3, 122 | stride=stride, 123 | act='relu') 124 | # init bn-weight0 125 | conv2 = self.conv_bn_layer( 126 | input=conv1, 127 | num_filters=num_filters * 4, 128 | filter_size=1, 129 | act=None, 130 | bn_init_value=0.0) 131 | 132 | short = self.shortcut(input, num_filters * 4, stride) 133 | 134 | return fluid.layers.elementwise_add(x=short, y=conv2, act='relu') 135 | 136 | 137 | def lr_decay(lrs, epochs, bs, total_image): 138 | boundaries = [] 139 | values = [] 140 | for idx, epoch in enumerate(epochs): 141 | step = total_image // bs[idx] 142 | if step * bs[idx] < total_image: 143 | step += 1 144 | ratio = (lrs[idx][1] - lrs[idx][0]) * 1.0 / (epoch[1] - epoch[0]) 145 | lr_base = lrs[idx][0] 146 | for s in range(epoch[0], epoch[1]): 147 | if boundaries: 148 | boundaries.append(boundaries[-1] + step + 1) 149 | else: 150 | boundaries = [step] 151 | lr = lr_base + ratio * (s - epoch[0]) 152 | values.append(lr) 153 | print("epoch: [%d], steps: [%d], lr: [%f]" % 154 | (s, boundaries[-1], values[-1])) 155 | values.append(lrs[-1]) 156 | print("epoch: [%d:], steps: [%d:], lr:[%f]" % 157 | (epochs[-1][-1], boundaries[-1], values[-1])) 158 | return boundaries, values 159 | -------------------------------------------------------------------------------- /paddle/models/resnext101_wsl.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | from __future__ import absolute_import 15 | from __future__ import division 16 | from __future__ import print_function 17 | import paddle 18 | import paddle.fluid as fluid 19 | import math 20 | from paddle.fluid.param_attr import ParamAttr 21 | 22 | __all__ = [ 23 | "ResNeXt101_32x8d_wsl", "ResNeXt101_32x16d_wsl", "ResNeXt101_32x32d_wsl", 24 | "ResNeXt101_32x48d_wsl", "Fix_ResNeXt101_32x48d_wsl" 25 | ] 26 | 27 | 28 | class ResNeXt101_wsl(): 29 | def __init__(self, layers=101, cardinality=32, width=48): 30 | self.layers = layers 31 | self.cardinality = cardinality 32 | self.width = width 33 | 34 | def net(self, input, class_dim=1000): 35 | layers = self.layers 36 | cardinality = self.cardinality 37 | width = self.width 38 | 39 | depth = [3, 4, 23, 3] 40 | base_width = cardinality * width 41 | num_filters = [base_width * i for i in [1, 2, 4, 8]] 42 | 43 | conv = self.conv_bn_layer( 44 | input=input, 45 | num_filters=64, 46 | filter_size=7, 47 | stride=2, 48 | act='relu', 49 | name="conv1") #debug 50 | conv = fluid.layers.pool2d( 51 | input=conv, 52 | pool_size=3, 53 | pool_stride=2, 54 | pool_padding=1, 55 | pool_type='max') 56 | 57 | for block in range(len(depth)): 58 | for i in range(depth[block]): 59 | conv_name = 'layer' + str(block + 1) + "." + str(i) 60 | conv = self.bottleneck_block( 61 | input=conv, 62 | num_filters=num_filters[block], 63 | stride=2 if i == 0 and block != 0 else 1, 64 | cardinality=cardinality, 65 | name=conv_name) 66 | 67 | pool = fluid.layers.pool2d( 68 | input=conv, pool_type='avg', global_pooling=True) 69 | stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0) 70 | out = fluid.layers.fc( 71 | input=pool, 72 | size=class_dim, 73 | param_attr=fluid.param_attr.ParamAttr( 74 | initializer=fluid.initializer.Uniform(-stdv, stdv), 75 | name='fc.weight'), 76 | bias_attr=fluid.param_attr.ParamAttr(name='fc.bias')) 77 | return out 78 | 79 | def conv_bn_layer(self, 80 | input, 81 | num_filters, 82 | filter_size, 83 | stride=1, 84 | groups=1, 85 | act=None, 86 | name=None): 87 | if "downsample" in name: 88 | conv_name = name + '.0' 89 | else: 90 | conv_name = name 91 | conv = fluid.layers.conv2d( 92 | input=input, 93 | num_filters=num_filters, 94 | filter_size=filter_size, 95 | stride=stride, 96 | padding=(filter_size - 1) // 2, 97 | groups=groups, 98 | act=None, 99 | param_attr=ParamAttr(name=conv_name + ".weight"), 100 | bias_attr=False) 101 | if "downsample" in name: 102 | bn_name = name[:9] + 'downsample' + '.1' 103 | else: 104 | if "conv1" == name: 105 | bn_name = 'bn' + name[-1] 106 | else: 107 | bn_name = (name[:10] if name[7:9].isdigit() else name[:9] 108 | ) + 'bn' + name[-1] 109 | return fluid.layers.batch_norm( 110 | input=conv, 111 | act=act, 112 | param_attr=ParamAttr(name=bn_name + '.weight'), 113 | bias_attr=ParamAttr(bn_name + '.bias'), 114 | moving_mean_name=bn_name + '.running_mean', 115 | moving_variance_name=bn_name + '.running_var', ) 116 | 117 | def shortcut(self, input, ch_out, stride, name): 118 | ch_in = input.shape[1] 119 | if ch_in != ch_out or stride != 1: 120 | return self.conv_bn_layer(input, ch_out, 1, stride, name=name) 121 | else: 122 | return input 123 | 124 | def bottleneck_block(self, input, num_filters, stride, cardinality, name): 125 | cardinality = self.cardinality 126 | width = self.width 127 | conv0 = self.conv_bn_layer( 128 | input=input, 129 | num_filters=num_filters, 130 | filter_size=1, 131 | act='relu', 132 | name=name + ".conv1") 133 | conv1 = self.conv_bn_layer( 134 | input=conv0, 135 | num_filters=num_filters, 136 | filter_size=3, 137 | stride=stride, 138 | groups=cardinality, 139 | act='relu', 140 | name=name + ".conv2") 141 | conv2 = self.conv_bn_layer( 142 | input=conv1, 143 | num_filters=num_filters // (width // 8), 144 | filter_size=1, 145 | act=None, 146 | name=name + ".conv3") 147 | 148 | short = self.shortcut( 149 | input, 150 | num_filters // (width // 8), 151 | stride, 152 | name=name + ".downsample") 153 | 154 | return fluid.layers.elementwise_add(x=short, y=conv2, act='relu') 155 | 156 | 157 | def ResNeXt101_32x8d_wsl(): 158 | model = ResNeXt101_wsl(cardinality=32, width=8) 159 | return model 160 | 161 | 162 | def ResNeXt101_32x16d_wsl(): 163 | model = ResNeXt101_wsl(cardinality=32, width=16) 164 | return model 165 | 166 | 167 | def ResNeXt101_32x32d_wsl(): 168 | model = ResNeXt101_wsl(cardinality=32, width=32) 169 | return model 170 | 171 | 172 | def ResNeXt101_32x48d_wsl(): 173 | model = ResNeXt101_wsl(cardinality=32, width=48) 174 | return model 175 | 176 | 177 | def Fix_ResNeXt101_32x48d_wsl(): 178 | model = ResNeXt101_wsl(cardinality=32, width=48) 179 | return model 180 | -------------------------------------------------------------------------------- /caffe/train.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import os 3 | import sys 4 | caffe_root = os.path.expanduser("~")+"/CNN/caffe" 5 | #sys.path.insert(0, caffe_root + '/python') 6 | import caffe 7 | from caffe import layers as L,params as P,to_proto 8 | from caffe.proto import caffe_pb2 9 | 10 | root_folder="../data/train/" 11 | batch_size=32 12 | 13 | def create_data_layer(split="train",from_lmdb=True): 14 | if split=="train": 15 | shuffle=True 16 | batch_size = 32 17 | mirror = True 18 | else: 19 | shuffle = False 20 | batch_size = 8 21 | mirror = False 22 | transform_param=dict(crop_size=227, mean_file="modeldef/mean.binaryproto", mirror=mirror) 23 | if from_lmdb: 24 | source = "lmdb/"+split+"_lmdb" 25 | data, label = L.Data(data_param=dict(source=source,batch_size=batch_size,backend=P.Data.LMDB),ntop=2,transform_param=transform_param) 26 | else: 27 | source = "util/"+split+".txt" 28 | data, label = L.ImageData(image_data_param=dict(source=source,root_folder=root_folder,batch_size=batch_size,shuffle=shuffle,new_width=256,new_height=256),ntop=2, 29 | transform_param=transform_param) 30 | return data, label 31 | 32 | def conv_bn_relu(input,num_output,stride=1,is_train=True): 33 | conv=L.Convolution(input,kernel_size=3, stride=stride,num_output=num_output,weight_filler=dict(type='xavier')) 34 | if is_train: 35 | bn=L.BatchNorm( 36 | conv, batch_norm_param = dict(use_global_stats = False), 37 | in_place = True, param = [dict(lr_mult = 0, decay_mult = 0), 38 | dict(lr_mult = 0, decay_mult = 0), 39 | dict(lr_mult = 0, decay_mult = 0)]) 40 | else: 41 | bn=L.BatchNorm( 42 | conv, batch_norm_param = dict(use_global_stats = True), 43 | in_place = True, param = [dict(lr_mult = 0, decay_mult = 0), 44 | dict(lr_mult = 0, decay_mult = 0), 45 | dict(lr_mult = 0, decay_mult = 0)]) 46 | relu = L.ReLU(bn, in_place = True) 47 | return relu 48 | 49 | def create_mrnet(net,num_class=2,is_train=True): 50 | x=conv_bn_relu(net.data,32,stride=2) 51 | x=conv_bn_relu(x,32) 52 | x=conv_bn_relu(x,64,stride=2) 53 | x=conv_bn_relu(x,64) 54 | x=conv_bn_relu(x,64) 55 | x=conv_bn_relu(x,128,stride=2) 56 | x=conv_bn_relu(x,128) 57 | x=conv_bn_relu(x,128) 58 | x=conv_bn_relu(x,128) 59 | x=conv_bn_relu(x,256,stride=2) 60 | x=conv_bn_relu(x,256) 61 | x=conv_bn_relu(x,256) 62 | x=conv_bn_relu(x,512,stride=2) 63 | x=conv_bn_relu(x,512) 64 | x=conv_bn_relu(x,512) 65 | x=L.InnerProduct(x,num_output=1024,weight_filler=dict(type='xavier')) 66 | x=L.InnerProduct(x,num_output=100,weight_filler=dict(type='xavier')) 67 | x=L.InnerProduct(x,num_output=num_class,weight_filler=dict(type='xavier')) 68 | return x 69 | 70 | def conv_relu(bottom, ks, nout, stride=1, pad=0, group=1): 71 | conv = L.Convolution(bottom, kernel_size=ks, stride=stride,weight_filler=dict(type='gaussian',std=0.01),bias_filler=dict(type="constant"), param = [dict(lr_mult = 1, decay_mult = 1),dict(lr_mult = 2, decay_mult = 0)], 72 | num_output=nout, pad=pad, group=group) 73 | return L.ReLU(conv, in_place=True) 74 | 75 | def fc_relu(bottom, nout): 76 | fc = L.InnerProduct(bottom, num_output=nout,weight_filler=dict(type='xavier')) 77 | return fc, L.ReLU(fc, in_place=True) 78 | 79 | def max_pool(bottom, ks, stride=1): 80 | return L.Pooling(bottom, pool=P.Pooling.MAX, kernel_size=ks, stride=stride) 81 | 82 | def create_alexnet(net,num_class=2): 83 | x = conv_relu(net.data, 11, 96, stride=4) 84 | x = max_pool(x, 3, stride=2) 85 | x = L.LRN(x, local_size=5, alpha=1e-4, beta=0.75) 86 | x = conv_relu(x, 5, 256, pad=2, group=2) 87 | x = max_pool(x, 3, stride=2) 88 | x = L.LRN(x, local_size=5, alpha=1e-4, beta=0.75) 89 | x = conv_relu(x, 3, 384, pad=1) 90 | x = conv_relu(x, 3, 384, pad=1, group=2) 91 | x = conv_relu(x, 3, 256, pad=1, group=2) 92 | x = max_pool(x, 3, stride=2) 93 | x = fc_relu(x, 4096) 94 | x = L.Dropout(x, in_place=True) 95 | x = fc_relu(x, 4096) 96 | x = L.Dropout(x, in_place=True) 97 | x = L.InnerProduct(x, num_output=num_class,weight_filler=dict(type='gaussian',std=0.01),bias_filler=dict(type="constant"), param = [dict(lr_mult = 1, decay_mult = 1), dict(lr_mult = 2, decay_mult = 0)]) 98 | return x 99 | 100 | def gen_prototxt(): 101 | num_class=0 102 | with open("modeldef/labels.txt") as f: 103 | lines=f.readlines() 104 | for line in lines: 105 | if len(line.split(" "))==2: 106 | num_class+=1 107 | net = caffe.NetSpec() 108 | net.data, net.label = create_data_layer() 109 | net.feature = create_mrnet(net,num_class=2) 110 | net.loss = L.SoftmaxWithLoss(net.feature, net.label) 111 | net.acc = L.Accuracy(net.feature, net.label) 112 | with open("train.prototxt","w")as f: 113 | f.write(str(net.to_proto())) 114 | 115 | net.data, net.label = create_data_layer("val") 116 | net.feature = create_mrnet(net,num_class=2,is_train=False) 117 | net.acc = L.Accuracy(net.feature, net.label) 118 | with open("val.prototxt","w")as f: 119 | f.write(str(net.to_proto())) 120 | 121 | def gen_solver_txt(solver_file="solver.prototxt"): 122 | test_iter=1 123 | with open("util/val.txt")as f: 124 | lines=f.readlines() 125 | test_iter=(int)(len(lines)/batch_size) 126 | s = caffe_pb2.SolverParameter() 127 | s.train_net = 'train.prototxt' 128 | s.test_net.append('val.prototxt') 129 | s.test_interval = 10000 130 | s.test_iter.append(test_iter) 131 | s.max_iter = 500000 132 | s.base_lr = 0.01 133 | s.momentum = 0.9 134 | s.weight_decay = 5e-4 135 | s.lr_policy = 'poly' 136 | s.stepsize=50000 137 | s.gamma = 0.9 138 | s.power=1 139 | s.display = 100 140 | s.snapshot = 10000 141 | s.snapshot_prefix = 'trainedmodels/' 142 | s.solver_mode = caffe_pb2.SolverParameter.GPU 143 | with open(solver_file, 'w') as f: 144 | f.write(str(s)) 145 | 146 | def train(solver_file='solver.prototxt'): 147 | caffe.set_mode_gpu() 148 | if not os.path.exists('trainedmodels'): 149 | os.makedirs('trainedmodels') 150 | solver = caffe.SGDSolver(solver_file) 151 | solver.solve() 152 | 153 | if __name__=="__main__": 154 | gen_prototxt() 155 | gen_solver_txt() 156 | train() -------------------------------------------------------------------------------- /paddle/models/alexnet.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | 15 | from __future__ import absolute_import 16 | from __future__ import division 17 | from __future__ import print_function 18 | 19 | import math 20 | 21 | import paddle 22 | import paddle.fluid as fluid 23 | 24 | __all__ = ['AlexNet'] 25 | 26 | 27 | class AlexNet(): 28 | def __init__(self): 29 | pass 30 | 31 | def net(self, input, class_dim=1000): 32 | stdv = 1.0 / math.sqrt(input.shape[1] * 11 * 11) 33 | layer_name = [ 34 | "conv1", "conv2", "conv3", "conv4", "conv5", "fc6", "fc7", "fc8" 35 | ] 36 | conv1 = fluid.layers.conv2d( 37 | input=input, 38 | num_filters=64, 39 | filter_size=11, 40 | stride=4, 41 | padding=2, 42 | groups=1, 43 | act='relu', 44 | bias_attr=fluid.param_attr.ParamAttr( 45 | initializer=fluid.initializer.Uniform(-stdv, stdv), 46 | name=layer_name[0] + "_offset"), 47 | param_attr=fluid.param_attr.ParamAttr( 48 | initializer=fluid.initializer.Uniform(-stdv, stdv), 49 | name=layer_name[0] + "_weights")) 50 | pool1 = fluid.layers.pool2d( 51 | input=conv1, 52 | pool_size=3, 53 | pool_stride=2, 54 | pool_padding=0, 55 | pool_type='max') 56 | 57 | stdv = 1.0 / math.sqrt(pool1.shape[1] * 5 * 5) 58 | conv2 = fluid.layers.conv2d( 59 | input=pool1, 60 | num_filters=192, 61 | filter_size=5, 62 | stride=1, 63 | padding=2, 64 | groups=1, 65 | act='relu', 66 | bias_attr=fluid.param_attr.ParamAttr( 67 | initializer=fluid.initializer.Uniform(-stdv, stdv), 68 | name=layer_name[1] + "_offset"), 69 | param_attr=fluid.param_attr.ParamAttr( 70 | initializer=fluid.initializer.Uniform(-stdv, stdv), 71 | name=layer_name[1] + "_weights")) 72 | pool2 = fluid.layers.pool2d( 73 | input=conv2, 74 | pool_size=3, 75 | pool_stride=2, 76 | pool_padding=0, 77 | pool_type='max') 78 | 79 | stdv = 1.0 / math.sqrt(pool2.shape[1] * 3 * 3) 80 | conv3 = fluid.layers.conv2d( 81 | input=pool2, 82 | num_filters=384, 83 | filter_size=3, 84 | stride=1, 85 | padding=1, 86 | groups=1, 87 | act='relu', 88 | bias_attr=fluid.param_attr.ParamAttr( 89 | initializer=fluid.initializer.Uniform(-stdv, stdv), 90 | name=layer_name[2] + "_offset"), 91 | param_attr=fluid.param_attr.ParamAttr( 92 | initializer=fluid.initializer.Uniform(-stdv, stdv), 93 | name=layer_name[2] + "_weights")) 94 | 95 | stdv = 1.0 / math.sqrt(conv3.shape[1] * 3 * 3) 96 | conv4 = fluid.layers.conv2d( 97 | input=conv3, 98 | num_filters=256, 99 | filter_size=3, 100 | stride=1, 101 | padding=1, 102 | groups=1, 103 | act='relu', 104 | bias_attr=fluid.param_attr.ParamAttr( 105 | initializer=fluid.initializer.Uniform(-stdv, stdv), 106 | name=layer_name[3] + "_offset"), 107 | param_attr=fluid.param_attr.ParamAttr( 108 | initializer=fluid.initializer.Uniform(-stdv, stdv), 109 | name=layer_name[3] + "_weights")) 110 | 111 | stdv = 1.0 / math.sqrt(conv4.shape[1] * 3 * 3) 112 | conv5 = fluid.layers.conv2d( 113 | input=conv4, 114 | num_filters=256, 115 | filter_size=3, 116 | stride=1, 117 | padding=1, 118 | groups=1, 119 | act='relu', 120 | bias_attr=fluid.param_attr.ParamAttr( 121 | initializer=fluid.initializer.Uniform(-stdv, stdv), 122 | name=layer_name[4] + "_offset"), 123 | param_attr=fluid.param_attr.ParamAttr( 124 | initializer=fluid.initializer.Uniform(-stdv, stdv), 125 | name=layer_name[4] + "_weights")) 126 | pool5 = fluid.layers.pool2d( 127 | input=conv5, 128 | pool_size=3, 129 | pool_stride=2, 130 | pool_padding=0, 131 | pool_type='max') 132 | 133 | drop6 = fluid.layers.dropout(x=pool5, dropout_prob=0.5) 134 | stdv = 1.0 / math.sqrt(drop6.shape[1] * drop6.shape[2] * 135 | drop6.shape[3] * 1.0) 136 | 137 | fc6 = fluid.layers.fc( 138 | input=drop6, 139 | size=4096, 140 | act='relu', 141 | bias_attr=fluid.param_attr.ParamAttr( 142 | initializer=fluid.initializer.Uniform(-stdv, stdv), 143 | name=layer_name[5] + "_offset"), 144 | param_attr=fluid.param_attr.ParamAttr( 145 | initializer=fluid.initializer.Uniform(-stdv, stdv), 146 | name=layer_name[5] + "_weights")) 147 | 148 | drop7 = fluid.layers.dropout(x=fc6, dropout_prob=0.5) 149 | stdv = 1.0 / math.sqrt(drop7.shape[1] * 1.0) 150 | 151 | fc7 = fluid.layers.fc( 152 | input=drop7, 153 | size=4096, 154 | act='relu', 155 | bias_attr=fluid.param_attr.ParamAttr( 156 | initializer=fluid.initializer.Uniform(-stdv, stdv), 157 | name=layer_name[6] + "_offset"), 158 | param_attr=fluid.param_attr.ParamAttr( 159 | initializer=fluid.initializer.Uniform(-stdv, stdv), 160 | name=layer_name[6] + "_weights")) 161 | 162 | stdv = 1.0 / math.sqrt(fc7.shape[1] * 1.0) 163 | out = fluid.layers.fc( 164 | input=fc7, 165 | size=class_dim, 166 | bias_attr=fluid.param_attr.ParamAttr( 167 | initializer=fluid.initializer.Uniform(-stdv, stdv), 168 | name=layer_name[7] + "_offset"), 169 | param_attr=fluid.param_attr.ParamAttr( 170 | initializer=fluid.initializer.Uniform(-stdv, stdv), 171 | name=layer_name[7] + "_weights")) 172 | return out 173 | -------------------------------------------------------------------------------- /paddle/models/resnet_vc.py: -------------------------------------------------------------------------------- 1 | #copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. 2 | # 3 | #Licensed under the Apache License, Version 2.0 (the "License"); 4 | #you may not use this file except in compliance with the License. 5 | #You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | #Unless required by applicable law or agreed to in writing, software 10 | #distributed under the License is distributed on an "AS IS" BASIS, 11 | #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | #See the License for the specific language governing permissions and 13 | #limitations under the License. 14 | 15 | from __future__ import absolute_import 16 | from __future__ import division 17 | from __future__ import print_function 18 | 19 | import math 20 | 21 | import paddle 22 | import paddle.fluid as fluid 23 | from paddle.fluid.param_attr import ParamAttr 24 | 25 | __all__ = ["ResNet", "ResNet50_vc", "ResNet101_vc", "ResNet152_vc"] 26 | 27 | train_parameters = { 28 | "input_size": [3, 224, 224], 29 | "input_mean": [0.485, 0.456, 0.406], 30 | "input_std": [0.229, 0.224, 0.225], 31 | "learning_strategy": { 32 | "name": "piecewise_decay", 33 | "batch_size": 256, 34 | "epochs": [30, 60, 90], 35 | "steps": [0.1, 0.01, 0.001, 0.0001] 36 | } 37 | } 38 | 39 | 40 | class ResNet(): 41 | def __init__(self, layers=50): 42 | self.params = train_parameters 43 | self.layers = layers 44 | 45 | def net(self, input, class_dim=1000): 46 | layers = self.layers 47 | supported_layers = [50, 101, 152] 48 | assert layers in supported_layers, \ 49 | "supported layers are {} but input layer is {}".format(supported_layers, layers) 50 | 51 | if layers == 50: 52 | depth = [3, 4, 6, 3] 53 | elif layers == 101: 54 | depth = [3, 4, 23, 3] 55 | elif layers == 152: 56 | depth = [3, 8, 36, 3] 57 | num_filters = [64, 128, 256, 512] 58 | 59 | conv = self.conv_bn_layer( 60 | input=input, 61 | num_filters=32, 62 | filter_size=3, 63 | stride=2, 64 | act='relu', 65 | name='conv1_1') 66 | conv = self.conv_bn_layer( 67 | input=conv, 68 | num_filters=32, 69 | filter_size=3, 70 | stride=1, 71 | act='relu', 72 | name='conv1_2') 73 | conv = self.conv_bn_layer( 74 | input=conv, 75 | num_filters=64, 76 | filter_size=3, 77 | stride=1, 78 | act='relu', 79 | name='conv1_3') 80 | 81 | conv = fluid.layers.pool2d( 82 | input=conv, 83 | pool_size=3, 84 | pool_stride=2, 85 | pool_padding=1, 86 | pool_type='max') 87 | 88 | for block in range(len(depth)): 89 | for i in range(depth[block]): 90 | if layers in [101, 152] and block == 2: 91 | if i == 0: 92 | conv_name = "res" + str(block + 2) + "a" 93 | else: 94 | conv_name = "res" + str(block + 2) + "b" + str(i) 95 | else: 96 | conv_name = "res" + str(block + 2) + chr(97 + i) 97 | conv = self.bottleneck_block( 98 | input=conv, 99 | num_filters=num_filters[block], 100 | stride=2 if i == 0 and block != 0 else 1, 101 | name=conv_name) 102 | 103 | pool = fluid.layers.pool2d( 104 | input=conv, pool_type='avg', global_pooling=True) 105 | stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0) 106 | out = fluid.layers.fc(input=pool, 107 | size=class_dim, 108 | param_attr=fluid.param_attr.ParamAttr( 109 | initializer=fluid.initializer.Uniform(-stdv, 110 | stdv))) 111 | return out 112 | 113 | def conv_bn_layer(self, 114 | input, 115 | num_filters, 116 | filter_size, 117 | stride=1, 118 | groups=1, 119 | act=None, 120 | name=None): 121 | conv = fluid.layers.conv2d( 122 | input=input, 123 | num_filters=num_filters, 124 | filter_size=filter_size, 125 | stride=stride, 126 | padding=(filter_size - 1) // 2, 127 | groups=groups, 128 | act=None, 129 | param_attr=ParamAttr(name=name + "_weights"), 130 | bias_attr=False, 131 | name=name + '.conv2d.output.1') 132 | if name == "conv1": 133 | bn_name = "bn_" + name 134 | else: 135 | bn_name = "bn" + name[3:] 136 | return fluid.layers.batch_norm( 137 | input=conv, 138 | act=act, 139 | name=bn_name + '.output.1', 140 | param_attr=ParamAttr(name=bn_name + '_scale'), 141 | bias_attr=ParamAttr(bn_name + '_offset'), 142 | moving_mean_name=bn_name + '_mean', 143 | moving_variance_name=bn_name + '_variance', ) 144 | 145 | def shortcut(self, input, ch_out, stride, name): 146 | ch_in = input.shape[1] 147 | if ch_in != ch_out or stride != 1: 148 | return self.conv_bn_layer(input, ch_out, 1, stride, name=name) 149 | else: 150 | return input 151 | 152 | def bottleneck_block(self, input, num_filters, stride, name): 153 | conv0 = self.conv_bn_layer( 154 | input=input, 155 | num_filters=num_filters, 156 | filter_size=1, 157 | act='relu', 158 | name=name + "_branch2a") 159 | conv1 = self.conv_bn_layer( 160 | input=conv0, 161 | num_filters=num_filters, 162 | filter_size=3, 163 | stride=stride, 164 | act='relu', 165 | name=name + "_branch2b") 166 | conv2 = self.conv_bn_layer( 167 | input=conv1, 168 | num_filters=num_filters * 4, 169 | filter_size=1, 170 | act=None, 171 | name=name + "_branch2c") 172 | 173 | short = self.shortcut( 174 | input, num_filters * 4, stride, name=name + "_branch1") 175 | 176 | return fluid.layers.elementwise_add( 177 | x=short, y=conv2, act='relu', name=name + ".add.output.5") 178 | 179 | 180 | def ResNet50_vc(): 181 | model = ResNet(layers=50) 182 | return model 183 | 184 | 185 | def ResNet101_vc(): 186 | model = ResNet(layers=101) 187 | return model 188 | 189 | 190 | def ResNet152_vc(): 191 | model = ResNet(layers=152) 192 | return model 193 | -------------------------------------------------------------------------------- /tensorflow/train_layers.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import tensorflow as tf 4 | import os 5 | 6 | # Dataset Parameters - CHANGE HERE 7 | MODE = 'folder' # or 'file', if you choose a plain text file (see above). 8 | DATASET_PATH = '../data/train2' # the dataset file or root folder path. 9 | 10 | # Image Parameters 11 | N_CLASSES = 2 # CHANGE HERE, total number of classes 12 | IMG_HEIGHT = 227 # CHANGE HERE, the image height to be resized to 13 | IMG_WIDTH = 227 # CHANGE HERE, the image width to be resized to 14 | CHANNELS = 3 # The 3 color channels, change to 1 if grayscale 15 | 16 | # Parameters 17 | learning_rate = 0.001 18 | num_steps = 10000 19 | batch_size = 32 20 | display_step = 100 21 | 22 | # Network Parameters 23 | dropout = 0.75 # Dropout, probability to keep units 24 | 25 | 26 | # Reading the dataset 27 | # 2 modes: 'file' or 'folder' 28 | def read_images(dataset_path, mode, batch_size): 29 | imagepaths, labels = list(), list() 30 | if mode == 'file': 31 | # Read dataset file 32 | data = open(dataset_path, 'r').read().splitlines() 33 | for d in data: 34 | imagepaths.append(d.split(' ')[0]) 35 | labels.append(int(d.split(' ')[1])) 36 | elif mode == 'folder': 37 | # An ID will be affected to each sub-folders by alphabetical order 38 | label = 0 39 | # List the directory 40 | try: # Python 2 41 | classes = sorted(os.walk(dataset_path).next()[1]) 42 | except Exception: # Python 3 43 | classes = sorted(os.walk(dataset_path).__next__()[1]) 44 | # List each sub-directory (the classes) 45 | for c in classes: 46 | c_dir = os.path.join(dataset_path, c) 47 | try: # Python 2 48 | walk = os.walk(c_dir).next() 49 | except Exception: # Python 3 50 | walk = os.walk(c_dir).__next__() 51 | # Add each image to the training set 52 | for sample in walk[2]: 53 | # Only keeps jpeg images 54 | if sample.endswith('.jpg') or sample.endswith('.jpeg'): 55 | imagepaths.append(os.path.join(c_dir, sample)) 56 | labels.append(label) 57 | label += 1 58 | else: 59 | raise Exception("Unknown mode.") 60 | 61 | # Convert to Tensor 62 | imagepaths = tf.convert_to_tensor(imagepaths, dtype=tf.string) 63 | labels = tf.convert_to_tensor(labels, dtype=tf.int32) 64 | # Build a TF Queue, shuffle data 65 | image, label = tf.train.slice_input_producer([imagepaths, labels], 66 | shuffle=True) 67 | 68 | # Read images from disk 69 | image = tf.read_file(image) 70 | image = tf.image.decode_jpeg(image, channels=CHANNELS) 71 | 72 | # Resize images to a common size 73 | image = tf.image.resize_images(image, [IMG_HEIGHT, IMG_WIDTH]) 74 | 75 | # Normalize 76 | image = image * 1.0/127.5 - 1.0 77 | 78 | # Create batches 79 | X, Y = tf.train.batch([image, label], batch_size=batch_size, 80 | capacity=batch_size * 8, 81 | num_threads=4) 82 | 83 | return X, Y 84 | 85 | # ----------------------------------------------- 86 | # THIS IS A CLASSIC CNN (see examples, section 3) 87 | # ----------------------------------------------- 88 | # Note that a few elements have changed (usage of queues). 89 | 90 | 91 | # Build the data input 92 | X, Y = read_images(DATASET_PATH, MODE, batch_size) 93 | 94 | # Create model 95 | def conv_net(x, n_classes, dropout, reuse, is_training): 96 | # Define a scope for reusing the variables 97 | with tf.variable_scope('ConvNet', reuse=reuse): 98 | 99 | # Convolution Layer with 32 filters and a kernel size of 5 100 | conv1 = tf.layers.conv2d(x, 32, 5, activation=tf.nn.relu) 101 | # Max Pooling (down-sampling) with strides of 2 and kernel size of 2 102 | conv1 = tf.layers.max_pooling2d(conv1, 2, 2) 103 | 104 | # Convolution Layer with 32 filters and a kernel size of 5 105 | conv2 = tf.layers.conv2d(conv1, 64, 3, activation=tf.nn.relu) 106 | # Max Pooling (down-sampling) with strides of 2 and kernel size of 2 107 | conv2 = tf.layers.max_pooling2d(conv2, 2, 2) 108 | 109 | # Flatten the data to a 1-D vector for the fully connected layer 110 | fc1 = tf.contrib.layers.flatten(conv2) 111 | 112 | # Fully connected layer (in contrib folder for now) 113 | fc1 = tf.layers.dense(fc1, 1024) 114 | # Apply Dropout (if is_training is False, dropout is not applied) 115 | fc1 = tf.layers.dropout(fc1, rate=dropout, training=is_training) 116 | 117 | # Output layer, class prediction 118 | out = tf.layers.dense(fc1, n_classes) 119 | # Because 'softmax_cross_entropy_with_logits' already apply softmax, 120 | # we only apply softmax to testing network 121 | out = tf.nn.softmax(out) if not is_training else out 122 | 123 | return out 124 | 125 | 126 | # Because Dropout have different behavior at training and prediction time, we 127 | # need to create 2 distinct computation graphs that share the same weights. 128 | 129 | # Create a graph for training 130 | logits_train = conv_net(X, N_CLASSES, dropout, reuse=False, is_training=True) 131 | # Create another graph for testing that reuse the same weights 132 | logits_test = conv_net(X, N_CLASSES, dropout, reuse=True, is_training=False) 133 | 134 | # Define loss and optimizer (with train logits, for dropout to take effect) 135 | loss_op = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits( 136 | logits=logits_train, labels=Y)) 137 | optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) 138 | train_op = optimizer.minimize(loss_op) 139 | 140 | # Evaluate model (with test logits, for dropout to be disabled) 141 | correct_pred = tf.equal(tf.argmax(logits_test, 1), tf.cast(Y, tf.int64)) 142 | accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) 143 | 144 | # Initialize the variables (i.e. assign their default value) 145 | init = tf.global_variables_initializer() 146 | 147 | # Saver object 148 | saver = tf.train.Saver() 149 | 150 | # Start training 151 | with tf.Session() as sess: 152 | 153 | # Run the initializer 154 | sess.run(init) 155 | 156 | # Start the data queue 157 | tf.train.start_queue_runners() 158 | 159 | # Training cycle 160 | for step in range(1, num_steps+1): 161 | 162 | if step % display_step == 0: 163 | # Run optimization and calculate batch loss and accuracy 164 | _, loss, acc = sess.run([train_op, loss_op, accuracy]) 165 | print("Step " + str(step) + ", Minibatch Loss= " + \ 166 | "{:.4f}".format(loss) + ", Training Accuracy= " + \ 167 | "{:.3f}".format(acc)) 168 | else: 169 | # Only run the optimization op (backprop) 170 | sess.run(train_op) 171 | 172 | print("Optimization Finished!") 173 | 174 | # Save your model 175 | saver.save(sess, './my_tf_model') 176 | -------------------------------------------------------------------------------- /paddle/utils/train.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import paddle.fluid as fluid 3 | import paddle 4 | import numpy as np 5 | from PIL import Image 6 | import os 7 | from multiprocessing import cpu_count 8 | import matplotlib.pyplot as plt 9 | 10 | # 定义训练的mapper 11 | def train_mapper(sample): 12 | img, label = sample 13 | img = paddle.dataset.image.load_image(file=img) 14 | img = paddle.dataset.image.simple_transform(im=img, resize_size=32, crop_size=28, is_train=True) 15 | img = img.flatten().astype('float32') / 255.0 16 | return img, label 17 | 18 | 19 | # 定义训练的reader 20 | def train_r(train_list_path): 21 | def reader(): 22 | with open(train_list_path, 'r') as f: 23 | lines = f.readlines() 24 | del lines[len(lines) - 1] 25 | for line in lines: 26 | img, label = line.split('\t') 27 | yield img, int(label) 28 | 29 | return paddle.reader.xmap_readers(train_mapper, reader, cpu_count(), 1024) 30 | 31 | 32 | # 定义测试的mapper 33 | def test_mapper(sample): 34 | img, label = sample 35 | img = paddle.dataset.image.load_image(file=img) 36 | img = paddle.dataset.image.simple_transform(im=img, resize_size=32, crop_size=28, is_train=False) 37 | img = img.flatten().astype('float32') / 255.0 38 | return img, label 39 | 40 | 41 | # 定义测试的reader 42 | def test_r(test_list_path): 43 | def reader(): 44 | with open(test_list_path, 'r') as f: 45 | lines = f.readlines() 46 | for line in lines: 47 | img, label = line.split('\t') 48 | yield img, int(label) 49 | 50 | return paddle.reader.xmap_readers(test_mapper, reader, cpu_count(), 1024) 51 | # 定义一个卷积神经网络 52 | def cnn(ipt): 53 | conv1 = fluid.layers.conv2d(input=ipt, 54 | num_filters=32, 55 | filter_size=3, 56 | padding=1, 57 | stride=1, 58 | name='conv1', 59 | act='relu') 60 | 61 | pool1 = fluid.layers.pool2d(input=conv1, 62 | pool_size=2, 63 | pool_stride=2, 64 | pool_type='max', 65 | name='pool1') 66 | 67 | bn1 = fluid.layers.batch_norm(input=pool1, name='bn1') 68 | 69 | conv2 = fluid.layers.conv2d(input=bn1, 70 | num_filters=64, 71 | filter_size=3, 72 | padding=1, 73 | stride=1, 74 | name='conv2', 75 | act='relu') 76 | 77 | pool2 = fluid.layers.pool2d(input=conv2, 78 | pool_size=2, 79 | pool_stride=2, 80 | pool_type='max', 81 | name='pool2') 82 | 83 | bn2 = fluid.layers.batch_norm(input=pool2, name='bn2') 84 | 85 | fc1 = fluid.layers.fc(input=bn2, size=1024, act='relu', name='fc1') 86 | 87 | fc2 = fluid.layers.fc(input=fc1, size=10, act='softmax', name='fc2') 88 | 89 | return fc2 90 | 91 | def train(): 92 | image = fluid.layers.data(name='image', shape=[1, 28, 28], dtype='float32') 93 | net = cnn(image) 94 | # 定义损失函数和准确率函数 95 | label = fluid.layers.data(name='label', shape=[1], dtype='int64') 96 | cost = fluid.layers.cross_entropy(input=net, label=label) 97 | avg_cost = fluid.layers.mean(x=cost) 98 | acc = fluid.layers.accuracy(input=net, label=label, k=1) 99 | 100 | # 克隆测试程序 101 | test_program = fluid.default_main_program().clone(for_test=True) 102 | 103 | # 定义优化方法 104 | optimizer = fluid.optimizer.AdamOptimizer(learning_rate=0.001) 105 | opt = optimizer.minimize(avg_cost) 106 | 107 | # 定义执行器 108 | place = fluid.CPUPlace() 109 | exe = fluid.Executor(place=place) 110 | exe.run(program=fluid.default_startup_program()) 111 | 112 | # 生成训练和测试的reader 113 | train_reader = paddle.batch(reader=paddle.reader.shuffle(reader=train_r('./train_data.list'), buf_size=3000), 114 | batch_size=128) 115 | test_reader = paddle.batch(reader=test_r('./test_data.list'), batch_size=128) 116 | 117 | # 定义输入数据的维度 118 | feeder = fluid.DataFeeder(place=place, feed_list=[image, label]) 119 | 120 | # 开始训练和测试 121 | for pass_id in range(2): 122 | for batch_id, data in enumerate(train_reader()): 123 | # 执行训练程序 124 | train_cost, train_acc = exe.run(program=fluid.default_main_program(), 125 | feed=feeder.feed(data), 126 | fetch_list=[avg_cost, acc]) 127 | if batch_id % 100 == 0: 128 | print('\nPass:%d, Batch:%d, Cost:%f, Accuracy:%f' % (pass_id, batch_id, train_cost[0], train_acc[0])) 129 | else: 130 | print('.') 131 | # 执行测试程序 132 | test_costs = [] 133 | test_accs = [] 134 | for batch_id, data in enumerate(test_reader()): 135 | test_cost, test_acc = exe.run(program=test_program, 136 | feed=feeder.feed(data), 137 | fetch_list=[avg_cost, acc]) 138 | test_costs.append(test_cost[0]) 139 | test_accs.append(test_acc[0]) 140 | test_cost = sum(test_costs) / len(test_costs) 141 | test_acc = sum(test_accs) / len(test_accs) 142 | print('\nTest:%d, Cost:%f, Accuracy:%f' % (pass_id, test_cost, test_acc)) 143 | 144 | # 保存模型 145 | fluid.io.save_inference_model(dirname='./model', feeded_var_names=['image'], target_vars=[net], executor=exe) 146 | 147 | # 预处理图片 148 | def load_image(path): 149 | img = paddle.dataset.image.load_image(file=path, is_color=False) 150 | img = paddle.dataset.image.simple_transform(im=img, resize_size=32, crop_size=28, is_color=False, is_train=False) 151 | img = img.astype('float32') 152 | img = img[np.newaxis,] / 255.0 153 | return img 154 | 155 | def test(): 156 | place = fluid.CPUPlace() 157 | exe = fluid.Executor(place=place) 158 | # 从保存的模型中获取预测程序、feed名称和网络分类器 159 | [infer_program, feeded_var_names, target_vars] = fluid.io.load_inference_model(dirname='./model', executor=exe) 160 | # 把处理后的图片加入到列表中 161 | infer_imgs = [] 162 | infer_imgs.append(load_image('./TibetanMnist(350x350)/0_10_398.jpg')) 163 | infer_imgs = np.array(infer_imgs) 164 | 165 | # 执行预测程序 166 | result = exe.run(program=infer_program, 167 | feed={feeded_var_names[0]: infer_imgs}, 168 | fetch_list=target_vars) 169 | 170 | # 显示图片并输出结果最大的label 171 | lab = np.argsort(result) 172 | 173 | im = Image.open('./TibetanMnist(350x350)/0_10_398.jpg') 174 | plt.imshow(im) 175 | plt.show() 176 | 177 | print('预测结果为:%d' % lab[0][0][-1]) 178 | 179 | def main(): 180 | train() 181 | #test() 182 | 183 | if __name__=="__main__": 184 | main() --------------------------------------------------------------------------------