Using Paddlepaddle to recognize flowers
PaddlePaddle is a Chinese based DL framework developped by China’s Google Baidu. If you are interested in exploring this DL framework, here is an example of how to use paddlepaddle to train a flower classification model.
Install paddlepaddle
Following the official instruction, which is pretty clear.
Prepare the code
git clone https://github.com/PaddlePaddle/PaddleClas.git
Dataset
Download the data
# Go to the root path of the PaddleClas repo
cd dataset/
wget https://paddle-imagenet-models-name.bj.bcebos.com/data/flowers102.zip
unzip flowers102.zip
After downlading the dataset, you will have
flowers102├── flowers102_label_list.txt├── jpg│ ├── image_00001.jpg│ ├── image_00002.jpg│ ├── image_00003.jpg│ ├── image_00004.jpg
...
│ ├── image_08185.jpg│ ├── image_08186.jpg│ ├── image_08187.jpg│ ├── image_08188.jpg│ └── image_08189.jpg├── train_extra_list.txt├── train_list.txt└── val_list.txt
Which means you have 8189 images in total. Some samples like the following:
How many labels (categories) do we have?
If you check the flowers102_label_list.txt, as the name suggested, we have 102 different types.
0 pink primrose1 hard-leaved pocket orchid2 canterbury bells3 sweet pea4 english marigold5 tiger lily6 moon orchid7 bird of paradise8 monkshood9 globe thistle
...
96 mallow97 mexican petunia98 bromelia99 blanket flower100 trumpet creeper101 blackberry lily
Train and val split
We have the file of
train_extra_list.txt train_list.txt val_list.txt
Here is the samples in train_list.txt which indicate the train dataset’s
file name and label id.
jpg/image_06765.jpg 0jpg/image_06755.jpg 0jpg/image_06768.jpg 0jpg/image_06736.jpg 0jpg/image_06744.jpg 0jpg/image_06766.jpg 0jpg/image_06771.jpg 0jpg/image_06750.jpg 0jpg/image_06741.jpg 0jpg/image_06762.jpg 0jpg/image_05145.jpg 1jpg/image_05137.jpg 1jpg/image_05142.jpg 1jpg/image_05115.jpg 1jpg/image_05091.jpg 1jpg/image_05106.jpg 1
Train the model
In order to run the code, you need install several packages except the paddlepaddle
pip install tqdm
conda install -c anaconda scikit-learn
pip install pyyaml
conda install -c conda-forge opencv
pip install visualdl
Using this command to train from a pretrained model
python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml -o Arch.pretrained=True
If the training process goes well, you will see something like this
[2022/01/24 23:15:44] root INFO: channel_first : False[2022/01/24 23:15:44] root INFO: to_rgb : True[2022/01/24 23:15:44] root INFO: ResizeImage :[2022/01/24 23:15:44] root INFO: resize_short : 256[2022/01/24 23:15:44] root INFO: CropImage :[2022/01/24 23:15:44] root INFO: size : 224[2022/01/24 23:15:44] root INFO: NormalizeImage :[2022/01/24 23:15:44] root INFO: mean : [0.485, 0.456, 0.406][2022/01/24 23:15:44] root INFO: order :[2022/01/24 23:15:44] root INFO: scale : 1.0/255.0[2022/01/24 23:15:44] root INFO: std : [0.229, 0.224, 0.225][2022/01/24 23:15:44] root INFO: ToCHWImage : None[2022/01/24 23:15:44] root INFO: Loss :[2022/01/24 23:15:44] root INFO: Eval :[2022/01/24 23:15:44] root INFO: CELoss :[2022/01/24 23:15:44] root INFO: weight : 1.0[2022/01/24 23:15:44] root INFO: Train :[2022/01/24 23:15:44] root INFO: CELoss :[2022/01/24 23:15:44] root INFO: weight : 1.0[2022/01/24 23:15:44] root INFO: Metric :[2022/01/24 23:15:44] root INFO: Eval :[2022/01/24 23:15:44] root INFO: TopkAcc :[2022/01/24 23:15:44] root INFO: topk : [1, 5][2022/01/24 23:15:44] root INFO: Train :[2022/01/24 23:15:44] root INFO: TopkAcc :[2022/01/24 23:15:44] root INFO: topk : [1, 5][2022/01/24 23:15:44] root INFO: Optimizer :[2022/01/24 23:15:44] root INFO: lr :[2022/01/24 23:15:44] root INFO: learning_rate : 0.0125[2022/01/24 23:15:44] root INFO: name : Cosine[2022/01/24 23:15:44] root INFO: warmup_epoch : 5[2022/01/24 23:15:44] root INFO: momentum : 0.9[2022/01/24 23:15:44] root INFO: name : Momentum[2022/01/24 23:15:44] root INFO: regularizer :[2022/01/24 23:15:44] root INFO: coeff : 1e-05[2022/01/24 23:15:44] root INFO: name : L2[2022/01/24 23:15:44] root INFO: profiler_options : None[2022/01/24 23:15:44] root INFO: train with paddle 2.2.1 and device CUDAPlace(0)W0124 23:15:44.645875 39134 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.0, Runtime API Version: 11.0W0124 23:15:45.481689 39134 device_context.cc:465] device: 0, cuDNN Version: 8.0.
[2022/01/24 23:17:25] root INFO: unique_endpoints {''}[2022/01/24 23:17:25] root INFO: Downloading ResNet50_vd_pretrained.pdparams from https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/ResNet50_vd_pretrained.pdparams100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 151674/151674 [00:44<00:00, 3438.65it/s]/home/ubuntu/anaconda3/envs/paddle/lib/python3.7/site-packages/paddle/fluid/dygraph/layers.py:1436: UserWarning: Skip loading for fc.weight. fc.weight receives a shape [2048, 1000], but the expected shape is [2048, 102].warnings.warn(("Skip loading for {}. ".format(key) + str(err)))/home/ubuntu/anaconda3/envs/paddle/lib/python3.7/site-packages/paddle/fluid/dygraph/layers.py:1436: UserWarning: Skip loading for fc.bias. fc.bias receives a shape [1000], but the expected shape is [102].warnings.warn(("Skip loading for {}. ".format(key) + str(err)))
...
0.33236, batch_cost: 0.20485s, reader_cost: 0.00014, ips: 156.21518 images/sec, eta: 0:01:08[2022/01/24 23:23:39] root INFO: [Train][Epoch 10/20][Iter: 30/32]lr: 0.00941, top1: 0.91230, top5: 0.97681, CELoss: 0.37659, loss: 0.37659, batch_cost: 0.20435s, reader_cost: 0.00012, ips: 156.59497 images/sec, eta: 0:01:05[2022/01/24 23:23:39] root INFO: [Train][Epoch 10/20][Avg]top1: 0.91373, top5: 0.97745, CELoss: 0.37335, loss: 0.37335[2022/01/24 23:23:40] root INFO: [Eval][Epoch 10][Iter: 0/16]CELoss: 0.75603, loss: 0.75603, top1: 0.82812, top5: 0.93750, batch_cost: 1.02958s, reader_cost: 0.91494, ips: 62.16100 images/sec[2022/01/24 23:23:42] root INFO: [Eval][Epoch 10][Iter: 10/16]CELoss: 0.24584, loss: 0.24584, top1: 0.92188, top5: 1.00000, batch_cost: 0.17600s, reader_cost: 0.06913, ips: 363.64605 images/sec[2022/01/24 23:23:43] root INFO: [Eval][Epoch 10][Avg]CELoss: 0.37863, loss: 0.37863, top1: 0.90000, top5: 0.97843[2022/01/24 23:23:49] root INFO: Already save model in ./output/ResNet50_vd/best_model[2022/01/24 23:23:49] root INFO: [Eval][Epoch 10][best metric: 0.8999999983637941][2022/01/24 23:23:50] root INFO: Already save model in ./output/ResNet50_vd/epoch_10[2022/01/24 23:23:54] root INFO: Already save model in ./output/ResNet50_vd/latest[2022/01/24 23:23:55] root INFO: [Train][Epoch 11/20][Iter: 0/32]lr: 0.00934, top1: 0.93750, top5: 1.00000, CELoss: 0.15017, loss: 0.15017, batch_cost: 0.21860s, reader_cost: 0.01467, ips: 146.38531 images/sec, eta: 0:01:09[2022/01/24 23:23:57] root INFO: [Train][Epoch 11/20][Iter: 10/32]lr: 0.00898, top1: 0.93466, top5: 0.99148, CELoss: 0.24013, loss: 0.24013, batch_cost: 0.20525s, reader_cost: 0
...[2022/01/24 23:26:21] root INFO: [Train][Epoch 20/20][Avg]top1: 0.98235, top5: 0.99608, CELoss: 0.07628, loss: 0.07628[2022/01/24 23:26:22] root INFO: [Eval][Epoch 20][Iter: 0/16]CELoss: 0.59098, loss: 0.59098, top1: 0.87500, top5: 0.95312, batch_cost: 1.02575s, reader_cost: 0.90770, ips: 62.39326 images/sec[2022/01/24 23:26:24] root INFO: [Eval][Epoch 20][Iter: 10/16]CELoss: 0.28884, loss: 0.28884, top1: 0.92188, top5: 0.98438, batch_cost: 0.16941s, reader_cost: 0.06267, ips: 377.79246 images/sec[2022/01/24 23:26:25] root INFO: [Eval][Epoch 20][Avg]CELoss: 0.23456, loss: 0.23456, top1: 0.94706, top5: 0.98627[2022/01/24 23:26:25] root INFO: [Eval][Epoch 20][best metric: 0.9470588244643866][2022/01/24 23:26:25] root INFO: Already save model in ./output/ResNet50_vd/epoch_20[2022/01/24 23:26:26] root INFO: Already save model in ./output/ResNet50_vd/latest
If you check you GPU usage
nvidia-smi
You can see
Inference
python tools/infer.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Infer.infer_imgs=dataset/flowers102/jpg/image_00001.jpg -o Global.pretrained_model=output/ResNet50_vd/best_model
output
Pretty good, the image tested has the label of 76. The model’s prediction matches.
[{'class_ids': [76, 11, 9, 70, 12], 'scores': [0.99713, 0.00109, 0.00042, 0.00016, 0.00012], 'file_name': 'dataset/flowers102/jpg/image_00001.jpg', 'label_names': ['passion flower', "colt's foot", 'globe thistle', 'gazania', 'king protea']}]