question about tf.data.Dataset.from_generator for bert

Viewed 339

I searched regarding this, but I cant find how to do. usually, they use tf.constant or tf.data.TFrecord.

I want to make bert input dataset api using generator from reading csv file. I try several hours, but various error happened. I confused hot to use output_types, and output_shape

below is my code. what is the problem??

import tensorflow as tf
print(tf.__version__)
import tensorflow_datasets
from transformers import *
import pandas as pd
import numpy as np
from tensorflow import keras

from tensorflow.keras.layers import *
from tensorflow.keras.models import *
from tqdm.notebook import tqdm
# from wandb.keras import WandbCallback
import tensorflow_datasets as tfds
import matplotlib.pyplot as plt
import feed
from feed import *
import time

train_df = pd.read_csv('files/train.csv')
from transformers import AlbertTokenizer, TFAlbertForSequenceClassification

tokenizer = AlbertTokenizer.from_pretrained('albert-base-v2')
model = TFAlbertForSequenceClassification.from_pretrained('albert-base-v2', num_labels=Num_class)

# usually error happened here or next line
train_dataset = create_dataset('files/train.csv',batch_size=32, 
                               tokenizer=tokenizer, max_seq_len=128 )

al_inputs,  label = next(iter(train_dataset))

feed.py

def convert_single_example(tokenizer, example, max_seq_length=512):
    """Converts a single `InputExample` into a single `InputFeatures`."""
    if isinstance(example, PaddingInputExample):
        input_ids = [0] * max_seq_length
        input_mask = [0] * max_seq_length
        segment_ids = [0] * max_seq_length
        label = 0
        return input_ids, input_mask, segment_ids, label

    tokens_a = tokenizer.tokenize(example.text_a)
    if len(tokens_a) > max_seq_length - 2:
        tokens_a = tokens_a[0 : (max_seq_length - 2)]

    tokens = []
    segment_ids = []
    tokens.append("[CLS]")
    segment_ids.append(0)
    for token in tokens_a:
        tokens.append(token)
        segment_ids.append(0)
    tokens.append("[SEP]")
    segment_ids.append(0)
    
    #print(tokens)
    input_ids = tokenizer.convert_tokens_to_ids(tokens)

    # The mask has 1 for real tokens and 0 for padding tokens. Only real
    # tokens are attended to.
    input_mask = [1] * len(input_ids)

    # Zero-pad up to the sequence length.
    while len(input_ids) < max_seq_length:
        input_ids.append(0)
        input_mask.append(0)
        segment_ids.append(0)

    assert len(input_ids) == max_seq_length
    assert len(input_mask) == max_seq_length
    assert len(segment_ids) == max_seq_length

    return input_ids, input_mask, segment_ids, example.label

def convert_text_to_features(texts, labels, tokenizer, max_seq_len) :
    InputExamples = []
#     for text, label in zip(texts, labels) :
    InputExamples.append(
        InputExample(guid=None, text_a=texts, text_b=None, label=labels)
    )
        
    input_ids, input_masks, segment_ids, labels = [], [], [], []
    for example in (InputExamples) :
        input_id, input_mask, segment_id, label = convert_single_example(
            tokenizer, example, max_seq_len
        )
        input_ids.append(input_id)
        input_masks.append(input_mask)
        segment_ids.append(segment_id)
        labels.append(label)   
    return (np.array(input_ids), np.array(input_masks),np.array(segment_ids)),np.array(labels).reshape(-1, 1)

def read_csvs(csv_files):
    sets = []
    for csv in csv_files:
        file = pandas.read_csv(csv, encoding='utf-8', na_filter=False)
        #FIXME: not cross-platform
#         csv_dir = os.path.dirname(os.path.abspath(csv))
        sets.append(file)
    # Concat all sets, drop any extra columns, re-index the final result as 0..N
    return pandas.concat(sets, join='inner', ignore_index=True)

def create_dataset(csvs, batch_size, tokenizer, max_seq_len):
    print(max_seq_len)
    csvs = csvs.split(',')
    df = read_csvs(csvs)

    def generate_values() :
        for _, row in df.iterrows() :
            yield convert_text_to_features(row.text, row.label_id, 
                                tokenizer=tokenizer,max_seq_len=max_seq_len)
    
   
    dataset = tf.data.Dataset.from_generator(generate_values, 
                                            output_types=((tf.int32, tf.int32, tf.int32), tf.int32), output_shapes=(tf.TensorShape([1, max_seq_len]), tf.TensorShape([1, max_seq_len]), tf.TensorShape([1, max_seq_len]), tf.TensorShape([1, 1])))
    
    dataset = dataset.shuffle(100, reshuffle_each_iteration = True).repeat(2).batch(batch_size, drop_remainder=True)

    return dataset
0 Answers
Related