Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/keras/src/utils/dataset_creator.py: 41%

17 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-03 07:57 +0000

1# Copyright 2021 The TensorFlow Authors. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14# ============================================================================== 

15 

16"""Input dataset creator for `model.fit`.""" 

17 

18import tensorflow.compat.v2 as tf 

19 

20# isort: off 

21from tensorflow.python.util.tf_export import keras_export 

22 

23 

24@keras_export("keras.utils.experimental.DatasetCreator", v1=[]) 

25class DatasetCreator: 

26 """Object that returns a `tf.data.Dataset` upon invoking. 

27 

28 `tf.keras.utils.experimental.DatasetCreator` is designated as a supported 

29 type for `x`, or the input, in `tf.keras.Model.fit`. Pass an instance of 

30 this class to `fit` when using a callable (with a `input_context` argument) 

31 that returns a `tf.data.Dataset`. 

32 

33 ```python 

34 model = tf.keras.Sequential([tf.keras.layers.Dense(10)]) 

35 model.compile(tf.keras.optimizers.SGD(), loss="mse") 

36 

37 def dataset_fn(input_context): 

38 global_batch_size = 64 

39 batch_size = input_context.get_per_replica_batch_size(global_batch_size) 

40 dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat() 

41 dataset = dataset.shard( 

42 input_context.num_input_pipelines, input_context.input_pipeline_id) 

43 dataset = dataset.batch(batch_size) 

44 dataset = dataset.prefetch(2) 

45 return dataset 

46 

47 input_options = tf.distribute.InputOptions( 

48 experimental_fetch_to_device=True, 

49 experimental_per_replica_buffer_size=2) 

50 model.fit(tf.keras.utils.experimental.DatasetCreator( 

51 dataset_fn, input_options=input_options), epochs=10, steps_per_epoch=10) 

52 ``` 

53 

54 `Model.fit` usage with `DatasetCreator` is intended to work across all 

55 `tf.distribute.Strategy`s, as long as `Strategy.scope` is used at model 

56 creation: 

57 

58 ```python 

59 strategy = tf.distribute.experimental.ParameterServerStrategy( 

60 cluster_resolver) 

61 with strategy.scope(): 

62 model = tf.keras.Sequential([tf.keras.layers.Dense(10)]) 

63 model.compile(tf.keras.optimizers.SGD(), loss="mse") 

64 

65 def dataset_fn(input_context): 

66 ... 

67 

68 input_options = ... 

69 model.fit(tf.keras.utils.experimental.DatasetCreator( 

70 dataset_fn, input_options=input_options), epochs=10, steps_per_epoch=10) 

71 ``` 

72 

73 Note: When using `DatasetCreator`, `steps_per_epoch` argument in `Model.fit` 

74 must be provided as the cardinality of such input cannot be inferred. 

75 

76 Args: 

77 dataset_fn: A callable that takes a single argument of type 

78 `tf.distribute.InputContext`, which is used for batch size calculation 

79 and cross-worker input pipeline sharding (if neither is needed, the 

80 `InputContext` parameter can be ignored in the `dataset_fn`), and 

81 returns a `tf.data.Dataset`. 

82 input_options: Optional `tf.distribute.InputOptions`, used for specific 

83 options when used with distribution, for example, whether to prefetch 

84 dataset elements to accelerator device memory or host device memory, and 

85 prefetch buffer size in the replica device memory. No effect if not used 

86 with distributed training. See `tf.distribute.InputOptions` for more 

87 information. 

88 """ 

89 

90 def __init__(self, dataset_fn, input_options=None): 

91 if not callable(dataset_fn): 

92 raise TypeError( 

93 "`dataset_fn` for `DatasetCreator` must be a `callable`. " 

94 f"Received: {dataset_fn}" 

95 ) 

96 if input_options and ( 

97 not isinstance(input_options, tf.distribute.InputOptions) 

98 ): 

99 raise TypeError( 

100 "`input_options` for `DatasetCreator` must be a " 

101 f"`tf.distribute.InputOptions`. Received: {input_options}" 

102 ) 

103 

104 self.dataset_fn = dataset_fn 

105 self.input_options = input_options 

106 

107 def __call__(self, *args, **kwargs): 

108 # When a `DatasetCreator` is invoked, it forwards args/kwargs straight 

109 # to the callable. 

110 dataset = self.dataset_fn(*args, **kwargs) 

111 if not isinstance(dataset, tf.data.Dataset): 

112 raise TypeError( 

113 "The `callable` provided to `DatasetCreator` must return " 

114 f'a Dataset. It returns "{dataset}"' 

115 ) 

116 return dataset 

117