diff --git a/my_network1.py b/my_network1.py new file mode 100644 index 0000000..5048d97 --- /dev/null +++ b/my_network1.py @@ -0,0 +1,157 @@ +# %load network.py +# %load network.py + +""" +network.py +~~~~~~~~~~ +IT WORKS + +A module to implement the stochastic gradient descent learning +algorithm for a feedforward neural network. Gradients are calculated +using backpropagation. Note that I have focused on making the code +simple, easily readable, and easily modifiable. It is not optimized, +and omits many desirable features. +""" + +#### Libraries +# Standard library +import random + +# Third-party libraries +import numpy as np + + +class Network(object): + + def __init__(self, sizes): + """如果输入的sizes为[2, 4, 1]表示神经网络总共有三层, + 第一层是输入层有2个节点,最后一层是输出层只有一个节点, + 中间的是hidden layer,有4个神经元。 + """ + np.random.seed(0) + self.num_layers = len(sizes) + self.sizes = sizes + # biases 包括2个(总共3层,3-1=2)一维数组,长度分别是4(第二层有4个神经元) + # 和1(输出层只有一个节点) + self.biases = [np.random.randn(y, 1) for y in sizes[1:]] + + # weights包括2个二维矩阵,矩阵的形状分别是4*2 和 1*4 + self.weights = [np.random.randn(y, x) + for x, y in zip(sizes[:-1], sizes[1:])] + + def feedforward(self, a): + """Return the output of the network if ``a`` is input.""" + for b, w in zip(self.biases, self.weights): + print(f"b's shape is {b.shape}.\n first 5:{b[:5]}") + print(f"w's shape is {w.shape}.\n first 5:{w[:5]}") + print(f"a's shape is {a.shape}.\n first 5:{a[:5]}") + a = sigmoid(np.dot(w, a)+b) + + print(f"After sigmoid, a's shape is {a.shape}.\n first 5:{a[:5]}") + return a + + def SGD(self, training_data, epochs, mini_batch_size, eta, + test_data=None): + """Train the neural network using mini-batch stochastic + gradient descent. The ``training_data`` is a list of tuples + ``(x, y)`` representing the training inputs and the desired + outputs. The other non-optional parameters are + self-explanatory. If ``test_data`` is provided then the + network will be evaluated against the test data after each + epoch, and partial progress printed out. This is useful for + tracking progress, but slows things down substantially.""" + + training_data = list(training_data) + n = len(training_data) + + if test_data: + test_data = list(test_data) + n_test = len(test_data) + + for j in range(epochs): + random.shuffle(training_data) + mini_batches = [ + training_data[k:k+mini_batch_size] + for k in range(0, n, mini_batch_size)] + for mini_batch in mini_batches: + self.update_mini_batch(mini_batch, eta) + if test_data: + print(f"Epoch {j} : {self.evaluate(test_data)} / {n_test}") + else: + print(f"Epoch {j} complete") + + def update_mini_batch(self, mini_batch, eta): + """Update the network's weights and biases by applying + gradient descent using backpropagation to a single mini batch. + The ``mini_batch`` is a list of tuples ``(x, y)``, and ``eta`` + is the learning rate.""" + nabla_b = [np.zeros(b.shape) for b in self.biases] + nabla_w = [np.zeros(w.shape) for w in self.weights] + for x, y in mini_batch: + delta_nabla_b, delta_nabla_w = self.backprop(x, y) + nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)] + nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)] + self.weights = [w-(eta/len(mini_batch))*nw + for w, nw in zip(self.weights, nabla_w)] + self.biases = [b-(eta/len(mini_batch))*nb + for b, nb in zip(self.biases, nabla_b)] + + def backprop(self, x, y): + """Return a tuple ``(nabla_b, nabla_w)`` representing the + gradient for the cost function C_x. ``nabla_b`` and + ``nabla_w`` are layer-by-layer lists of numpy arrays, similar + to ``self.biases`` and ``self.weights``.""" + nabla_b = [np.zeros(b.shape) for b in self.biases] + nabla_w = [np.zeros(w.shape) for w in self.weights] + # feedforward + activation = x + activations = [x] # list to store all the activations, layer by layer + zs = [] # list to store all the z vectors, layer by layer + for b, w in zip(self.biases, self.weights): + z = np.dot(w, activation)+b + zs.append(z) + activation = sigmoid(z) + activations.append(activation) + # backward pass + delta = self.cost_derivative(activations[-1], y) * \ + sigmoid_prime(zs[-1]) + nabla_b[-1] = delta + nabla_w[-1] = np.dot(delta, activations[-2].transpose()) + # Note that the variable l in the loop below is used a little + # differently to the notation in Chapter 2 of the book. Here, + # l = 1 means the last layer of neurons, l = 2 is the + # second-last layer, and so on. It's a renumbering of the + # scheme in the book, used here to take advantage of the fact + # that Python can use negative indices in lists. + for l in range(2, self.num_layers): + z = zs[-l] + sp = sigmoid_prime(z) + delta = np.dot(self.weights[-l+1].transpose(), delta) * sp + nabla_b[-l] = delta + nabla_w[-l] = np.dot(delta, activations[-l-1].transpose()) + return (nabla_b, nabla_w) + + def evaluate(self, test_data): + """Return the number of test inputs for which the neural + network outputs the correct result. Note that the neural + network's output is assumed to be the index of whichever + neuron in the final layer has the highest activation.""" + test_results = [(np.argmax(self.feedforward(x)), y) + for (x, y) in test_data] + return sum(int(x == y) for (x, y) in test_results) + + def cost_derivative(self, output_activations, y): + """Return the vector of partial derivatives \partial C_x / + \partial a for the output activations.""" + return (output_activations-y) + +#### Miscellaneous functions +def sigmoid(z): + """The sigmoid function.""" + return 1.0/(1.0+np.exp(-z)) + +def sigmoid_prime(z): + """Derivative of the sigmoid function.""" + return sigmoid(z)*(1-sigmoid(z)) + + diff --git a/network.py b/network.py index 78629cf..f4dd120 100644 --- a/network.py +++ b/network.py @@ -1,4 +1,5 @@ # %load network.py +# %load network.py """ network.py @@ -70,9 +71,9 @@ def SGD(self, training_data, epochs, mini_batch_size, eta, for mini_batch in mini_batches: self.update_mini_batch(mini_batch, eta) if test_data: - print("Epoch {} : {} / {}".format(j,self.evaluate(test_data),n_test)) + print(f"Epoch {j} : {self.evaluate(test_data)} / {n_test}") else: - print("Epoch {} complete".format(j)) + print(f"Epoch {j} complete") def update_mini_batch(self, mini_batch, eta): """Update the network's weights and biases by applying diff --git a/network2.py b/network2.py index 9ecaa5b..6663f68 100644 --- a/network2.py +++ b/network2.py @@ -179,24 +179,26 @@ def SGD(self, training_data, epochs, mini_batch_size, eta, self.update_mini_batch( mini_batch, eta, lmbda, len(training_data)) - print("Epoch %s training complete" % j) + print(f"Epoch {j} training complete") if monitor_training_cost: cost = self.total_cost(training_data, lmbda) training_cost.append(cost) - print("Cost on training data: {}".format(cost)) + print(f"Cost on training data: {cost}") if monitor_training_accuracy: accuracy = self.accuracy(training_data, convert=True) training_accuracy.append(accuracy) - print("Accuracy on training data: {} / {}".format(accuracy, n)) + print(f"Accuracy on training data: {accuracy} / {n}") if monitor_evaluation_cost: cost = self.total_cost(evaluation_data, lmbda, convert=True) evaluation_cost.append(cost) - print("Cost on evaluation data: {}".format(cost)) + print(f"Cost on evaluation data: {cost}") if monitor_evaluation_accuracy: accuracy = self.accuracy(evaluation_data) evaluation_accuracy.append(accuracy) - print("Accuracy on evaluation data: {} / {}".format(self.accuracy(evaluation_data), n_data)) + print( + f"Accuracy on evaluation data: {self.accuracy(evaluation_data)} / {n_data}" + ) # Early stopping: if early_stopping_n > 0: @@ -212,7 +214,7 @@ def SGD(self, training_data, epochs, mini_batch_size, eta, return evaluation_cost, evaluation_accuracy, training_cost, training_accuracy return evaluation_cost, evaluation_accuracy, \ - training_cost, training_accuracy + training_cost, training_accuracy def update_mini_batch(self, mini_batch, eta, lmbda, n): """Update the network's weights and biases by applying gradient @@ -297,8 +299,7 @@ def accuracy(self, data, convert=False): results = [(np.argmax(self.feedforward(x)), y) for (x, y) in data] - result_accuracy = sum(int(x == y) for (x, y) in results) - return result_accuracy + return sum(int(x == y) for (x, y) in results) def total_cost(self, data, lmbda, convert=False): """Return the total cost for the data set ``data``. The flag @@ -321,9 +322,8 @@ def save(self, filename): "weights": [w.tolist() for w in self.weights], "biases": [b.tolist() for b in self.biases], "cost": str(self.cost.__name__)} - f = open(filename, "w") - json.dump(data, f) - f.close() + with open(filename, "w") as f: + json.dump(data, f) #### Loading a Network def load(filename): @@ -331,14 +331,13 @@ def load(filename): instance of Network. """ - f = open(filename, "r") - data = json.load(f) - f.close() - cost = getattr(sys.modules[__name__], data["cost"]) - net = Network(data["sizes"], cost=cost) - net.weights = [np.array(w) for w in data["weights"]] - net.biases = [np.array(b) for b in data["biases"]] - return net + with open(filename, "r") as f: + data = json.load(f) + cost = getattr(sys.modules[__name__], data["cost"]) + net = Network(data["sizes"], cost=cost) + net.weights = [np.array(w) for w in data["weights"]] + net.biases = [np.array(b) for b in data["biases"]] + return net #### Miscellaneous functions def vectorized_result(j): diff --git a/network3_pytorch.py b/network3_pytorch.py new file mode 100644 index 0000000..602083b --- /dev/null +++ b/network3_pytorch.py @@ -0,0 +1,238 @@ +import pickle +import gzip +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + + +def linear(z): return z +def ReLU(z): return F.relu(z) +def sigmoid(z): return F.sigmoid(z) +def tanh(z): return F.tanh(z) + +GPU = True +if GPU: + print("Trying to run under a GPU. If this is not desired, then modify network3.py to set the GPU flag to False.") + device = torch.device('cuda') +else: + print("Running with a CPU. If this is not desired, then modify network3.py to set the GPU flag to True.") + device = torch.device('cpu') + +torch.set_default_tensor_type(torch.FloatTensor) # set default tensor type to float32, equivalent to theano's config.floatX = 'float32' + +def load_data_shared(filename="mnist.pkl.gz"): + """ Load and preprocess the MNIST dataset and returns as a list of shared variables. + + Args: filename (string): The path to the MNIST dataset file which includes training, validation and test data. + + Returns: list: A list of shared variables. Each shared variable is a tuple of input and output. + + Example: + >>> data = load_data_shared("mnist.pkl.gz") + >>> print(len(data)) # output: 3 + >>> print(len(data[0])) # output: 2 """ + + f = gzip.open(filename, 'rb') + training_data, validation_data, test_data = pickle.load(f, encoding="latin1") + f.close() + + def shared(data): + """Place the data into shared variables. This allows PyTorch to copy the data to the GPU, if one is available.""" + shared_x = torch.tensor(np.asarray(data[0]),dtype=torch.float32).share_memory_() + shared_y = torch.tensor(np.asarray(data[1]),dtype=torch.int32).share_memory_() + return shared_x, shared_y + + return [shared(training_data), shared(validation_data), shared(test_data)] + +class Network(object): + + def __init__(self, layers, mini_batch_size): + """Initialize the neural network with architecture `layers` and takes a value for `mini_batch_size` to be used during training by stochastic gradient descent. + + Args: + layers (List): A list of layers that define the network architecture. + mini_batch_size (int): The number of examples in each mini-batch. + + """ + self.layers = layers + self.mini_batch_size = mini_batch_size + self.params = [param for layer in self.layers for param in layer.params] + self.x = torch.tensor(np.float32(self.mini_batch_size)) + self.y = torch.tensor(np.int32(self.mini_batch_size)) + init_layer = self.layers[0] + init_layer.forward(self.x, self.x, self.mini_batch_size) + for j in range(1, len(self.layers)): + prev_layer, layer = self.layers[j-1], self.layers[j] + layer.forward(prev_layer.output, prev_layer.output_dropout, self.mini_batch_size) + self.output = self.layers[-1].output + self.output_dropout = self.layers[-1].output_dropout + + def SGD(self, training_data, epochs, mini_batch_size, eta, validation_data, test_data, lmbda=0.0): + """Train the network using mini-batch stochastic gradient descent. + + Args: + training_data (List): A list of training examples and corresponding labels. + epochs (int): The number of times to loop over the entire training set. + mini_batch_size (int): The number of examples in each mini-batch. + eta (float): The learning rate hyperparameter. + validation_data (List): A list of validation examples and corresponding labels. + test_data (List): A list of test examples and corresponding labels. + lmbda (float): The hyperparameter for L2 regularization. + + """ + training_x, training_y = training_data + validation_x, validation_y = validation_data + test_x, test_y = test_data + + # compute number of minibatches for training, validation and testing + num_training_batches = int(len(training_data)/mini_batch_size) + num_validation_batches = int(len(validation_data)/mini_batch_size) + num_test_batches = int(len(test_data)/mini_batch_size) + + # define the (regularized) cost function, symbolic gradients, and updates + l2_norm_squared = sum([(layer.w**2).sum() for layer in self.layers]) + cost = self.layers[-1].cost(self)+0.5*lmbda*l2_norm_squared/num_training_batches + grads = torch.autograd.grad(cost, self.params, create_graph=True) + updates = [(param, param-eta*grad) for param, grad in zip(self.params, grads)] + + # define functions for training, validation, and testing + i = 0 + training_accuracy = [] + validation_accuracy = [] + test_accuracy = [] + while i < epochs: + i += 1 + np.random.shuffle(training_data) + mini_batches = [training_data[k:k+mini_batch_size] for k in range(0, len(training_data), mini_batch_size)] + for mini_batch in mini_batches: + x_mini_batch, y_mini_batch = mini_batch + x_mini_batch = torch.tensor(np.float32(x_mini_batch)) + y_mini_batch = torch.tensor(np.int64(y_mini_batch)) + cost_ = cost(x_mini_batch, y_mini_batch) + grads_ = torch.autograd.grad(cost_, self.params) + updates_ = [(param, param-eta*grad) for param, grad in zip(self.params, grads_)] + for update in updates_: + param, new_param = update[0], update[1] + param.data.copy_(new_param) + training_accuracy.append(self.accuracy(training_data)) + validation_accuracy.append(self.accuracy(validation_data)) + test_accuracy.append(self.accuracy(test_data)) + return training_accuracy, validation_accuracy, test_accuracy + + def accuracy(self, data_set): + """Returns the accuracy of the model on a given `data_set` of examples.""" + results = [(self.predict(x) == y) for (x, y) in data_set] + return sum(result for result in results)/len(results) + + def predict(self, x): + """Predict the output of the network for input `x`.""" + output = self.output + f = torch.function([self.x], output) + return np.argmax(f(x)) + + +class ConvPoolLayer(object): + """Used to create a combination of a convolutional and a max-pooling + layer. A more sophisticated implementation would separate the + two, but for our purposes we'll always use them together, and it + simplifies the code, so it makes sense to combine them. + + """ + def __init__(self, filter_shape, image_shape, poolsize=(2, 2), activation_fn=F.sigmoid): + """`filter_shape` is a tuple of length 4, whose entries are the number + of filters, the number of input feature maps, the filter height, and the + filter width. + + `image_shape` is a tuple of length 4, whose entries are the + mini-batch size, the number of input feature maps, the image + height, and the image width. + + `poolsize` is a tuple of length 2, whose entries are the y and + x pooling sizes. + + """ + + self.filter_shape = filter_shape + self.image_shape = image_shape + self.poolsize = poolsize + self.activation_fn = activation_fn + self.w = nn.Parameter(torch.randn(filter_shape), requires_grad=True) + self.b = nn.Parameter(torch.randn(filter_shape[0]), requires_grad=True) + + def forward(self, inpt, inpt_dropout, mini_batch_size): + self.inpt = inpt.view(self.image_shape) + conv_out = F.conv2d(input=self.inpt, weight=self.w, bias=self.b, stride=(1, 1), padding=0) + pooled_out = F.max_pool2d(conv_out, kernel_size=self.poolsize, stride=self.poolsize) + self.output = self.activation_fn(pooled_out) + self.output_dropout = self.output # no dropout in the convolutional layers + + +class FullyConnectedLayer(object): + def __init__(self, n_in, n_out, activation_fn=F.sigmoid, p_dropout=0.0): + + self.n_in = n_in + self.n_out = n_out + self.activation_fn = activation_fn + self.p_dropout = p_dropout + self.w = nn.Parameter(torch.randn(n_in, n_out) * np.sqrt(1.0 / n_out)) # Initialized weights + self.b = nn.Parameter(torch.zeros(n_out)) # Initialized biases + self.params = [self.w, self.b] + + def forward(self, inpt, inpt_dropout, mini_batch_size): + self.inpt = inpt.view(mini_batch_size, self.n_in) + self.output = self.activation_fn((1-self.p_dropout) * torch.matmul(self.inpt, self.w) + self.b) # dot product of input and weights and apply activation function + self.y_out = torch.argmax(self.output, dim=1) # index of the highest probability class + self.inpt_dropout = F.dropout(inpt_dropout.view(mini_batch_size, self.n_in), p=self.p_dropout, training=self.training) # apply dropout to the inputs + self.output_dropout = self.activation_fn(torch.matmul(self.inpt_dropout, self.w) + self.b) # dot product of input with weights with dropout applied to the inputs + return self.output, self.output_dropout + + def accuracy(self, y): + return torch.mean(torch.eq(y, self.y_out).float()) # calculated accuracy + + +class SoftmaxLayer(object): + + def __init__(self, n_in, n_out, p_dropout=0.0): + + self.n_in = n_in + self.n_out = n_out + self.p_dropout = p_dropout + self.w = nn.Parameter(torch.zeros(n_in, n_out)) # Initialized weights + self.b = nn.Parameter(torch.zeros(n_out)) # Initialized biases + self.params = [self.w, self.b] + + def forward(self, inpt, inpt_dropout, mini_batch_size): + self.inpt = inpt.view(mini_batch_size, self.n_in) + self.output = F.softmax((1-self.p_dropout) * torch.matmul(self.inpt, self.w) + self.b, dim=1) # apply softmax to the dot product of input and weights + self.y_out = torch.argmax(self.output, dim=1) # index of highest probability class + self.inpt_dropout = F.dropout(inpt_dropout.view(mini_batch_size, self.n_in), p=self.p_dropout, training=self.training) # apply dropout to the inputs + self.output_dropout = F.softmax(torch.matmul(self.inpt_dropout, self.w) + self.b, dim=1) # apply softmax to the dot product of the inputs with dropout applied + return self.output, self.output_dropout + + def cost(self, net): + return -torch.mean(torch.log(self.output_dropout)[torch.arange(net.y.shape[0]), net.y]) # calculate log-likelihood cost + + def accuracy(self, y): + return torch.mean(torch.eq(y, self.y_out).float()) # calculate accuracy + + +#### Miscellanea + +def size(data): + "Return the size of the dataset `data`." + return data[0].shape[0] + +def dropout_layer(layer, p_dropout): + mask = torch.bernoulli(torch.ones_like(layer) - p_dropout) # generate a binary dropout mask for given layer + return layer * mask # apply the dropout mask to the layer inputs + + + + + + + + + + diff --git a/test.py b/test.py index d1f4996..21fbf02 100644 --- a/test.py +++ b/test.py @@ -17,19 +17,19 @@ # ---------------------- # - read the input data: -''' + import mnist_loader training_data, validation_data, test_data = mnist_loader.load_data_wrapper() training_data = list(training_data) -''' + # --------------------- # - network.py example: -#import network +import network + -''' net = network.Network([784, 30, 10]) net.SGD(training_data, 30, 10, 3.0, test_data=test_data) -''' + # ---------------------- # - network2.py example: @@ -195,16 +195,16 @@ def testTheano(): ''' # chapter 6 - rectified linear units and some l2 regularization (lmbda=0.1) => even better accuracy -from network3 import ReLU -net = Network([ - ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), - filter_shape=(20, 1, 5, 5), - poolsize=(2, 2), - activation_fn=ReLU), - ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12), - filter_shape=(40, 20, 5, 5), - poolsize=(2, 2), - activation_fn=ReLU), - FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU), - SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size) -net.SGD(training_data, 60, mini_batch_size, 0.03, validation_data, test_data, lmbda=0.1) +# from network3 import ReLU +# net = Network([ +# ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), +# filter_shape=(20, 1, 5, 5), +# poolsize=(2, 2), +# activation_fn=ReLU), +# ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12), +# filter_shape=(40, 20, 5, 5), +# poolsize=(2, 2), +# activation_fn=ReLU), +# FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU), +# SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size) +# net.SGD(training_data, 60, mini_batch_size, 0.03, validation_data, test_data, lmbda=0.1) diff --git a/test_1.py b/test_1.py new file mode 100644 index 0000000..9355aee --- /dev/null +++ b/test_1.py @@ -0,0 +1,31 @@ +""" + Testing code for different neural network configurations. + Adapted for Python 3.5.2 + + Usage in shell: + python3.5 test.py + + Network (network.py and network2.py) parameters: + 2nd param is epochs count + 3rd param is batch size + 4th param is learning rate (eta) + + Author: + Michał Dobrzański, 2016 + dobrzanski.michal.daniel@gmail.com +""" + +# ---------------------- +# - read the input data: + +import mnist_loader +training_data, validation_data, test_data = mnist_loader.load_data_wrapper() +training_data = list(training_data) + +# --------------------- +# - network.py example: +import network + + +net = network.Network([784, 30, 10]) +net.SGD(training_data, 30, 10, 3.0, test_data=test_data) diff --git a/test_2.py b/test_2.py new file mode 100644 index 0000000..56fa29a --- /dev/null +++ b/test_2.py @@ -0,0 +1,33 @@ +""" + Testing code for different neural network configurations. + Adapted for Python 3.5.2 + + Usage in shell: + python3.5 test.py + + Network (network.py and network2.py) parameters: + 2nd param is epochs count + 3rd param is batch size + 4th param is learning rate (eta) + + Author: + Michał Dobrzański, 2016 + dobrzanski.michal.daniel@gmail.com +""" + +# ---------------------- +# - read the input data: + +import mnist_loader +training_data, validation_data, test_data = mnist_loader.load_data_wrapper() +training_data = list(training_data) + +# ---------------------- +# - network2.py example: +import network2 + + +net = network2.Network([784, 30, 10], cost=network2.CrossEntropyCost) +#net.large_weight_initializer() +net.SGD(training_data, 30, 10, 0.1, lmbda = 5.0,evaluation_data=validation_data, + monitor_evaluation_accuracy=True) diff --git a/test_3.py b/test_3.py new file mode 100644 index 0000000..12d951c --- /dev/null +++ b/test_3.py @@ -0,0 +1,38 @@ +""" + Testing code for different neural network configurations. + Adapted for Python 3.5.2 + + Usage in shell: + python3.5 test.py + + Network (network.py and network2.py) parameters: + 2nd param is epochs count + 3rd param is batch size + 4th param is learning rate (eta) + + Author: + Michał Dobrzański, 2016 + dobrzanski.michal.daniel@gmail.com +""" + +# ---------------------- +# - read the input data: + +import mnist_loader +training_data, validation_data, test_data = mnist_loader.load_data_wrapper() +training_data = list(training_data) + +# ---------------------- +# - network2.py example: +import network2 + + +# chapter 3 - Overfitting example - too many epochs of learning applied on small (1k samples) amount od data. +# Overfitting is treating noise as a signal. + +net = network2.Network([784, 30, 10], cost=network2.CrossEntropyCost) +net.large_weight_initializer() +net.SGD(training_data[:1000], 400, 10, 0.5, evaluation_data=test_data, + monitor_evaluation_accuracy=True, + monitor_training_cost=True) + diff --git a/test_4.py b/test_4.py new file mode 100644 index 0000000..0c1a63a --- /dev/null +++ b/test_4.py @@ -0,0 +1,42 @@ +""" + Testing code for different neural network configurations. + Adapted for Python 3.5.2 + + Usage in shell: + python3.5 test.py + + Network (network.py and network2.py) parameters: + 2nd param is epochs count + 3rd param is batch size + 4th param is learning rate (eta) + + Author: + Michał Dobrzański, 2016 + dobrzanski.michal.daniel@gmail.com +""" + +# ---------------------- +# - read the input data: + +import mnist_loader +training_data, validation_data, test_data = mnist_loader.load_data_wrapper() +training_data = list(training_data) + +# ---------------------- +# - network2.py example: +import network2 + + +# chapter 3 - Regularization (weight decay) example 1 (only 1000 of training data and 30 hidden neurons) + +net = network2.Network([784, 30, 10], cost=network2.CrossEntropyCost) +net.large_weight_initializer() +net.SGD(training_data[:1000], 400, 10, 0.5, + evaluation_data=test_data, + lmbda = 0.1, # this is a regularization parameter + monitor_evaluation_cost=True, + monitor_evaluation_accuracy=True, + monitor_training_cost=True, + monitor_training_accuracy=True) + + diff --git a/test_5.py b/test_5.py new file mode 100644 index 0000000..74de66a --- /dev/null +++ b/test_5.py @@ -0,0 +1,41 @@ +""" + Testing code for different neural network configurations. + Adapted for Python 3.5.2 + + Usage in shell: + python3.5 test.py + + Network (network.py and network2.py) parameters: + 2nd param is epochs count + 3rd param is batch size + 4th param is learning rate (eta) + + Author: + Michał Dobrzański, 2016 + dobrzanski.michal.daniel@gmail.com +""" + +# ---------------------- +# - read the input data: + +import mnist_loader +training_data, validation_data, test_data = mnist_loader.load_data_wrapper() +training_data = list(training_data) + +# ---------------------- +# - network2.py example: +import network2 + + +# chapter 3 - Early stopping implemented + +net = network2.Network([784, 30, 10], cost=network2.CrossEntropyCost) +net.SGD(training_data[:1000], 30, 10, 0.5, + lmbda=5.0, + evaluation_data=validation_data, + monitor_evaluation_accuracy=True, + monitor_training_cost=True, + early_stopping_n=10) + + + diff --git a/test_6.py b/test_6.py new file mode 100644 index 0000000..16a0b91 --- /dev/null +++ b/test_6.py @@ -0,0 +1,41 @@ +""" + Testing code for different neural network configurations. + Adapted for Python 3.5.2 + + Usage in shell: + python3.5 test.py + + Network (network.py and network2.py) parameters: + 2nd param is epochs count + 3rd param is batch size + 4th param is learning rate (eta) + + Author: + Michał Dobrzański, 2016 + dobrzanski.michal.daniel@gmail.com +""" + +# ---------------------- +# - read the input data: + +import mnist_loader +training_data, validation_data, test_data = mnist_loader.load_data_wrapper() +training_data = list(training_data) + +# ---------------------- +# - network2.py example: +import network2 + + +# chapter 4 - The vanishing gradient problem - deep networks are hard to train with simple SGD algorithm +# this network learns much slower than a shallow one. + +net = network2.Network([784, 30, 30, 30, 30, 10], cost=network2.CrossEntropyCost) +net.SGD(training_data, 30, 10, 0.1, + lmbda=5.0, + evaluation_data=validation_data, + monitor_evaluation_accuracy=True) + + + + diff --git a/test_7.py b/test_7.py new file mode 100644 index 0000000..0f90071 --- /dev/null +++ b/test_7.py @@ -0,0 +1,70 @@ +# ---------------------- +# - read the input data: + +import mnist_loader +training_data, validation_data, test_data = mnist_loader.load_data_wrapper() +training_data = list(training_data) + +# ---------------------- +# - network3.py example: +import network3_pytorch as nwpytorch +from network3_pytorch import Network, ConvPoolLayer, FullyConnectedLayer, SoftmaxLayer # softmax plus log-likelihood cost is more common in modern image classification networks. + +# read data: +training_data, validation_data, test_data = nwpytorch.load_data_shared() +# mini-batch size: +mini_batch_size = 10 + +# chapter 6 - shallow architecture using just a single hidden layer, containing 100 hidden neurons. + +net = Network([ + FullyConnectedLayer(n_in=784, n_out=100), + SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size) +net.SGD(training_data, 60, mini_batch_size, 0.1, validation_data, test_data) + + +# chapter 6 - 5x5 local receptive fields, 20 feature maps, max-pooling layer 2x2 +''' +net = Network([ + ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), + filter_shape=(20, 1, 5, 5), + poolsize=(2, 2)), + FullyConnectedLayer(n_in=20*12*12, n_out=100), + SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size) +net.SGD(training_data, 60, mini_batch_size, 0.1, validation_data, test_data) +''' + +# chapter 6 - inserting a second convolutional-pooling layer to the previous example => better accuracy +''' +net = Network([ + ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), + filter_shape=(20, 1, 5, 5), + poolsize=(2, 2)), + ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12), + filter_shape=(40, 20, 5, 5), + poolsize=(2, 2)), + FullyConnectedLayer(n_in=40*4*4, n_out=100), + SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size) +net.SGD(training_data, 60, mini_batch_size, 0.1, validation_data, test_data) +''' + +# chapter 6 - rectified linear units and some l2 regularization (lmbda=0.1) => even better accuracy +# from network3 import ReLU +# net = Network([ +# ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), +# filter_shape=(20, 1, 5, 5), +# poolsize=(2, 2), +# activation_fn=ReLU), +# ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12), +# filter_shape=(40, 20, 5, 5), +# poolsize=(2, 2), +# activation_fn=ReLU), +# FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU), +# SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size) +# net.SGD(training_data, 60, mini_batch_size, 0.03, validation_data, test_data, lmbda=0.1) + + + + + + diff --git a/test_network1.py b/test_network1.py new file mode 100644 index 0000000..00e5672 --- /dev/null +++ b/test_network1.py @@ -0,0 +1,56 @@ + +import my_network1 +import numpy as np + +# np.random.seed(0) +# network = Network([2, 4, 1]) +# # inpuy a +# a = [0.5, 0.5] + +# print(network.weights) +# print(network.biases) + + +# print(network.weights[0]) +# print(np.dot(network.weights[0], a)) +# print(np.dot(network.weights[0], a) + network.biases[0]) + +# a = sigmoid(np.dot(network.weights[0], a) + network.biases[0]) +# print(a) + +# print(np.dot(network.weights[1], a)) +# print(np.dot(network.weights[1], a) + network.biases[1]) + + +""" + Testing code for different neural network configurations. + Adapted for Python 3.5.2 + + Usage in shell: + python3.5 test.py + + Network (network.py and network2.py) parameters: + 2nd param is epochs count + 3rd param is batch size + 4th param is learning rate (eta) + + Author: + Michał Dobrzański, 2016 + dobrzanski.michal.daniel@gmail.com +""" + +# ---------------------- +# - read the input data: + +import mnist_loader +training_data, validation_data, test_data = mnist_loader.load_data_wrapper() +training_data = list(training_data) + +# --------------------- +# - network.py example: +import network + +net = my_network1.Network([784, 30, 10]) +net.SGD(training_data, 30, 10, 3.0, test_data=test_data) + +