Point 1
We read:
Since TensorFlow Datasets are generators, you can’t access directly the contents unless you iterate over them in a for loop, or by explicitly creating a Python iterator using iter and consuming its elements using next. Also, you can inspect the shape and dtype of each element using the element_spec attribute.
That should probably be “you can inspect the shape and dtype of all elements” because what happens is that we interrogate the Tensorflow dataset:
# x_train is a tf.data.Dataset
print(x_train.element_spec)
which gives us the spec of all the Tensors in the Dataset
TensorSpec(shape=(64, 64, 3), dtype=tf.uint8, name=None)
Point 2
There is a function called normalize(image)
(image is a Tensor) which flattens the tensor in a shape (p,1) and transforms the RGB values in 0-255 to values in [0,1].
This function should really be called preprocess_single_image
as “normalization” has a specific meaning now (as given in the course) and what is being done here doesn’t even look like normalization.
Here it is, a bit modified.
def preprocess_single_image(image: Tensor) -> Tensor:
result = tf.cast(image, tf.float32) / 255.0
result = tf.reshape(result, [-1, ])
print(f"Preprocessed single image in: type = {type(image).__name__}: shape = {image.shape}, dtype = {image.dtype}")
print(f"Preprocessed single image out: type = {type(result).__name__}: shape = {result.shape}, dtype = {result.dtype}")
return result
And then it is called like this:
def preprocess_dataset(dset: tf.data.Dataset, dset_name: str) -> tf.data.Dataset:
# https://www.tensorflow.org/api_docs/python/tf/data/Dataset
result = dset.map(preprocess_single_image)
# No *actual* preprocessing has happened yet
print(f"Result of preprocessing dataset '{dset_name}': class = {type(result)}, spec = {result.element_spec} ")
return result
One may note that it isn’t being used immediately by tensorflow, it will apparently called “on need” and is put (for now) into an evaluable data structure by dset.map()
, very interesting.
Point 3
In graded functions
def linear_function():
and
def initialize_parameters():
we are filling the b
vectors with random numbers from the normal distribution. However, in the course it was said “don’t bother with that, let them remain at 0”. So is, this really appropriate?