0
\$\begingroup\$

I wrote a Logistic Regression model that classifies MNIST digits.

I used tensorflow & keras only for import the dataset.

from tensorflow import keras
import time
import numpy as np
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

I sliced the dataset for binary classification.

# generate the indices
idx_digit_0 = np.argwhere(y_train == 0)
idx_digit_0 = idx_digit_0.flatten()
idx_digit_1 = np.argwhere(y_train == 1)
idx_digit_1 = idx_digit_1.flatten()
idx_test_digit_0 = np.argwhere(y_test == 0).flatten()
idx_test_digit_1 = np.argwhere(y_test == 1).flatten()

# slicing digit 0 and 1
y_train_digit_0 = y_train[idx_digit_0]
x_train_digit_0 = x_train[idx_digit_0]
y_train_digit_1 = y_train[idx_digit_1]
x_train_digit_1 = x_train[idx_digit_1]
y_test_digit_0 = y_test[idx_test_digit_0]
y_test_digit_1 = y_test[idx_test_digit_1]
x_test_digit_0 = x_test[idx_test_digit_0]
x_test_digit_1 = x_test[idx_test_digit_1]

# generate the dataset
y_train_mnist = np.concatenate((y_train_digit_0, y_train_digit_1), axis=0)
x_train_mnist = np.concatenate((x_train_digit_0, x_train_digit_1), axis=0)
y_test_mnist = np.concatenate((y_test_digit_0, y_test_digit_1), axis=0)
x_test_mnist = np.concatenate((x_test_digit_0, x_test_digit_1), axis=0)

# normalization
x_train_mnist = x_train_mnist/255.
x_test_mnist = x_test_mnist/255.

# flatten
x_train_mnist = x_train_mnist.reshape(len(x_train_mnist), -1)
x_test_mnist = x_test_mnist.reshape(len(x_test_mnist), -1)

def sigmoid(z):
    s = 1 / (1 + np.exp(-z))
    return s

class LogisticRegressionM3:
    def __init__(self, eta=.05, n_epoch=10, model_w=np.full(784, .5), model_b=.0):
        self.eta = eta
        self.n_epoch = n_epoch
        self.model_w = model_w
        self.model_b = model_b
        self.zz = []

    def activation(self, x):
        z = np.dot(x, self.model_w) + self.model_b
        return sigmoid(z)
        
    def predict(self, x):
        a = self.activation(x)
        if a >= 0.5:
            return 1
        else:
            return 0
        
    def fit(self, x, y, verbose=False):
        idx = np.arange(len(x))
        batch_size = 10
        for i in range(self.n_epoch):
            n_batches = int(len(x_train_mnist)/batch_size)
            batches = np.split(idx[:batch_size*n_batches], n_batches)
            for batch in batches:
                a = self.activation(x[batch])
                dz = a - y[batch]
                dw = np.dot(dz, x[batch])/batch_size
                self.model_w -= self.eta * dw
                self.model_b -= self.eta * np.mean(dz)


start_time = time.time()
w_mnist = np.random.uniform(size=784)
classifier_mnist = LogisticRegressionM3(.1, 1, w_mnist)
classifier_mnist.fit(x_train_mnist, y_train_mnist)
print('model trained {:.5f} s'.format(time.time() - start_time))

y_prediction = np.array(list(map(classifier_mnist.predict, x_train_mnist)))
acc = np.count_nonzero(y_prediction==y_train_mnist)
print('train accuracy {:.5f}'.format(acc/len(y_train_mnist)))

y_prediction = np.array(list(map(classifier_mnist.predict, x_test_mnist)))
acc = np.count_nonzero(y_prediction==y_test_mnist)
print('test accuracy {:.5f}'.format(acc/len(y_test_mnist)))

Here is the code and results

\$\endgroup\$
1
  • \$\begingroup\$ It's almost always preferred to include all relevant code in the question itself (as opposed to linking to github). Also, be explicit about what currently dissatisfies you about your code, or how you imagine it might be improved. \$\endgroup\$ Aug 9 at 17:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.