Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
keras-team
GitHub Repository: keras-team/keras-io
Path: blob/master/scripts/generate_tf_guides.py
3273 views
1
from pathlib import Path
2
import tutobooks
3
import copy
4
import json
5
import hashlib
6
import string
7
import re
8
import yaml
9
10
# The order of CONFIG is also used to generate the _toc.yaml for tensorflow.org.
11
CONFIG = [
12
{
13
"title": "The Sequential model",
14
"source_name": "sequential_model",
15
"target_name": "sequential_model",
16
},
17
{
18
"title": "The Functional API",
19
"source_name": "functional_api",
20
"target_name": "functional",
21
},
22
{
23
"title": "Training and evaluation with the built-in methods",
24
"source_name": "training_with_built_in_methods",
25
"target_name": "train_and_evaluate",
26
},
27
{
28
"title": "Making new Layers and Models via subclassing",
29
"source_name": "making_new_layers_and_models_via_subclassing",
30
"target_name": "custom_layers_and_models",
31
},
32
{
33
"title": "Save and load Keras models",
34
"source_name": "serialization_and_saving",
35
"target_name": "save_and_serialize",
36
},
37
{
38
"title": "Working with preprocessing layers",
39
"source_name": "preprocessing_layers",
40
"target_name": "preprocessing_layers",
41
},
42
{
43
"title": "Customize what happens in Model.fit",
44
"source_name": "customizing_what_happens_in_fit",
45
"target_name": "customizing_what_happens_in_fit",
46
},
47
{
48
"title": "Writing a training loop from scratch",
49
"source_name": "writing_a_training_loop_from_scratch",
50
"target_name": "writing_a_training_loop_from_scratch",
51
},
52
{
53
"title": "Recurrent Neural Networks (RNN) with Keras",
54
"source_name": "working_with_rnns",
55
"target_name": "rnn",
56
},
57
{
58
"title": "Masking and padding with Keras",
59
"source_name": "understanding_masking_and_padding",
60
"target_name": "masking_and_padding",
61
},
62
{
63
"title": "Writing your own callbacks",
64
"source_name": "writing_your_own_callbacks",
65
"target_name": "custom_callback",
66
},
67
{
68
"title": "Transfer learning and fine-tuning",
69
"source_name": "transfer_learning",
70
"target_name": "transfer_learning",
71
},
72
{
73
"title": "Training Keras models with TensorFlow Cloud",
74
"source_name": "training_keras_models_on_cloud",
75
"target_name": "training_keras_models_on_cloud",
76
},
77
]
78
79
80
TF_BUTTONS_TEMPLATE = {
81
"cell_type": "markdown",
82
"metadata": {
83
"colab_type": "text",
84
},
85
"source": [
86
'<table class="tfo-notebook-buttons" align="left">\n',
87
" <td>\n",
88
' <a target="_blank" href="https://www.tensorflow.org/guide/keras/TARGET_NAME"><img src="https://www.tensorflow.org/images/tf_logo_32px.png" />View on TensorFlow.org</a>\n',
89
" </td>\n",
90
" <td>\n",
91
' <a target="_blank" href="https://colab.research.google.com/github/tensorflow/docs/blob/snapshot-keras/site/en/guide/keras/TARGET_NAME.ipynb"><img src="https://www.tensorflow.org/images/colab_logo_32px.png" />Run in Google Colab</a>\n',
92
" </td>\n",
93
" <td>\n",
94
' <a target="_blank" href="https://github.com/keras-team/keras-io/blob/master/guides/SOURCE_NAME.py"><img src="https://www.tensorflow.org/images/GitHub-Mark-32px.png" />View source on GitHub</a>\n',
95
" </td>\n",
96
" <td>\n",
97
' <a href="https://storage.googleapis.com/tensorflow_docs/docs/site/en/guide/keras/TARGET_NAME.ipynb"><img src="https://www.tensorflow.org/images/download_logo_32px.png" />Download notebook</a>\n',
98
" </td>\n",
99
"</table>",
100
],
101
}
102
103
104
TF_IPYNB_CELLS_TEMPLATE = [
105
{
106
"cell_type": "markdown",
107
"metadata": {
108
"colab_type": "text",
109
},
110
"source": ["##### Copyright 2020 The TensorFlow Authors."],
111
},
112
{
113
"cell_type": "code",
114
"execution_count": 0,
115
"metadata": {
116
"cellView": "form",
117
"colab": {},
118
"colab_type": "code",
119
},
120
"outputs": [],
121
"source": [
122
'#@title Licensed under the Apache License, Version 2.0 (the "License");\n',
123
"# you may not use this file except in compliance with the License.\n",
124
"# You may obtain a copy of the License at\n",
125
"#\n",
126
"# https://www.apache.org/licenses/LICENSE-2.0\n",
127
"#\n",
128
"# Unless required by applicable law or agreed to in writing, software\n",
129
'# distributed under the License is distributed on an "AS IS" BASIS,\n',
130
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
131
"# See the License for the specific language governing permissions and\n",
132
"# limitations under the License.",
133
],
134
},
135
# Then: title
136
# Then: buttons
137
]
138
139
TF_IPYNB_BASE = {
140
"metadata": {
141
"colab": {
142
"collapsed_sections": [],
143
"name": "", # FILL ME
144
"private_outputs": True,
145
"provenance": [],
146
"toc_visible": True,
147
},
148
"kernelspec": {
149
"display_name": "Python 3",
150
"language": "python",
151
"name": "python3",
152
},
153
},
154
"nbformat": 4,
155
"nbformat_minor": 0,
156
}
157
158
159
def generate_single_tf_guide(source_dir, target_dir, title, source_name, target_name):
160
# Before we start, regenerate the ipynb.
161
max_loc = tutobooks.MAX_LOC
162
tutobooks.MAX_LOC = 400
163
py_path = (Path(source_dir).parent / source_name).with_suffix(".py")
164
nb_path = (Path(source_dir) / source_name).with_suffix(".ipynb")
165
tutobooks.py_to_nb(py_path, nb_path, fill_outputs=False)
166
tutobooks.MAX_LOC = max_loc
167
168
original_ipynb = json.loads(nb_path.read_text())
169
170
# Skip first title cell
171
cells = original_ipynb["cells"][1:]
172
# Strip Keras tags
173
for cell in cells:
174
if cell["cell_type"] == "markdown":
175
new_lines = []
176
lines = cell["source"]
177
num_lines = len(lines)
178
for i in range(num_lines - 1):
179
if lines[i].startswith('<div class="k-default-codeblock">') and lines[
180
i + 1
181
].startswith("```"):
182
continue
183
elif lines[i].startswith("</div>") and lines[i - 1].startswith("```"):
184
continue
185
else:
186
new_lines.append(lines[i])
187
if len(lines) >= 2 and not (
188
lines[-1].startswith("</div>") and lines[-2].startswith("```")
189
):
190
new_lines.append(lines[-1])
191
if len(lines) < 2:
192
new_lines.append(lines[-1])
193
cell["source"] = new_lines
194
elif cell["cell_type"] == "code":
195
lines = cell["source"]
196
if not lines[0].strip():
197
lines = lines[1:]
198
if not lines[-1].strip():
199
lines = lines[:-1]
200
cell["source"] = lines
201
202
# Add header cells
203
header_cells = copy.deepcopy(TF_IPYNB_CELLS_TEMPLATE)
204
# Add title cell
205
header_cells.append(
206
{
207
"cell_type": "markdown",
208
"metadata": {"colab_type": "text"},
209
"source": ["# " + title],
210
}
211
)
212
buttons = copy.deepcopy(TF_BUTTONS_TEMPLATE)
213
for i in range(len(buttons["source"])):
214
buttons["source"][i] = buttons["source"][i].replace("TARGET_NAME", target_name)
215
buttons["source"][i] = buttons["source"][i].replace("SOURCE_NAME", source_name)
216
header_cells.append(buttons)
217
cells = header_cells + cells
218
219
cell_count = 0
220
for cell in cells:
221
cell_count += 1
222
str_to_hash = f"{cell_count} {cell['source']}"
223
cell_id = hashlib.sha256(str_to_hash.encode("utf-8")).hexdigest()
224
cell["metadata"]["id"] = cell_id[:12]
225
226
notebook = {}
227
for key in TF_IPYNB_BASE.keys():
228
notebook[key] = TF_IPYNB_BASE[key]
229
notebook["metadata"]["colab"]["name"] = target_name + ".ipynb"
230
notebook["cells"] = cells
231
232
f = open(Path(target_dir) / (target_name + ".ipynb"), "w")
233
json_st = json.dumps(notebook, indent=1, sort_keys=True)
234
235
# Apply link conversion
236
json_st = json_st.replace(
237
"(/api/callbacks/",
238
"(https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/",
239
)
240
json_st = json_st.replace(
241
"keras.io/api/layers/recurrent_layers/rnn/",
242
"https://www.tensorflow.org/api_docs/python/tf/keras/layers/RNN/",
243
)
244
json_st = json_st.replace(
245
"https://keras.io/api/layers/recurrent_layers/gru/",
246
"https://www.tensorflow.org/api_docs/python/tf/keras/layers/GRU/",
247
)
248
json_st = json_st.replace(
249
"https://keras.io/api/layers/recurrent_layers/lstm/",
250
"https://www.tensorflow.org/api_docs/python/tf/keras/layers/LSTM/",
251
)
252
json_st = json_st.replace(
253
"https://keras.io/api/layers/recurrent_layers/bidirectional/",
254
"https://www.tensorflow.org/api_docs/python/tf/keras/layers/Bidirectional/",
255
)
256
json_st = json_st.replace(
257
"https://keras.io/api/callbacks/",
258
"https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/",
259
)
260
for entry in CONFIG:
261
src = entry["source_name"]
262
dst = entry["target_name"]
263
json_st = re.sub(
264
r"(?is)]\((\s*)/guides/" + src,
265
"](https://www.tensorflow.org/guide/keras/" + dst,
266
json_st,
267
)
268
json_st = re.sub(
269
r"(?is)(\s+)/guides/" + src,
270
"https://www.tensorflow.org/guide/keras/" + dst,
271
json_st,
272
)
273
f.write(json_st)
274
f.close()
275
276
277
def generate_toc(target_dir):
278
target_dir = Path(target_dir)
279
280
toc = []
281
for config in CONFIG:
282
toc.append(
283
{
284
"title": config["title"],
285
"path": str(Path("/guide/keras") / config["target_name"]),
286
}
287
)
288
toc_dict = {"toc": toc}
289
290
with open(str(target_dir / "_toc.yaml"), "w") as toc_file:
291
yaml.dump(toc_dict, toc_file, sort_keys=False)
292
293
294
def generate_tf_guides():
295
generate_toc(target_dir="../tf")
296
297
for entry in CONFIG:
298
generate_single_tf_guide(
299
source_dir="../guides/ipynb/",
300
target_dir="../tf/",
301
title=entry["title"],
302
source_name=entry["source_name"],
303
target_name=entry["target_name"],
304
)
305
306