Function that returns predictions, training loss, and training op.
(features, labels, mode)
| 169 | model_head = _get_default_head(params, weights_name, output_type) |
| 170 | |
| 171 | def _model_fn(features, labels, mode): |
| 172 | """Function that returns predictions, training loss, and training op.""" |
| 173 | |
| 174 | if (isinstance(features, ops.Tensor) or |
| 175 | isinstance(features, sparse_tensor.SparseTensor)): |
| 176 | features = {'features': features} |
| 177 | if feature_columns: |
| 178 | features = features.copy() |
| 179 | |
| 180 | if output_type == ModelBuilderOutputType.MODEL_FN_OPS: |
| 181 | features.update(layers.transform_features(features, feature_columns)) |
| 182 | else: |
| 183 | for fc in feature_columns: |
| 184 | tensor = fc_core._transform_features(features, [fc])[fc] # pylint: disable=protected-access |
| 185 | features[fc.name] = tensor |
| 186 | |
| 187 | weights = None |
| 188 | if weights_name and weights_name in features: |
| 189 | weights = features.pop(weights_name) |
| 190 | |
| 191 | keys = None |
| 192 | if keys_name and keys_name in features: |
| 193 | keys = features.pop(keys_name) |
| 194 | |
| 195 | # If we're doing eval, optionally ignore device_assigner. |
| 196 | # Also ignore device assigner if we're exporting (mode == INFER) |
| 197 | dev_assn = device_assigner |
| 198 | if (mode == model_fn_lib.ModeKeys.INFER or |
| 199 | (local_eval and mode == model_fn_lib.ModeKeys.EVAL)): |
| 200 | dev_assn = None |
| 201 | |
| 202 | graph_builder = graph_builder_class(params, |
| 203 | device_assigner=dev_assn) |
| 204 | |
| 205 | logits, tree_paths, regression_variance = graph_builder.inference_graph( |
| 206 | features) |
| 207 | |
| 208 | summary.scalar('average_tree_size', graph_builder.average_size()) |
| 209 | # For binary classification problems, convert probabilities to logits. |
| 210 | # Includes hack to get around the fact that a probability might be 0 or 1. |
| 211 | if not params.regression and params.num_classes == 2: |
| 212 | class_1_probs = array_ops.slice(logits, [0, 1], [-1, 1]) |
| 213 | logits = math_ops.log( |
| 214 | math_ops.maximum(class_1_probs / math_ops.maximum( |
| 215 | 1.0 - class_1_probs, EPSILON), EPSILON)) |
| 216 | |
| 217 | # labels might be None if we're doing prediction (which brings up the |
| 218 | # question of why we force everything to adhere to a single model_fn). |
| 219 | training_graph = None |
| 220 | training_hooks = [] |
| 221 | if labels is not None and mode == model_fn_lib.ModeKeys.TRAIN: |
| 222 | with ops.control_dependencies([logits.op]): |
| 223 | training_graph = control_flow_ops.group( |
| 224 | graph_builder.training_graph( |
| 225 | features, labels, input_weights=weights, |
| 226 | num_trainers=num_trainers, |
| 227 | trainer_id=trainer_id), |
| 228 | state_ops.assign_add(training_util.get_global_step(), 1)) |
nothing calls this directly
no test coverage detected