# import necessary packages import numpy as np import matplotlib.pyplot as plt from sklearn import datasets # ensure the same random numbers appear every time np.random.seed(0) # display images in notebook plt.rcParams['figure.figsize'] = (12,12) # download MNIST dataset digits = datasets.load_digits() # define inputs and labels inputs = digits.images labels = digits.target # RGB images have a depth of 3 # our images are grayscale so they should have a depth of 1 inputs = inputs[:,:,:,np.newaxis] print("inputs = (n_inputs, pixel_width, pixel_height, depth) = " + str(inputs.shape)) print("labels = (n_inputs) = " + str(labels.shape)) # choose some random images to display n_inputs = len(inputs) indices = np.arange(n_inputs) random_indices = np.random.choice(indices, size=5) for i, image in enumerate(digits.images[random_indices]): plt.subplot(1, 5, i+1) plt.axis('off') plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest') plt.title("Label: %d" % digits.target[random_indices[i]]) plt.show() from keras.utils import to_categorical from sklearn.model_selection import train_test_split # representation of labels labels = to_categorical(labels) # split into train and test data # one-liner from scikit-learn library train_size = 0.8 test_size = 1 - train_size X_train, X_test, Y_train, Y_test = train_test_split(inputs, labels, train_size=train_size, test_size=test_size) import tensorflow as tf from keras.models import Sequential from keras.layers.convolutional import Conv2D from keras.layers.convolutional import MaxPooling2D from keras.layers import Flatten from keras.layers import Dense from keras.regularizers import l2 from keras.optimizers import SGD def create_convolutional_neural_network_keras(input_shape, receptive_field, n_filters, n_neurons_connected, n_categories, eta, lmbd): model = Sequential() model.add(Conv2D(n_filters, (receptive_field, receptive_field), input_shape=input_shape, padding='same', activation='relu', kernel_regularizer=l2(lmbd))) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(n_neurons_connected, activation='relu', kernel_regularizer=l2(lmbd))) model.add(Dense(n_categories, activation='softmax', kernel_regularizer=l2(lmbd))) sgd = SGD(lr=eta) model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy']) return model epochs = 100 batch_size = 100 input_shape = X_train.shape[1:4] receptive_field = 3 n_filters = 10 n_neurons_connected = 50 n_categories = 10 eta_vals = np.logspace(-5, 1, 7) lmbd_vals = np.logspace(-5, 1, 7) CNN_keras = np.zeros((len(eta_vals), len(lmbd_vals)), dtype=object) for i, eta in enumerate(eta_vals): for j, lmbd in enumerate(lmbd_vals): CNN = create_convolutional_neural_network_keras(input_shape, receptive_field, n_filters, n_neurons_connected, n_categories, eta, lmbd) CNN.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size, verbose=0) scores = CNN.evaluate(X_test, Y_test) CNN_keras[i][j] = CNN print("Learning rate = ", eta) print("Lambda = ", lmbd) print("Test accuracy: %.3f" % scores[1]) print() # visual representation of grid search # uses seaborn heatmap, could probably do this in matplotlib import seaborn as sns sns.set() train_accuracy = np.zeros((len(eta_vals), len(lmbd_vals))) test_accuracy = np.zeros((len(eta_vals), len(lmbd_vals))) for i in range(len(eta_vals)): for j in range(len(lmbd_vals)): CNN = CNN_keras[i][j] train_accuracy[i][j] = CNN.evaluate(X_train, Y_train)[1] test_accuracy[i][j] = CNN.evaluate(X_test, Y_test)[1] fig, ax = plt.subplots(figsize = (10, 10)) sns.heatmap(train_accuracy, annot=True, ax=ax, cmap="viridis") ax.set_title("Training Accuracy") ax.set_ylabel("$\eta$") ax.set_xlabel("$\lambda$") plt.show() fig, ax = plt.subplots(figsize = (10, 10)) sns.heatmap(test_accuracy, annot=True, ax=ax, cmap="viridis") ax.set_title("Test Accuracy") ax.set_ylabel("$\eta$") ax.set_xlabel("$\lambda$") plt.show()