|
8 | 8 |
|
9 | 9 | import tornasole.tensorflow as ts
|
10 | 10 | from tornasole.tensorflow import reset_collections
|
| 11 | +from tornasole.tensorflow.hook import TornasoleHook |
11 | 12 | from tornasole.trials import create_trial
|
12 | 13 |
|
| 14 | + |
13 | 15 | def help_test_mnist(path, save_config=None, hook=None):
|
14 |
| - trial_dir = path |
15 |
| - tf.reset_default_graph() |
16 |
| - if hook is None: |
17 |
| - reset_collections() |
18 |
| - |
19 |
| - def cnn_model_fn(features, labels, mode): |
20 |
| - """Model function for CNN.""" |
21 |
| - # Input Layer |
22 |
| - input_layer = tf.reshape(features["x"], [-1, 28, 28, 1]) |
23 |
| - |
24 |
| - # Convolutional Layer #1 |
25 |
| - conv1 = tf.layers.conv2d( |
26 |
| - inputs=input_layer, |
27 |
| - filters=32, |
28 |
| - kernel_size=[5, 5], |
29 |
| - padding="same", |
30 |
| - activation=tf.nn.relu) |
31 |
| - |
32 |
| - # Pooling Layer #1 |
33 |
| - pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2) |
34 |
| - |
35 |
| - # Convolutional Layer #2 and Pooling Layer #2 |
36 |
| - conv2 = tf.layers.conv2d( |
37 |
| - inputs=pool1, |
38 |
| - filters=64, |
39 |
| - kernel_size=[5, 5], |
40 |
| - padding="same", |
41 |
| - activation=tf.nn.relu) |
42 |
| - pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2) |
43 |
| - |
44 |
| - # Dense Layer |
45 |
| - pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64]) |
46 |
| - dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu) |
47 |
| - dropout = tf.layers.dropout( |
48 |
| - inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN) |
49 |
| - |
50 |
| - # Logits Layer |
51 |
| - logits = tf.layers.dense(inputs=dropout, units=10) |
52 |
| - |
53 |
| - predictions = { |
54 |
| - # Generate predictions (for PREDICT and EVAL mode) |
55 |
| - "classes": tf.argmax(input=logits, axis=1), |
56 |
| - # Add `softmax_tensor` to the graph. It is used for PREDICT and by the |
57 |
| - # `logging_hook`. |
58 |
| - "probabilities": tf.nn.softmax(logits, name="softmax_tensor") |
59 |
| - } |
60 |
| - |
61 |
| - if mode == tf.estimator.ModeKeys.PREDICT: |
62 |
| - return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions) |
63 |
| - |
64 |
| - # Calculate Loss (for both TRAIN and EVAL modes) |
65 |
| - loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits) |
66 |
| - |
67 |
| - # Configure the Training Op (for TRAIN mode) |
68 |
| - if mode == tf.estimator.ModeKeys.TRAIN: |
69 |
| - optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001) |
70 |
| - optimizer = ts.TornasoleOptimizer(optimizer) |
71 |
| - train_op = optimizer.minimize( |
72 |
| - loss=loss, |
73 |
| - global_step=tf.train.get_global_step()) |
74 |
| - return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op) |
75 |
| - |
76 |
| - # Add evaluation metrics (for EVAL mode) |
77 |
| - eval_metric_ops = { |
78 |
| - "accuracy": tf.metrics.accuracy( |
79 |
| - labels=labels, predictions=predictions["classes"]) |
80 |
| - } |
81 |
| - return tf.estimator.EstimatorSpec( |
82 |
| - mode=mode, loss=loss, eval_metric_ops=eval_metric_ops) |
83 |
| - |
84 |
| - # Load training and eval data |
85 |
| - ((train_data, train_labels), |
86 |
| - (eval_data, eval_labels)) = tf.keras.datasets.mnist.load_data() |
87 |
| - |
88 |
| - train_data = train_data / np.float32(255) |
89 |
| - train_labels = train_labels.astype(np.int32) # not required |
90 |
| - |
91 |
| - eval_data = eval_data / np.float32(255) |
92 |
| - eval_labels = eval_labels.astype(np.int32) # not required |
93 |
| - |
94 |
| - mnist_classifier = tf.estimator.Estimator( |
95 |
| - model_fn=cnn_model_fn, model_dir="/tmp/mnist_convnet_model") |
96 |
| - |
97 |
| - train_input_fn = tf.estimator.inputs.numpy_input_fn( |
98 |
| - x={"x": train_data}, |
99 |
| - y=train_labels, |
100 |
| - batch_size=100, |
101 |
| - num_epochs=None, |
102 |
| - shuffle=True) |
103 |
| - |
104 |
| - eval_input_fn = tf.estimator.inputs.numpy_input_fn( |
105 |
| - x={"x": eval_data}, |
106 |
| - y=eval_labels, |
107 |
| - num_epochs=1, |
108 |
| - shuffle=False) |
109 |
| - if hook is None: |
110 |
| - hook = ts.TornasoleHook(out_dir=trial_dir, |
111 |
| - save_config=save_config) |
112 |
| - hook.set_mode(ts.modes.TRAIN) |
113 |
| - # train one step and display the probabilties |
114 |
| - mnist_classifier.train( |
115 |
| - input_fn=train_input_fn, |
116 |
| - steps=10, |
117 |
| - hooks=[hook]) |
118 |
| - |
119 |
| - hook.set_mode(ts.modes.EVAL) |
120 |
| - mnist_classifier.evaluate(input_fn=eval_input_fn, hooks=[hook]) |
121 |
| - |
122 |
| - hook.set_mode(ts.modes.TRAIN) |
123 |
| - mnist_classifier.train( |
124 |
| - input_fn=train_input_fn, |
125 |
| - steps=20, |
126 |
| - hooks=[hook]) |
127 |
| - |
128 |
| - tr = create_trial(trial_dir) |
129 |
| - return tr |
| 16 | + trial_dir = path |
| 17 | + tf.reset_default_graph() |
| 18 | + if hook is None: |
| 19 | + reset_collections() |
| 20 | + |
| 21 | + def cnn_model_fn(features, labels, mode): |
| 22 | + """Model function for CNN.""" |
| 23 | + # Input Layer |
| 24 | + input_layer = tf.reshape(features["x"], [-1, 28, 28, 1]) |
| 25 | + |
| 26 | + # Convolutional Layer #1 |
| 27 | + conv1 = tf.layers.conv2d( |
| 28 | + inputs=input_layer, |
| 29 | + filters=32, |
| 30 | + kernel_size=[5, 5], |
| 31 | + padding="same", |
| 32 | + activation=tf.nn.relu) |
| 33 | + |
| 34 | + # Pooling Layer #1 |
| 35 | + pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2) |
| 36 | + |
| 37 | + # Convolutional Layer #2 and Pooling Layer #2 |
| 38 | + conv2 = tf.layers.conv2d( |
| 39 | + inputs=pool1, |
| 40 | + filters=64, |
| 41 | + kernel_size=[5, 5], |
| 42 | + padding="same", |
| 43 | + activation=tf.nn.relu) |
| 44 | + pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2) |
| 45 | + |
| 46 | + # Dense Layer |
| 47 | + pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64]) |
| 48 | + dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu) |
| 49 | + dropout = tf.layers.dropout( |
| 50 | + inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN) |
| 51 | + |
| 52 | + # Logits Layer |
| 53 | + logits = tf.layers.dense(inputs=dropout, units=10) |
| 54 | + |
| 55 | + predictions = { |
| 56 | + # Generate predictions (for PREDICT and EVAL mode) |
| 57 | + "classes": tf.argmax(input=logits, axis=1), |
| 58 | + # Add `softmax_tensor` to the graph. It is used for PREDICT and by the |
| 59 | + # `logging_hook`. |
| 60 | + "probabilities": tf.nn.softmax(logits, name="softmax_tensor") |
| 61 | + } |
| 62 | + |
| 63 | + if mode == tf.estimator.ModeKeys.PREDICT: |
| 64 | + return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions) |
| 65 | + |
| 66 | + # Calculate Loss (for both TRAIN and EVAL modes) |
| 67 | + loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits) |
| 68 | + |
| 69 | + # Configure the Training Op (for TRAIN mode) |
| 70 | + if mode == tf.estimator.ModeKeys.TRAIN: |
| 71 | + optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001) |
| 72 | + optimizer = ts.TornasoleOptimizer(optimizer) |
| 73 | + train_op = optimizer.minimize( |
| 74 | + loss=loss, |
| 75 | + global_step=tf.train.get_global_step()) |
| 76 | + return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op) |
| 77 | + |
| 78 | + # Add evaluation metrics (for EVAL mode) |
| 79 | + eval_metric_ops = { |
| 80 | + "accuracy": tf.metrics.accuracy( |
| 81 | + labels=labels, predictions=predictions["classes"]) |
| 82 | + } |
| 83 | + return tf.estimator.EstimatorSpec( |
| 84 | + mode=mode, loss=loss, eval_metric_ops=eval_metric_ops) |
| 85 | + |
| 86 | + # Load training and eval data |
| 87 | + ((train_data, train_labels), |
| 88 | + (eval_data, eval_labels)) = tf.keras.datasets.mnist.load_data() |
| 89 | + |
| 90 | + train_data = train_data / np.float32(255) |
| 91 | + train_labels = train_labels.astype(np.int32) # not required |
| 92 | + |
| 93 | + eval_data = eval_data / np.float32(255) |
| 94 | + eval_labels = eval_labels.astype(np.int32) # not required |
| 95 | + |
| 96 | + mnist_classifier = tf.estimator.Estimator( |
| 97 | + model_fn=cnn_model_fn, model_dir="/tmp/mnist_convnet_model") |
| 98 | + |
| 99 | + train_input_fn = tf.estimator.inputs.numpy_input_fn( |
| 100 | + x={"x": train_data}, |
| 101 | + y=train_labels, |
| 102 | + batch_size=100, |
| 103 | + num_epochs=None, |
| 104 | + shuffle=True) |
| 105 | + |
| 106 | + eval_input_fn = tf.estimator.inputs.numpy_input_fn( |
| 107 | + x={"x": eval_data}, |
| 108 | + y=eval_labels, |
| 109 | + num_epochs=1, |
| 110 | + shuffle=False) |
| 111 | + if hook is None: |
| 112 | + hook = ts.TornasoleHook(out_dir=trial_dir, |
| 113 | + save_config=save_config) |
| 114 | + hook.set_mode(ts.modes.TRAIN) |
| 115 | + # train one step and display the probabilties |
| 116 | + mnist_classifier.train( |
| 117 | + input_fn=train_input_fn, |
| 118 | + steps=10, |
| 119 | + hooks=[hook]) |
| 120 | + |
| 121 | + hook.set_mode(ts.modes.EVAL) |
| 122 | + mnist_classifier.evaluate(input_fn=eval_input_fn, hooks=[hook]) |
| 123 | + |
| 124 | + hook.set_mode(ts.modes.TRAIN) |
| 125 | + mnist_classifier.train( |
| 126 | + input_fn=train_input_fn, |
| 127 | + steps=20, |
| 128 | + hooks=[hook]) |
| 129 | + |
| 130 | + tr = create_trial(trial_dir) |
| 131 | + return tr |
| 132 | + |
130 | 133 |
|
131 | 134 | def test_mnist_local():
|
132 |
| - run_id = 'trial_' + datetime.now().strftime('%Y%m%d-%H%M%S%f') |
133 |
| - trial_dir = os.path.join(TORNASOLE_TF_HOOK_TESTS_DIR, run_id) |
134 |
| - tr = help_test_mnist(trial_dir, ts.SaveConfig(save_interval=2)) |
135 |
| - assert len(tr.available_steps()) == 55 |
136 |
| - assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
137 |
| - assert len(tr.available_steps(mode=ts.modes.EVAL)) == 40 |
138 |
| - assert len(tr.tensors()) == 16 |
139 |
| - shutil.rmtree(trial_dir) |
| 135 | + run_id = 'trial_' + datetime.now().strftime('%Y%m%d-%H%M%S%f') |
| 136 | + trial_dir = os.path.join(TORNASOLE_TF_HOOK_TESTS_DIR, run_id) |
| 137 | + tr = help_test_mnist(trial_dir, ts.SaveConfig(save_interval=2)) |
| 138 | + assert len(tr.available_steps()) == 55 |
| 139 | + assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
| 140 | + assert len(tr.available_steps(mode=ts.modes.EVAL)) == 40 |
| 141 | + assert len(tr.tensors()) == 16 |
| 142 | + shutil.rmtree(trial_dir) |
| 143 | + |
| 144 | + |
| 145 | +def test_mnist_local_json(): |
| 146 | + out_dir = 'newlogsRunTest1/test_mnist_local_json_config' |
| 147 | + shutil.rmtree(out_dir, ignore_errors=True) |
| 148 | + os.environ[TORNASOLE_CONFIG_FILE_PATH_ENV_STR] = 'tests/tensorflow/hooks/test_json_configs/test_mnist_local.json' |
| 149 | + hook = TornasoleHook.hook_from_config() |
| 150 | + tr = help_test_mnist(path=out_dir, hook=hook) |
| 151 | + assert len(tr.available_steps()) == 55 |
| 152 | + assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
| 153 | + assert len(tr.available_steps(mode=ts.modes.EVAL)) == 40 |
| 154 | + assert len(tr.tensors()) == 16 |
| 155 | + shutil.rmtree(out_dir, ignore_errors=True) |
| 156 | + |
140 | 157 |
|
141 | 158 | def test_mnist_s3():
|
142 |
| - run_id = 'trial_' + datetime.now().strftime('%Y%m%d-%H%M%S%f') |
143 |
| - trial_dir = 's3://tornasole-testing/tornasole_tf/hooks/estimator_modes/' + run_id |
144 |
| - tr = help_test_mnist(trial_dir, ts.SaveConfig(save_interval=2)) |
145 |
| - assert len(tr.available_steps()) == 55 |
146 |
| - assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
147 |
| - assert len(tr.available_steps(mode=ts.modes.EVAL)) == 40 |
148 |
| - assert len(tr.tensors()) == 16 |
| 159 | + run_id = 'trial_' + datetime.now().strftime('%Y%m%d-%H%M%S%f') |
| 160 | + trial_dir = 's3://tornasole-testing/tornasole_tf/hooks/estimator_modes/' + run_id |
| 161 | + tr = help_test_mnist(trial_dir, ts.SaveConfig(save_interval=2)) |
| 162 | + assert len(tr.available_steps()) == 55 |
| 163 | + assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
| 164 | + assert len(tr.available_steps(mode=ts.modes.EVAL)) == 40 |
| 165 | + assert len(tr.tensors()) == 16 |
149 | 166 |
|
150 | 167 |
|
151 | 168 | def test_mnist_local_multi_save_configs():
|
152 |
| - run_id = 'trial_' + datetime.now().strftime('%Y%m%d-%H%M%S%f') |
153 |
| - trial_dir = os.path.join(TORNASOLE_TF_HOOK_TESTS_DIR, run_id) |
154 |
| - tr = help_test_mnist(trial_dir, {ts.modes.TRAIN: ts.SaveConfig(save_interval=2), |
155 |
| - ts.modes.EVAL: ts.SaveConfig(save_interval=1)}) |
156 |
| - assert len(tr.available_steps()) == 94 |
157 |
| - assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
158 |
| - assert len(tr.available_steps(mode=ts.modes.EVAL)) == 79 |
159 |
| - assert len(tr.tensors()) == 16 |
160 |
| - shutil.rmtree(trial_dir) |
| 169 | + run_id = 'trial_' + datetime.now().strftime('%Y%m%d-%H%M%S%f') |
| 170 | + trial_dir = os.path.join(TORNASOLE_TF_HOOK_TESTS_DIR, run_id) |
| 171 | + tr = help_test_mnist(trial_dir, {ts.modes.TRAIN: ts.SaveConfig(save_interval=2), |
| 172 | + ts.modes.EVAL: ts.SaveConfig(save_interval=1)}) |
| 173 | + assert len(tr.available_steps()) == 94 |
| 174 | + assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
| 175 | + assert len(tr.available_steps(mode=ts.modes.EVAL)) == 79 |
| 176 | + assert len(tr.tensors()) == 16 |
| 177 | + shutil.rmtree(trial_dir) |
| 178 | + |
161 | 179 |
|
162 | 180 | def test_mnist_s3_multi_save_configs():
|
163 |
| - run_id = 'trial_' + datetime.now().strftime('%Y%m%d-%H%M%S%f') |
164 |
| - trial_dir = 's3://tornasole-testing/tornasole_tf/hooks/estimator_modes/' + run_id |
165 |
| - tr = help_test_mnist(trial_dir, {ts.modes.TRAIN: ts.SaveConfig(save_interval=2), |
166 |
| - ts.modes.EVAL: ts.SaveConfig(save_interval=1)}) |
167 |
| - assert len(tr.available_steps()) == 94 |
168 |
| - assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
169 |
| - assert len(tr.available_steps(mode=ts.modes.EVAL)) == 79 |
170 |
| - assert len(tr.tensors()) == 16 |
| 181 | + run_id = 'trial_' + datetime.now().strftime('%Y%m%d-%H%M%S%f') |
| 182 | + trial_dir = 's3://tornasole-testing/tornasole_tf/hooks/estimator_modes/' + run_id |
| 183 | + tr = help_test_mnist(trial_dir, {ts.modes.TRAIN: ts.SaveConfig(save_interval=2), |
| 184 | + ts.modes.EVAL: ts.SaveConfig(save_interval=1)}) |
| 185 | + assert len(tr.available_steps()) == 94 |
| 186 | + assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
| 187 | + assert len(tr.available_steps(mode=ts.modes.EVAL)) == 79 |
| 188 | + assert len(tr.tensors()) == 16 |
| 189 | + |
171 | 190 |
|
172 | 191 | def test_mnist_local_multi_save_configs_json():
|
173 |
| - out_dir = 'newlogsRunTest1/test_save_config_modes_hook_config' |
174 |
| - shutil.rmtree(out_dir, ignore_errors=True) |
175 |
| - os.environ[TORNASOLE_CONFIG_FILE_PATH_ENV_STR] = 'tests/tensorflow/hooks/test_json_configs/test_save_config_modes_hook_config.json' |
176 |
| - hook = ts.TornasoleHook.hook_from_config() |
177 |
| - tr = help_test_mnist(out_dir, hook=hook) |
178 |
| - assert len(tr.available_steps()) == 94 |
179 |
| - assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
180 |
| - assert len(tr.available_steps(mode=ts.modes.EVAL)) == 79 |
181 |
| - assert len(tr.tensors()) == 16 |
182 |
| - shutil.rmtree(out_dir) |
| 192 | + out_dir = 'newlogsRunTest1/test_save_config_modes_hook_config' |
| 193 | + shutil.rmtree(out_dir, ignore_errors=True) |
| 194 | + os.environ[ |
| 195 | + TORNASOLE_CONFIG_FILE_PATH_ENV_STR] = 'tests/tensorflow/hooks/test_json_configs/test_save_config_modes_hook_config.json' |
| 196 | + hook = ts.TornasoleHook.hook_from_config() |
| 197 | + tr = help_test_mnist(out_dir, hook=hook) |
| 198 | + assert len(tr.available_steps()) == 94 |
| 199 | + assert len(tr.available_steps(mode=ts.modes.TRAIN)) == 15 |
| 200 | + assert len(tr.available_steps(mode=ts.modes.EVAL)) == 79 |
| 201 | + assert len(tr.tensors()) == 16 |
| 202 | + shutil.rmtree(out_dir) |
0 commit comments