Skip to content

Commit 3c10f58

Browse files
committed
More vignette edits
1 parent 73a1a81 commit 3c10f58

File tree

1 file changed

+55
-65
lines changed

1 file changed

+55
-65
lines changed

vignettes/new-guides/preprocessing_layers.Rmd

Lines changed: 55 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ are only active during training.
8787
- `layer_random_contrast()`
8888

8989

90-
## The `adapt()` method
90+
## The `adapt()` function
9191

9292
Some preprocessing layers have an internal state that can be computed based on
9393
a sample of the training data. The list of stateful preprocessing layers is:
@@ -102,12 +102,12 @@ Crucially, these layers are **non-trainable**. Their state is not set during tra
102102
must be set **before training**, either by initializing them from a precomputed constant,
103103
or by "adapting" them on data.
104104

105-
You set the state of a preprocessing layer by exposing it to training data, via the
106-
`adapt()` method:
105+
You set the state of a preprocessing layer by exposing it to training data, via
106+
`adapt()`:
107107

108108
```{r}
109-
data <- rbind(c(0.1, 0.2, 0.3),
110-
c(0.8, 0.9, 1.0),
109+
data <- rbind(c(0.1, 0.2, 0.3),
110+
c(0.8, 0.9, 1.0),
111111
c(1.5, 1.6, 1.7))
112112
layer <- layer_normalization()
113113
adapt(layer, data)
@@ -118,22 +118,25 @@ sprintf("Features std: %.2f", sd(normalized_data))
118118
```
119119

120120

121-
The `adapt()` method takes either an R array, numpy array, or a
122-
`tf.data.Dataset` object. In the case of `layer_string_lookup()` and
121+
`adapt()` takes either an array or a
122+
`tf.data.Dataset`. In the case of `layer_string_lookup()` and
123123
`layer_text_vectorization()`, you can also pass a character vector:
124124

125125

126126
```{r}
127127
data <- c(
128-
"ξεῖν᾽, ἦ τοι μὲν ὄνειροι ἀμήχανοι ἀκριτόμυθοι",
129-
"γίγνοντ᾽, οὐδέ τι πάντα τελείεται ἀνθρώποισι.",
130-
"δοιαὶ γάρ τε πύλαι ἀμενηνῶν εἰσὶν ὀνείρων:",
131-
"αἱ μὲν γὰρ κεράεσσι τετεύχαται, αἱ δ᾽ ἐλέφαντι:",
132-
"τῶν οἳ μέν κ᾽ ἔλθωσι διὰ πριστοῦ ἐλέφαντος,",
133-
"οἵ ῥ᾽ ἐλεφαίρονται, ἔπε᾽ ἀκράαντα φέροντες:",
134-
"οἱ δὲ διὰ ξεστῶν κεράων ἔλθωσι θύραζε,",
135-
"οἵ ῥ᾽ ἔτυμα κραίνουσι, βροτῶν ὅτε κέν τις ἴδηται."
128+
"Congratulations!",
129+
"Today is your day.",
130+
"You're off to Great Places!",
131+
"You're off and away!",
132+
"You have brains in your head.",
133+
"You have feet in your shoes.",
134+
"You can steer yourself",
135+
"any direction you choose.",
136+
"You're on your own. And you know what you know.",
137+
"And YOU are the one who'll decide where to go."
136138
)
139+
137140
layer = layer_text_vectorization()
138141
layer %>% adapt(data)
139142
vectorized_text <- layer(data)
@@ -170,7 +173,7 @@ There are two ways you could be using preprocessing layers:
170173

171174
```{r, eval = FALSE}
172175
input <- layer_input(shape = input_shape)
173-
output <- inputs %>%
176+
output <- input %>%
174177
preprocessing_layer() %>%
175178
rest_of_the_model()
176179
model <- keras_model(input, output)
@@ -189,7 +192,7 @@ batches of preprocessed data, like this:
189192
```{r, eval = FALSE}
190193
library(tfdatasets)
191194
dataset <- ... # define dataset
192-
dataset <- dataset %>%
195+
dataset <- dataset %>%
193196
dataset_map(function(x, y) list(preprocessing_layer(x), y))
194197
```
195198

@@ -200,7 +203,7 @@ efficiently in parallel with training:
200203

201204
```{r, eval = FALSE}
202205
dataset <- dataset %>%
203-
dataset_map(function(x, y) list(preprocessing_layer(x), y)) %>%
206+
dataset_map(function(x, y) list(preprocessing_layer(x), y)) %>%
204207
dataset_prefetch()
205208
model %>% fit(dataset)
206209
```
@@ -209,10 +212,6 @@ This is the best option for `layer_text_vectorization()`, and all structured
209212
data preprocessing layers. It can also be a good option if you're training on
210213
CPU and you use image preprocessing layers.
211214

212-
**When running on TPU, you should always place preprocessing layers in the `tf.data` pipeline**
213-
(with the exception of `layer_normalization()` and `layer_rescaling`, which run
214-
fine on TPU and are commonly used as the first layer is an image model).
215-
216215

217216
## Benefits of doing preprocessing inside the model at inference time
218217

@@ -226,7 +225,7 @@ your model without having to be aware of how each feature is expected to be
226225
encoded & normalized. Your inference model will be able to process raw images or
227226
raw structured data, and will not require users of the model to be aware of the
228227
details of e.g. the tokenization scheme used for text, the indexing scheme used
229-
for categorical features, whether image pixel values are normalized to `[-1, +1]`
228+
for categorical features, whether image pixel values are normalized to `[-1, +1]`
230229
or to `[0, 1]`, etc. This is especially powerful if you're exporting your model
231230
to another runtime, such as TensorFlow.js: you won't have to reimplement your
232231
preprocessing pipeline in JavaScript.
@@ -257,7 +256,7 @@ library(keras)
257256
library(tfdatasets)
258257
259258
# Create a data augmentation stage with horizontal flipping, rotations, zooms
260-
data_augmentation <-
259+
data_augmentation <-
261260
keras_model_sequential() %>%
262261
layer_random_flip("horizontal") %>%
263262
layer_random_rotation(0.1) %>%
@@ -281,7 +280,7 @@ resnet <- application_resnet50(weights = NULL,
281280
classes = classes)
282281
283282
input <- layer_input(shape = input_shape)
284-
output <- input %>%
283+
output <- input %>%
285284
layer_rescaling(1 / 255) %>% # Rescale inputs
286285
resnet()
287286
@@ -301,9 +300,9 @@ You can see a similar setup in action in the example
301300
library(tensorflow)
302301
library(keras)
303302
c(c(x_train, y_train), ...) %<-% dataset_cifar10()
304-
x_train <- x_train %>%
303+
x_train <- x_train %>%
305304
array_reshape(c(dim(x_train)[1], -1L)) # flatten each case
306-
305+
307306
input_shape <- dim(x_train)[-1] # keras layers automatically add the batch dim
308307
classes <- 10
309308
@@ -313,16 +312,16 @@ normalizer %>% adapt(x_train)
313312
314313
# Create a model that include the normalization layer
315314
input <- layer_input(shape = input_shape)
316-
output <- input %>%
317-
normalizer() %>%
318-
layer_dense(classes, activation = "softmax")
315+
output <- input %>%
316+
normalizer() %>%
317+
layer_dense(classes, activation = "softmax")
319318
320319
model <- keras_model(input, output) %>%
321-
compile(optimizer = "adam",
320+
compile(optimizer = "adam",
322321
loss = "sparse_categorical_crossentropy")
323322
324323
# Train the model
325-
model %>%
324+
model %>%
326325
fit(x_train, y_train)
327326
```
328327

@@ -331,7 +330,7 @@ model %>%
331330

332331
```{r}
333332
# Define some toy data
334-
data <- as_tensor(c("a", "b", "c", "b", "c", "a")) %>%
333+
data <- as_tensor(c("a", "b", "c", "b", "c", "a")) %>%
335334
k_reshape(c(-1, 1)) # reshape into matrix with shape: (6, 1)
336335
337336
# Use layer_string_lookup() to build an index of the feature values and encode output.
@@ -396,8 +395,8 @@ data <- k_random_uniform(shape = c(10000, 1), dtype = "int64")
396395
hasher <- layer_hashing(num_bins = 64, salt = 1337)
397396
398397
# Use the CategoryEncoding layer to multi-hot encode the hashed values
399-
encoder <- layer_category_encoding(num_tokens=64, output_mode="multi_hot")
400-
encoded_data <- encoder(hasher(data))
398+
encoder <- layer_category_encoding(num_tokens=64, output_mode="multi_hot")
399+
encoded_data <- encoder(hasher(data))
401400
print(encoded_data$shape)
402401
```
403402

@@ -425,7 +424,7 @@ text_vectorizer <- layer_text_vectorization(output_mode="int")
425424
text_vectorizer %>% adapt(adapt_data)
426425
427426
# Try out the layer
428-
cat("Encoded text:\n",
427+
cat("Encoded text:\n",
429428
as.array(text_vectorizer("The Brain is deeper than the sea")))
430429
431430
# Create a simple model
@@ -434,20 +433,20 @@ input = layer_input(shape(NULL), dtype="int64")
434433
output <- input %>%
435434
layer_embedding(input_dim = text_vectorizer$vocabulary_size(),
436435
output_dim = 16) %>%
437-
layer_gru(8) %>%
436+
layer_gru(8) %>%
438437
layer_dense(1)
439438
440439
model <- keras_model(input, output)
441440
442441
# Create a labeled dataset (which includes unknown tokens)
443442
train_dataset <- tensor_slices_dataset(list(
444-
c("The Brain is deeper than the sea", "for if they are held Blue to Blue"),
443+
c("The Brain is deeper than the sea", "for if they are held Blue to Blue"),
445444
c(1L, 0L)
446445
))
447446
448447
# Preprocess the string inputs, turning them into int sequences
449-
train_dataset <- train_dataset %>%
450-
dataset_batch(2) %>%
448+
train_dataset <- train_dataset %>%
449+
dataset_batch(2) %>%
451450
dataset_map(~list(text_vectorizer(.x), .y))
452451
453452
# Train the model on the int sequences
@@ -458,8 +457,8 @@ model %>%
458457
459458
# For inference, you can export a model that accepts strings as input
460459
input <- layer_input(shape = 1, dtype="string")
461-
output <- input %>%
462-
text_vectorizer() %>%
460+
output <- input %>%
461+
text_vectorizer() %>%
463462
model()
464463
465464
end_to_end_model <- keras_model(input, output)
@@ -514,26 +513,26 @@ model <- keras_model(input, output)
514513
515514
# Create a labeled dataset (which includes unknown tokens)
516515
train_dataset = tensor_slices_dataset(list(
517-
c("The Brain is deeper than the sea", "for if they are held Blue to Blue"),
516+
c("The Brain is deeper than the sea", "for if they are held Blue to Blue"),
518517
c(1L, 0L)
519518
))
520519
521520
# Preprocess the string inputs, turning them into int sequences
522-
train_dataset <- train_dataset %>%
523-
dataset_batch(2) %>%
521+
train_dataset <- train_dataset %>%
522+
dataset_batch(2) %>%
524523
dataset_map(~list(text_vectorizer(.x), .y))
525524
526525
# Train the model on the int sequences
527526
cat("Training model...\n")
528-
model %>%
529-
compile(optimizer="rmsprop", loss="mse") %>%
527+
model %>%
528+
compile(optimizer="rmsprop", loss="mse") %>%
530529
fit(train_dataset)
531530
532531
# For inference, you can export a model that accepts strings as input
533532
input <- layer_input(shape = 1, dtype="string")
534533
535-
output <- input %>%
536-
text_vectorizer() %>%
534+
output <- input %>%
535+
text_vectorizer() %>%
537536
model()
538537
539538
end_to_end_model = keras_model(input, output)
@@ -578,27 +577,27 @@ model <- keras_model(input, output)
578577
579578
# Create a labeled dataset (which includes unknown tokens)
580579
train_dataset = tensor_slices_dataset(list(
581-
c("The Brain is deeper than the sea", "for if they are held Blue to Blue"),
580+
c("The Brain is deeper than the sea", "for if they are held Blue to Blue"),
582581
c(1L, 0L)
583582
))
584583
585584
# Preprocess the string inputs, turning them into int sequences
586-
train_dataset <- train_dataset %>%
587-
dataset_batch(2) %>%
585+
train_dataset <- train_dataset %>%
586+
dataset_batch(2) %>%
588587
dataset_map(~list(text_vectorizer(.x), .y))
589588
590589
591590
# Train the model on the int sequences
592591
cat("Training model...")
593-
model %>%
594-
compile(optimizer="rmsprop", loss="mse") %>%
592+
model %>%
593+
compile(optimizer="rmsprop", loss="mse") %>%
595594
fit(train_dataset)
596595
597596
# For inference, you can export a model that accepts strings as input
598597
input <- layer_input(shape = 1, dtype="string")
599598
600-
output <- input %>%
601-
text_vectorizer() %>%
599+
output <- input %>%
600+
text_vectorizer() %>%
602601
model()
603602
604603
end_to_end_model = keras_model(input, output)
@@ -625,12 +624,3 @@ Instead, pre-compute your vocabulary in advance
625624
(you could use Apache Beam or TF Transform for this)
626625
and store it in a file. Then load the vocabulary into the layer at construction
627626
time by passing the filepath as the `vocabulary` argument.
628-
629-
630-
### Using lookup layers on a TPU pod or with `ParameterServerStrategy`.
631-
632-
There is an outstanding issue that causes performance to degrade when using a
633-
`layer_text_vectorization()`, `layer_string_lookup()`, or
634-
`layer_integer_lookup()` layer while training on a TPU pod or on multiple
635-
machines via `ParameterServerStrategy`. This is slated to be fixed in TensorFlow
636-
2.7.

0 commit comments

Comments
 (0)