<jupyter_start><jupyter_text>Train and visualize a model in Tensorflow - Part 2: The Basics of TensorflowThis notebook will explain the basics to create a linear model with Tensorflow. This part uses the 20 newsgroup dataset obtained in the previous part of the tutorial. Remember the dataset, comprised of documents, was converted to a matrix of document embeddings and splitted into train and test datasets.<jupyter_code>import numpy as np
import tensorflow as tf<jupyter_output><empty_output><jupyter_text>Data managementBefore creating the model, we need to specify what the input and output is going to be. For that we use the document matrix obtained in the previous part as input to the the classifier.However, most optimization algorithms similar to Stochastic Gradient Descent need the data in small portions for optimization purposes. On top of that, the training cycle goes through the entire dataset several times (epochs) before converging to a good solution.Fortunately, Tensorflow has the solution to iterate over datasets several times in small batches. These function are called input functions, and they can take a numpy array or a pandas dataframe. It's worth noticing that, during the past updates, Tensorflow has been including more functions to transform the input data in batches handling enconding of categorical features, embeddings, etc, althoug we wont use those function here.We load our dataset and create the input function to handle it with the following code:<jupyter_code># Load the dataset into a numpy keyed structure
newsgroups = np.load('./resources/newsgroup.npz')

# Define the batch size and the number of labels
batch_size = 100
num_classes = newsgroups['labels'].shape[0]

def dataset_input_fn(dataset):
    """
    Creates an input function using the `numpy_input_fn` method from
    tensorflow, based on the dataset we want to use.
    
    Args:
        dataset: String that represents the dataset (should be `train` or `test`)
    
    Returns:
        An `numpy_input_fn` function to feed to an estimator
    """
    assert dataset in ('train', 'test'), "The selected dataset should be `train` or `test`"
    
    return tf.estimator.inputs.numpy_input_fn(
        # A dictionary of numpy arrays that match each array with the corresponding column in the model.
        # For this case we only have "one" colum which represents all the dimensions in the embeddings.
        x={'input_data': newsgroups['%s_data' % dataset]},
        # The target array
        y=newsgroups['%s_target' % dataset],
        # The batch size to iterate the data in small fractions
        batch_size=batch_size,
        # If the dataset is `test` only run once
        num_epochs=1 if dataset == 'test' else None,
        # Only shuffle the dataset for the `train` data
        shuffle=dataset == 'train'
    )<jupyter_output><empty_output><jupyter_text>Defining the modelThe classifier to train is a `tf.estimator.LinearClassifier` which is basically a wrapper in Tensorflow for a Logistic Regression classifier. The object instantiation takes as input an iterator (i.e. `feature_columns`) that match the dictionary fed to the input function. As the input function only takes one column with a number of dimensions equal to the number of dimensions in the embeddings, there is only one feature column of that number of dimensions.<jupyter_code>embedding_size = newsgroups['train_data'].shape[1]

feature_columns = [tf.feature_column.numeric_column('input_data', shape=(embedding_size,))]

linear_classifier = tf.estimator.LinearClassifier(feature_columns=feature_columns, n_classes=num_classes)<jupyter_output><empty_output><jupyter_text>Training cicleNow that we have the function that build the model, we can create the training cycle.<jupyter_code>linear_classifier.train(input_fn=dataset_input_fn("train"), steps=2000)<jupyter_output><empty_output><jupyter_text>EvaluationAs seen before, it is also quite easy to get the evaluation metrics defined in the model after traning:<jupyter_code># Evaluate the model and print results
eval_results = linear_classifier.evaluate(input_fn=dataset_input_fn("test"))
print(eval_results)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.06020066889632107, 'fraction_numerical': 0.003105590062111801, 'mean_word_length': 4.839609483960948, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '152440', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1110, 'n_tokens_neox': 1065, 'n_words': 499, 'path': 'tensorflow_tutorial_2.ipynb', 'repo_name': 'fMercury/tensorflowTutorial2017', 'size': '4186'}