Package loading, environment variables, generic functions and data loading


In [1]:
## Load packages

import matplotlib.pyplot as plt
import numpy as np
import os
from six.moves import cPickle as pickle
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import SGDClassifier
import string
import time
import tensorflow as tf

In [2]:
## Define environment variables

HOMEDIR = os.environ["HOME"]

BASEDIR = os.path.join(HOMEDIR, "workspace", "jupyterlab", "TensorFlowUdacity")

DATADIR = os.path.join(BASEDIR, "data")
SANITIZEDDATADIR = os.path.join(DATADIR, "notmnist", "sanitized")

SANITIZEDDATAFILE = os.path.join(SANITIZEDDATADIR, 'notmnist.pickle')

In [3]:
## Load pickled sanitized train, validation and test datasets

with open(SANITIZEDDATAFILE, 'rb') as f:
    sane_datasets = pickle.load(f)
    train_dataset = sane_datasets['train_dataset']
    train_labels = sane_datasets['train_labels']
    ntrain = sane_datasets['ntrain']
    validation_dataset = sane_datasets['validation_dataset']
    validation_labels = sane_datasets['validation_labels']
    nvalidation = sane_datasets['nvalidation']
    test_dataset = sane_datasets['test_dataset']
    test_labels = sane_datasets['test_labels']
    ntest = sane_datasets['ntest']
    del sane_datasets
    
print('Number of images in train set:', ntrain)
print('Number of images in validation set:', nvalidation)
print('Number of images in test set:', ntrain)


Number of images in train set: 151349
Number of images in validation set: 8882
Number of images in test set: 151349

In [4]:
## Set image properties and number of classes

image_size = 28 # Pixel width and height
npixels = image_size**2 # Total number of pixels in an image

nclasses = 10 # Number of classes (letters)

In [5]:
## Function for reformatting data in format compatible with scikit-learn and TensorFlow

def reformat(dataset, labels, npixels, nclasses):
    formatted_dataset = dataset.reshape(-1, npixels).astype(np.float32)
    formatted_labels = (np.arange(nclasses) == labels[:, None]).astype(np.float32) # Vectorize each label (one-hot encoding)
    return formatted_dataset, formatted_labels

In [6]:
## Reformat data in format compatible with scikit-learn and TensorFlow

train_dataset, onehot_train_labels = reformat(train_dataset, train_labels, npixels, nclasses)
validation_dataset, onehot_validation_labels = reformat(validation_dataset, validation_labels, npixels, nclasses)
test_dataset, onehot_test_labels = reformat(test_dataset, test_labels, npixels, nclasses)

print('Dimension of training set:', train_dataset.shape)
print('Dimension of validation set:', validation_dataset.shape)
print('Dimension of test set:', test_dataset.shape)

print('Dimension of train labels:', onehot_train_labels.shape)
print('Dimension of validation labels:', onehot_validation_labels.shape)
print('Dimension of test labels:', onehot_test_labels.shape)


Dimension of training set: (151349, 784)
Dimension of validation set: (8882, 784)
Dimension of test set: (9006, 784)
Dimension of train labels: (151349, 10)
Dimension of validation labels: (8882, 10)
Dimension of test labels: (9006, 10)

In [7]:
## Compute absolute frequencies per class in train, validation and test datasets

train_bincount = np.bincount(train_labels)
validation_bincount = np.bincount(validation_labels)
test_bincount = np.bincount(test_labels)

In [8]:
## Plot relative frequency of each class (letter) in each dataset

plt.gca().set_prop_cycle('color', ['green', 'blue', 'red'])

plt.plot(np.arange(nclasses), np.round(100*np.bincount(train_labels)/ntrain, 2), marker='o', markersize=5)
plt.plot(np.arange(nclasses), np.round(100*np.bincount(validation_labels)/nvalidation, 2), marker='o', markersize=5)
plt.plot(np.arange(nclasses), np.round(100*np.bincount(test_labels)/ntest, 2), marker='o', markersize=5)

plt.ylim([0, 12])

plt.xlabel('Class (letter)')
plt.ylabel('Relative frequency (%)')
plt.title('Frequency of each class in each dataset')

plt.xticks(np.arange(nclasses), string.ascii_uppercase[:nclasses])

plt.legend(('Train set', 'Validation set', 'Test set'), loc='lower left')

plt.show()



In [9]:
## Function for counting elements per class

def element_count_per_class(labels, nclasses):
    counts = np.zeros(nclasses, dtype=np.int64)
    for label in np.nditer(labels):
        counts[int(label)] += 1
                
    return counts

In [10]:
## Function for counting correct predictions per class

def prediction_count_per_class(labels, predictions, nclasses):
    counts = np.zeros(nclasses, dtype=np.int64)
    for label, prediction in np.nditer([labels, predictions]):
        if label == prediction:
            counts[int(label)] += 1
                
    return counts

In [11]:
## Function for plotting prediction accuracy per class across different data sets

def plot_prediction_accuracy_per_class(scores, nclasses, color, legend, xticks, marker='o', markersize=5, show=True):
    plt.gca().set_prop_cycle('color', color)

    for score in scores:
        plt.plot(np.arange(nclasses), score, marker=marker, markersize=markersize)

    plt.ylim((0, 100))

    plt.xlabel('Class')
    plt.ylabel('Prediction accuracy (%)')
    plt.title('Prediction accuracy per class')

    plt.xticks(np.arange(nclasses), xticks)

    plt.legend(legend, loc='lower left')

    if show:
        plt.show()

Logistic regression using scikit-learn


In [12]:
## Fit logistic regression with L-BFGS optimizer using scikit-learn

logreg = LogisticRegression(C=1e5, multi_class='multinomial', solver='lbfgs')

start_time = time.process_time()
logreg.fit(train_dataset, train_labels)
end_time = time.process_time()
sklearn_logreg_lbfgs_time = end_time-start_time

sklearn_logreg_lbfgs_score = logreg.score(test_dataset, test_labels)

print('Logistic regression with L-BFGS optimizer using scikit-learn')
print('Time ellapsed: %f seconds' % sklearn_logreg_lbfgs_time)
print('Prediction accuracy: %.3f%%' % round(100*sklearn_logreg_lbfgs_score))


Logistic regression with L-BFGS optimizer using scikit-learn
Time ellapsed: 62.944475 seconds
Prediction accuracy: 89.000%

In [13]:
## Count correct predictions per class in train set for logistic regression with L-BGFS optimizer in scikit-learn

train_sklearn_logreg_lbfgs_pred_count_per_class = prediction_count_per_class(
    train_labels, logreg.predict(train_dataset), nclasses
)

train_sklearn_logreg_lbfgs_pred_count_per_class


Out[13]:
array([12911, 11434, 14709, 11679, 12827, 14155, 14300,  8511,  7229,
       13929])

In [14]:
## Compute prediction accuracy per class in train set for logistic regression with L-BGFS optimizer in scikit-learn

train_sklearn_logreg_lbfgs_pred_score_per_class = np.round(
    100*train_sklearn_logreg_lbfgs_pred_count_per_class/train_bincount, 2
)

train_sklearn_logreg_lbfgs_pred_score_per_class


Out[14]:
array([81.43, 77.69, 85.9 , 81.18, 77.83, 86.13, 81.7 , 75.95, 65.28,
       84.08])

In [15]:
## Count correct predictions per class in test set for logistic regression with L-BGFS optimizer in scikit-learn

test_sklearn_logreg_lbfgs_pred_count_per_class = prediction_count_per_class(
    test_labels, logreg.predict(test_dataset), nclasses
)

test_sklearn_logreg_lbfgs_pred_count_per_class


Out[15]:
array([854, 772, 905, 824, 847, 896, 853, 608, 526, 894])

In [16]:
## Compute prediction accuracy per class in train set for logistic regression with L-BGFS optimizer in scikit-learn

test_sklearn_logreg_lbfgs_pred_score_per_class = np.round(
    100*test_sklearn_logreg_lbfgs_pred_count_per_class/test_bincount, 2
)

test_sklearn_logreg_lbfgs_pred_score_per_class


Out[16]:
array([88.87, 86.55, 93.69, 91.76, 86.69, 92.95, 86.86, 86.12, 76.56,
       91.88])

In [17]:
## Plot prediction accuracy per class in train and test set for logistic regression with L-BGFS optimizer in scikit-learn

plot_prediction_accuracy_per_class(
    [train_sklearn_logreg_lbfgs_pred_score_per_class, test_sklearn_logreg_lbfgs_pred_score_per_class], nclasses, 
    ('green', 'red'), ('Train set', 'Test set'), string.ascii_uppercase[:nclasses]
)



In [18]:
## Fit logistic regression with SGD optimizer using scikit-learn

logreg = SGDClassifier(loss='log', penalty='l2', max_iter=10)
# logreg = SGDClassifier(loss='log', penalty='l2', tol=1e5)

start_time = time.process_time()
logreg.fit(train_dataset, train_labels)
end_time = time.process_time()
sklearn_logreg_sgd_time = end_time-start_time

sklearn_logreg_sgd_score = logreg.score(test_dataset, test_labels)

print('Logistic regression with SGD optimizer using scikit-learn')
print('Time ellapsed: %f seconds' % sklearn_logreg_sgd_time)
print('Prediction accuracy: %.3f%%' % round(100*sklearn_logreg_sgd_score))


Logistic regression with SGD optimizer using scikit-learn
Time ellapsed: 62.892016 seconds
Prediction accuracy: 88.000%

In [19]:
## Count correct predictions per class in train set for logistic regression with SGD optimizer in scikit-learn

train_sklearn_logreg_sgd_pred_count_per_class = prediction_count_per_class(
    train_labels, logreg.predict(train_dataset), nclasses
)

train_sklearn_logreg_sgd_pred_count_per_class


Out[19]:
array([12724, 10883, 14402, 11726, 12748, 13921, 13981,  8106,  6688,
       14010])

In [20]:
## Compute prediction accuracy per class in train set for logistic regression with SGD optimizer in scikit-learn

train_sklearn_logreg_sgd_pred_score_per_class = np.round(
    100*train_sklearn_logreg_sgd_pred_count_per_class/train_bincount, 2
)

train_sklearn_logreg_sgd_pred_score_per_class


Out[20]:
array([80.25, 73.95, 84.1 , 81.5 , 77.35, 84.7 , 79.88, 72.34, 60.39,
       84.57])

In [21]:
## Count correct predictions per class in test set for logistic regression with SGD optimizer in scikit-learn

test_sklearn_logreg_sgd_pred_count_per_class = prediction_count_per_class(
    test_labels, logreg.predict(test_dataset), nclasses
)

test_sklearn_logreg_sgd_pred_count_per_class


Out[21]:
array([845, 744, 896, 831, 836, 891, 852, 586, 503, 897])

In [22]:
## Compute prediction accuracy per class in train set for logistic regression with SGD optimizer in scikit-learn

test_sklearn_logreg_sgd_pred_score_per_class = np.round(100*test_sklearn_logreg_sgd_pred_count_per_class/test_bincount, 2)

test_sklearn_logreg_sgd_pred_score_per_class


Out[22]:
array([87.93, 83.41, 92.75, 92.54, 85.57, 92.43, 86.76, 83.  , 73.22,
       92.19])

In [23]:
## Plot prediction accuracy per class in train and test set for logistic regression with SGD optimizer in scikit-learn

plot_prediction_accuracy_per_class(
    [train_sklearn_logreg_sgd_pred_score_per_class, test_sklearn_logreg_sgd_pred_score_per_class], nclasses, 
    ('green', 'red'), ('Train set', 'Test set'), string.ascii_uppercase[:nclasses]
)


Generic functions for graph building and for session running in tensorflow


In [24]:
## Function for building a logistic regression model in tensorflow in the form of a graph

def build_logreg_model(nw, nclasses, initw, initb, board=()):
    graph = tf.get_default_graph()
    
    with graph.as_default():
        with tf.name_scope('data'):
            X = tf.placeholder(tf.float32, [None, nw]) # mnist data image of shape 28*28=784
            y = tf.placeholder(tf.float32, [None, nclasses]) # 0-9 digits recognition => 10 classes
            
        with tf.name_scope('parameters'):
            W = tf.Variable(initw)
            b = tf.Variable(initb)

        with tf.name_scope('outlayer'):
            outlayer = tf.matmul(X, W)+b

        if 'histogram' in board:
            with tf.name_scope('summaries') as summaries_scope:
                tf.summary.histogram('weights', W)
                tf.summary.histogram('bias', b)
            
    build = {'graph': graph, 'X': X, 'y': y, 'outlayer': outlayer}
    
    if 'histogram' in board:
        build['summaries_scope'] = summaries_scope
    
    return build

In [25]:
## Function for completing build of a graph in tensorflow given inputted model ('build' input argument)

def build_classifier_graph(build, optimizer, activation='softmax', monitor=(), board=()):
    monitor_predictions = ('accuracy', 'accuracy_per_class')
    has_monitor_predictions = any(p in monitor_predictions for p in monitor)
    
    with build['graph'].as_default():        
        with tf.name_scope('loss'):            
            if activation == 'softmax_with_logits':
                loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=build['y'], logits=build['outlayer']))
            elif activation == 'sigmoid_with_logits':
                loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits_v2(labels=build['y'], logits=build['outlayer']))
            elif activation == 'mse':
                loss = tf.losses.mean_squared_error(labels=build['y'], predictions=build['outlayer'])
            else:
                raise ValueError('Wrong value passed to activation input argument')
                
        with tf.name_scope('optimization'):
            optimization = optimizer.minimize(loss)

        if (has_monitor_predictions or ('accuracy' in board)):
            with tf.name_scope('predictions'):
                yargmax = tf.argmax(build['y'], 1)
                predictions = tf.argmax(tf.nn.softmax(build['outlayer']), 1)
                
                if ('accuracy' in board):
                    accuracy = tf.reduce_mean(tf.cast(tf.equal(predictions, yargmax), tf.float32))

        if board:
            summaries_scope = build['summaries_scope'] if ('summaries_scope' in build) else tf.name_scope('summaries')
            
            with tf.name_scope(summaries_scope):
                if 'loss' in board:
                    tf.summary.scalar('loss', loss)
                if 'accuracy' in board:
                    tf.summary.scalar('accuracy', accuracy)

                summaries = tf.summary.merge_all()

    build['loss'] = loss
    build['optimization'] = optimization
    
    if has_monitor_predictions:
        build['yargmax'] = yargmax
        build['predictions'] = predictions

    if board:
        build['summaries'] = summaries

In [26]:
## Function for running a session to train a model in tensorflow

def train_classifier(
    session, build, feed, ndata, batchsize, nclasses, nepochs,
    saver=None, restore=False, save=False, monitor=(), board=(), multibatchsize=100, permute=True,
    sessiondir=os.path.join('log', 'session'), boarddir=os.path.join('log', 'board'), verbose=False
):
    if restore:
        saver.restore(session, sessiondir)
    
    nbatches = ndata//batchsize
    nsteps = nepochs*nbatches
    epochsize = nbatches*batchsize

    monitor_predictions = ('accuracy', 'accuracy_per_class')
    has_monitor_predictions = any(p in monitor_predictions for p in monitor)
    
    if multibatchsize is None:
        multibatchsize = batchsize
        m = 1
    else:
        if (multibatchsize % batchsize) != 0:
            raise ValueError('multibatchsize must be a multiple of batchsize')
        else:
            m = multibatchsize//batchsize
      
    nmultibatches = (nepochs*epochsize)//multibatchsize

    fetches = []
    
    if monitor:
        if 'loss' in monitor:
            fetches.append(build['loss'])
            loss_within_multipbatch = np.empty((m,), dtype=np.float32)
            loss = np.empty((nmultibatches,), dtype=np.float32)
        
        if has_monitor_predictions:
            fetches.append(build['yargmax'])
            fetches.append(build['predictions'])
            
            yargmax = np.empty((multibatchsize,), dtype=np.float32)
            predictions = np.empty((multibatchsize,), dtype=np.float32)
            
            if 'accuracy' in monitor:
                accuracy = np.empty((nmultibatches,), dtype=np.float32)
            if 'accuracy_per_class' in monitor:
                nlabels_per_class = np.empty((nmultibatches, nclasses), dtype=np.int64)
                npredictions_per_class = np.empty((nmultibatches, nclasses), dtype=np.int64)
                accuracy_per_class = np.empty((nmultibatches, nclasses), dtype=np.float32)

    if board:
        fetches.append(build['summaries'])
        writer = tf.summary.FileWriter(boarddir, build['graph'])

    fetches.append(build['optimization'])
    
    fetches.reverse()
    
    if verbose:
        msg_template = "Multibach {:"+str(len(str(nmultibatches)))+"} of {:"+str(len(str(nmultibatches)))
        msg_template += "} with ending batch {:"+str(len(str(nbatches)))+"} of {:"+str(len(str(nbatches)))
        msg_template += "} in epoch {:"+str(len(str(nepochs)))+"} of {:"+str(len(str(nepochs)))+"}"
        
        if monitor:
            if 'loss' in monitor:
                msg_template += "\n  Loss: {:.3E}"
                
            if has_monitor_predictions:
                if 'accuracy' in monitor:
                    msg_template += "\n  Accuracy: {:.3f}"
                if 'accuracy_per_class' in monitor:
                    msg_template += "\n  Accuracy per class: "+", ".join(["{:.3f}" for _ in range(nclasses)])

    step = 0
    if monitor or verbose:
        i = 0 # i refers to the i-th multibach for storing monitored variables
        if monitor:
            j = 0 # j refers to the j-th batch within a multibach

    for epoch in range(nepochs):
        if permute:
            permutation = np.random.permutation(ndata)
            
        for batch in range(nbatches):
            batch_start = batch*batchsize
            batch_end = batch_start+batchsize

            if permute:
                batch_feed = {
                    build['X']: feed[build['X']][permutation[batch_start:batch_end], :],
                    build['y']: feed[build['y']][permutation[batch_start:batch_end]]
                }
            else:
                batch_feed = {
                    build['X']: feed[build['X']][batch_start:batch_end, :],
                    build['y']: feed[build['y']][batch_start:batch_end]
                }
                
            values = list(session.run(fetches=fetches, feed_dict=batch_feed))

            if monitor:
                j_batch_start = j*batchsize
                j_batch_end = j_batch_start+batchsize
                
                if 'loss' in monitor:
                    loss_within_multipbatch[j] = values.pop()
                
                if has_monitor_predictions:
                    yargmax[j_batch_start:j_batch_end] = values.pop()
                    predictions[j_batch_start:j_batch_end] = values.pop()
            
            if monitor or verbose:
                if ((step+1) % m) != 0:
                    if monitor:
                        j += 1
                else:
                    if monitor:
                        if 'loss' in monitor:
                            loss[i] = np.mean(loss_within_multipbatch)
                            
                        if has_monitor_predictions:
                            if 'accuracy' in monitor:
                                accuracy[i] = np.count_nonzero(yargmax == predictions)/multibatchsize
                            if 'accuracy_per_class' in monitor:
                                nlabels_per_class[i, :] = element_count_per_class(yargmax, nclasses)
                                npredictions_per_class[i, :] = prediction_count_per_class(yargmax, predictions, nclasses)
                                accuracy_per_class[i, :] = np.divide(npredictions_per_class[i, :], nlabels_per_class[i, :])
                    
                        j = 0

                    if verbose:
                        msg_args = [i+1, nmultibatches, batch+1, nbatches, epoch+1, nepochs]
                
                        if monitor:
                            if 'loss' in monitor:
                                msg_args.append(loss[i])
                                
                            if has_monitor_predictions:
                                if 'accuracy' in monitor:
                                    msg_args.append(accuracy[i])
                                if 'accuracy_per_class' in monitor:
                                    msg_args.extend(accuracy_per_class[i, :])

                        print(msg_template.format(*msg_args))

                    i += 1

            if board:
                writer.add_summary(values.pop(), step)
                
            step += 1

    output = {}
    
    if monitor:
        if 'loss' in monitor:
            output['loss'] = loss
            
        if has_monitor_predictions:
            if 'accuracy' in monitor:
                output['accuracy'] = accuracy
            if 'accuracy_per_class' in monitor:
                output['nlabels_per_class'] = nlabels_per_class
                output['npredictions_per_class'] = npredictions_per_class
                output['accuracy_per_class'] = accuracy_per_class

    if save:
        saver.save(session, sessiondir)
    
    return output

In [27]:
## Function for running a session to evaluate a model on a test set in tensorflow

def evaluate_classifier(
    session, saver, build, feed, batchsize, nclasses,
    monitor=('accuracy'), sessiondir=os.path.join('log', 'session'), verbose=False
):
    saver.restore(session, sessiondir)
    
    monitor_predictions = ('accuracy', 'accuracy_per_class')
    has_monitor_predictions = any(p in monitor_predictions for p in monitor)
    
    fetches = []

    if monitor:
        if 'loss' in monitor:
            fetches.append(build['loss'])
            
        if has_monitor_predictions:
            fetches.append(build['yargmax'])
            fetches.append(build['predictions'])

    fetches.append(build['optimization'])
    
    fetches.reverse()

    values = list(session.run(fetches=fetches, feed_dict=feed))
                        
    if monitor:
        if 'loss' in monitor:
            loss = values.pop()
            
        if has_monitor_predictions:
            yargmax = values.pop()
            predictions = values.pop()

            if 'accuracy' in monitor:
                accuracy = np.count_nonzero(yargmax == predictions)/batchsize
            if 'accuracy_per_class' in monitor:
                nlabels_per_class = element_count_per_class(yargmax, nclasses)
                npredictions_per_class = prediction_count_per_class(yargmax, predictions, nclasses)
                accuracy_per_class = np.divide(npredictions_per_class, nlabels_per_class)

    if verbose:
        msg_template = "Evaluating model..."
        msg_args = []
        
        if monitor:
            if 'loss' in monitor:
                msg_template += "\n  Loss: {:.3E}"
                msg_args.append(loss)

            if has_monitor_predictions:
                if 'accuracy' in monitor:
                    msg_template += "\n  Accuracy: {:.3f}"
                    msg_args.append(accuracy)
                if 'accuracy_per_class' in monitor:
                    msg_template += "\n  Accuracy per class: "+", ".join(["{:.3f}" for _ in range(nclasses)])
                    msg_args.extend(accuracy_per_class)
                
        msg_template += "\nModel evaluation completed"

        print(msg_template.format(*msg_args))
     
    output = {}
    
    if monitor:
        if 'loss' in monitor:
            output['loss'] = loss
            
        if has_monitor_predictions:
            if 'accuracy' in monitor:
                output['accuracy'] = accuracy
            if 'accuracy_per_class' in monitor:
                output['nlabels_per_class'] = nlabels_per_class
                output['npredictions_per_class'] = npredictions_per_class
                output['accuracy_per_class'] = accuracy_per_class

    return output

In [28]:
## Function for plotting loss returned as output['loss'] by train()

def plot_loss(loss, marker=None, markersize=5, color='C0', show=True):    
    plt.plot(np.arange(loss.size)+1, loss, marker=marker, markersize=5, color=color)

    plt.xlabel('Step')
    plt.ylabel('Loss')

    if show:
        plt.show()

In [29]:
## Function for plotting accuracy returned as output['accuracy'] by train()

def plot_accuracy(accuracy, marker=None, markersize=5, color='C0', show=True):    
    plt.plot(np.arange(accuracy.size)+1, accuracy, marker=marker, markersize=5, color=color)

    plt.ylim([0, 1])
    
    plt.xlabel('Step')
    plt.ylabel('Accuracy')

    if show:
        plt.show()

Logistic regression with gradient descent using tensorflow

Recall that the data have been standardized before feeding them to the model. Data standardization can speed up the convergence of the gradient descent optimizer by orders of magnitude. The batchsize is set to be equal to the size of the train set (by setting batchsize = train_dataset.shape[0] below), so the optimizer uses all the data at each iteration, hence the optimization is not stochastic.

Notice below that the batchsize is set to be equal to the size of the train set (ndata = train_dataset.shape[0] and batchsize = ndata). Since the batchsize concides with an epoch, every iteration uses the whole train set, so the optimizer is not stochastic. 1000 epochs are run (nepochs=1000), while results are printed and stored for each multibatch consisting of 10 batches-epochs (multibatchsize=10*ndata).

Multibatches are utilized for reducing the amount of monitoring information printed and stored during training. In the example below, results are printed for 100 multibatches, each containing 10 epochs, instead of printing results for all 1000 epochs.

For every multibatch of 10 epochs, the loss, prediction accuracy and prediction accuracy per class are reported. Since the number of samples is not the same for all classes, the accuracy is a weighted average of the per-class accuracies in each multibatch.


In [30]:
## Reset default graph

tf.reset_default_graph()

In [31]:
## Build graph for logistic regression on train set with gradient descent using tensorflow

# Initialize logistic regression parameters
initw = tf.truncated_normal([npixels, nclasses])
initb = tf.zeros([nclasses])

# Specify what will be monitored and what will be stored in tensorboard
monitor = ('loss', 'accuracy', 'accuracy_per_class') # To select a single summary, say 'accuracy', set monitor = ('accuracy',)
board = ('loss', 'accuracy', 'histogram')

# Build graph
build = build_logreg_model(npixels, nclasses, initw, initb, board=board)
build_classifier_graph(build, tf.train.GradientDescentOptimizer(0.1), activation='softmax_with_logits', monitor=monitor, board=board)

To check the graph version, run the command build['graph'].version.


In [32]:
## Run session to train logistic regression model with gradient descent in tensorflow

ndata = train_dataset.shape[0]
batchsize = ndata # Batch size is equal to the size of the train set, so non-stochastic gradient descent is run

# Set up dictionary feed
feed = {build['X']: train_dataset[0:ndata, :], build['y']: onehot_train_labels[0:ndata]}

nepochs = 1000 # Go through the training set 1000 times
multibatchsize = 10*ndata # Stored monitored output every 100-th step (summaries per 100 epochs)

# Initialize session
session = tf.Session(graph=build['graph'])

# Initialize saver
saver = tf.train.Saver(max_to_keep=5)

# Train the classifier
with session.as_default():
    # Initialize saver
    saver = tf.train.Saver(max_to_keep=5)
    
    # Initialize variables
    session.run(tf.global_variables_initializer())
    
    start_time = time.process_time()
    train_output = train_classifier(
        session, build, feed, ndata, batchsize, nclasses, nepochs,
        saver=saver, save=True, monitor=monitor, board=board, multibatchsize=multibatchsize,
        permute=False,
        sessiondir=os.path.join('log', 'session', 'logreg_gd'),
        boarddir=os.path.join('log', 'board', 'logreg_gd'),
        verbose=True
    )
    end_time = time.process_time()
    tf_logreg_gd_time = end_time-start_time

print('\nTrain logistic regression model with gradient descent using tensorflow')
print('Time ellapsed: %f seconds' % tf_logreg_gd_time)


Multibach   1 of 100 with ending batch 1 of 1 in epoch   10 of 1000
  Loss: 1.343E+01
  Accuracy: 0.146
  Accuracy per class: 0.380, 0.266, 0.222, 0.078, 0.027, 0.078, 0.045, 0.136, 0.191, 0.060
Multibach   2 of 100 with ending batch 1 of 1 in epoch   20 of 1000
  Loss: 1.031E+01
  Accuracy: 0.204
  Accuracy per class: 0.424, 0.307, 0.312, 0.136, 0.053, 0.198, 0.081, 0.153, 0.244, 0.146
Multibach   3 of 100 with ending batch 1 of 1 in epoch   30 of 1000
  Loss: 8.411E+00
  Accuracy: 0.260
  Accuracy per class: 0.454, 0.342, 0.355, 0.197, 0.095, 0.297, 0.159, 0.170, 0.274, 0.246
Multibach   4 of 100 with ending batch 1 of 1 in epoch   40 of 1000
  Loss: 7.164E+00
  Accuracy: 0.315
  Accuracy per class: 0.481, 0.374, 0.384, 0.259, 0.157, 0.364, 0.248, 0.191, 0.294, 0.354
Multibach   5 of 100 with ending batch 1 of 1 in epoch   50 of 1000
  Loss: 6.327E+00
  Accuracy: 0.363
  Accuracy per class: 0.504, 0.401, 0.414, 0.324, 0.222, 0.413, 0.323, 0.216, 0.314, 0.437
Multibach   6 of 100 with ending batch 1 of 1 in epoch   60 of 1000
  Loss: 5.741E+00
  Accuracy: 0.402
  Accuracy per class: 0.527, 0.422, 0.443, 0.381, 0.277, 0.450, 0.377, 0.246, 0.331, 0.493
Multibach   7 of 100 with ending batch 1 of 1 in epoch   70 of 1000
  Loss: 5.312E+00
  Accuracy: 0.434
  Accuracy per class: 0.545, 0.440, 0.474, 0.429, 0.323, 0.480, 0.418, 0.276, 0.346, 0.530
Multibach   8 of 100 with ending batch 1 of 1 in epoch   80 of 1000
  Loss: 4.985E+00
  Accuracy: 0.460
  Accuracy per class: 0.560, 0.457, 0.503, 0.467, 0.357, 0.507, 0.450, 0.302, 0.358, 0.555
Multibach   9 of 100 with ending batch 1 of 1 in epoch   90 of 1000
  Loss: 4.728E+00
  Accuracy: 0.481
  Accuracy per class: 0.572, 0.472, 0.530, 0.496, 0.385, 0.529, 0.475, 0.326, 0.370, 0.574
Multibach  10 of 100 with ending batch 1 of 1 in epoch  100 of 1000
  Loss: 4.521E+00
  Accuracy: 0.500
  Accuracy per class: 0.583, 0.486, 0.551, 0.520, 0.410, 0.548, 0.496, 0.346, 0.382, 0.591
Multibach  11 of 100 with ending batch 1 of 1 in epoch  110 of 1000
  Loss: 4.350E+00
  Accuracy: 0.516
  Accuracy per class: 0.593, 0.497, 0.569, 0.540, 0.432, 0.566, 0.513, 0.365, 0.391, 0.604
Multibach  12 of 100 with ending batch 1 of 1 in epoch  120 of 1000
  Loss: 4.207E+00
  Accuracy: 0.530
  Accuracy per class: 0.600, 0.508, 0.585, 0.555, 0.452, 0.583, 0.529, 0.381, 0.401, 0.615
Multibach  13 of 100 with ending batch 1 of 1 in epoch  130 of 1000
  Loss: 4.085E+00
  Accuracy: 0.542
  Accuracy per class: 0.606, 0.518, 0.598, 0.568, 0.468, 0.598, 0.542, 0.396, 0.411, 0.623
Multibach  14 of 100 with ending batch 1 of 1 in epoch  140 of 1000
  Loss: 3.980E+00
  Accuracy: 0.552
  Accuracy per class: 0.613, 0.526, 0.610, 0.579, 0.482, 0.610, 0.554, 0.409, 0.419, 0.632
Multibach  15 of 100 with ending batch 1 of 1 in epoch  150 of 1000
  Loss: 3.888E+00
  Accuracy: 0.562
  Accuracy per class: 0.619, 0.534, 0.620, 0.589, 0.494, 0.621, 0.564, 0.421, 0.427, 0.638
Multibach  16 of 100 with ending batch 1 of 1 in epoch  160 of 1000
  Loss: 3.807E+00
  Accuracy: 0.570
  Accuracy per class: 0.624, 0.541, 0.631, 0.599, 0.506, 0.631, 0.572, 0.430, 0.433, 0.644
Multibach  17 of 100 with ending batch 1 of 1 in epoch  170 of 1000
  Loss: 3.734E+00
  Accuracy: 0.577
  Accuracy per class: 0.628, 0.547, 0.638, 0.606, 0.516, 0.640, 0.580, 0.440, 0.439, 0.650
Multibach  18 of 100 with ending batch 1 of 1 in epoch  180 of 1000
  Loss: 3.668E+00
  Accuracy: 0.584
  Accuracy per class: 0.633, 0.554, 0.645, 0.614, 0.525, 0.649, 0.587, 0.449, 0.445, 0.655
Multibach  19 of 100 with ending batch 1 of 1 in epoch  190 of 1000
  Loss: 3.609E+00
  Accuracy: 0.591
  Accuracy per class: 0.637, 0.560, 0.652, 0.621, 0.534, 0.655, 0.593, 0.457, 0.450, 0.660
Multibach  20 of 100 with ending batch 1 of 1 in epoch  200 of 1000
  Loss: 3.555E+00
  Accuracy: 0.596
  Accuracy per class: 0.641, 0.564, 0.657, 0.626, 0.542, 0.661, 0.599, 0.466, 0.455, 0.664
Multibach  21 of 100 with ending batch 1 of 1 in epoch  210 of 1000
  Loss: 3.505E+00
  Accuracy: 0.602
  Accuracy per class: 0.644, 0.569, 0.662, 0.631, 0.549, 0.667, 0.605, 0.473, 0.459, 0.668
Multibach  22 of 100 with ending batch 1 of 1 in epoch  220 of 1000
  Loss: 3.459E+00
  Accuracy: 0.606
  Accuracy per class: 0.647, 0.574, 0.667, 0.635, 0.554, 0.673, 0.610, 0.478, 0.461, 0.672
Multibach  23 of 100 with ending batch 1 of 1 in epoch  230 of 1000
  Loss: 3.416E+00
  Accuracy: 0.611
  Accuracy per class: 0.650, 0.578, 0.672, 0.640, 0.560, 0.679, 0.614, 0.485, 0.463, 0.676
Multibach  24 of 100 with ending batch 1 of 1 in epoch  240 of 1000
  Loss: 3.376E+00
  Accuracy: 0.615
  Accuracy per class: 0.654, 0.582, 0.676, 0.645, 0.565, 0.682, 0.619, 0.491, 0.465, 0.678
Multibach  25 of 100 with ending batch 1 of 1 in epoch  250 of 1000
  Loss: 3.339E+00
  Accuracy: 0.618
  Accuracy per class: 0.657, 0.587, 0.680, 0.648, 0.569, 0.686, 0.623, 0.495, 0.467, 0.681
Multibach  26 of 100 with ending batch 1 of 1 in epoch  260 of 1000
  Loss: 3.304E+00
  Accuracy: 0.622
  Accuracy per class: 0.660, 0.590, 0.684, 0.651, 0.573, 0.690, 0.627, 0.499, 0.468, 0.684
Multibach  27 of 100 with ending batch 1 of 1 in epoch  270 of 1000
  Loss: 3.270E+00
  Accuracy: 0.625
  Accuracy per class: 0.662, 0.593, 0.687, 0.654, 0.577, 0.694, 0.631, 0.503, 0.470, 0.686
Multibach  28 of 100 with ending batch 1 of 1 in epoch  280 of 1000
  Loss: 3.239E+00
  Accuracy: 0.628
  Accuracy per class: 0.665, 0.596, 0.690, 0.657, 0.582, 0.696, 0.635, 0.507, 0.471, 0.688
Multibach  29 of 100 with ending batch 1 of 1 in epoch  290 of 1000
  Loss: 3.209E+00
  Accuracy: 0.630
  Accuracy per class: 0.667, 0.598, 0.694, 0.658, 0.586, 0.698, 0.638, 0.511, 0.472, 0.689
Multibach  30 of 100 with ending batch 1 of 1 in epoch  300 of 1000
  Loss: 3.181E+00
  Accuracy: 0.633
  Accuracy per class: 0.670, 0.601, 0.696, 0.661, 0.589, 0.701, 0.641, 0.515, 0.474, 0.692
Multibach  31 of 100 with ending batch 1 of 1 in epoch  310 of 1000
  Loss: 3.154E+00
  Accuracy: 0.635
  Accuracy per class: 0.671, 0.604, 0.699, 0.663, 0.591, 0.704, 0.644, 0.519, 0.475, 0.693
Multibach  32 of 100 with ending batch 1 of 1 in epoch  320 of 1000
  Loss: 3.129E+00
  Accuracy: 0.638
  Accuracy per class: 0.673, 0.607, 0.701, 0.665, 0.594, 0.707, 0.647, 0.522, 0.476, 0.695
Multibach  33 of 100 with ending batch 1 of 1 in epoch  330 of 1000
  Loss: 3.104E+00
  Accuracy: 0.640
  Accuracy per class: 0.675, 0.610, 0.703, 0.668, 0.597, 0.709, 0.650, 0.525, 0.477, 0.697
Multibach  34 of 100 with ending batch 1 of 1 in epoch  340 of 1000
  Loss: 3.080E+00
  Accuracy: 0.643
  Accuracy per class: 0.678, 0.613, 0.705, 0.670, 0.599, 0.711, 0.652, 0.528, 0.478, 0.700
Multibach  35 of 100 with ending batch 1 of 1 in epoch  350 of 1000
  Loss: 3.058E+00
  Accuracy: 0.645
  Accuracy per class: 0.680, 0.615, 0.707, 0.672, 0.602, 0.713, 0.655, 0.532, 0.479, 0.701
Multibach  36 of 100 with ending batch 1 of 1 in epoch  360 of 1000
  Loss: 3.036E+00
  Accuracy: 0.647
  Accuracy per class: 0.681, 0.617, 0.709, 0.674, 0.604, 0.714, 0.658, 0.535, 0.480, 0.702
Multibach  37 of 100 with ending batch 1 of 1 in epoch  370 of 1000
  Loss: 3.015E+00
  Accuracy: 0.648
  Accuracy per class: 0.683, 0.619, 0.710, 0.676, 0.606, 0.716, 0.660, 0.539, 0.481, 0.703
Multibach  38 of 100 with ending batch 1 of 1 in epoch  380 of 1000
  Loss: 2.995E+00
  Accuracy: 0.650
  Accuracy per class: 0.684, 0.620, 0.712, 0.677, 0.608, 0.718, 0.662, 0.541, 0.482, 0.704
Multibach  39 of 100 with ending batch 1 of 1 in epoch  390 of 1000
  Loss: 2.975E+00
  Accuracy: 0.652
  Accuracy per class: 0.685, 0.622, 0.713, 0.678, 0.610, 0.720, 0.664, 0.544, 0.483, 0.705
Multibach  40 of 100 with ending batch 1 of 1 in epoch  400 of 1000
  Loss: 2.956E+00
  Accuracy: 0.653
  Accuracy per class: 0.686, 0.623, 0.715, 0.679, 0.611, 0.721, 0.666, 0.547, 0.484, 0.706
Multibach  41 of 100 with ending batch 1 of 1 in epoch  410 of 1000
  Loss: 2.938E+00
  Accuracy: 0.655
  Accuracy per class: 0.688, 0.625, 0.716, 0.680, 0.613, 0.723, 0.668, 0.549, 0.485, 0.707
Multibach  42 of 100 with ending batch 1 of 1 in epoch  420 of 1000
  Loss: 2.920E+00
  Accuracy: 0.656
  Accuracy per class: 0.689, 0.627, 0.718, 0.682, 0.615, 0.724, 0.670, 0.551, 0.485, 0.708
Multibach  43 of 100 with ending batch 1 of 1 in epoch  430 of 1000
  Loss: 2.902E+00
  Accuracy: 0.657
  Accuracy per class: 0.691, 0.628, 0.719, 0.683, 0.617, 0.725, 0.672, 0.553, 0.486, 0.709
Multibach  44 of 100 with ending batch 1 of 1 in epoch  440 of 1000
  Loss: 2.886E+00
  Accuracy: 0.659
  Accuracy per class: 0.692, 0.629, 0.721, 0.684, 0.619, 0.726, 0.673, 0.555, 0.487, 0.710
Multibach  45 of 100 with ending batch 1 of 1 in epoch  450 of 1000
  Loss: 2.869E+00
  Accuracy: 0.660
  Accuracy per class: 0.692, 0.631, 0.722, 0.685, 0.620, 0.727, 0.675, 0.557, 0.488, 0.711
Multibach  46 of 100 with ending batch 1 of 1 in epoch  460 of 1000
  Loss: 2.853E+00
  Accuracy: 0.661
  Accuracy per class: 0.693, 0.632, 0.723, 0.686, 0.622, 0.728, 0.676, 0.558, 0.489, 0.711
Multibach  47 of 100 with ending batch 1 of 1 in epoch  470 of 1000
  Loss: 2.838E+00
  Accuracy: 0.662
  Accuracy per class: 0.694, 0.633, 0.723, 0.687, 0.623, 0.728, 0.678, 0.559, 0.489, 0.711
Multibach  48 of 100 with ending batch 1 of 1 in epoch  480 of 1000
  Loss: 2.823E+00
  Accuracy: 0.663
  Accuracy per class: 0.695, 0.634, 0.724, 0.688, 0.624, 0.729, 0.679, 0.561, 0.490, 0.712
Multibach  49 of 100 with ending batch 1 of 1 in epoch  490 of 1000
  Loss: 2.808E+00
  Accuracy: 0.664
  Accuracy per class: 0.696, 0.636, 0.725, 0.689, 0.625, 0.730, 0.680, 0.562, 0.490, 0.713
Multibach  50 of 100 with ending batch 1 of 1 in epoch  500 of 1000
  Loss: 2.794E+00
  Accuracy: 0.665
  Accuracy per class: 0.698, 0.637, 0.726, 0.690, 0.626, 0.731, 0.682, 0.564, 0.491, 0.714
Multibach  51 of 100 with ending batch 1 of 1 in epoch  510 of 1000
  Loss: 2.779E+00
  Accuracy: 0.666
  Accuracy per class: 0.699, 0.637, 0.727, 0.690, 0.627, 0.732, 0.683, 0.565, 0.492, 0.715
Multibach  52 of 100 with ending batch 1 of 1 in epoch  520 of 1000
  Loss: 2.766E+00
  Accuracy: 0.667
  Accuracy per class: 0.700, 0.638, 0.728, 0.691, 0.628, 0.732, 0.684, 0.567, 0.492, 0.716
Multibach  53 of 100 with ending batch 1 of 1 in epoch  530 of 1000
  Loss: 2.752E+00
  Accuracy: 0.668
  Accuracy per class: 0.701, 0.639, 0.729, 0.691, 0.630, 0.733, 0.685, 0.568, 0.493, 0.716
Multibach  54 of 100 with ending batch 1 of 1 in epoch  540 of 1000
  Loss: 2.739E+00
  Accuracy: 0.669
  Accuracy per class: 0.702, 0.640, 0.730, 0.692, 0.631, 0.733, 0.686, 0.569, 0.494, 0.717
Multibach  55 of 100 with ending batch 1 of 1 in epoch  550 of 1000
  Loss: 2.726E+00
  Accuracy: 0.669
  Accuracy per class: 0.702, 0.641, 0.731, 0.693, 0.632, 0.733, 0.687, 0.570, 0.495, 0.717
Multibach  56 of 100 with ending batch 1 of 1 in epoch  560 of 1000
  Loss: 2.714E+00
  Accuracy: 0.670
  Accuracy per class: 0.704, 0.642, 0.732, 0.694, 0.633, 0.734, 0.688, 0.571, 0.496, 0.718
Multibach  57 of 100 with ending batch 1 of 1 in epoch  570 of 1000
  Loss: 2.701E+00
  Accuracy: 0.671
  Accuracy per class: 0.705, 0.643, 0.733, 0.695, 0.634, 0.735, 0.689, 0.573, 0.496, 0.719
Multibach  58 of 100 with ending batch 1 of 1 in epoch  580 of 1000
  Loss: 2.689E+00
  Accuracy: 0.672
  Accuracy per class: 0.705, 0.644, 0.733, 0.695, 0.635, 0.735, 0.690, 0.574, 0.496, 0.720
Multibach  59 of 100 with ending batch 1 of 1 in epoch  590 of 1000
  Loss: 2.677E+00
  Accuracy: 0.673
  Accuracy per class: 0.705, 0.645, 0.734, 0.696, 0.636, 0.736, 0.691, 0.575, 0.496, 0.721
Multibach  60 of 100 with ending batch 1 of 1 in epoch  600 of 1000
  Loss: 2.666E+00
  Accuracy: 0.673
  Accuracy per class: 0.706, 0.646, 0.734, 0.697, 0.636, 0.737, 0.692, 0.577, 0.497, 0.721
Multibach  61 of 100 with ending batch 1 of 1 in epoch  610 of 1000
  Loss: 2.654E+00
  Accuracy: 0.674
  Accuracy per class: 0.707, 0.647, 0.735, 0.698, 0.637, 0.737, 0.693, 0.577, 0.497, 0.722
Multibach  62 of 100 with ending batch 1 of 1 in epoch  620 of 1000
  Loss: 2.643E+00
  Accuracy: 0.675
  Accuracy per class: 0.707, 0.648, 0.736, 0.698, 0.638, 0.738, 0.694, 0.578, 0.497, 0.723
Multibach  63 of 100 with ending batch 1 of 1 in epoch  630 of 1000
  Loss: 2.632E+00
  Accuracy: 0.676
  Accuracy per class: 0.708, 0.649, 0.736, 0.699, 0.638, 0.738, 0.694, 0.579, 0.498, 0.723
Multibach  64 of 100 with ending batch 1 of 1 in epoch  640 of 1000
  Loss: 2.621E+00
  Accuracy: 0.676
  Accuracy per class: 0.709, 0.650, 0.737, 0.700, 0.639, 0.739, 0.695, 0.580, 0.499, 0.724
Multibach  65 of 100 with ending batch 1 of 1 in epoch  650 of 1000
  Loss: 2.611E+00
  Accuracy: 0.677
  Accuracy per class: 0.709, 0.651, 0.738, 0.701, 0.640, 0.739, 0.696, 0.581, 0.499, 0.724
Multibach  66 of 100 with ending batch 1 of 1 in epoch  660 of 1000
  Loss: 2.600E+00
  Accuracy: 0.678
  Accuracy per class: 0.710, 0.651, 0.739, 0.702, 0.641, 0.740, 0.697, 0.582, 0.500, 0.725
Multibach  67 of 100 with ending batch 1 of 1 in epoch  670 of 1000
  Loss: 2.590E+00
  Accuracy: 0.678
  Accuracy per class: 0.711, 0.652, 0.739, 0.702, 0.642, 0.740, 0.698, 0.583, 0.501, 0.725
Multibach  68 of 100 with ending batch 1 of 1 in epoch  680 of 1000
  Loss: 2.580E+00
  Accuracy: 0.679
  Accuracy per class: 0.711, 0.652, 0.739, 0.703, 0.643, 0.741, 0.699, 0.584, 0.501, 0.726
Multibach  69 of 100 with ending batch 1 of 1 in epoch  690 of 1000
  Loss: 2.570E+00
  Accuracy: 0.679
  Accuracy per class: 0.712, 0.653, 0.740, 0.703, 0.643, 0.741, 0.700, 0.585, 0.501, 0.726
Multibach  70 of 100 with ending batch 1 of 1 in epoch  700 of 1000
  Loss: 2.560E+00
  Accuracy: 0.680
  Accuracy per class: 0.713, 0.653, 0.741, 0.703, 0.643, 0.742, 0.701, 0.586, 0.501, 0.726
Multibach  71 of 100 with ending batch 1 of 1 in epoch  710 of 1000
  Loss: 2.550E+00
  Accuracy: 0.680
  Accuracy per class: 0.713, 0.654, 0.741, 0.704, 0.644, 0.742, 0.701, 0.586, 0.502, 0.727
Multibach  72 of 100 with ending batch 1 of 1 in epoch  720 of 1000
  Loss: 2.541E+00
  Accuracy: 0.681
  Accuracy per class: 0.714, 0.655, 0.742, 0.704, 0.645, 0.742, 0.702, 0.587, 0.502, 0.727
Multibach  73 of 100 with ending batch 1 of 1 in epoch  730 of 1000
  Loss: 2.532E+00
  Accuracy: 0.681
  Accuracy per class: 0.714, 0.655, 0.742, 0.704, 0.645, 0.742, 0.702, 0.588, 0.503, 0.727
Multibach  74 of 100 with ending batch 1 of 1 in epoch  740 of 1000
  Loss: 2.522E+00
  Accuracy: 0.682
  Accuracy per class: 0.715, 0.656, 0.743, 0.705, 0.646, 0.743, 0.703, 0.588, 0.503, 0.728
Multibach  75 of 100 with ending batch 1 of 1 in epoch  750 of 1000
  Loss: 2.513E+00
  Accuracy: 0.683
  Accuracy per class: 0.716, 0.657, 0.743, 0.705, 0.647, 0.743, 0.703, 0.589, 0.504, 0.728
Multibach  76 of 100 with ending batch 1 of 1 in epoch  760 of 1000
  Loss: 2.504E+00
  Accuracy: 0.683
  Accuracy per class: 0.716, 0.657, 0.744, 0.706, 0.647, 0.744, 0.703, 0.589, 0.504, 0.729
Multibach  77 of 100 with ending batch 1 of 1 in epoch  770 of 1000
  Loss: 2.496E+00
  Accuracy: 0.684
  Accuracy per class: 0.717, 0.658, 0.745, 0.706, 0.647, 0.745, 0.704, 0.590, 0.505, 0.729
Multibach  78 of 100 with ending batch 1 of 1 in epoch  780 of 1000
  Loss: 2.487E+00
  Accuracy: 0.684
  Accuracy per class: 0.717, 0.658, 0.745, 0.706, 0.648, 0.745, 0.705, 0.590, 0.505, 0.730
Multibach  79 of 100 with ending batch 1 of 1 in epoch  790 of 1000
  Loss: 2.478E+00
  Accuracy: 0.684
  Accuracy per class: 0.717, 0.658, 0.746, 0.706, 0.648, 0.746, 0.705, 0.591, 0.506, 0.730
Multibach  80 of 100 with ending batch 1 of 1 in epoch  800 of 1000
  Loss: 2.470E+00
  Accuracy: 0.685
  Accuracy per class: 0.718, 0.659, 0.746, 0.706, 0.648, 0.746, 0.706, 0.592, 0.506, 0.731
Multibach  81 of 100 with ending batch 1 of 1 in epoch  810 of 1000
  Loss: 2.462E+00
  Accuracy: 0.685
  Accuracy per class: 0.718, 0.659, 0.746, 0.706, 0.649, 0.746, 0.706, 0.592, 0.506, 0.731
Multibach  82 of 100 with ending batch 1 of 1 in epoch  820 of 1000
  Loss: 2.453E+00
  Accuracy: 0.686
  Accuracy per class: 0.718, 0.659, 0.747, 0.706, 0.649, 0.747, 0.706, 0.593, 0.507, 0.732
Multibach  83 of 100 with ending batch 1 of 1 in epoch  830 of 1000
  Loss: 2.445E+00
  Accuracy: 0.686
  Accuracy per class: 0.719, 0.660, 0.747, 0.707, 0.649, 0.747, 0.707, 0.594, 0.507, 0.732
Multibach  84 of 100 with ending batch 1 of 1 in epoch  840 of 1000
  Loss: 2.437E+00
  Accuracy: 0.686
  Accuracy per class: 0.719, 0.660, 0.747, 0.707, 0.650, 0.747, 0.707, 0.595, 0.508, 0.732
Multibach  85 of 100 with ending batch 1 of 1 in epoch  850 of 1000
  Loss: 2.429E+00
  Accuracy: 0.687
  Accuracy per class: 0.720, 0.660, 0.748, 0.707, 0.650, 0.747, 0.707, 0.596, 0.508, 0.733
Multibach  86 of 100 with ending batch 1 of 1 in epoch  860 of 1000
  Loss: 2.422E+00
  Accuracy: 0.687
  Accuracy per class: 0.720, 0.661, 0.749, 0.708, 0.650, 0.748, 0.707, 0.597, 0.509, 0.733
Multibach  87 of 100 with ending batch 1 of 1 in epoch  870 of 1000
  Loss: 2.414E+00
  Accuracy: 0.688
  Accuracy per class: 0.721, 0.661, 0.749, 0.708, 0.651, 0.748, 0.708, 0.597, 0.509, 0.733
Multibach  88 of 100 with ending batch 1 of 1 in epoch  880 of 1000
  Loss: 2.406E+00
  Accuracy: 0.688
  Accuracy per class: 0.721, 0.661, 0.750, 0.708, 0.651, 0.748, 0.708, 0.597, 0.510, 0.734
Multibach  89 of 100 with ending batch 1 of 1 in epoch  890 of 1000
  Loss: 2.399E+00
  Accuracy: 0.688
  Accuracy per class: 0.721, 0.661, 0.750, 0.708, 0.652, 0.749, 0.709, 0.598, 0.510, 0.734
Multibach  90 of 100 with ending batch 1 of 1 in epoch  900 of 1000
  Loss: 2.392E+00
  Accuracy: 0.689
  Accuracy per class: 0.722, 0.662, 0.750, 0.709, 0.652, 0.749, 0.709, 0.598, 0.510, 0.735
Multibach  91 of 100 with ending batch 1 of 1 in epoch  910 of 1000
  Loss: 2.384E+00
  Accuracy: 0.689
  Accuracy per class: 0.722, 0.662, 0.750, 0.709, 0.652, 0.749, 0.709, 0.599, 0.511, 0.735
Multibach  92 of 100 with ending batch 1 of 1 in epoch  920 of 1000
  Loss: 2.377E+00
  Accuracy: 0.689
  Accuracy per class: 0.722, 0.662, 0.750, 0.709, 0.653, 0.750, 0.710, 0.599, 0.511, 0.735
Multibach  93 of 100 with ending batch 1 of 1 in epoch  930 of 1000
  Loss: 2.370E+00
  Accuracy: 0.689
  Accuracy per class: 0.723, 0.663, 0.750, 0.710, 0.653, 0.750, 0.710, 0.599, 0.512, 0.736
Multibach  94 of 100 with ending batch 1 of 1 in epoch  940 of 1000
  Loss: 2.363E+00
  Accuracy: 0.690
  Accuracy per class: 0.723, 0.663, 0.751, 0.710, 0.653, 0.750, 0.710, 0.600, 0.512, 0.736
Multibach  95 of 100 with ending batch 1 of 1 in epoch  950 of 1000
  Loss: 2.356E+00
  Accuracy: 0.690
  Accuracy per class: 0.723, 0.663, 0.751, 0.710, 0.654, 0.750, 0.710, 0.600, 0.513, 0.736
Multibach  96 of 100 with ending batch 1 of 1 in epoch  960 of 1000
  Loss: 2.349E+00
  Accuracy: 0.690
  Accuracy per class: 0.724, 0.663, 0.751, 0.710, 0.654, 0.750, 0.711, 0.601, 0.512, 0.737
Multibach  97 of 100 with ending batch 1 of 1 in epoch  970 of 1000
  Loss: 2.342E+00
  Accuracy: 0.691
  Accuracy per class: 0.724, 0.664, 0.751, 0.710, 0.654, 0.751, 0.711, 0.602, 0.513, 0.737
Multibach  98 of 100 with ending batch 1 of 1 in epoch  980 of 1000
  Loss: 2.336E+00
  Accuracy: 0.691
  Accuracy per class: 0.724, 0.664, 0.751, 0.711, 0.654, 0.751, 0.711, 0.603, 0.514, 0.737
Multibach  99 of 100 with ending batch 1 of 1 in epoch  990 of 1000
  Loss: 2.329E+00
  Accuracy: 0.691
  Accuracy per class: 0.725, 0.664, 0.752, 0.711, 0.655, 0.751, 0.711, 0.603, 0.514, 0.737
Multibach 100 of 100 with ending batch 1 of 1 in epoch 1000 of 1000
  Loss: 2.322E+00
  Accuracy: 0.691
  Accuracy per class: 0.725, 0.664, 0.752, 0.711, 0.655, 0.751, 0.711, 0.603, 0.514, 0.737

Train logistic regression model with gradient descent using tensorflow
Time ellapsed: 1079.136537 seconds

In [33]:
## Plot loss for logistic regression on train set with gradient descent in tensorflow

plot_loss(train_output['loss'], marker='o')



In [34]:
## Plot accuracy for logistic regression on train set with gradient descent in tensorflow

plot_accuracy(train_output['accuracy'], marker='o')



In [35]:
## Count number of samples per class in train set for logistic regression with gradient descent in tensorflow

train_tf_logreg_gd_element_count_per_class = np.sum(train_output['nlabels_per_class'], axis=0)

train_tf_logreg_gd_element_count_per_class


Out[35]:
array([15856000, 14717000, 17124000, 14387000, 16481000, 16435000,
       17502000, 11206000, 11074000, 16567000])

In [36]:
## Count correct predictions per class in train set for logistic regression with gradient descent in TensorFlow

train_tf_logreg_gd_pred_count_per_class = np.sum(train_output['npredictions_per_class'], axis=0)

train_tf_logreg_gd_pred_count_per_class


Out[36]:
array([10660885,  8884437, 11749624,  9266926,  9462875, 11258015,
       11082324,  5806274,  5194804, 11216242])

In [37]:
## Compute prediction accuracy per class in train set for logistic regression with gradient descent in TensorFlow

train_tf_logreg_gd_pred_score_per_class = np.round(
    100*train_tf_logreg_gd_pred_count_per_class/train_tf_logreg_gd_element_count_per_class, 2
)

train_tf_logreg_gd_pred_score_per_class


Out[37]:
array([67.24, 60.37, 68.61, 64.41, 57.42, 68.5 , 63.32, 51.81, 46.91,
       67.7 ])

In [38]:
## Run session to evaluate logistic regression model (trained with gradient descent in tensorflow) on test set

batchsize = test_dataset.shape[0]

# Set up dictionary feed
feed = {build['X']: test_dataset, build['y']: onehot_test_labels}

# Evaluate the model on the test set
test_output = evaluate_classifier(
    session, saver, build, feed, batchsize, nclasses,
    monitor=monitor,
    sessiondir=os.path.join('log', 'session', 'logreg_gd'),
    verbose=True
)

print('\nEvaluate logistic regression model (trained with gradient descent using tensorflow) on test set')


INFO:tensorflow:Restoring parameters from log/session/logreg_gd
Evaluating model...
  Loss: 1.351E+00
  Accuracy: 0.796
  Accuracy per class: 0.813, 0.781, 0.836, 0.847, 0.751, 0.854, 0.796, 0.721, 0.665, 0.837
Model evaluation completed

Evaluate logistic regression model (trained with gradient descent using tensorflow) on test set

In [39]:
## Display number of samples per class in test set for logistic regression with gradient descent in tensorflow

test_tf_logreg_gd_element_count_per_class = test_output['nlabels_per_class']

test_tf_logreg_gd_element_count_per_class


Out[39]:
array([961, 892, 966, 898, 977, 964, 982, 706, 687, 973])

In [40]:
## Display correct predictions per class in test set for logistic regression with gradient descent in tensorflow

test_tf_logreg_gd_pred_count_per_class = test_output['npredictions_per_class']

test_tf_logreg_gd_pred_count_per_class


Out[40]:
array([781, 697, 808, 761, 734, 823, 782, 509, 457, 814])

In [41]:
## Compute prediction accuracy per class in test set for logistic regression with gradient descent in fensorflow

test_tf_logreg_gd_pred_score_per_class = np.round(100*test_output['accuracy_per_class'], 2)

test_tf_logreg_gd_pred_score_per_class


Out[41]:
array([81.27, 78.14, 83.64, 84.74, 75.13, 85.37, 79.63, 72.1 , 66.52,
       83.66])

In [42]:
## Plot prediction accuracy per class in train and test set for logistic regression with gradient descent in tensorflow

plot_prediction_accuracy_per_class(
    [train_tf_logreg_gd_pred_score_per_class, test_tf_logreg_gd_pred_score_per_class], nclasses, 
    ('green', 'red'), ('Train set', 'Test set'), string.ascii_uppercase[:nclasses]
)


To use tensorboard, follow two steps:

  1. Run tensorboard via the shell command tensorboard --logdir=log/session/logreg_gd.
  2. Open tensorboard on the browser at 'localhost:6006'.

Logistic regression with stochastic gradient descent using tensorflow

To run stochastic gradient descent, a subset of the train set is selected randomly at each iteration of the optimizer. In the example below, the batch size is set to 157 (batchsize = 157), so a subset of 157 letters is used at each iteration. To select a batch of 157 letters randomly, the optional argument permute=True is passed to the function train_classifier().

100 epochs are run (nepochs = 100). Each multibatch is set to be equal to an epoch (ndata = train_dataset.shape[0], nbatches = ndata//batchsize and multibatchsize = nbatches*batchsize), therefore results are printed and stored for each epoch.

Due to the smaller batchsize (157 letters instead of the whole train set), an iteration for stochastic gradient descent has smaller computational cost than an iteration for gradient descent.


In [43]:
## Reset default graph

tf.reset_default_graph()

In [44]:
## Build graph for logistic regression on train set with stochastic gradient descent using tensorflow

# Initialize logistic regression parameters
initw = tf.truncated_normal([npixels, nclasses])
initb = tf.zeros([nclasses])

# Specify what will be monitored and what will be stored in tensorboard
monitor = ('loss', 'accuracy', 'accuracy_per_class')
board = ('loss', 'accuracy', 'histogram')

# Build graph
build = build_logreg_model(npixels, nclasses, initw, initb, board=board)
build_classifier_graph(build, tf.train.GradientDescentOptimizer(0.1), activation='softmax_with_logits', monitor=monitor, board=board)

In [45]:
## Run session to train logistic regression model with stochastic gradient descent in tensorflow

ndata = train_dataset.shape[0]
batchsize = 157 # Stochastic gradient descent is run since batchsize < ndata

# Set up dictionary feed
feed = {build['X']: train_dataset[0:ndata, :], build['y']: onehot_train_labels[0:ndata]}

nepochs = 100 # Go through the training set 100 times
nbatches = ndata//batchsize # Calculate number of batches (per epoch)
multibatchsize = nbatches*batchsize # Stored monitored output every epoch

# Initialize session
session = tf.Session(graph=build['graph'])

# Initialize saver
saver = tf.train.Saver(max_to_keep=5)

with session.as_default():
    # Initialize saver
    saver = tf.train.Saver(max_to_keep=5)
    
    # Initialize variables
    session.run(tf.global_variables_initializer())
    
    start_time = time.process_time()
    train_output = train_classifier(
        session, build, feed, ndata, batchsize, nclasses, nepochs,
        saver=saver, save=True, monitor=monitor, board=board, multibatchsize=multibatchsize,
        permute=True, # Train set is permuted across epochs
        sessiondir=os.path.join('log', 'session', 'logreg_sgd'),
        boarddir=os.path.join('log', 'board', 'logreg_sgd'),
        verbose=True
    )
    end_time = time.process_time()
    tf_logreg_sgd_time = end_time-start_time

print('\nTrain logistic regression model with stochastic gradient descent using tensorflow')
print('Time ellapsed: %f seconds' % tf_logreg_sgd_time)


Multibach   1 of 100 with ending batch 964 of 964 in epoch   1 of 100
  Loss: 3.465E+00
  Accuracy: 0.614
  Accuracy per class: 0.663, 0.542, 0.664, 0.595, 0.582, 0.678, 0.640, 0.514, 0.484, 0.692
Multibach   2 of 100 with ending batch 964 of 964 in epoch   2 of 100
  Loss: 2.144E+00
  Accuracy: 0.697
  Accuracy per class: 0.736, 0.656, 0.758, 0.700, 0.664, 0.757, 0.726, 0.611, 0.536, 0.743
Multibach   3 of 100 with ending batch 964 of 964 in epoch   3 of 100
  Loss: 1.829E+00
  Accuracy: 0.709
  Accuracy per class: 0.739, 0.677, 0.771, 0.714, 0.676, 0.765, 0.734, 0.628, 0.549, 0.756
Multibach   4 of 100 with ending batch 964 of 964 in epoch   4 of 100
  Loss: 1.640E+00
  Accuracy: 0.715
  Accuracy per class: 0.743, 0.684, 0.778, 0.719, 0.682, 0.770, 0.737, 0.637, 0.561, 0.763
Multibach   5 of 100 with ending batch 964 of 964 in epoch   5 of 100
  Loss: 1.508E+00
  Accuracy: 0.721
  Accuracy per class: 0.745, 0.689, 0.784, 0.723, 0.690, 0.776, 0.742, 0.641, 0.570, 0.767
Multibach   6 of 100 with ending batch 964 of 964 in epoch   6 of 100
  Loss: 1.408E+00
  Accuracy: 0.725
  Accuracy per class: 0.748, 0.693, 0.790, 0.727, 0.694, 0.780, 0.745, 0.645, 0.575, 0.772
Multibach   7 of 100 with ending batch 964 of 964 in epoch   7 of 100
  Loss: 1.330E+00
  Accuracy: 0.729
  Accuracy per class: 0.748, 0.698, 0.795, 0.732, 0.699, 0.784, 0.747, 0.650, 0.581, 0.774
Multibach   8 of 100 with ending batch 964 of 964 in epoch   8 of 100
  Loss: 1.268E+00
  Accuracy: 0.732
  Accuracy per class: 0.749, 0.700, 0.798, 0.735, 0.701, 0.788, 0.751, 0.658, 0.585, 0.778
Multibach   9 of 100 with ending batch 964 of 964 in epoch   9 of 100
  Loss: 1.216E+00
  Accuracy: 0.736
  Accuracy per class: 0.753, 0.704, 0.802, 0.739, 0.706, 0.792, 0.752, 0.660, 0.589, 0.781
Multibach  10 of 100 with ending batch 964 of 964 in epoch  10 of 100
  Loss: 1.172E+00
  Accuracy: 0.739
  Accuracy per class: 0.756, 0.707, 0.806, 0.743, 0.706, 0.794, 0.756, 0.665, 0.595, 0.787
Multibach  11 of 100 with ending batch 964 of 964 in epoch  11 of 100
  Loss: 1.135E+00
  Accuracy: 0.742
  Accuracy per class: 0.757, 0.709, 0.810, 0.744, 0.713, 0.799, 0.757, 0.667, 0.596, 0.786
Multibach  12 of 100 with ending batch 964 of 964 in epoch  12 of 100
  Loss: 1.103E+00
  Accuracy: 0.745
  Accuracy per class: 0.761, 0.713, 0.811, 0.751, 0.713, 0.800, 0.760, 0.675, 0.599, 0.791
Multibach  13 of 100 with ending batch 964 of 964 in epoch  13 of 100
  Loss: 1.074E+00
  Accuracy: 0.747
  Accuracy per class: 0.762, 0.715, 0.812, 0.752, 0.718, 0.804, 0.762, 0.675, 0.601, 0.791
Multibach  14 of 100 with ending batch 964 of 964 in epoch  14 of 100
  Loss: 1.050E+00
  Accuracy: 0.749
  Accuracy per class: 0.764, 0.718, 0.816, 0.753, 0.720, 0.805, 0.765, 0.677, 0.608, 0.793
Multibach  15 of 100 with ending batch 964 of 964 in epoch  15 of 100
  Loss: 1.027E+00
  Accuracy: 0.752
  Accuracy per class: 0.767, 0.721, 0.818, 0.755, 0.725, 0.808, 0.768, 0.681, 0.606, 0.796
Multibach  16 of 100 with ending batch 964 of 964 in epoch  16 of 100
  Loss: 1.007E+00
  Accuracy: 0.754
  Accuracy per class: 0.768, 0.723, 0.820, 0.758, 0.726, 0.809, 0.768, 0.683, 0.610, 0.795
Multibach  17 of 100 with ending batch 964 of 964 in epoch  17 of 100
  Loss: 9.896E-01
  Accuracy: 0.755
  Accuracy per class: 0.768, 0.725, 0.820, 0.760, 0.727, 0.811, 0.770, 0.687, 0.609, 0.799
Multibach  18 of 100 with ending batch 964 of 964 in epoch  18 of 100
  Loss: 9.736E-01
  Accuracy: 0.758
  Accuracy per class: 0.772, 0.725, 0.823, 0.764, 0.730, 0.813, 0.774, 0.690, 0.610, 0.801
Multibach  19 of 100 with ending batch 964 of 964 in epoch  19 of 100
  Loss: 9.592E-01
  Accuracy: 0.760
  Accuracy per class: 0.773, 0.729, 0.824, 0.764, 0.733, 0.816, 0.775, 0.692, 0.615, 0.802
Multibach  20 of 100 with ending batch 964 of 964 in epoch  20 of 100
  Loss: 9.455E-01
  Accuracy: 0.761
  Accuracy per class: 0.774, 0.729, 0.826, 0.766, 0.734, 0.817, 0.776, 0.695, 0.613, 0.802
Multibach  21 of 100 with ending batch 964 of 964 in epoch  21 of 100
  Loss: 9.333E-01
  Accuracy: 0.763
  Accuracy per class: 0.775, 0.734, 0.828, 0.768, 0.735, 0.818, 0.780, 0.697, 0.617, 0.806
Multibach  22 of 100 with ending batch 964 of 964 in epoch  22 of 100
  Loss: 9.222E-01
  Accuracy: 0.764
  Accuracy per class: 0.777, 0.733, 0.828, 0.769, 0.736, 0.819, 0.779, 0.701, 0.618, 0.805
Multibach  23 of 100 with ending batch 964 of 964 in epoch  23 of 100
  Loss: 9.118E-01
  Accuracy: 0.766
  Accuracy per class: 0.778, 0.735, 0.830, 0.773, 0.739, 0.820, 0.781, 0.701, 0.618, 0.808
Multibach  24 of 100 with ending batch 964 of 964 in epoch  24 of 100
  Loss: 9.026E-01
  Accuracy: 0.767
  Accuracy per class: 0.778, 0.738, 0.833, 0.774, 0.740, 0.822, 0.783, 0.704, 0.619, 0.808
Multibach  25 of 100 with ending batch 964 of 964 in epoch  25 of 100
  Loss: 8.936E-01
  Accuracy: 0.768
  Accuracy per class: 0.779, 0.737, 0.832, 0.775, 0.741, 0.824, 0.785, 0.705, 0.623, 0.810
Multibach  26 of 100 with ending batch 964 of 964 in epoch  26 of 100
  Loss: 8.856E-01
  Accuracy: 0.770
  Accuracy per class: 0.782, 0.739, 0.833, 0.778, 0.742, 0.826, 0.784, 0.709, 0.620, 0.811
Multibach  27 of 100 with ending batch 964 of 964 in epoch  27 of 100
  Loss: 8.780E-01
  Accuracy: 0.771
  Accuracy per class: 0.782, 0.741, 0.836, 0.780, 0.744, 0.826, 0.784, 0.709, 0.627, 0.812
Multibach  28 of 100 with ending batch 964 of 964 in epoch  28 of 100
  Loss: 8.710E-01
  Accuracy: 0.772
  Accuracy per class: 0.783, 0.742, 0.835, 0.780, 0.746, 0.829, 0.786, 0.709, 0.625, 0.812
Multibach  29 of 100 with ending batch 964 of 964 in epoch  29 of 100
  Loss: 8.643E-01
  Accuracy: 0.773
  Accuracy per class: 0.785, 0.746, 0.837, 0.780, 0.746, 0.829, 0.787, 0.712, 0.625, 0.813
Multibach  30 of 100 with ending batch 964 of 964 in epoch  30 of 100
  Loss: 8.582E-01
  Accuracy: 0.774
  Accuracy per class: 0.784, 0.744, 0.838, 0.782, 0.747, 0.829, 0.789, 0.712, 0.626, 0.815
Multibach  31 of 100 with ending batch 964 of 964 in epoch  31 of 100
  Loss: 8.526E-01
  Accuracy: 0.775
  Accuracy per class: 0.786, 0.746, 0.838, 0.782, 0.748, 0.831, 0.791, 0.716, 0.628, 0.816
Multibach  32 of 100 with ending batch 964 of 964 in epoch  32 of 100
  Loss: 8.473E-01
  Accuracy: 0.776
  Accuracy per class: 0.786, 0.748, 0.837, 0.784, 0.749, 0.832, 0.790, 0.717, 0.629, 0.817
Multibach  33 of 100 with ending batch 964 of 964 in epoch  33 of 100
  Loss: 8.423E-01
  Accuracy: 0.777
  Accuracy per class: 0.790, 0.748, 0.841, 0.786, 0.750, 0.832, 0.790, 0.718, 0.627, 0.818
Multibach  34 of 100 with ending batch 964 of 964 in epoch  34 of 100
  Loss: 8.376E-01
  Accuracy: 0.778
  Accuracy per class: 0.788, 0.749, 0.840, 0.786, 0.752, 0.833, 0.792, 0.719, 0.632, 0.818
Multibach  35 of 100 with ending batch 964 of 964 in epoch  35 of 100
  Loss: 8.331E-01
  Accuracy: 0.779
  Accuracy per class: 0.789, 0.751, 0.842, 0.786, 0.753, 0.834, 0.793, 0.720, 0.630, 0.820
Multibach  36 of 100 with ending batch 964 of 964 in epoch  36 of 100
  Loss: 8.292E-01
  Accuracy: 0.779
  Accuracy per class: 0.789, 0.750, 0.839, 0.788, 0.753, 0.836, 0.795, 0.721, 0.631, 0.820
Multibach  37 of 100 with ending batch 964 of 964 in epoch  37 of 100
  Loss: 8.253E-01
  Accuracy: 0.780
  Accuracy per class: 0.790, 0.749, 0.841, 0.788, 0.753, 0.836, 0.794, 0.723, 0.634, 0.818
Multibach  38 of 100 with ending batch 964 of 964 in epoch  38 of 100
  Loss: 8.214E-01
  Accuracy: 0.781
  Accuracy per class: 0.790, 0.753, 0.842, 0.787, 0.753, 0.836, 0.795, 0.723, 0.635, 0.823
Multibach  39 of 100 with ending batch 964 of 964 in epoch  39 of 100
  Loss: 8.180E-01
  Accuracy: 0.782
  Accuracy per class: 0.792, 0.753, 0.842, 0.792, 0.754, 0.837, 0.796, 0.724, 0.636, 0.822
Multibach  40 of 100 with ending batch 964 of 964 in epoch  40 of 100
  Loss: 8.150E-01
  Accuracy: 0.782
  Accuracy per class: 0.792, 0.754, 0.842, 0.788, 0.755, 0.839, 0.796, 0.725, 0.634, 0.823
Multibach  41 of 100 with ending batch 964 of 964 in epoch  41 of 100
  Loss: 8.119E-01
  Accuracy: 0.783
  Accuracy per class: 0.794, 0.753, 0.843, 0.791, 0.756, 0.839, 0.797, 0.725, 0.637, 0.821
Multibach  42 of 100 with ending batch 964 of 964 in epoch  42 of 100
  Loss: 8.088E-01
  Accuracy: 0.784
  Accuracy per class: 0.793, 0.755, 0.844, 0.792, 0.757, 0.838, 0.798, 0.728, 0.636, 0.824
Multibach  43 of 100 with ending batch 964 of 964 in epoch  43 of 100
  Loss: 8.058E-01
  Accuracy: 0.784
  Accuracy per class: 0.794, 0.756, 0.844, 0.794, 0.757, 0.840, 0.798, 0.728, 0.638, 0.824
Multibach  44 of 100 with ending batch 964 of 964 in epoch  44 of 100
  Loss: 8.034E-01
  Accuracy: 0.784
  Accuracy per class: 0.794, 0.756, 0.844, 0.792, 0.757, 0.839, 0.799, 0.729, 0.638, 0.824
Multibach  45 of 100 with ending batch 964 of 964 in epoch  45 of 100
  Loss: 8.007E-01
  Accuracy: 0.785
  Accuracy per class: 0.795, 0.757, 0.846, 0.793, 0.759, 0.841, 0.800, 0.728, 0.638, 0.825
Multibach  46 of 100 with ending batch 964 of 964 in epoch  46 of 100
  Loss: 7.984E-01
  Accuracy: 0.785
  Accuracy per class: 0.795, 0.758, 0.844, 0.793, 0.758, 0.842, 0.799, 0.732, 0.636, 0.825
Multibach  47 of 100 with ending batch 964 of 964 in epoch  47 of 100
  Loss: 7.960E-01
  Accuracy: 0.786
  Accuracy per class: 0.796, 0.757, 0.846, 0.794, 0.759, 0.842, 0.800, 0.730, 0.639, 0.825
Multibach  48 of 100 with ending batch 964 of 964 in epoch  48 of 100
  Loss: 7.941E-01
  Accuracy: 0.786
  Accuracy per class: 0.797, 0.757, 0.845, 0.794, 0.759, 0.843, 0.801, 0.731, 0.641, 0.827
Multibach  49 of 100 with ending batch 964 of 964 in epoch  49 of 100
  Loss: 7.919E-01
  Accuracy: 0.787
  Accuracy per class: 0.798, 0.759, 0.846, 0.794, 0.760, 0.843, 0.799, 0.732, 0.639, 0.828
Multibach  50 of 100 with ending batch 964 of 964 in epoch  50 of 100
  Loss: 7.900E-01
  Accuracy: 0.787
  Accuracy per class: 0.796, 0.760, 0.847, 0.795, 0.759, 0.844, 0.802, 0.735, 0.641, 0.826
Multibach  51 of 100 with ending batch 964 of 964 in epoch  51 of 100
  Loss: 7.879E-01
  Accuracy: 0.787
  Accuracy per class: 0.797, 0.757, 0.847, 0.795, 0.762, 0.844, 0.801, 0.735, 0.640, 0.826
Multibach  52 of 100 with ending batch 964 of 964 in epoch  52 of 100
  Loss: 7.860E-01
  Accuracy: 0.788
  Accuracy per class: 0.796, 0.761, 0.847, 0.796, 0.761, 0.845, 0.803, 0.733, 0.642, 0.827
Multibach  53 of 100 with ending batch 964 of 964 in epoch  53 of 100
  Loss: 7.846E-01
  Accuracy: 0.789
  Accuracy per class: 0.798, 0.761, 0.847, 0.796, 0.762, 0.844, 0.803, 0.735, 0.641, 0.827
Multibach  54 of 100 with ending batch 964 of 964 in epoch  54 of 100
  Loss: 7.829E-01
  Accuracy: 0.789
  Accuracy per class: 0.797, 0.761, 0.846, 0.798, 0.761, 0.845, 0.802, 0.736, 0.641, 0.830
Multibach  55 of 100 with ending batch 964 of 964 in epoch  55 of 100
  Loss: 7.816E-01
  Accuracy: 0.789
  Accuracy per class: 0.800, 0.760, 0.848, 0.797, 0.762, 0.847, 0.803, 0.734, 0.641, 0.829
Multibach  56 of 100 with ending batch 964 of 964 in epoch  56 of 100
  Loss: 7.798E-01
  Accuracy: 0.790
  Accuracy per class: 0.799, 0.761, 0.849, 0.798, 0.762, 0.847, 0.803, 0.735, 0.641, 0.829
Multibach  57 of 100 with ending batch 964 of 964 in epoch  57 of 100
  Loss: 7.785E-01
  Accuracy: 0.790
  Accuracy per class: 0.801, 0.761, 0.850, 0.798, 0.762, 0.846, 0.803, 0.738, 0.639, 0.827
Multibach  58 of 100 with ending batch 964 of 964 in epoch  58 of 100
  Loss: 7.770E-01
  Accuracy: 0.791
  Accuracy per class: 0.800, 0.762, 0.849, 0.799, 0.763, 0.846, 0.805, 0.740, 0.642, 0.830
Multibach  59 of 100 with ending batch 964 of 964 in epoch  59 of 100
  Loss: 7.757E-01
  Accuracy: 0.791
  Accuracy per class: 0.800, 0.762, 0.851, 0.799, 0.764, 0.846, 0.805, 0.737, 0.642, 0.828
Multibach  60 of 100 with ending batch 964 of 964 in epoch  60 of 100
  Loss: 7.744E-01
  Accuracy: 0.791
  Accuracy per class: 0.800, 0.763, 0.849, 0.799, 0.764, 0.847, 0.806, 0.738, 0.643, 0.828
Multibach  61 of 100 with ending batch 964 of 964 in epoch  61 of 100
  Loss: 7.732E-01
  Accuracy: 0.791
  Accuracy per class: 0.801, 0.761, 0.849, 0.801, 0.764, 0.846, 0.804, 0.739, 0.642, 0.830
Multibach  62 of 100 with ending batch 964 of 964 in epoch  62 of 100
  Loss: 7.720E-01
  Accuracy: 0.791
  Accuracy per class: 0.801, 0.763, 0.851, 0.799, 0.763, 0.848, 0.806, 0.740, 0.641, 0.830
Multibach  63 of 100 with ending batch 964 of 964 in epoch  63 of 100
  Loss: 7.710E-01
  Accuracy: 0.791
  Accuracy per class: 0.800, 0.765, 0.851, 0.799, 0.765, 0.848, 0.807, 0.738, 0.642, 0.829
Multibach  64 of 100 with ending batch 964 of 964 in epoch  64 of 100
  Loss: 7.700E-01
  Accuracy: 0.792
  Accuracy per class: 0.802, 0.763, 0.850, 0.801, 0.765, 0.848, 0.806, 0.740, 0.642, 0.830
Multibach  65 of 100 with ending batch 964 of 964 in epoch  65 of 100
  Loss: 7.687E-01
  Accuracy: 0.792
  Accuracy per class: 0.800, 0.764, 0.850, 0.800, 0.764, 0.848, 0.806, 0.739, 0.644, 0.831
Multibach  66 of 100 with ending batch 964 of 964 in epoch  66 of 100
  Loss: 7.677E-01
  Accuracy: 0.792
  Accuracy per class: 0.804, 0.765, 0.851, 0.801, 0.764, 0.847, 0.806, 0.740, 0.642, 0.830
Multibach  67 of 100 with ending batch 964 of 964 in epoch  67 of 100
  Loss: 7.667E-01
  Accuracy: 0.793
  Accuracy per class: 0.804, 0.764, 0.851, 0.800, 0.764, 0.851, 0.805, 0.741, 0.643, 0.833
Multibach  68 of 100 with ending batch 964 of 964 in epoch  68 of 100
  Loss: 7.660E-01
  Accuracy: 0.792
  Accuracy per class: 0.801, 0.765, 0.851, 0.800, 0.766, 0.850, 0.804, 0.740, 0.644, 0.829
Multibach  69 of 100 with ending batch 964 of 964 in epoch  69 of 100
  Loss: 7.648E-01
  Accuracy: 0.793
  Accuracy per class: 0.801, 0.766, 0.850, 0.802, 0.765, 0.850, 0.807, 0.740, 0.643, 0.832
Multibach  70 of 100 with ending batch 964 of 964 in epoch  70 of 100
  Loss: 7.641E-01
  Accuracy: 0.793
  Accuracy per class: 0.803, 0.766, 0.852, 0.802, 0.767, 0.850, 0.806, 0.741, 0.644, 0.832
Multibach  71 of 100 with ending batch 964 of 964 in epoch  71 of 100
  Loss: 7.631E-01
  Accuracy: 0.793
  Accuracy per class: 0.803, 0.765, 0.851, 0.804, 0.764, 0.850, 0.807, 0.744, 0.641, 0.831
Multibach  72 of 100 with ending batch 964 of 964 in epoch  72 of 100
  Loss: 7.622E-01
  Accuracy: 0.794
  Accuracy per class: 0.803, 0.766, 0.851, 0.800, 0.768, 0.851, 0.808, 0.744, 0.643, 0.833
Multibach  73 of 100 with ending batch 964 of 964 in epoch  73 of 100
  Loss: 7.617E-01
  Accuracy: 0.793
  Accuracy per class: 0.804, 0.766, 0.852, 0.801, 0.765, 0.850, 0.807, 0.743, 0.644, 0.831
Multibach  74 of 100 with ending batch 964 of 964 in epoch  74 of 100
  Loss: 7.610E-01
  Accuracy: 0.793
  Accuracy per class: 0.804, 0.765, 0.853, 0.801, 0.765, 0.851, 0.806, 0.743, 0.645, 0.831
Multibach  75 of 100 with ending batch 964 of 964 in epoch  75 of 100
  Loss: 7.603E-01
  Accuracy: 0.794
  Accuracy per class: 0.803, 0.765, 0.853, 0.803, 0.766, 0.851, 0.807, 0.743, 0.644, 0.831
Multibach  76 of 100 with ending batch 964 of 964 in epoch  76 of 100
  Loss: 7.595E-01
  Accuracy: 0.794
  Accuracy per class: 0.805, 0.767, 0.853, 0.803, 0.766, 0.852, 0.807, 0.743, 0.644, 0.833
Multibach  77 of 100 with ending batch 964 of 964 in epoch  77 of 100
  Loss: 7.587E-01
  Accuracy: 0.794
  Accuracy per class: 0.804, 0.766, 0.852, 0.802, 0.767, 0.851, 0.807, 0.746, 0.645, 0.832
Multibach  78 of 100 with ending batch 964 of 964 in epoch  78 of 100
  Loss: 7.580E-01
  Accuracy: 0.795
  Accuracy per class: 0.806, 0.768, 0.853, 0.803, 0.767, 0.851, 0.809, 0.746, 0.644, 0.833
Multibach  79 of 100 with ending batch 964 of 964 in epoch  79 of 100
  Loss: 7.574E-01
  Accuracy: 0.795
  Accuracy per class: 0.807, 0.766, 0.853, 0.804, 0.768, 0.851, 0.807, 0.745, 0.646, 0.833
Multibach  80 of 100 with ending batch 964 of 964 in epoch  80 of 100
  Loss: 7.567E-01
  Accuracy: 0.795
  Accuracy per class: 0.804, 0.768, 0.854, 0.803, 0.766, 0.852, 0.810, 0.745, 0.642, 0.834
Multibach  81 of 100 with ending batch 964 of 964 in epoch  81 of 100
  Loss: 7.561E-01
  Accuracy: 0.795
  Accuracy per class: 0.805, 0.766, 0.854, 0.805, 0.767, 0.852, 0.807, 0.746, 0.647, 0.833
Multibach  82 of 100 with ending batch 964 of 964 in epoch  82 of 100
  Loss: 7.554E-01
  Accuracy: 0.794
  Accuracy per class: 0.805, 0.765, 0.853, 0.804, 0.767, 0.852, 0.808, 0.743, 0.642, 0.832
Multibach  83 of 100 with ending batch 964 of 964 in epoch  83 of 100
  Loss: 7.549E-01
  Accuracy: 0.795
  Accuracy per class: 0.807, 0.768, 0.853, 0.803, 0.768, 0.852, 0.809, 0.746, 0.646, 0.832
Multibach  84 of 100 with ending batch 964 of 964 in epoch  84 of 100
  Loss: 7.547E-01
  Accuracy: 0.795
  Accuracy per class: 0.806, 0.769, 0.853, 0.804, 0.767, 0.853, 0.809, 0.747, 0.644, 0.833
Multibach  85 of 100 with ending batch 964 of 964 in epoch  85 of 100
  Loss: 7.540E-01
  Accuracy: 0.796
  Accuracy per class: 0.805, 0.767, 0.853, 0.804, 0.769, 0.853, 0.810, 0.745, 0.645, 0.836
Multibach  86 of 100 with ending batch 964 of 964 in epoch  86 of 100
  Loss: 7.534E-01
  Accuracy: 0.796
  Accuracy per class: 0.807, 0.768, 0.853, 0.805, 0.767, 0.853, 0.809, 0.747, 0.647, 0.834
Multibach  87 of 100 with ending batch 964 of 964 in epoch  87 of 100
  Loss: 7.531E-01
  Accuracy: 0.795
  Accuracy per class: 0.806, 0.769, 0.852, 0.804, 0.766, 0.852, 0.809, 0.744, 0.647, 0.832
Multibach  88 of 100 with ending batch 964 of 964 in epoch  88 of 100
  Loss: 7.523E-01
  Accuracy: 0.796
  Accuracy per class: 0.807, 0.770, 0.853, 0.805, 0.769, 0.853, 0.809, 0.747, 0.645, 0.834
Multibach  89 of 100 with ending batch 964 of 964 in epoch  89 of 100
  Loss: 7.521E-01
  Accuracy: 0.796
  Accuracy per class: 0.806, 0.769, 0.855, 0.806, 0.768, 0.853, 0.810, 0.748, 0.643, 0.834
Multibach  90 of 100 with ending batch 964 of 964 in epoch  90 of 100
  Loss: 7.515E-01
  Accuracy: 0.796
  Accuracy per class: 0.807, 0.769, 0.853, 0.803, 0.770, 0.853, 0.811, 0.750, 0.645, 0.832
Multibach  91 of 100 with ending batch 964 of 964 in epoch  91 of 100
  Loss: 7.511E-01
  Accuracy: 0.796
  Accuracy per class: 0.809, 0.770, 0.853, 0.804, 0.767, 0.853, 0.810, 0.747, 0.645, 0.834
Multibach  92 of 100 with ending batch 964 of 964 in epoch  92 of 100
  Loss: 7.507E-01
  Accuracy: 0.796
  Accuracy per class: 0.806, 0.769, 0.854, 0.806, 0.768, 0.853, 0.809, 0.749, 0.646, 0.835
Multibach  93 of 100 with ending batch 964 of 964 in epoch  93 of 100
  Loss: 7.504E-01
  Accuracy: 0.797
  Accuracy per class: 0.808, 0.770, 0.855, 0.804, 0.768, 0.852, 0.810, 0.746, 0.647, 0.834
Multibach  94 of 100 with ending batch 964 of 964 in epoch  94 of 100
  Loss: 7.497E-01
  Accuracy: 0.797
  Accuracy per class: 0.807, 0.770, 0.854, 0.806, 0.770, 0.854, 0.810, 0.749, 0.648, 0.835
Multibach  95 of 100 with ending batch 964 of 964 in epoch  95 of 100
  Loss: 7.496E-01
  Accuracy: 0.796
  Accuracy per class: 0.807, 0.771, 0.855, 0.804, 0.769, 0.853, 0.810, 0.746, 0.645, 0.834
Multibach  96 of 100 with ending batch 964 of 964 in epoch  96 of 100
  Loss: 7.492E-01
  Accuracy: 0.797
  Accuracy per class: 0.807, 0.771, 0.854, 0.807, 0.769, 0.854, 0.809, 0.747, 0.646, 0.834
Multibach  97 of 100 with ending batch 964 of 964 in epoch  97 of 100
  Loss: 7.486E-01
  Accuracy: 0.797
  Accuracy per class: 0.809, 0.771, 0.854, 0.805, 0.770, 0.853, 0.810, 0.750, 0.646, 0.834
Multibach  98 of 100 with ending batch 964 of 964 in epoch  98 of 100
  Loss: 7.482E-01
  Accuracy: 0.797
  Accuracy per class: 0.809, 0.767, 0.855, 0.806, 0.771, 0.854, 0.810, 0.748, 0.645, 0.834
Multibach  99 of 100 with ending batch 964 of 964 in epoch  99 of 100
  Loss: 7.479E-01
  Accuracy: 0.797
  Accuracy per class: 0.807, 0.770, 0.854, 0.806, 0.770, 0.854, 0.811, 0.750, 0.647, 0.835
Multibach 100 of 100 with ending batch 964 of 964 in epoch 100 of 100
  Loss: 7.477E-01
  Accuracy: 0.797
  Accuracy per class: 0.808, 0.771, 0.856, 0.807, 0.767, 0.853, 0.810, 0.748, 0.648, 0.834

Train logistic regression model with stochastic gradient descent using tensorflow
Time ellapsed: 841.965552 seconds

In [46]:
## Plot loss for logistic regression on train set with stochastic gradient descent in tensorflow

plot_loss(train_output['loss'], marker='o')



In [47]:
## Plot accuracy for logistic regression on train set with stochastic gradient descent in tensorflow

plot_accuracy(train_output['accuracy'], marker='o')



In [48]:
## Display number of samples per class in train set for logistic regression with stochastic gradient descent in tensorflow

train_tf_logreg_sgd_element_count_per_class = np.sum(train_output['nlabels_per_class'], axis=0)

train_tf_logreg_sgd_element_count_per_class


Out[48]:
array([1585590, 1471691, 1712394, 1438690, 1648092, 1643494, 1750187,
       1120588, 1107395, 1656679])

In [49]:
## Count correct predictions per class in train set for logistic regression with stochastic gradient descent in TensorFlow

train_tf_logreg_sgd_pred_count_per_class = np.sum(train_output['npredictions_per_class'], axis=0)

train_tf_logreg_sgd_pred_count_per_class


Out[49]:
array([1250741, 1099380, 1433220, 1127202, 1233647, 1368623, 1384880,
        805009,  695401, 1353471])

In [50]:
## Compute prediction accuracy per class in train set for logistic regression with stochastic gradient descent in TensorFlow

train_tf_logreg_sgd_pred_score_per_class = np.round(
    100*train_tf_logreg_sgd_pred_count_per_class/train_tf_logreg_sgd_element_count_per_class, 2
)

train_tf_logreg_sgd_pred_score_per_class


Out[50]:
array([78.88, 74.7 , 83.7 , 78.35, 74.85, 83.28, 79.13, 71.84, 62.8 ,
       81.7 ])

In [51]:
## Run session to evaluate logistic regression model (trained with stochastic gradient descent in tensorflow) on test set

batchsize = test_dataset.shape[0]

# Set up dictionary feed
feed = {build['X']: test_dataset, build['y']: onehot_test_labels}

test_output = evaluate_classifier(
    session, saver, build, feed, batchsize, nclasses,
    monitor=monitor,
    sessiondir=os.path.join('log', 'session', 'logreg_sgd'),
    verbose=True
)

print('\nEvaluate logistic regression model (trained with stochastic gradient descent using tensorflow) on test set')


INFO:tensorflow:Restoring parameters from log/session/logreg_sgd
Evaluating model...
  Loss: 4.413E-01
  Accuracy: 0.882
  Accuracy per class: 0.887, 0.854, 0.928, 0.922, 0.855, 0.925, 0.876, 0.858, 0.750, 0.918
Model evaluation completed

Evaluate logistic regression model (trained with stochastic gradient descent using tensorflow) on test set

In [52]:
## Display number of samples per class in test set for logistic regression with stochastic gradient descent in tensorflow

test_tf_logreg_sgd_element_count_per_class = test_output['nlabels_per_class']

test_tf_logreg_sgd_element_count_per_class


Out[52]:
array([961, 892, 966, 898, 977, 964, 982, 706, 687, 973])

In [53]:
## Count correct predictions per class in test set for logistic regression with stochastic gradient descent in tensorflow

test_tf_logreg_sgd_pred_count_per_class = test_output['npredictions_per_class']

test_tf_logreg_sgd_pred_count_per_class


Out[53]:
array([852, 762, 896, 828, 835, 892, 860, 606, 515, 893])

In [54]:
## Compute prediction accuracy per class in test set for logistic regression with stochastic gradient descent in fensorflow

test_tf_logreg_sgd_pred_score_per_class = np.round(100*test_output['accuracy_per_class'], 2)

test_tf_logreg_sgd_pred_score_per_class


Out[54]:
array([88.66, 85.43, 92.75, 92.2 , 85.47, 92.53, 87.58, 85.84, 74.96,
       91.78])

In [55]:
## Plot prediction accuracy per class in train and test set for logistic regression with stochastic gradient descent in tensorflow

plot_prediction_accuracy_per_class(
    [train_tf_logreg_sgd_pred_score_per_class, test_tf_logreg_sgd_pred_score_per_class], nclasses, 
    ('green', 'red'), ('Train set', 'Test set'), string.ascii_uppercase[:nclasses]
)


Neural network with one hidden layer using tensorflow

In comparison to logistic regression, one linear fully connected layer and one activation layer are added before the linear fully connected layer already existent in the linear regression model.

The activation layer adds non-linearity to the classifier. Notice how such non-linearity increases the prediction accuracy in comparison to linear regression.


In [56]:
## Function for building a logistic regression model with one hidden layer in tensorflow

def build_logreg_model_with_hidden_layer(nw, nclasses, initw01, initb01, initw02, initb02, activation='relu', board=()):
    graph = tf.get_default_graph()
    
    with graph.as_default():
        with tf.name_scope('data'): # Input layer
            X = tf.placeholder(tf.float32, [None, nw]) # mnist data image of shape 28*28=784
            y = tf.placeholder(tf.float32, [None, nclasses]) # 0-9 digits recognition => 10 classes
        
        with tf.name_scope('fc_layer_01'): # Linear fully connected layer
            W01 = tf.Variable(initw01)
            b01 = tf.Variable(initb01)
            
            fc_layer_01 = tf.matmul(X, W01)+b01
        
        with tf.name_scope('act_layer_02'): # Activation layer
            if activation == 'relu':
                act_layer_02 = tf.nn.relu(fc_layer_01)
            elif activation == 'sigmoid':
                act_layer_02 = tf.sigmoid(fc_layer_01)
            elif activation == 'tanh':
                act_layer_02 = tf.tanh(fc_layer_01)
            else:
                raise ValueError('Wrong value passed to activation input argument')

        with tf.name_scope('outlayer'): # Linear fully connected layer
            W02 = tf.Variable(initw02)
            b02 = tf.Variable(initb02)
        
            outlayer = tf.matmul(act_layer_02, W02)+b02

        if 'histogram' in board:
            with tf.name_scope('summaries') as summaries_scope:
                tf.summary.histogram('weights01', W01)
                tf.summary.histogram('bias01', b01)
                tf.summary.histogram('weights02', W02)
                tf.summary.histogram('bias02', b02)
            
    build = {'graph': graph, 'X': X, 'y': y, 'outlayer': outlayer}
    
    if 'histogram' in board:
        build['summaries_scope'] = summaries_scope
    
    return build

In [57]:
## Reset default graph

tf.reset_default_graph()

In [58]:
## Build graph for logistic regression with one hidden layer on train set using tensorflow

ninterunits = 1024

# Initialize logistic regression parameters
initw01 = tf.truncated_normal([npixels, ninterunits])
initb01 = tf.zeros([ninterunits])
initw02 = tf.truncated_normal([ninterunits, nclasses])
initb02 = tf.zeros([nclasses])

# Specify what will be monitored and what will be stored in tensorboard
monitor = ('loss', 'accuracy', 'accuracy_per_class') # To select a single summary, say 'accuracy', set monitor = ('accuracy',)
board = ('loss', 'accuracy', 'histogram')

# Build graph
build = build_logreg_model_with_hidden_layer(npixels, nclasses, initw01, initb01, initw02, initb02, board=board)
build_classifier_graph(build, tf.train.GradientDescentOptimizer(0.1), activation='softmax_with_logits', monitor=monitor, board=board)

In [59]:
## Run session to train logistic regression with one hidden layer in tensorflow

ndata = train_dataset.shape[0]
batchsize = 157 # Stochastic gradient descent is run since batchsize < ndata

# Set up dictionary feed
feed = {build['X']: train_dataset[0:ndata, :], build['y']: onehot_train_labels[0:ndata]}

nepochs = 50 # Go through the training set 50 times
nbatches = ndata//batchsize # Calculate number of batches (per epoch)
multibatchsize = nbatches*batchsize # Stored monitored output every epoch

# Initialize session
session = tf.Session(graph=build['graph'])

# Initialize saver
saver = tf.train.Saver(max_to_keep=5)

with session.as_default():
    # Initialize saver
    saver = tf.train.Saver(max_to_keep=5)
    
    # Initialize variables
    session.run(tf.global_variables_initializer())
    
    start_time = time.process_time()
    train_output = train_classifier(
        session, build, feed, ndata, batchsize, nclasses, nepochs,
        saver=saver, save=True, monitor=monitor, board=board, multibatchsize=multibatchsize,
        permute=True, # Train set is permuted across epochs
        sessiondir=os.path.join('log', 'session', 'logreg_with_hidden_layer_sgd'),
        boarddir=os.path.join('log', 'board', 'logreg_with_hidden_layer_sgd'),
        verbose=True
    )
    end_time = time.process_time()
    tf_logreg_sgd_time = end_time-start_time

print('\nTrain logistic regression model with stochastic gradient descent using tensorflow')
print('Time ellapsed: %f seconds' % tf_logreg_sgd_time)


Multibach  1 of 50 with ending batch 964 of 964 in epoch  1 of 50
  Loss: 2.975E+01
  Accuracy: 0.750
  Accuracy per class: 0.772, 0.713, 0.795, 0.744, 0.739, 0.803, 0.761, 0.694, 0.618, 0.791
Multibach  2 of 50 with ending batch 964 of 964 in epoch  2 of 50
  Loss: 1.165E+01
  Accuracy: 0.798
  Accuracy per class: 0.816, 0.774, 0.828, 0.797, 0.799, 0.841, 0.803, 0.754, 0.677, 0.832
Multibach  3 of 50 with ending batch 964 of 964 in epoch  3 of 50
  Loss: 7.813E+00
  Accuracy: 0.811
  Accuracy per class: 0.827, 0.789, 0.843, 0.809, 0.813, 0.855, 0.821, 0.773, 0.686, 0.839
Multibach  4 of 50 with ending batch 964 of 964 in epoch  4 of 50
  Loss: 5.941E+00
  Accuracy: 0.819
  Accuracy per class: 0.835, 0.799, 0.847, 0.819, 0.818, 0.858, 0.826, 0.783, 0.704, 0.849
Multibach  5 of 50 with ending batch 964 of 964 in epoch  5 of 50
  Loss: 4.995E+00
  Accuracy: 0.822
  Accuracy per class: 0.838, 0.800, 0.851, 0.820, 0.823, 0.862, 0.829, 0.787, 0.709, 0.852
Multibach  6 of 50 with ending batch 964 of 964 in epoch  6 of 50
  Loss: 4.305E+00
  Accuracy: 0.826
  Accuracy per class: 0.840, 0.808, 0.854, 0.825, 0.828, 0.868, 0.831, 0.796, 0.707, 0.853
Multibach  7 of 50 with ending batch 964 of 964 in epoch  7 of 50
  Loss: 3.724E+00
  Accuracy: 0.829
  Accuracy per class: 0.844, 0.811, 0.854, 0.829, 0.831, 0.869, 0.835, 0.797, 0.718, 0.858
Multibach  8 of 50 with ending batch 964 of 964 in epoch  8 of 50
  Loss: 3.418E+00
  Accuracy: 0.831
  Accuracy per class: 0.845, 0.813, 0.860, 0.834, 0.831, 0.867, 0.836, 0.799, 0.719, 0.857
Multibach  9 of 50 with ending batch 964 of 964 in epoch  9 of 50
  Loss: 3.070E+00
  Accuracy: 0.834
  Accuracy per class: 0.848, 0.816, 0.857, 0.837, 0.837, 0.872, 0.839, 0.804, 0.724, 0.861
Multibach 10 of 50 with ending batch 964 of 964 in epoch 10 of 50
  Loss: 2.847E+00
  Accuracy: 0.838
  Accuracy per class: 0.851, 0.822, 0.864, 0.838, 0.835, 0.873, 0.844, 0.803, 0.735, 0.862
Multibach 11 of 50 with ending batch 964 of 964 in epoch 11 of 50
  Loss: 2.743E+00
  Accuracy: 0.838
  Accuracy per class: 0.851, 0.825, 0.862, 0.844, 0.837, 0.873, 0.842, 0.807, 0.731, 0.862
Multibach 12 of 50 with ending batch 964 of 964 in epoch 12 of 50
  Loss: 2.519E+00
  Accuracy: 0.841
  Accuracy per class: 0.854, 0.825, 0.867, 0.843, 0.843, 0.874, 0.845, 0.808, 0.736, 0.866
Multibach 13 of 50 with ending batch 964 of 964 in epoch 13 of 50
  Loss: 2.311E+00
  Accuracy: 0.844
  Accuracy per class: 0.858, 0.834, 0.866, 0.845, 0.845, 0.877, 0.848, 0.817, 0.742, 0.867
Multibach 14 of 50 with ending batch 964 of 964 in epoch 14 of 50
  Loss: 2.269E+00
  Accuracy: 0.844
  Accuracy per class: 0.856, 0.834, 0.864, 0.844, 0.846, 0.877, 0.850, 0.816, 0.743, 0.868
Multibach 15 of 50 with ending batch 964 of 964 in epoch 15 of 50
  Loss: 2.129E+00
  Accuracy: 0.848
  Accuracy per class: 0.859, 0.836, 0.870, 0.850, 0.849, 0.879, 0.854, 0.819, 0.750, 0.871
Multibach 16 of 50 with ending batch 964 of 964 in epoch 16 of 50
  Loss: 2.008E+00
  Accuracy: 0.851
  Accuracy per class: 0.861, 0.839, 0.875, 0.854, 0.854, 0.882, 0.855, 0.821, 0.750, 0.875
Multibach 17 of 50 with ending batch 964 of 964 in epoch 17 of 50
  Loss: 1.902E+00
  Accuracy: 0.853
  Accuracy per class: 0.868, 0.845, 0.871, 0.855, 0.853, 0.883, 0.856, 0.828, 0.756, 0.873
Multibach 18 of 50 with ending batch 964 of 964 in epoch 18 of 50
  Loss: 1.829E+00
  Accuracy: 0.855
  Accuracy per class: 0.865, 0.845, 0.873, 0.855, 0.857, 0.887, 0.857, 0.834, 0.757, 0.876
Multibach 19 of 50 with ending batch 964 of 964 in epoch 19 of 50
  Loss: 1.729E+00
  Accuracy: 0.857
  Accuracy per class: 0.870, 0.848, 0.875, 0.859, 0.857, 0.888, 0.861, 0.830, 0.767, 0.877
Multibach 20 of 50 with ending batch 964 of 964 in epoch 20 of 50
  Loss: 1.704E+00
  Accuracy: 0.859
  Accuracy per class: 0.872, 0.846, 0.875, 0.865, 0.861, 0.888, 0.863, 0.833, 0.766, 0.878
Multibach 21 of 50 with ending batch 964 of 964 in epoch 21 of 50
  Loss: 1.607E+00
  Accuracy: 0.863
  Accuracy per class: 0.873, 0.853, 0.883, 0.867, 0.863, 0.888, 0.866, 0.839, 0.775, 0.883
Multibach 22 of 50 with ending batch 964 of 964 in epoch 22 of 50
  Loss: 1.531E+00
  Accuracy: 0.864
  Accuracy per class: 0.878, 0.855, 0.878, 0.870, 0.863, 0.892, 0.868, 0.841, 0.774, 0.885
Multibach 23 of 50 with ending batch 964 of 964 in epoch 23 of 50
  Loss: 1.464E+00
  Accuracy: 0.867
  Accuracy per class: 0.878, 0.857, 0.884, 0.871, 0.866, 0.895, 0.873, 0.846, 0.782, 0.885
Multibach 24 of 50 with ending batch 964 of 964 in epoch 24 of 50
  Loss: 1.420E+00
  Accuracy: 0.869
  Accuracy per class: 0.881, 0.861, 0.884, 0.872, 0.869, 0.894, 0.872, 0.847, 0.785, 0.886
Multibach 25 of 50 with ending batch 964 of 964 in epoch 25 of 50
  Loss: 1.390E+00
  Accuracy: 0.871
  Accuracy per class: 0.882, 0.862, 0.888, 0.876, 0.873, 0.898, 0.873, 0.849, 0.788, 0.887
Multibach 26 of 50 with ending batch 964 of 964 in epoch 26 of 50
  Loss: 1.345E+00
  Accuracy: 0.873
  Accuracy per class: 0.887, 0.865, 0.886, 0.877, 0.873, 0.897, 0.876, 0.851, 0.787, 0.893
Multibach 27 of 50 with ending batch 964 of 964 in epoch 27 of 50
  Loss: 1.290E+00
  Accuracy: 0.874
  Accuracy per class: 0.885, 0.868, 0.888, 0.877, 0.875, 0.901, 0.878, 0.854, 0.790, 0.891
Multibach 28 of 50 with ending batch 964 of 964 in epoch 28 of 50
  Loss: 1.223E+00
  Accuracy: 0.878
  Accuracy per class: 0.887, 0.873, 0.893, 0.883, 0.878, 0.900, 0.881, 0.857, 0.798, 0.896
Multibach 29 of 50 with ending batch 964 of 964 in epoch 29 of 50
  Loss: 1.173E+00
  Accuracy: 0.881
  Accuracy per class: 0.892, 0.875, 0.893, 0.888, 0.880, 0.904, 0.883, 0.861, 0.804, 0.895
Multibach 30 of 50 with ending batch 964 of 964 in epoch 30 of 50
  Loss: 1.156E+00
  Accuracy: 0.882
  Accuracy per class: 0.893, 0.876, 0.895, 0.887, 0.881, 0.905, 0.883, 0.866, 0.801, 0.900
Multibach 31 of 50 with ending batch 964 of 964 in epoch 31 of 50
  Loss: 1.120E+00
  Accuracy: 0.883
  Accuracy per class: 0.895, 0.879, 0.897, 0.886, 0.883, 0.907, 0.883, 0.865, 0.805, 0.900
Multibach 32 of 50 with ending batch 964 of 964 in epoch 32 of 50
  Loss: 1.094E+00
  Accuracy: 0.884
  Accuracy per class: 0.896, 0.877, 0.897, 0.886, 0.884, 0.907, 0.888, 0.869, 0.806, 0.900
Multibach 33 of 50 with ending batch 964 of 964 in epoch 33 of 50
  Loss: 1.044E+00
  Accuracy: 0.888
  Accuracy per class: 0.900, 0.881, 0.898, 0.894, 0.887, 0.912, 0.890, 0.872, 0.816, 0.904
Multibach 34 of 50 with ending batch 964 of 964 in epoch 34 of 50
  Loss: 1.014E+00
  Accuracy: 0.890
  Accuracy per class: 0.902, 0.883, 0.902, 0.896, 0.888, 0.910, 0.892, 0.874, 0.817, 0.906
Multibach 35 of 50 with ending batch 964 of 964 in epoch 35 of 50
  Loss: 9.748E-01
  Accuracy: 0.892
  Accuracy per class: 0.903, 0.889, 0.901, 0.897, 0.891, 0.914, 0.894, 0.876, 0.816, 0.907
Multibach 36 of 50 with ending batch 964 of 964 in epoch 36 of 50
  Loss: 9.307E-01
  Accuracy: 0.894
  Accuracy per class: 0.906, 0.890, 0.906, 0.899, 0.892, 0.916, 0.894, 0.876, 0.825, 0.910
Multibach 37 of 50 with ending batch 964 of 964 in epoch 37 of 50
  Loss: 9.030E-01
  Accuracy: 0.895
  Accuracy per class: 0.907, 0.891, 0.905, 0.900, 0.894, 0.915, 0.897, 0.882, 0.827, 0.910
Multibach 38 of 50 with ending batch 964 of 964 in epoch 38 of 50
  Loss: 8.669E-01
  Accuracy: 0.898
  Accuracy per class: 0.910, 0.897, 0.907, 0.903, 0.898, 0.916, 0.900, 0.885, 0.830, 0.909
Multibach 39 of 50 with ending batch 964 of 964 in epoch 39 of 50
  Loss: 8.428E-01
  Accuracy: 0.901
  Accuracy per class: 0.910, 0.899, 0.909, 0.907, 0.901, 0.919, 0.903, 0.889, 0.836, 0.914
Multibach 40 of 50 with ending batch 964 of 964 in epoch 40 of 50
  Loss: 8.165E-01
  Accuracy: 0.902
  Accuracy per class: 0.915, 0.898, 0.910, 0.907, 0.902, 0.921, 0.903, 0.889, 0.833, 0.915
Multibach 41 of 50 with ending batch 964 of 964 in epoch 41 of 50
  Loss: 7.839E-01
  Accuracy: 0.905
  Accuracy per class: 0.916, 0.901, 0.914, 0.912, 0.903, 0.924, 0.906, 0.895, 0.839, 0.917
Multibach 42 of 50 with ending batch 964 of 964 in epoch 42 of 50
  Loss: 7.568E-01
  Accuracy: 0.906
  Accuracy per class: 0.917, 0.904, 0.914, 0.909, 0.907, 0.924, 0.906, 0.894, 0.844, 0.919
Multibach 43 of 50 with ending batch 964 of 964 in epoch 43 of 50
  Loss: 7.296E-01
  Accuracy: 0.909
  Accuracy per class: 0.921, 0.905, 0.917, 0.914, 0.909, 0.926, 0.910, 0.898, 0.840, 0.921
Multibach 44 of 50 with ending batch 964 of 964 in epoch 44 of 50
  Loss: 6.944E-01
  Accuracy: 0.911
  Accuracy per class: 0.921, 0.909, 0.916, 0.916, 0.909, 0.926, 0.912, 0.903, 0.852, 0.924
Multibach 45 of 50 with ending batch 964 of 964 in epoch 45 of 50
  Loss: 6.760E-01
  Accuracy: 0.913
  Accuracy per class: 0.925, 0.912, 0.920, 0.920, 0.912, 0.930, 0.916, 0.904, 0.848, 0.923
Multibach 46 of 50 with ending batch 964 of 964 in epoch 46 of 50
  Loss: 6.506E-01
  Accuracy: 0.915
  Accuracy per class: 0.924, 0.913, 0.921, 0.919, 0.913, 0.931, 0.918, 0.905, 0.853, 0.928
Multibach 47 of 50 with ending batch 964 of 964 in epoch 47 of 50
  Loss: 6.191E-01
  Accuracy: 0.917
  Accuracy per class: 0.928, 0.915, 0.922, 0.921, 0.916, 0.933, 0.919, 0.910, 0.859, 0.928
Multibach 48 of 50 with ending batch 964 of 964 in epoch 48 of 50
  Loss: 5.928E-01
  Accuracy: 0.920
  Accuracy per class: 0.931, 0.920, 0.925, 0.923, 0.917, 0.936, 0.922, 0.913, 0.863, 0.931
Multibach 49 of 50 with ending batch 964 of 964 in epoch 49 of 50
  Loss: 5.734E-01
  Accuracy: 0.921
  Accuracy per class: 0.931, 0.921, 0.927, 0.926, 0.921, 0.935, 0.922, 0.913, 0.864, 0.931
Multibach 50 of 50 with ending batch 964 of 964 in epoch 50 of 50
  Loss: 5.549E-01
  Accuracy: 0.923
  Accuracy per class: 0.934, 0.920, 0.927, 0.927, 0.923, 0.938, 0.923, 0.914, 0.867, 0.933

Train logistic regression model with stochastic gradient descent using tensorflow
Time ellapsed: 3656.445488 seconds

In [60]:
## Plot loss for logistic regression with one hidden layer on train set in tensorflow

plot_loss(train_output['loss'], marker='o')



In [61]:
## Plot accuracy for logistic regression with one hidden layer on train set in tensorflow

plot_accuracy(train_output['accuracy'], marker='o')



In [62]:
## Display number of samples per class in train set for logistic regression with one hidden layer in tensorflow

train_tf_logreg_with_hidden_layer_sgd_element_count_per_class = np.sum(train_output['nlabels_per_class'], axis=0)

train_tf_logreg_with_hidden_layer_sgd_element_count_per_class


Out[62]:
array([792795, 735844, 856194, 719345, 824047, 821743, 875093, 560296,
       553698, 828345])

In [63]:
## Count correct predictions per class in train set for logistic regression with one hidden layer in tensorflow

train_tf_logreg_with_hidden_layer_sgd_pred_count_per_class = np.sum(train_output['npredictions_per_class'], axis=0)

train_tf_logreg_with_hidden_layer_sgd_pred_count_per_class


Out[63]:
array([698581, 632367, 757884, 627189, 715710, 736120, 763205, 474439,
       433185, 735530])

In [64]:
## Compute prediction accuracy per class in train set for logistic regression with one hidden layer in tensorflow

train_tf_logreg_with_hidden_layer_sgd_pred_score_per_class = np.round(
    100*train_tf_logreg_with_hidden_layer_sgd_pred_count_per_class/train_tf_logreg_with_hidden_layer_sgd_element_count_per_class, 2
)

train_tf_logreg_with_hidden_layer_sgd_pred_score_per_class


Out[64]:
array([88.12, 85.94, 88.52, 87.19, 86.85, 89.58, 87.21, 84.68, 78.23,
       88.8 ])

In [65]:
## Run session to evaluate logistic regression with one hidden layer on test set in tensorflow

batchsize = test_dataset.shape[0]

# Set up dictionary feed
feed = {build['X']: test_dataset, build['y']: onehot_test_labels}

test_output = evaluate_classifier(
    session, saver, build, feed, batchsize, nclasses,
    monitor=monitor,
    sessiondir=os.path.join('log', 'session', 'logreg_with_hidden_layer_sgd'),
    verbose=True
)

print('\nEvaluate logistic regression with one hidden layer on test set')


INFO:tensorflow:Restoring parameters from log/session/logreg_with_hidden_layer_sgd
Evaluating model...
  Loss: 1.360E+00
  Accuracy: 0.910
  Accuracy per class: 0.917, 0.895, 0.901, 0.932, 0.902, 0.936, 0.935, 0.909, 0.822, 0.926
Model evaluation completed

Evaluate logistic regression with one hidden layer on test set

In [66]:
## Display number of samples per class in test set for logistic regression with stochastic gradient descent in tensorflow

test_tf_logreg_with_hidden_layer_sgd_element_count_per_class = test_output['nlabels_per_class']

test_tf_logreg_with_hidden_layer_sgd_element_count_per_class


Out[66]:
array([961, 892, 966, 898, 977, 964, 982, 706, 687, 973])

In [67]:
## Count correct predictions per class in test set for logistic regression with stochastic gradient descent in tensorflow

test_tf_logreg_with_hidden_layer_sgd_pred_count_per_class = test_output['npredictions_per_class']

test_tf_logreg_with_hidden_layer_sgd_pred_count_per_class


Out[67]:
array([881, 798, 870, 837, 881, 902, 918, 642, 565, 901])

In [68]:
## Compute prediction accuracy per class in test set for logistic regression with stochastic gradient descent in fensorflow

test_tf_logreg_with_hidden_layer_sgd_pred_score_per_class = np.round(100*test_output['accuracy_per_class'], 2)

test_tf_logreg_with_hidden_layer_sgd_pred_score_per_class


Out[68]:
array([91.68, 89.46, 90.06, 93.21, 90.17, 93.57, 93.48, 90.93, 82.24,
       92.6 ])

In [69]:
## Plot prediction accuracy per class in train and test set for logistic regression with stochastic gradient descent in tensorflow

plot_prediction_accuracy_per_class(
    [train_tf_logreg_with_hidden_layer_sgd_pred_score_per_class, test_tf_logreg_with_hidden_layer_sgd_pred_score_per_class], nclasses, 
    ('green', 'red'), ('Train set', 'Test set'), string.ascii_uppercase[:nclasses]
)