I get the following error from running your code: AttributeError: 'Tensor' object has no attribute 'ndim'. It doesn't seem possible to run the augment function with tf.data.Dataset because it can't deal with the Tensor(s). A workaround is to wrap your augment function in tf.py_function:
import tensorflow as tf
import numpy as np
def augment(x, y):
x = x.numpy()
x = tf.keras.preprocessing.image.random_shift(x, 0.1, 0.1)
x = tf.keras.preprocessing.image.random_rotation(
x, 10, row_axis=1, col_axis=2, channel_axis=0, fill_mode='nearest', cval=0.0,
interpolation_order=1)
return x, y
X = np.random.random(size=(256, 48, 48, 1))
y = np.random.randint(0, 7, size=(256,))
dataset = tf.data.Dataset.from_tensor_slices((X, y))
dataset = dataset.map(
lambda x, y: tf.py_function(
func=augment,
inp=[x, y],
Tout=[tf.float32, tf.int64]))
dataset = dataset.batch(16, drop_remainder=False)
dataset = dataset.prefetch(buffer_size=1)
The code above should run without any errors. If you often need to wrap your functions with tf.py_function, it can be convenient (and also clean) to write a decorator instead. Something like this:
import tensorflow as tf
import numpy as np
def map_decorator(func):
def wrapper(*args):
return tf.py_function(
func=func,
inp=[*args],
Tout=[a.dtype for a in args])
return wrapper
@map_decorator
def augment(x, y):
x = x.numpy()
x = tf.keras.preprocessing.image.random_shift(x, 0.1, 0.1)
x = tf.keras.preprocessing.image.random_rotation(
x, 10, row_axis=1, col_axis=2, channel_axis=0, fill_mode='nearest', cval=0.0,
interpolation_order=1)
return x, y
X = np.random.random(size=(256, 48, 48, 1))
y = np.random.randint(0, 7, size=(256,))
dataset = tf.data.Dataset.from_tensor_slices((X, y))
dataset = dataset.map(augment)
dataset = dataset.batch(16, drop_remainder=False)
dataset = dataset.prefetch(buffer_size=1)
Hope it helps!