1

I'm trying to augment the imdb movie reviews dataset by adding a random swap of some words. Unlike with image data, I don't think this function is originally in tensorflow. For example with images, you could do something like

def transform(image, label):
    image = tf.image.flip_left_right(image)
    return image, label

Where you use tensorflow's native functions for flipping images. But for augmenting text, I don't see anything that can do that in tf.string. So I am using the Easy Data Augmentation implementation from textaugment. https://github.com/dsfsi/textaugment

EG:

try:
  import textaugment
except ModuleNotFoundError:
  !pip install textaugment
  import textaugment
from textaugment import EDA
import nltk
nltk.download('stopwords')

t = EDA()
t.random_swap("John is going to town")

Returns "John going to town is"

But now when I try to use this random_swap command to augment the entire imdb reviews dataset, it runs into an error because it's trying to act on tensors.

Example:

try:
  import textaugment
except ModuleNotFoundError:
  !pip install textaugment
  import textaugment

import pandas as pd

import tensorflow as tf
from tensorflow.keras.preprocessing import sequence
from tensorflow.keras.models import Sequential
from tensorflow.keras.datasets import imdb

# set parameters:
max_features = 5000
maxlen = 400
batch_size = 32
embedding_dims = 50
filters = 250
kernel_size = 3
hidden_dims = 250
epochs = 1
runs = 1

(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
print(len(x_train), 'train sequences')
print(len(x_test), 'test sequences')

print('Pad sequences (samples x time)')
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
print('x_train shape:', x_train.shape)
print('x_test shape:', x_test.shape)

from textaugment import EDA
import nltk
nltk.download('stopwords')
t = EDA()
for text in x_train:
  text = t.random_swap(text)

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-7fc9edb2f37b> in <module>()
      1 for text in x_train:
----> 2   text = t.random_swap(text)

1 frames
/usr/local/lib/python3.7/dist-packages/textaugment/eda.py in validate(**kwargs)
     72                 raise TypeError("p must be a fraction between 0 and 1")
     73         if 'sentence' in kwargs:
---> 74             if not isinstance(kwargs['sentence'].strip(), str) or len(kwargs['sentence'].strip()) == 0:
     75                 raise TypeError("sentence must be a valid sentence")
     76         if 'n' in kwargs:

AttributeError: 'numpy.ndarray' object has no attribute 'strip'

So how do you augment data in TensorFlow, when the native commands don't exist and you want to make a custom function to do the augmentation?

iYOA
  • 132
  • 6

1 Answers1

1

By loading the dataset with imdb.load_data() you don't get the film reviews as text. It has already been preprocessed: the reviews (sequences of words) have been turned into sequences of integers, where each integer stands for a specific word in a dictionary.

For this reason, you cannot apply t.random_swap(text) to it. You have to decode these reviews back to English words first.

Therefor you'll need the corresponding word_index. It is a dictionary mapping words to an integer index.

In the next step you should revers it, to get a dictionary mapping integer indices to words. Note that the indices are offset by 3 because 0, 1, and 2 are reserved indices, for padding start of sequence, and unknown. You can find more details here.

word_index = imdb.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])

You should decode the reviews before you're applying sequence.pad_sequences() to them. Otherwise there will be a lot of unknown words represented by zeros in the reviews.

For print(x_train[0]) you'll get:

[1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 2, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 2, 15, 256, 4, 2, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 1029, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 2, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 2, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 2, 19, 178, 32]

Let's decode this review:

decoded_review = ' '.join([reverse_word_index.get(i - 3, '?') for i in x_train[0]])

And you'll get:

print(decoded_review)
>>> "? this film was just brilliant casting location scenery story direction everyone's really suited the part they played and you could just imagine being there robert ? is an amazing actor and now the same being director ? father came from the same scottish island as myself so i loved the fact there was a real connection with this film the witty remarks throughout the film were great it was just brilliant so much that i bought the film as soon as it was released for ? and would recommend it to everyone to watch and the fly ? was amazing really cried at the end it was so sad and you know what they say if you cry at a film it must have been good and this definitely was also ? to the two little ? that played the ? of norman and paul they were just brilliant children are often left out of the ? list i think because the stars that play them all grown up are such a big ? for the whole film but these children are amazing and should be ? for what they have done don't you think the whole story was so lovely because it was true and was someone's life after all that was ? with us all"

After the reviews are decoded back to text you are able to augment them with t.random_swap(decoded_review). The augmented data can be encoded back to a sequence of integers with the word_index dictionary.

kindustrii
  • 369
  • 1
  • 8