未验证 提交 a4ee18df 编写于 作者: W Wei Shengyu 提交者: GitHub

Merge pull request #1014 from PaddlePaddle/develop

Develop
......@@ -31,6 +31,7 @@ IndexProcess:
index_path: "./recognition_demo_data_v1.0/gallery_cartoon/index/"
image_root: "./recognition_demo_data_v1.0/gallery_cartoon/"
data_file: "./recognition_demo_data_v1.0/gallery_cartoon/data_file.txt"
append_index: False
delimiter: "\t"
dist_type: "IP"
pq_size: 100
......
......@@ -29,6 +29,7 @@ IndexProcess:
index_path: "./recognition_demo_data_v1.0/gallery_logo/index/"
image_root: "./recognition_demo_data_v1.0/gallery_logo/"
data_file: "./recognition_demo_data_v1.0/gallery_logo/data_file.txt"
append_index: False
delimiter: "\t"
dist_type: "IP"
pq_size: 100
......
......@@ -29,6 +29,7 @@ IndexProcess:
index_path: "./recognition_demo_data_v1.0/gallery_product/index"
image_root: "./recognition_demo_data_v1.0/gallery_product/"
data_file: "./recognition_demo_data_v1.0/gallery_product/data_file.txt"
append_index: False
delimiter: "\t"
dist_type: "IP"
pq_size: 100
......
......@@ -29,6 +29,7 @@ IndexProcess:
index_path: "./recognition_demo_data_v1.0/gallery_vehicle/index/"
image_root: "./recognition_demo_data_v1.0/gallery_vehicle/"
data_file: "./recognition_demo_data_v1.0/gallery_vehicle/data_file.txt"
append_index: False
delimiter: "\t"
dist_type: "IP"
pq_size: 100
......
......@@ -86,7 +86,8 @@ class GalleryBuilder(object):
gallery_vectors=gallery_features,
gallery_docs=gallery_docs,
pq_size=config['pq_size'],
index_path=config['index_path'])
index_path=config['index_path'],
append_index=config["append_index"])
def main(config):
......
......@@ -132,7 +132,8 @@ class Graph_Index(object):
gallery_vectors,
gallery_docs=[],
pq_size=100,
index_path='graph_index/'):
index_path='graph_index/',
append_index=False):
"""
build index
"""
......@@ -181,7 +182,25 @@ class Graph_Index(object):
self.gallery_doc_dict["dist_type"] = self.dist_type
self.gallery_doc_dict["with_attr"] = self.with_attr
with open(index_path + "/info.json", "w") as f:
output_path = os.path.join(index_path, "info.json")
if append_index is True and os.path.exists(output_path):
with open(output_path, "r") as fin:
lines = fin.readlines()[0]
ori_gallery_doc_dict = json.loads(lines)
assert ori_gallery_doc_dict["dist_type"] == self.gallery_doc_dict[
"dist_type"]
assert ori_gallery_doc_dict["dim"] == self.gallery_doc_dict["dim"]
assert ori_gallery_doc_dict["with_attr"] == self.gallery_doc_dict[
"with_attr"]
offset = ori_gallery_doc_dict["total_num"]
for i in range(0, self.gallery_doc_dict["total_num"]):
ori_gallery_doc_dict[str(i + offset)] = self.gallery_doc_dict[
str(i)]
ori_gallery_doc_dict["total_num"] += self.gallery_doc_dict[
"total_num"]
self.gallery_doc_dict = ori_gallery_doc_dict
with open(output_path, "w") as f:
json.dump(self.gallery_doc_dict, f)
print("finished creating index ...")
......
......@@ -58,10 +58,7 @@ This method is used in VERI-Wild dataset. This dataset was captured in a large C
| GLAMOR(Resnet50+PGN)[3] | 77.15 | 92.13 | 97.43 |
| PVEN(Resnet50)[4] | 79.8 | 94.01 | 98.06 |
| SAVER(VAE+Resnet50)[5] | 80.9 | 93.78 | 97.93 |
| PaddleClas baseline1 | 65.6 | 92.37 | 97.23 |
| PaddleClas baseline2 | 80.09 | **93.81** | **98.26** |
Baseline1 is the released, and baseline2 will be released soon.
| PaddleClas baseline | 80.57 | **93.81** | **98.06** |
### 2.2 Vehicle Fine-grained Classification
......@@ -79,7 +76,7 @@ The images in the dataset mainly come from the network and monitoring data. The
| Fine-Tuning DARTS[7] | 95.9% |
| Resnet50 + COOC[8] | 95.6% |
| A3M[9] | 95.4% |
| PaddleClas baseline (ResNet50) | **97.36**% |
| PaddleClas baseline (ResNet50) | **97.37**% |
## 3 References
......
......@@ -41,7 +41,7 @@ The detection model with the recognition inference model for the 4 directions (L
| Cartoon Face Recognition Model| Cartoon Face Scenario | [Model Download Link](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/cartoon_rec_ResNet50_iCartoon_v1.0_infer.tar) | [inference_cartoon.yaml](../../../deploy/configs/inference_cartoon.yaml) | [build_cartoon.yaml](../../../deploy/configs/build_cartoon.yaml) |
| Vehicle Fine-Grained Classfication Model | Vehicle Scenario | [Model Download Link](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/vehicle_cls_ResNet50_CompCars_v1.0_infer.tar) | [inference_vehicle.yaml](../../../deploy/configs/inference_vehicle.yaml) | [build_vehicle.yaml](../../../deploy/configs/build_vehicle.yaml) |
| Product Recignition Model | Product Scenario | [Model Download Link](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/product_ResNet50_vd_Inshop_v1.0_infer.tar) | [inference_product.yaml](../../../deploy/configs/inference_product.yaml) | [build_product.yaml](../../../deploy/configs/build_product.yaml) |
| Vehicle ReID Model | Vehicle ReID Scenario | [Model Download Link](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/vehicle_reid_ResNet50_VERI_Wild_v1.0_infer.tar) | - | - |
| Vehicle ReID Model | Vehicle ReID Scenario | [Model Download Link](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/vehicle_reid_ResNet50_VERIWild_v1.0_infer.tar) | - | - |
Demo data in this tutorial can be downloaded here: [download link](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognition_demo_data_en_v1.0.tar).
......
......@@ -57,10 +57,7 @@ ReID,也就是 Re-identification,其定义是利用算法,在图像库中
| GLAMOR(Resnet50+PGN)[3] | 77.15 | 92.13 | 97.43 |
| PVEN(Resnet50)[4] | 79.8 | 94.01 | 98.06 |
| SAVER(VAE+Resnet50)[5] | 80.9 | 93.78 | 97.93 |
| PaddleClas baseline1 | 65.6 | 92.37 | 97.23 |
| PaddleClas baseline2 | 80.09 | **93.81** | **98.26** |
注:baseline1 为目前的开源模型,baseline2即将开源
| PaddleClas baseline | 80.57 | **93.81** | **98.06** |
### 2.2 车辆细分类
......
......@@ -40,7 +40,7 @@
* 进入PaddleClas目录。
```bash
## linux or mac, $path_to_PaddleClas表示PaddleClas的根目录,用户需要根据自己的真实目录修改
# linux or mac, $path_to_PaddleClas表示PaddleClas的根目录,用户需要根据自己的真实目录修改
cd $path_to_PaddleClas
```
......@@ -61,7 +61,9 @@ unzip flowers102.zip
此时flowers102数据集存放在**dataset/flowers102/jpg** 文件夹中,图像示例如下:
<img src="../../images/quick_start/Examples-Flower-102.png" style="zoom:50%;" />
<div align="center">
<img src="../../images/quick_start/Examples-Flower-102.png" width = "800" />
</div>
* 返回`PaddleClas`根目录
......@@ -73,18 +75,14 @@ cd ../../
## 四、模型训练
### 预训练模型下载
### 训练模型
#### 使用CPU进行模型训练
### 使用CPU进行模型训练
由于使用CPU来进行模型训练,计算速度较慢,因此,此处以ShuffleNetV2_x0_25为例。此模型计算量较小,在CPU上计算速度较快。但是也因为模型较小,训练好的模型精度也不会太高。
##### 不使用预训练模型
#### 不使用预训练模型
```shell
#windows在cmd中进入PaddleClas根目录,执行此命令
# windows在cmd中进入PaddleClas根目录,执行此命令
python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml
```
......@@ -92,16 +90,17 @@ python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25
- `yaml``Global.device` 参数设置为`cpu`,即使用CPU进行训练(若不设置,此参数默认为`True`
- `yaml`文件中`epochs`参数设置为20,说明对整个数据集进行20个epoch迭代,预计训练20分钟左右(不同CPU,训练时间略有不同),此时训练模型不充分。若提高训练模型精度,请将此参数设大,如**40**,训练时间也会相应延长
##### 使用预训练模型
#### 使用预训练模型
```shell
python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml -o Arch.pretrained=True
```
- `-o` 参数可以选择为True或False,也可以是预训练模型存放路径,当选择为True时,预训练权重会自动下载到本地。注意:若为预训练模型路径,则不要加上:`.pdparams`
可以使用将使用与不使用预训练模型训练进行对比,观察loss的下降情况。
#### 使用GPU进行模型训练
### 使用GPU进行模型训练
由于GPU训练速度更快,可以使用更复杂模型,因此以ResNet50_vd为例。与ShuffleNetV2_x0_25相比,此模型计算量较大, 训练好的模型精度也会更高。
......@@ -119,7 +118,7 @@ python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25
set CUDA_VISIBLE_DEVICES=0
```
##### 不使用预训练模型
#### 不使用预训练模型
```shell
python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml
......@@ -127,9 +126,11 @@ python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml
训练完成后,验证集的`Top1 Acc`曲线如下所示,最高准确率为0.2735。训练精度曲线下图所示
![image-20210329103510936](../../images/quick_start/r50_vd_acc.png)
<div align="center">
<img src="../../images/quick_start/r50_vd_acc.png" width = "800" />
</div>
##### 使用预训练模型进行训练
#### 使用预训练模型进行训练
基于ImageNet1k分类预训练模型进行微调,训练脚本如下所示
......@@ -143,7 +144,9 @@ python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Arch.p
验证集的`Top1 Acc`曲线如下所示,最高准确率为0.9402,加载预训练模型之后,flowers102数据集精度大幅提升,绝对精度涨幅超过65%。
![image-20210329105947361](../../images/quick_start/r50_vd_pretrained_acc.png)
<div align="center">
<img src="../../images/quick_start/r50_vd_pretrained_acc.png" width = "800" />
</div>
## 五、模型预测
......
......@@ -41,7 +41,7 @@
| 动漫人物识别模型 | 动漫人物场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/cartoon_rec_ResNet50_iCartoon_v1.0_infer.tar) | [inference_cartoon.yaml](../../../deploy/configs/inference_cartoon.yaml) | [build_cartoon.yaml](../../../deploy/configs/build_cartoon.yaml) |
| 车辆细分类模型 | 车辆场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/vehicle_cls_ResNet50_CompCars_v1.0_infer.tar) | [inference_vehicle.yaml](../../../deploy/configs/inference_vehicle.yaml) | [build_vehicle.yaml](../../../deploy/configs/build_vehicle.yaml) |
| 商品识别模型 | 商品场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/product_ResNet50_vd_aliproduct_v1.0_infer.tar) | [inference_product.yaml](../../../deploy/configs/inference_product.yaml) | [build_product.yaml](../../../deploy/configs/build_product.yaml) |
| 车辆ReID模型 | 车辆ReID场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/vehicle_reid_ResNet50_VERI_Wild_v1.0_infer.tar) | - | - |
| 车辆ReID模型 | 车辆ReID场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/vehicle_reid_ResNet50_VERIWild_v1.0_infer.tar) | - | - |
本章节demo数据下载地址如下: [数据下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognition_demo_data_v1.0.tar)
......
......@@ -80,7 +80,10 @@ class Linear_BN(nn.Sequential):
super().__init__()
self.add_sublayer('c', nn.Linear(a, b, bias_attr=False))
bn = nn.BatchNorm1D(b)
ones_(bn.weight)
if bn_weight_init == 0:
zeros_(bn.weight)
else:
ones_(bn.weight)
zeros_(bn.bias)
self.add_sublayer('bn', bn)
......
......@@ -44,7 +44,7 @@ def drop_path(x, drop_prob=0., training=False):
return x
keep_prob = paddle.to_tensor(1 - drop_prob)
shape = (paddle.shape(x)[0], ) + (1, ) * (x.ndim - 1)
random_tensor = keep_prob + paddle.rand(shape, dtype=x.dtype)
random_tensor = paddle.add(keep_prob, paddle.rand(shape, dtype=x.dtype))
random_tensor = paddle.floor(random_tensor) # binarize
output = x.divide(keep_prob) * random_tensor
return output
......@@ -114,14 +114,17 @@ class Attention(nn.Layer):
(2, 0, 3, 1, 4))
q, k = qk[0], qk[1]
v = self.v(x).reshape((B, N, self.num_heads, -1)).transpose(
(0, 2, 1, 3))
v = self.v(x).reshape(
(B, N, self.num_heads, x.shape[-1] // self.num_heads)).transpose(
(0, 2, 1, 3))
attn = (q @k.transpose((0, 1, 3, 2))) * self.scale
attn = paddle.matmul(q, k.transpose((0, 1, 3, 2))) * self.scale
attn = nn.functional.softmax(attn, axis=-1)
attn = self.attn_drop(attn)
x = (attn @v).transpose((0, 2, 1, 3)).reshape((B, N, -1))
x = paddle.matmul(attn, v)
x = x.transpose((0, 2, 1, 3)).reshape(
(B, N, x.shape[-1] * x.shape[-3]))
x = self.proj(x)
x = self.proj_drop(x)
return x
......@@ -182,18 +185,22 @@ class Block(nn.Layer):
def forward(self, pixel_embed, patch_embed):
# inner
pixel_embed = pixel_embed + self.drop_path(
self.attn_in(self.norm_in(pixel_embed)))
pixel_embed = pixel_embed + self.drop_path(
self.mlp_in(self.norm_mlp_in(pixel_embed)))
pixel_embed = paddle.add(
pixel_embed,
self.drop_path(self.attn_in(self.norm_in(pixel_embed))))
pixel_embed = paddle.add(
pixel_embed,
self.drop_path(self.mlp_in(self.norm_mlp_in(pixel_embed))))
# outer
B, N, C = patch_embed.shape
patch_embed[:, 1:] = patch_embed[:, 1:] + self.proj(
self.norm1_proj(pixel_embed).reshape((B, N - 1, -1)))
patch_embed = patch_embed + self.drop_path(
self.attn_out(self.norm_out(patch_embed)))
patch_embed = patch_embed + self.drop_path(
self.mlp(self.norm_mlp(patch_embed)))
patch_embed[:, 1:] = paddle.add(
patch_embed[:, 1:],
self.proj(self.norm1_proj(pixel_embed).reshape((B, N - 1, -1))))
patch_embed = paddle.add(
patch_embed,
self.drop_path(self.attn_out(self.norm_out(patch_embed))))
patch_embed = paddle.add(
patch_embed, self.drop_path(self.mlp(self.norm_mlp(patch_embed))))
return pixel_embed, patch_embed
......@@ -222,11 +229,10 @@ class PixelEmbed(nn.Layer):
x = self.proj(x)
x = nn.functional.unfold(x, self.new_patch_size, self.new_patch_size)
x = x.transpose((0, 2, 1)).reshape(
(B * self.num_patches, self.in_dim, self.new_patch_size,
self.new_patch_size))
(-1, self.in_dim, self.new_patch_size, self.new_patch_size))
x = x + pixel_pos
x = x.reshape((B * self.num_patches, self.in_dim, -1)).transpose(
(0, 2, 1))
x = x.reshape((-1, self.in_dim, self.new_patch_size *
self.new_patch_size)).transpose((0, 2, 1))
return x
......@@ -328,7 +334,8 @@ class TNT(nn.Layer):
patch_embed = self.norm2_proj(
self.proj(
self.norm1_proj(
pixel_embed.reshape((B, self.num_patches, -1)))))
pixel_embed.reshape((-1, self.num_patches, pixel_embed.
shape[-1] * pixel_embed.shape[-2])))))
patch_embed = paddle.concat(
(self.cls_token.expand((B, -1, -1)), patch_embed), axis=1)
patch_embed = patch_embed + self.patch_pos
......
from paddle.nn import Conv2D
from ppcls.arch.backbone.legendary_models.resnet import ResNet50
from ppcls.arch.backbone.legendary_models.resnet import ResNet50, MODEL_URLS, _load_pretrained
__all__ = ["ResNet50_last_stage_stride1"]
......@@ -17,6 +17,7 @@ def ResNet50_last_stage_stride1(pretrained=False, use_ssld=False, **kwargs):
return new_conv
match_re = "conv2d_4[4|6]"
model = ResNet50(pretrained=pretrained, use_ssld=use_ssld, **kwargs)
model = ResNet50(pretrained=False, use_ssld=use_ssld, **kwargs)
model.replace_sub(match_re, replace_function, True)
_load_pretrained(pretrained, model, MODEL_URLS["ResNet50"], use_ssld)
return model
......@@ -52,11 +52,8 @@ Optimizer:
name: Momentum
momentum: 0.9
lr:
name: MultiStepDecay
name: Cosine
learning_rate: 0.01
milestones: [30, 60, 70, 80, 90, 100, 120, 140]
gamma: 0.5
verbose: False
last_epoch: -1
regularizer:
name: 'L2'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册