11from typing import Dict
22import pathlib
3-
43import tensorflow as tf
54
5+ from .freeze_graph import freeze_graph , create_session_from_graphdef
6+
67
78class Saver :
89
@@ -11,35 +12,71 @@ def __init__(
1112 session : tf .Session ,
1213 output_dir : str ,
1314 signature_def_map : Dict [str , tf .saved_model .signature_def_utils .predict_signature_def ],
15+ freeze : bool = True ,
1416 ) -> None :
1517 self .session = session
1618 self .signature_def_map = signature_def_map
1719 self .output_dir = pathlib .Path (output_dir )
1820 self .output_dir .mkdir (parents = True , exist_ok = True )
21+ self .freeze = freeze
1922
20- @staticmethod
21- def _get_next_version (
22- path : pathlib .PosixPath ,
23- ) -> pathlib .PosixPath :
24- candidate_paths = path .glob ('**/*' )
25- dirs = [x .name for x in candidate_paths if x .is_dir ()]
26- versions = [int (dir_name ) for dir_name in dirs if dir_name .isdigit ()]
27- new_version = max (versions ) + 1 if versions else 0
28- return path / str (new_version )
23+ def save (self , ** kwargs ) -> str :
24+ """Save model given session and signature
25+
26+ Save frozen model if self.freeze is True.
27+
28+ Return:
29+ output_version_dir
30+
31+ """
32+ if self .freeze :
33+ output_op_names = self ._get_op_names ()
34+ frozen_graphdef = freeze_graph (self .session , output_op_names )
35+ session_to_be_saved = create_session_from_graphdef (frozen_graphdef )
36+ else :
37+ session_to_be_saved = self .session
2938
30- def save (
31- self ,
32- ** kwargs
33- ) -> str :
3439 output_version_dir = str (self ._get_next_version (self .output_dir ))
35- with self . session .graph .as_default ():
40+ with session_to_be_saved .graph .as_default ():
3641 builder = tf .saved_model .builder .SavedModelBuilder (
3742 export_dir = output_version_dir ,
3843 )
3944 builder .add_meta_graph_and_variables (
40- sess = self . session ,
45+ sess = session_to_be_saved ,
4146 tags = [tf .saved_model .tag_constants .SERVING ],
4247 signature_def_map = self .signature_def_map ,
4348 )
4449 builder .save ()
50+
51+ if self .freeze :
52+ session_to_be_saved .close ()
53+
4554 return output_version_dir
55+
56+ @staticmethod
57+ def _get_next_version (path : pathlib .PosixPath ) -> pathlib .PosixPath :
58+ candidate_paths = path .glob ('**/*' )
59+ dirs = [x .name for x in candidate_paths if x .is_dir ()]
60+ versions = [int (dir_name ) for dir_name in dirs if dir_name .isdigit ()]
61+ new_version = max (versions ) + 1 if versions else 0
62+ return path / str (new_version )
63+
64+ def _get_op_names (self ):
65+ """
66+ Extract output operation names from signature
67+
68+ Return:
69+ output_op_names (strs): a list of operation names
70+ for output recorded in signature.
71+
72+ """
73+ output_op_names = []
74+ for signature_value in self .signature_def_map .values ():
75+ for _ , tensor_info in signature_value .outputs .items ():
76+ tensor_name = tensor_info .name
77+ if ':' in tensor_name :
78+ op_name = tensor_name .split (':' )[0 ]
79+ else :
80+ op_name = tensor_name
81+ output_op_names .append (op_name )
82+ return output_op_names
0 commit comments