未验证 提交 d2702f14 编写于 作者: B Bin Lu 提交者: GitHub

Merge branch 'PaddlePaddle:develop' into develop

Global: Global:
infer_imgs: "./recognition_demo_data_v1.1/test_product/daoxiangcunjinzhubing_6.jpg" infer_imgs: "./drink_dataset_v1.0/test_images/001.jpeg"
det_inference_model_dir: "./models/ppyolov2_r50vd_dcn_mainbody_v1.0_infer" det_inference_model_dir: "./models/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer"
rec_inference_model_dir: "./models/product_MV3_x1_0_aliproduct_bin_v1.0_infer" rec_inference_model_dir: "./models/general_PPLCNet_x2_5_lite_binary_v1.0_infer"
rec_nms_thresold: 0.05 rec_nms_thresold: 0.05
batch_size: 1 batch_size: 1
...@@ -11,7 +11,6 @@ Global: ...@@ -11,7 +11,6 @@ Global:
labe_list: labe_list:
- foreground - foreground
# inference engine config
use_gpu: True use_gpu: True
enable_mkldnn: True enable_mkldnn: True
cpu_num_threads: 10 cpu_num_threads: 10
...@@ -49,19 +48,18 @@ RecPreProcess: ...@@ -49,19 +48,18 @@ RecPreProcess:
RecPostProcess: RecPostProcess:
main_indicator: Binarize main_indicator: Binarize
Binarize: Binarize:
method: "round" method: "sign"
# indexing engine config # indexing engine config
IndexProcess: IndexProcess:
index_method: "Flat" # supported: HNSW32, Flat index_method: "Flat" # supported: HNSW32, Flat
index_dir: "./recognition_demo_data_v1.1/gallery_product/index_binary" image_root: "./drink_dataset_v1.0/gallery/"
image_root: "./recognition_demo_data_v1.1/gallery_product/" index_dir: "./drink_dataset_v1.0/index_bin"
data_file: "./recognition_demo_data_v1.1/gallery_product/data_file.txt" data_file: "./drink_dataset_v1.0/gallery/drink_label.txt"
index_operation: "new" # suported: "append", "remove", "new" index_operation: "new" # suported: "append", "remove", "new"
delimiter: "\t" delimiter: "\t"
dist_type: "hamming" dist_type: "hamming"
embedding_size: 512 embedding_size: 512
batch_size: 32 batch_size: 32
binary_index: true
return_k: 5 return_k: 5
score_thres: 0 hamming_radius: 100
\ No newline at end of file
...@@ -47,14 +47,14 @@ class SystemPredictor(object): ...@@ -47,14 +47,14 @@ class SystemPredictor(object):
index_dir, "vector.index")), "vector.index not found ..." index_dir, "vector.index")), "vector.index not found ..."
assert os.path.exists(os.path.join( assert os.path.exists(os.path.join(
index_dir, "id_map.pkl")), "id_map.pkl not found ... " index_dir, "id_map.pkl")), "id_map.pkl not found ... "
if config['IndexProcess'].get("binary_index", False): if config['IndexProcess'].get("dist_type") == "hamming":
self.Searcher = faiss.read_index_binary( self.Searcher = faiss.read_index_binary(
os.path.join(index_dir, "vector.index")) os.path.join(index_dir, "vector.index"))
else: else:
self.Searcher = faiss.read_index( self.Searcher = faiss.read_index(
os.path.join(index_dir, "vector.index")) os.path.join(index_dir, "vector.index"))
with open(os.path.join(index_dir, "id_map.pkl"), "rb") as fd: with open(os.path.join(index_dir, "id_map.pkl"), "rb") as fd:
self.id_map = pickle.load(fd) self.id_map = pickle.load(fd)
...@@ -111,12 +111,19 @@ class SystemPredictor(object): ...@@ -111,12 +111,19 @@ class SystemPredictor(object):
rec_results = self.rec_predictor.predict(crop_img) rec_results = self.rec_predictor.predict(crop_img)
preds["bbox"] = [xmin, ymin, xmax, ymax] preds["bbox"] = [xmin, ymin, xmax, ymax]
scores, docs = self.Searcher.search(rec_results, self.return_k) scores, docs = self.Searcher.search(rec_results, self.return_k)
# just top-1 result will be returned for the final # just top-1 result will be returned for the final
if scores[0][0] >= self.config["IndexProcess"]["score_thres"]: if self.config["IndexProcess"]["dist_type"] == "hamming":
preds["rec_docs"] = self.id_map[docs[0][0]].split()[1] if scores[0][0] <= self.config["IndexProcess"][
preds["rec_scores"] = scores[0][0] "hamming_radius"]:
output.append(preds) preds["rec_docs"] = self.id_map[docs[0][0]].split()[1]
preds["rec_scores"] = scores[0][0]
output.append(preds)
else:
if scores[0][0] >= self.config["IndexProcess"]["score_thres"]:
preds["rec_docs"] = self.id_map[docs[0][0]].split()[1]
preds["rec_scores"] = scores[0][0]
output.append(preds)
# st5: nms to the final results to avoid fetching duplicate results # st5: nms to the final results to avoid fetching duplicate results
output = self.nms_to_rec_results( output = self.nms_to_rec_results(
......
docs/images/wx_group.png

57.2 KB | W: | H:

docs/images/wx_group.png

201.8 KB | W: | H:

docs/images/wx_group.png
docs/images/wx_group.png
docs/images/wx_group.png
docs/images/wx_group.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -40,8 +40,9 @@ ...@@ -40,8 +40,9 @@
| 模型简介 | 推荐场景 | inference 模型 | 预测配置文件 | | 模型简介 | 推荐场景 | inference 模型 | 预测配置文件 |
| ------------ | ------------- | -------- | ------- | | ------------ | ------------- | -------- | ------- |
| 轻量级通用主体检测模型 | 通用场景 |[tar 格式文件下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar) [zip 格式文件下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.zip) | - | | 轻量级通用主体检测模型 | 通用场景 |[tar 格式下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar) [zip 格式文件下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.zip) | - |
| 轻量级通用识别模型 | 通用场景 | [tar 格式下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_v1.0_infer.tar) [zip 格式文件下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_v1.0_infer.zip) | [inference_general.yaml](../../../deploy/configs/inference_general.yaml) | | 轻量级通用识别模型 | 通用场景 | [tar 格式下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_v1.0_infer.tar) [zip 格式文件下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_v1.0_infer.zip) | [inference_general.yaml](../../../deploy/configs/inference_general.yaml) |
| 轻量级通用识别二值模型 | 检索库很大, 存储受限场景 | [tar 格式下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_binary_v1.0_infer.tar) [zip 格式文件下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_binary_v1.0_infer.zip)| [inference_general_binary.yaml](../../../deploy/configs/inference_general_binary.yaml) |
注意:由于部分解压缩软件在解压上述 `tar` 格式文件时存在问题,建议非命令行用户下载 `zip` 格式文件并解压。`tar` 格式文件建议使用命令 `tar xf xxx.tar` 解压。 注意:由于部分解压缩软件在解压上述 `tar` 格式文件时存在问题,建议非命令行用户下载 `zip` 格式文件并解压。`tar` 格式文件建议使用命令 `tar xf xxx.tar` 解压。
...@@ -339,4 +340,3 @@ wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognit ...@@ -339,4 +340,3 @@ wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognit
按照上述步骤下载模型和测试数据后,您可以进行相关方向识别模型的测试。 按照上述步骤下载模型和测试数据后,您可以进行相关方向识别模型的测试。
* 更多关于主体检测的介绍可以参考:[主体检测教程文档](../image_recognition_pipeline/mainbody_detection.md);关于特征提取的介绍可以参考:[特征提取教程文档](../image_recognition_pipeline/feature_extraction.md);关于向量检索的介绍可以参考:[向量检索教程文档](../image_recognition_pipeline/vector_search.md) * 更多关于主体检测的介绍可以参考:[主体检测教程文档](../image_recognition_pipeline/mainbody_detection.md);关于特征提取的介绍可以参考:[特征提取教程文档](../image_recognition_pipeline/feature_extraction.md);关于向量检索的介绍可以参考:[向量检索教程文档](../image_recognition_pipeline/vector_search.md)
from abc import ABC # copyright (c) 2021 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Tuple, List, Dict, Union, Callable, Any
from paddle import nn from paddle import nn
import re from ppcls.utils import logger
class Identity(nn.Layer): class Identity(nn.Layer):
...@@ -19,110 +33,239 @@ class TheseusLayer(nn.Layer): ...@@ -19,110 +33,239 @@ class TheseusLayer(nn.Layer):
self.pruner = None self.pruner = None
self.quanter = None self.quanter = None
# stop doesn't work when stop layer has a parallel branch. def _return_dict_hook(self, layer, input, output):
def stop_after(self, stop_layer_name: str): res_dict = {"output": output}
after_stop = False # 'list' is needed to avoid error raised by popping self.res_dict
for layer_i in self._sub_layers: for res_key in list(self.res_dict):
if after_stop: # clear the res_dict because the forward process may change according to input
self._sub_layers[layer_i] = Identity() res_dict[res_key] = self.res_dict.pop(res_key)
continue return res_dict
layer_name = self._sub_layers[layer_i].full_name()
if layer_name == stop_layer_name: def _save_sub_res_hook(self, layer, input, output):
after_stop = True self.res_dict[self.res_name] = output
continue
if isinstance(self._sub_layers[layer_i], TheseusLayer): def replace_sub(self, *args, **kwargs) -> None:
after_stop = self._sub_layers[layer_i].stop_after( msg = "The function 'replace_sub()' is deprecated, please use 'upgrade_sublayer()' instead."
stop_layer_name) logger.error(DeprecationWarning(msg))
return after_stop raise DeprecationWarning(msg)
def update_res(self, return_patterns): def upgrade_sublayer(self,
for return_pattern in return_patterns: layer_name_pattern: Union[str, List[str]],
pattern_list = return_pattern.split(".") handle_func: Callable[[nn.Layer, str], nn.Layer]
if not pattern_list: ) -> Dict[str, nn.Layer]:
continue """use 'handle_func' to modify the sub-layer(s) specified by 'layer_name_pattern'.
sub_layer_parent = self
while len(pattern_list) > 1: Args:
if '[' in pattern_list[0]: layer_name_pattern (Union[str, List[str]]): The name of layer to be modified by 'handle_func'.
sub_layer_name = pattern_list[0].split('[')[0] handle_func (Callable[[nn.Layer, str], nn.Layer]): The function to modify target layer specified by 'layer_name_pattern'. The formal params are the layer(nn.Layer) and pattern(str) that is (a member of) layer_name_pattern (when layer_name_pattern is List type). And the return is the layer processed.
sub_layer_index = pattern_list[0].split('[')[1].split(']')[0]
sub_layer_parent = getattr(sub_layer_parent, sub_layer_name)[sub_layer_index] Returns:
else: Dict[str, nn.Layer]: The key is the pattern and corresponding value is the result returned by 'handle_func()'.
sub_layer_parent = getattr(sub_layer_parent, pattern_list[0],
None) Examples:
if sub_layer_parent is None:
break from paddle import nn
if isinstance(sub_layer_parent, WrapLayer): import paddleclas
sub_layer_parent = sub_layer_parent.sub_layer
pattern_list = pattern_list[1:] def rep_func(layer: nn.Layer, pattern: str):
if sub_layer_parent is None: new_layer = nn.Conv2D(
in_channels=layer._in_channels,
out_channels=layer._out_channels,
kernel_size=5,
padding=2
)
return new_layer
net = paddleclas.MobileNetV1()
res = net.replace_sub(layer_name_pattern=["blocks[11].depthwise_conv.conv", "blocks[12].depthwise_conv.conv"], handle_func=rep_func)
print(res)
# {'blocks[11].depthwise_conv.conv': the corresponding new_layer, 'blocks[12].depthwise_conv.conv': the corresponding new_layer}
"""
if not isinstance(layer_name_pattern, list):
layer_name_pattern = [layer_name_pattern]
handle_res_dict = {}
for pattern in layer_name_pattern:
# parse pattern to find target layer and its parent
layer_list = parse_pattern_str(pattern=pattern, parent_layer=self)
if not layer_list:
continue continue
if '[' in pattern_list[0]: sub_layer_parent = layer_list[-2]["layer"] if len(
sub_layer_name = pattern_list[0].split('[')[0] layer_list) > 1 else self
sub_layer_index = pattern_list[0].split('[')[1].split(']')[0]
sub_layer = getattr(sub_layer_parent, sub_layer_name)[sub_layer_index] sub_layer = layer_list[-1]["layer"]
if not isinstance(sub_layer, TheseusLayer): sub_layer_name = layer_list[-1]["name"]
sub_layer = wrap_theseus(sub_layer) sub_layer_index = layer_list[-1]["index"]
getattr(sub_layer_parent, sub_layer_name)[sub_layer_index] = sub_layer
new_sub_layer = handle_func(sub_layer, pattern)
if sub_layer_index:
getattr(sub_layer_parent,
sub_layer_name)[sub_layer_index] = new_sub_layer
else: else:
sub_layer = getattr(sub_layer_parent, pattern_list[0]) setattr(sub_layer_parent, sub_layer_name, new_sub_layer)
if not isinstance(sub_layer, TheseusLayer):
sub_layer = wrap_theseus(sub_layer)
setattr(sub_layer_parent, pattern_list[0], sub_layer)
sub_layer.res_dict = self.res_dict handle_res_dict[pattern] = new_sub_layer
sub_layer.res_name = return_pattern return handle_res_dict
sub_layer.register_forward_post_hook(sub_layer._save_sub_res_hook)
def _save_sub_res_hook(self, layer, input, output): def stop_after(self, stop_layer_name: str) -> bool:
self.res_dict[self.res_name] = output """stop forward and backward after 'stop_layer_name'.
Args:
stop_layer_name (str): The name of layer that stop forward and backward after this layer.
Returns:
bool: 'True' if successful, 'False' otherwise.
"""
layer_list = parse_pattern_str(stop_layer_name, self)
if not layer_list:
return False
parent_layer = self
for layer_dict in layer_list:
name, index = layer_dict["name"], layer_dict["index"]
if not set_identity(parent_layer, name, index):
msg = f"Failed to set the layers that after stop_layer_name('{stop_layer_name}') to IdentityLayer. The error layer's name is '{name}'."
logger.warning(msg)
return False
parent_layer = layer_dict["layer"]
return True
def update_res(
self,
return_patterns: Union[str, List[str]]) -> Dict[str, nn.Layer]:
"""update the result(s) to be returned.
Args:
return_patterns (Union[str, List[str]]): The name of layer to return output.
Returns:
Dict[str, nn.Layer]: The pattern(str) and corresponding layer(nn.Layer) that have been set successfully.
"""
# clear res_dict that could have been set
self.res_dict = {}
class Handler(object):
def __init__(self, res_dict):
# res_dict is a reference
self.res_dict = res_dict
def __call__(self, layer, pattern):
layer.res_dict = self.res_dict
layer.res_name = pattern
if hasattr(layer, "hook_remove_helper"):
layer.hook_remove_helper.remove()
layer.hook_remove_helper = layer.register_forward_post_hook(
layer._save_sub_res_hook)
return layer
handle_func = Handler(self.res_dict)
res_dict = self.upgrade_sublayer(
return_patterns, handle_func=handle_func)
if hasattr(self, "hook_remove_helper"):
self.hook_remove_helper.remove()
self.hook_remove_helper = self.register_forward_post_hook(
self._return_dict_hook)
def _return_dict_hook(self, layer, input, output):
res_dict = {"output": output}
for res_key in list(self.res_dict):
res_dict[res_key] = self.res_dict.pop(res_key)
return res_dict return res_dict
def replace_sub(self, layer_name_pattern, replace_function,
recursive=True): def set_identity(parent_layer: nn.Layer,
for layer_i in self._sub_layers: layer_name: str,
layer_name = self._sub_layers[layer_i].full_name() layer_index: str=None) -> bool:
if re.match(layer_name_pattern, layer_name): """set the layer specified by layer_name and layer_index to Indentity.
self._sub_layers[layer_i] = replace_function(self._sub_layers[
layer_i]) Args:
if recursive: parent_layer (nn.Layer): The parent layer of target layer specified by layer_name and layer_index.
if isinstance(self._sub_layers[layer_i], TheseusLayer): layer_name (str): The name of target layer to be set to Indentity.
self._sub_layers[layer_i].replace_sub( layer_index (str, optional): The index of target layer to be set to Indentity in parent_layer. Defaults to None.
layer_name_pattern, replace_function, recursive)
elif isinstance(self._sub_layers[layer_i], Returns:
(nn.Sequential, nn.LayerList)): bool: True if successfully, False otherwise.
for layer_j in self._sub_layers[layer_i]._sub_layers: """
self._sub_layers[layer_i]._sub_layers[
layer_j].replace_sub(layer_name_pattern, stop_after = False
replace_function, recursive) for sub_layer_name in parent_layer._sub_layers:
if stop_after:
''' parent_layer._sub_layers[sub_layer_name] = Identity()
example of replace function: continue
def replace_conv(origin_conv: nn.Conv2D): if sub_layer_name == layer_name:
new_conv = nn.Conv2D( stop_after = True
in_channels=origin_conv._in_channels,
out_channels=origin_conv._out_channels, if layer_index and stop_after:
kernel_size=origin_conv._kernel_size, stop_after = False
stride=2 for sub_layer_index in parent_layer._sub_layers[
) layer_name]._sub_layers:
return new_conv if stop_after:
parent_layer._sub_layers[layer_name][
''' sub_layer_index] = Identity()
continue
if layer_index == sub_layer_index:
class WrapLayer(TheseusLayer): stop_after = True
def __init__(self, sub_layer):
super(WrapLayer, self).__init__() return stop_after
self.sub_layer = sub_layer
def forward(self, *inputs, **kwargs): def parse_pattern_str(pattern: str, parent_layer: nn.Layer) -> Union[
return self.sub_layer(*inputs, **kwargs) None, List[Dict[str, Union[nn.Layer, str, None]]]]:
"""parse the string type pattern.
def wrap_theseus(sub_layer): Args:
wrapped_layer = WrapLayer(sub_layer) pattern (str): The pattern to discribe layer.
return wrapped_layer parent_layer (nn.Layer): The root layer relative to the pattern.
Returns:
Union[None, List[Dict[str, Union[nn.Layer, str, None]]]]: None if failed. If successfully, the members are layers parsed in order:
[
{"layer": first layer, "name": first layer's name parsed, "index": first layer's index parsed if exist},
{"layer": second layer, "name": second layer's name parsed, "index": second layer's index parsed if exist},
...
]
"""
pattern_list = pattern.split(".")
if not pattern_list:
msg = f"The pattern('{pattern}') is illegal. Please check and retry."
logger.warning(msg)
return None
layer_list = []
while len(pattern_list) > 0:
if '[' in pattern_list[0]:
target_layer_name = pattern_list[0].split('[')[0]
target_layer_index = pattern_list[0].split('[')[1].split(']')[0]
else:
target_layer_name = pattern_list[0]
target_layer_index = None
target_layer = getattr(parent_layer, target_layer_name, None)
if target_layer is None:
msg = f"Not found layer named('{target_layer_name}') specifed in pattern('{pattern}')."
logger.warning(msg)
return None
if target_layer_index and target_layer:
if int(target_layer_index) < 0 or int(target_layer_index) >= len(
target_layer):
msg = f"Not found layer by index('{target_layer_index}') specifed in pattern('{pattern}'). The index should < {len(target_layer)} and > 0."
logger.warning(msg)
return None
target_layer = target_layer[target_layer_index]
layer_list.append({
"layer": target_layer,
"name": target_layer_name,
"index": target_layer_index
})
pattern_list = pattern_list[1:]
parent_layer = target_layer
return layer_list
...@@ -217,7 +217,8 @@ class ESNet(TheseusLayer): ...@@ -217,7 +217,8 @@ class ESNet(TheseusLayer):
class_num=1000, class_num=1000,
scale=1.0, scale=1.0,
dropout_prob=0.2, dropout_prob=0.2,
class_expand=1280): class_expand=1280,
return_patterns=None):
super().__init__() super().__init__()
self.scale = scale self.scale = scale
self.class_num = class_num self.class_num = class_num
...@@ -268,6 +269,9 @@ class ESNet(TheseusLayer): ...@@ -268,6 +269,9 @@ class ESNet(TheseusLayer):
self.flatten = nn.Flatten(start_axis=1, stop_axis=-1) self.flatten = nn.Flatten(start_axis=1, stop_axis=-1)
self.fc = Linear(self.class_expand, self.class_num) self.fc = Linear(self.class_expand, self.class_num)
if return_patterns is not None:
self.update_res(return_patterns)
def forward(self, x): def forward(self, x):
x = self.conv1(x) x = self.conv1(x)
x = self.max_pool(x) x = self.max_pool(x)
......
...@@ -244,7 +244,7 @@ class HighResolutionModule(TheseusLayer): ...@@ -244,7 +244,7 @@ class HighResolutionModule(TheseusLayer):
for i in range(len(num_filters)): for i in range(len(num_filters)):
self.basic_block_list.append( self.basic_block_list.append(
nn.Sequential(*[ nn.Sequential(* [
BasicBlock( BasicBlock(
num_channels=num_filters[i], num_channels=num_filters[i],
num_filters=num_filters[i], num_filters=num_filters[i],
...@@ -367,7 +367,11 @@ class HRNet(TheseusLayer): ...@@ -367,7 +367,11 @@ class HRNet(TheseusLayer):
model: nn.Layer. Specific HRNet model depends on args. model: nn.Layer. Specific HRNet model depends on args.
""" """
def __init__(self, width=18, has_se=False, class_num=1000, return_patterns=None): def __init__(self,
width=18,
has_se=False,
class_num=1000,
return_patterns=None):
super().__init__() super().__init__()
self.width = width self.width = width
...@@ -394,7 +398,7 @@ class HRNet(TheseusLayer): ...@@ -394,7 +398,7 @@ class HRNet(TheseusLayer):
stride=2, stride=2,
act="relu") act="relu")
self.layer1 = nn.Sequential(*[ self.layer1 = nn.Sequential(* [
BottleneckBlock( BottleneckBlock(
num_channels=64 if i == 0 else 256, num_channels=64 if i == 0 else 256,
num_filters=64, num_filters=64,
...@@ -458,7 +462,6 @@ class HRNet(TheseusLayer): ...@@ -458,7 +462,6 @@ class HRNet(TheseusLayer):
weight_attr=ParamAttr(initializer=Uniform(-stdv, stdv))) weight_attr=ParamAttr(initializer=Uniform(-stdv, stdv)))
if return_patterns is not None: if return_patterns is not None:
self.update_res(return_patterns) self.update_res(return_patterns)
self.register_forward_post_hook(self._return_dict_hook)
def forward(self, x): def forward(self, x):
x = self.conv_layer1_1(x) x = self.conv_layer1_1(x)
......
...@@ -498,7 +498,6 @@ class Inception_V3(TheseusLayer): ...@@ -498,7 +498,6 @@ class Inception_V3(TheseusLayer):
bias_attr=ParamAttr()) bias_attr=ParamAttr())
if return_patterns is not None: if return_patterns is not None:
self.update_res(return_patterns) self.update_res(return_patterns)
self.register_forward_post_hook(self._return_dict_hook)
def forward(self, x): def forward(self, x):
x = self.inception_stem(x) x = self.inception_stem(x)
......
...@@ -128,7 +128,7 @@ class MobileNet(TheseusLayer): ...@@ -128,7 +128,7 @@ class MobileNet(TheseusLayer):
[int(512 * scale), 512, 1024, 512, 2], [int(512 * scale), 512, 1024, 512, 2],
[int(1024 * scale), 1024, 1024, 1024, 1]] [int(1024 * scale), 1024, 1024, 1024, 1]]
self.blocks = nn.Sequential(*[ self.blocks = nn.Sequential(* [
DepthwiseSeparable( DepthwiseSeparable(
num_channels=params[0], num_channels=params[0],
num_filters1=params[1], num_filters1=params[1],
...@@ -147,7 +147,6 @@ class MobileNet(TheseusLayer): ...@@ -147,7 +147,6 @@ class MobileNet(TheseusLayer):
weight_attr=ParamAttr(initializer=KaimingNormal())) weight_attr=ParamAttr(initializer=KaimingNormal()))
if return_patterns is not None: if return_patterns is not None:
self.update_res(return_patterns) self.update_res(return_patterns)
self.register_forward_post_hook(self._return_dict_hook)
def forward(self, x): def forward(self, x):
x = self.conv(x) x = self.conv(x)
......
...@@ -202,7 +202,6 @@ class MobileNetV3(TheseusLayer): ...@@ -202,7 +202,6 @@ class MobileNetV3(TheseusLayer):
self.fc = Linear(self.class_expand, class_num) self.fc = Linear(self.class_expand, class_num)
if return_patterns is not None: if return_patterns is not None:
self.update_res(return_patterns) self.update_res(return_patterns)
self.register_forward_post_hook(self._return_dict_hook)
def forward(self, x): def forward(self, x):
x = self.conv(x) x = self.conv(x)
......
...@@ -171,7 +171,8 @@ class PPLCNet(TheseusLayer): ...@@ -171,7 +171,8 @@ class PPLCNet(TheseusLayer):
scale=1.0, scale=1.0,
class_num=1000, class_num=1000,
dropout_prob=0.2, dropout_prob=0.2,
class_expand=1280): class_expand=1280,
return_patterns=None):
super().__init__() super().__init__()
self.scale = scale self.scale = scale
self.class_expand = class_expand self.class_expand = class_expand
...@@ -182,7 +183,7 @@ class PPLCNet(TheseusLayer): ...@@ -182,7 +183,7 @@ class PPLCNet(TheseusLayer):
num_filters=make_divisible(16 * scale), num_filters=make_divisible(16 * scale),
stride=2) stride=2)
self.blocks2 = nn.Sequential(*[ self.blocks2 = nn.Sequential(* [
DepthwiseSeparable( DepthwiseSeparable(
num_channels=make_divisible(in_c * scale), num_channels=make_divisible(in_c * scale),
num_filters=make_divisible(out_c * scale), num_filters=make_divisible(out_c * scale),
...@@ -192,7 +193,7 @@ class PPLCNet(TheseusLayer): ...@@ -192,7 +193,7 @@ class PPLCNet(TheseusLayer):
for i, (k, in_c, out_c, s, se) in enumerate(NET_CONFIG["blocks2"]) for i, (k, in_c, out_c, s, se) in enumerate(NET_CONFIG["blocks2"])
]) ])
self.blocks3 = nn.Sequential(*[ self.blocks3 = nn.Sequential(* [
DepthwiseSeparable( DepthwiseSeparable(
num_channels=make_divisible(in_c * scale), num_channels=make_divisible(in_c * scale),
num_filters=make_divisible(out_c * scale), num_filters=make_divisible(out_c * scale),
...@@ -202,7 +203,7 @@ class PPLCNet(TheseusLayer): ...@@ -202,7 +203,7 @@ class PPLCNet(TheseusLayer):
for i, (k, in_c, out_c, s, se) in enumerate(NET_CONFIG["blocks3"]) for i, (k, in_c, out_c, s, se) in enumerate(NET_CONFIG["blocks3"])
]) ])
self.blocks4 = nn.Sequential(*[ self.blocks4 = nn.Sequential(* [
DepthwiseSeparable( DepthwiseSeparable(
num_channels=make_divisible(in_c * scale), num_channels=make_divisible(in_c * scale),
num_filters=make_divisible(out_c * scale), num_filters=make_divisible(out_c * scale),
...@@ -212,7 +213,7 @@ class PPLCNet(TheseusLayer): ...@@ -212,7 +213,7 @@ class PPLCNet(TheseusLayer):
for i, (k, in_c, out_c, s, se) in enumerate(NET_CONFIG["blocks4"]) for i, (k, in_c, out_c, s, se) in enumerate(NET_CONFIG["blocks4"])
]) ])
self.blocks5 = nn.Sequential(*[ self.blocks5 = nn.Sequential(* [
DepthwiseSeparable( DepthwiseSeparable(
num_channels=make_divisible(in_c * scale), num_channels=make_divisible(in_c * scale),
num_filters=make_divisible(out_c * scale), num_filters=make_divisible(out_c * scale),
...@@ -222,7 +223,7 @@ class PPLCNet(TheseusLayer): ...@@ -222,7 +223,7 @@ class PPLCNet(TheseusLayer):
for i, (k, in_c, out_c, s, se) in enumerate(NET_CONFIG["blocks5"]) for i, (k, in_c, out_c, s, se) in enumerate(NET_CONFIG["blocks5"])
]) ])
self.blocks6 = nn.Sequential(*[ self.blocks6 = nn.Sequential(* [
DepthwiseSeparable( DepthwiseSeparable(
num_channels=make_divisible(in_c * scale), num_channels=make_divisible(in_c * scale),
num_filters=make_divisible(out_c * scale), num_filters=make_divisible(out_c * scale),
...@@ -248,6 +249,9 @@ class PPLCNet(TheseusLayer): ...@@ -248,6 +249,9 @@ class PPLCNet(TheseusLayer):
self.fc = Linear(self.class_expand, class_num) self.fc = Linear(self.class_expand, class_num)
if return_patterns is not None:
self.update_res(return_patterns)
def forward(self, x): def forward(self, x):
x = self.conv1(x) x = self.conv1(x)
......
...@@ -340,7 +340,6 @@ class ResNet(TheseusLayer): ...@@ -340,7 +340,6 @@ class ResNet(TheseusLayer):
self.data_format = data_format self.data_format = data_format
if return_patterns is not None: if return_patterns is not None:
self.update_res(return_patterns) self.update_res(return_patterns)
self.register_forward_post_hook(self._return_dict_hook)
def forward(self, x): def forward(self, x):
with paddle.static.amp.fp16_guard(): with paddle.static.amp.fp16_guard():
......
...@@ -111,7 +111,11 @@ class VGGNet(TheseusLayer): ...@@ -111,7 +111,11 @@ class VGGNet(TheseusLayer):
model: nn.Layer. Specific VGG model depends on args. model: nn.Layer. Specific VGG model depends on args.
""" """
def __init__(self, config, stop_grad_layers=0, class_num=1000, return_patterns=None): def __init__(self,
config,
stop_grad_layers=0,
class_num=1000,
return_patterns=None):
super().__init__() super().__init__()
self.stop_grad_layers = stop_grad_layers self.stop_grad_layers = stop_grad_layers
...@@ -139,7 +143,6 @@ class VGGNet(TheseusLayer): ...@@ -139,7 +143,6 @@ class VGGNet(TheseusLayer):
self.fc3 = Linear(4096, class_num) self.fc3 = Linear(4096, class_num)
if return_patterns is not None: if return_patterns is not None:
self.update_res(return_patterns) self.update_res(return_patterns)
self.register_forward_post_hook(self._return_dict_hook)
def forward(self, inputs): def forward(self, inputs):
x = self.conv_block_1(inputs) x = self.conv_block_1(inputs)
......
...@@ -19,11 +19,11 @@ class TanhSuffix(paddle.nn.Layer): ...@@ -19,11 +19,11 @@ class TanhSuffix(paddle.nn.Layer):
def PPLCNet_x2_5_Tanh(pretrained=False, use_ssld=False, **kwargs): def PPLCNet_x2_5_Tanh(pretrained=False, use_ssld=False, **kwargs):
def replace_function(origin_layer): def replace_function(origin_layer, pattern):
new_layer = TanhSuffix(origin_layer) new_layer = TanhSuffix(origin_layer)
return new_layer return new_layer
match_re = "linear_0" pattern = "fc"
model = PPLCNet_x2_5(pretrained=pretrained, use_ssld=use_ssld, **kwargs) model = PPLCNet_x2_5(pretrained=pretrained, use_ssld=use_ssld, **kwargs)
model.replace_sub(match_re, replace_function, True) model.upgrade_sublayer(pattern, replace_function)
return model return model
...@@ -5,7 +5,7 @@ __all__ = ["ResNet50_last_stage_stride1"] ...@@ -5,7 +5,7 @@ __all__ = ["ResNet50_last_stage_stride1"]
def ResNet50_last_stage_stride1(pretrained=False, use_ssld=False, **kwargs): def ResNet50_last_stage_stride1(pretrained=False, use_ssld=False, **kwargs):
def replace_function(conv): def replace_function(conv, pattern):
new_conv = Conv2D( new_conv = Conv2D(
in_channels=conv._in_channels, in_channels=conv._in_channels,
out_channels=conv._out_channels, out_channels=conv._out_channels,
...@@ -16,8 +16,8 @@ def ResNet50_last_stage_stride1(pretrained=False, use_ssld=False, **kwargs): ...@@ -16,8 +16,8 @@ def ResNet50_last_stage_stride1(pretrained=False, use_ssld=False, **kwargs):
bias_attr=conv._bias_attr) bias_attr=conv._bias_attr)
return new_conv return new_conv
match_re = "conv2d_4[4|6]" pattern = ["blocks[13].conv1.conv", "blocks[13].short.conv"]
model = ResNet50(pretrained=False, use_ssld=use_ssld, **kwargs) model = ResNet50(pretrained=False, use_ssld=use_ssld, **kwargs)
model.replace_sub(match_re, replace_function, True) model.upgrade_sublayer(pattern, replace_function)
_load_pretrained(pretrained, model, MODEL_URLS["ResNet50"], use_ssld) _load_pretrained(pretrained, model, MODEL_URLS["ResNet50"], use_ssld)
return model return model
import paddle import paddle
from paddle.nn import Sigmoid from paddle.nn import Sigmoid
from ppcls.arch.backbone.legendary_models.vgg import VGG19 from ppcls.arch.backbone.legendary_models.vgg import VGG19
__all__ = ["VGG19Sigmoid"] __all__ = ["VGG19Sigmoid"]
class SigmoidSuffix(paddle.nn.Layer): class SigmoidSuffix(paddle.nn.Layer):
def __init__(self, origin_layer): def __init__(self, origin_layer):
super(SigmoidSuffix, self).__init__() super().__init__()
self.origin_layer = origin_layer self.origin_layer = origin_layer
self.sigmoid = Sigmoid() self.sigmoid = Sigmoid()
def forward(self, input, res_dict=None, **kwargs): def forward(self, input, res_dict=None, **kwargs):
x = self.origin_layer(input) x = self.origin_layer(input)
x = self.sigmoid(x) x = self.sigmoid(x)
return x return x
def VGG19Sigmoid(pretrained=False, use_ssld=False, **kwargs): def VGG19Sigmoid(pretrained=False, use_ssld=False, **kwargs):
def replace_function(origin_layer): def replace_function(origin_layer, pattern):
new_layer = SigmoidSuffix(origin_layer) new_layer = SigmoidSuffix(origin_layer)
return new_layer return new_layer
match_re = "linear_2" pattern = "fc2"
model = VGG19(pretrained=pretrained, use_ssld=use_ssld, **kwargs) model = VGG19(pretrained=pretrained, use_ssld=use_ssld, **kwargs)
model.replace_sub(match_re, replace_function, True) model.upgrade_sublayer(pattern, replace_function)
return model return model
...@@ -22,7 +22,7 @@ Arch: ...@@ -22,7 +22,7 @@ Arch:
name: "ResNet50" name: "ResNet50"
pretrained: True pretrained: True
BackboneStopLayer: BackboneStopLayer:
name: "flatten_0" name: "flatten"
output_dim: 2048 output_dim: 2048
Head: Head:
name: "FC" name: "FC"
......
...@@ -28,7 +28,7 @@ Arch: ...@@ -28,7 +28,7 @@ Arch:
pretrained: True pretrained: True
use_ssld: True use_ssld: True
BackboneStopLayer: BackboneStopLayer:
name: flatten_0 name: "flatten"
Neck: Neck:
name: FC name: FC
embedding_size: 1280 embedding_size: 1280
......
...@@ -24,7 +24,7 @@ Arch: ...@@ -24,7 +24,7 @@ Arch:
name: "ResNet50_last_stage_stride1" name: "ResNet50_last_stage_stride1"
pretrained: True pretrained: True
BackboneStopLayer: BackboneStopLayer:
name: "adaptive_avg_pool2d_0" name: "avg_pool"
Neck: Neck:
name: "VehicleNeck" name: "VehicleNeck"
in_channels: 2048 in_channels: 2048
......
...@@ -25,7 +25,7 @@ Arch: ...@@ -25,7 +25,7 @@ Arch:
name: ResNet50_vd name: ResNet50_vd
pretrained: True pretrained: True
BackboneStopLayer: BackboneStopLayer:
name: flatten_0 name: "flatten"
Neck: Neck:
name: FC name: FC
embedding_size: 2048 embedding_size: 2048
......
...@@ -25,7 +25,7 @@ Arch: ...@@ -25,7 +25,7 @@ Arch:
name: ResNet50_vd name: ResNet50_vd
pretrained: False pretrained: False
BackboneStopLayer: BackboneStopLayer:
name: flatten_0 name: "flatten"
Neck: Neck:
name: FC name: FC
embedding_size: 2048 embedding_size: 2048
......
...@@ -22,7 +22,7 @@ Arch: ...@@ -22,7 +22,7 @@ Arch:
name: ResNet50_vd name: ResNet50_vd
pretrained: False pretrained: False
BackboneStopLayer: BackboneStopLayer:
name: flatten_0 name: "flatten"
Neck: Neck:
name: FC name: FC
embedding_size: 2048 embedding_size: 2048
......
...@@ -27,7 +27,7 @@ Arch: ...@@ -27,7 +27,7 @@ Arch:
pretrained: True pretrained: True
use_ssld: True use_ssld: True
BackboneStopLayer: BackboneStopLayer:
name: "flatten_0" name: "flatten"
Neck: Neck:
name: "FC" name: "FC"
embedding_size: 1280 embedding_size: 1280
......
...@@ -23,7 +23,7 @@ Arch: ...@@ -23,7 +23,7 @@ Arch:
name: "ResNet50_last_stage_stride1" name: "ResNet50_last_stage_stride1"
pretrained: True pretrained: True
BackboneStopLayer: BackboneStopLayer:
name: "adaptive_avg_pool2d_0" name: "avg_pool"
Neck: Neck:
name: "VehicleNeck" name: "VehicleNeck"
in_channels: 2048 in_channels: 2048
......
...@@ -24,7 +24,7 @@ Arch: ...@@ -24,7 +24,7 @@ Arch:
name: "ResNet50_last_stage_stride1" name: "ResNet50_last_stage_stride1"
pretrained: True pretrained: True
BackboneStopLayer: BackboneStopLayer:
name: "adaptive_avg_pool2d_0" name: "avg_pool"
Neck: Neck:
name: "VehicleNeck" name: "VehicleNeck"
in_channels: 2048 in_channels: 2048
......
...@@ -25,7 +25,7 @@ Arch: ...@@ -25,7 +25,7 @@ Arch:
name: MobileNetV1 name: MobileNetV1
pretrained: False pretrained: False
BackboneStopLayer: BackboneStopLayer:
name: flatten_0 name: "flatten"
Neck: Neck:
name: FC name: FC
embedding_size: 1024 embedding_size: 1024
......
...@@ -34,7 +34,7 @@ Arch: ...@@ -34,7 +34,7 @@ Arch:
pretrained: False pretrained: False
use_ssld: True use_ssld: True
BackboneStopLayer: BackboneStopLayer:
name: flatten_0 name: "flatten"
Neck: Neck:
name: FC name: FC
embedding_size: 1280 embedding_size: 1280
......
...@@ -28,7 +28,7 @@ Arch: ...@@ -28,7 +28,7 @@ Arch:
name: "ResNet50_last_stage_stride1" name: "ResNet50_last_stage_stride1"
pretrained: True pretrained: True
BackboneStopLayer: BackboneStopLayer:
name: "adaptive_avg_pool2d_0" name: "avg_pool"
Neck: Neck:
name: "VehicleNeck" name: "VehicleNeck"
in_channels: 2048 in_channels: 2048
......
...@@ -27,7 +27,7 @@ Arch: ...@@ -27,7 +27,7 @@ Arch:
name: "ResNet50_last_stage_stride1" name: "ResNet50_last_stage_stride1"
pretrained: True pretrained: True
BackboneStopLayer: BackboneStopLayer:
name: "adaptive_avg_pool2d_0" name: "avg_pool"
Neck: Neck:
name: "VehicleNeck" name: "VehicleNeck"
in_channels: 2048 in_channels: 2048
......
...@@ -31,7 +31,7 @@ Arch: ...@@ -31,7 +31,7 @@ Arch:
name: "ResNet50_last_stage_stride1" name: "ResNet50_last_stage_stride1"
pretrained: True pretrained: True
BackboneStopLayer: BackboneStopLayer:
name: "adaptive_avg_pool2d_0" name: "avg_pool"
Neck: Neck:
name: "VehicleNeck" name: "VehicleNeck"
in_channels: 2048 in_channels: 2048
......
...@@ -30,7 +30,7 @@ Arch: ...@@ -30,7 +30,7 @@ Arch:
name: "ResNet50_last_stage_stride1" name: "ResNet50_last_stage_stride1"
pretrained: True pretrained: True
BackboneStopLayer: BackboneStopLayer:
name: "adaptive_avg_pool2d_0" name: "avg_pool"
Neck: Neck:
name: "VehicleNeck" name: "VehicleNeck"
in_channels: 2048 in_channels: 2048
......
...@@ -161,7 +161,7 @@ class Engine(object): ...@@ -161,7 +161,7 @@ class Engine(object):
if metric_config is not None: if metric_config is not None:
metric_config = metric_config.get("Train") metric_config = metric_config.get("Train")
if metric_config is not None: if metric_config is not None:
if self.train_dataloader.collate_fn: if hasattr(self.train_dataloader, "collate_fn"):
for m_idx, m in enumerate(metric_config): for m_idx, m in enumerate(metric_config):
if "TopkAcc" in m: if "TopkAcc" in m:
msg = f"'TopkAcc' metric can not be used when setting 'batch_transform_ops' in config. The 'TopkAcc' metric has been removed." msg = f"'TopkAcc' metric can not be used when setting 'batch_transform_ops' in config. The 'TopkAcc' metric has been removed."
...@@ -312,14 +312,14 @@ class Engine(object): ...@@ -312,14 +312,14 @@ class Engine(object):
self.output_dir, self.output_dir,
model_name=self.config["Arch"]["name"], model_name=self.config["Arch"]["name"],
prefix="epoch_{}".format(epoch_id)) prefix="epoch_{}".format(epoch_id))
# save the latest model # save the latest model
save_load.save_model( save_load.save_model(
self.model, self.model,
self.optimizer, {"metric": acc, self.optimizer, {"metric": acc,
"epoch": epoch_id}, "epoch": epoch_id},
self.output_dir, self.output_dir,
model_name=self.config["Arch"]["name"], model_name=self.config["Arch"]["name"],
prefix="latest") prefix="latest")
if self.vdl_writer is not None: if self.vdl_writer is not None:
self.vdl_writer.close() self.vdl_writer.close()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册