{"id":986,"date":"2019-01-22T10:52:25","date_gmt":"2019-01-22T02:52:25","guid":{"rendered":"http:\/\/www.max-shu.com\/blog\/?p=986"},"modified":"2019-01-22T10:52:25","modified_gmt":"2019-01-22T02:52:25","slug":"%e3%80%8a%e7%a5%9e%e7%bb%8f%e7%bd%91%e7%bb%9c%e4%b8%8e%e6%b7%b1%e5%ba%a6%e5%ad%a6%e4%b9%a0%e3%80%8b%e4%b8%ad%e7%9a%84python-3-x-%e4%bb%a3%e7%a0%81network2-py","status":"publish","type":"post","link":"http:\/\/www.max-shu.com\/blog\/?p=986","title":{"rendered":"\u300a\u795e\u7ecf\u7f51\u7edc\u4e0e\u6df1\u5ea6\u5b66\u4e60\u300b\u4e2d\u7684Python 3.x \u4ee3\u7801network2.py"},"content":{"rendered":"<p>\u300a\u795e\u7ecf\u7f51\u7edc\u4e0e\u6df1\u5ea6\u5b66\u4e60\u300b\uff08<span class=\"fontstyle2\">Michael Nielsen<\/span><span class=\"fontstyle0\">\u8457<\/span>\uff09\u4e2d\u7684\u4ee3\u7801\u662f\u57fa\u4e8epython2.7\u7684\uff0c\u4e0b\u9762\u4e3a\u79fb\u690d\u5230python3\u4e0b\u7684\u4ee3\u7801\uff1a<\/p>\n<p><span style=\"color: #ff0000;\"><strong>network2.py\u4ee3\u7801\uff1a<\/strong><\/span><\/p>\n<p><span style=\"color: #ff0000;\"><strong>\u70b9\u51fb\u4e0b\u8f7d\uff1a<a href=\"http:\/\/www.max-shu.com\/blog\/wp-content\/uploads\/2019\/01\/network2.zip\">network2<\/a><\/strong><\/span><\/p>\n<div>\n<div><\/div>\n<div>&#8220;&#8221;&#8221;network2.py<\/div>\n<div>~~~~~~~~~~~~~~<\/div>\n<div>An improved version of network.py, implementing the stochastic<\/div>\n<div>gradient descent learning algorithm for a feedforward neural network.<\/div>\n<div>Improvements include the addition of the cross-entropy cost function,<\/div>\n<div>regularization, and better initialization of network weights. Note<\/div>\n<div>that I have focused on making the code simple, easily readable, and<\/div>\n<div>easily modifiable. It is not optimized, and omits many desirable<\/div>\n<div>features.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>#### Libraries<\/div>\n<div># Standard library<\/div>\n<div>import json<\/div>\n<div>import random<\/div>\n<div>import sys<\/div>\n<div># Third-party libraries<\/div>\n<div>import numpy as np<\/div>\n<div>import time<\/div>\n<div>#### Define the quadratic and cross-entropy cost functions<\/div>\n<div>class QuadraticCost(object):<\/div>\n<div>@staticmethod<\/div>\n<div>deffn(a, y):<\/div>\n<div>&#8220;&#8221;&#8221;Return the cost associated with an output &#8220;a&#8220; and desired output<\/div>\n<div>&#8220;y&#8220;.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>return0.5*np.linalg.norm(a-y)**2<\/div>\n<div>@staticmethod<\/div>\n<div>defdelta(z, a, y):<\/div>\n<div>&#8220;&#8221;&#8221;Return the error delta from the output layer.&#8221;&#8221;&#8221;<\/div>\n<div>return (a-y) * sigmoid_prime(z)<\/div>\n<div>class CrossEntropyCost(object):<\/div>\n<div>@staticmethod<\/div>\n<div>deffn(a, y):<\/div>\n<div>&#8220;&#8221;&#8221;Return the cost associated with an output &#8220;a&#8220; and desired output<\/div>\n<div>&#8220;y&#8220;. Note that np.nan_to_num is used to ensure numerical<\/div>\n<div>stability. In particular, if both &#8220;a&#8220; and &#8220;y&#8220; have a 1.0<\/div>\n<div>in the same slot, then the expression (1-y)*np.log(1-a)<\/div>\n<div>returns nan. The np.nan_to_num ensures that that is converted<\/div>\n<div>to the correct value (0.0).<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>return np.sum(np.nan_to_num(-y*np.log(a)-(1-y)*np.log(1-a)))<\/div>\n<div>@staticmethod<\/div>\n<div>defdelta(z, a, y):<\/div>\n<div>&#8220;&#8221;&#8221;Return the error delta from the output layer. Note that the<\/div>\n<div>parameter &#8220;z&#8220; is not used by the method. It is included in<\/div>\n<div>the method&#8217;s parameters in order to make the interface<\/div>\n<div>consistent with the delta method for other cost classes.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>return (a-y)<\/div>\n<div>#### Main Network class<\/div>\n<div>class Network(object):<\/div>\n<div>def__init__(self, sizes, cost=CrossEntropyCost):<\/div>\n<div>&#8220;&#8221;&#8221;The list &#8220;sizes&#8220; contains the number of neurons in the respective<\/div>\n<div>layers of the network. For example, if the list was [2, 3, 1]<\/div>\n<div>then it would be a three-layer network, with the first layer<\/div>\n<div>containing 2 neurons, the second layer 3 neurons, and the<\/div>\n<div>third layer 1 neuron. The biases and weights for the network<\/div>\n<div>are initialized randomly, using<\/div>\n<div>&#8220;self.default_weight_initializer&#8220; (see docstring for that<\/div>\n<div>method).<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>self.num_layers =len(sizes)<\/div>\n<div>self.sizes = sizes<\/div>\n<div>self.default_weight_initializer()<\/div>\n<div>self.cost=cost<\/div>\n<div>defprint_init_bias_weight(self):<\/div>\n<div>print(&#8220;Time: &#8220;+str(time.strftime(&#8216;%Y-%m-%d %H:%M:%S&#8217;,time.localtime(time.time()))))<\/div>\n<div>print(&#8220;\u8f93\u5165\u56fe\u7247\u50cf\u7d20\u70b9\u6570\uff1a&#8221;+str(self.sizes[0]) +&#8221;, \u8f93\u5165\u795e\u7ecf\u7f51\u7edc\u5c42\u6570\uff1a&#8221;+str(self.num_layers))<\/div>\n<div>print(&#8220;\u7b2c 1 \u5c42\u4e3a\u8f93\u5165\u5c42\uff08\u5171 &#8220;+str(self.sizes[0])+&#8221; \u4e2a\u795e\u7ecf\u5143\uff09\uff0c\u6743\u91cd\u548c\u504f\u7f6e\u90fd\u4e0d\u9700\u8981\u3002&#8221;)<\/div>\n<div>for i inrange(1, self.num_layers):<\/div>\n<div>print(&#8220;\u7b2c &#8220;+str(i+1)+&#8221; \u5c42\u5171\u6709 &#8220;+str(self.sizes[i])+&#8221; \u4e2a\u795e\u7ecf\u5143\uff0c\u521d\u59cb\u6743\u91cd\u548c\u504f\u7f6e\u5982\u4e0b\u3002&#8221;)<\/div>\n<div>print(&#8221; &#8220;)<\/div>\n<div>layer = 1<\/div>\n<div>print(&#8220;\u8bad\u7ec3\u524d\u7684\u6743\u91cd\u548c\u504f\u7f6e\uff1a&#8221;)<\/div>\n<div>for lw, lb inzip(self.weights, self.biases):<\/div>\n<div>layer += 1<\/div>\n<div>num_nw = 0<\/div>\n<div>for w, b inzip(lw, lb):<\/div>\n<div>num_nw += 1<\/div>\n<div>print(&#8220;\u7b2c &#8220;+str(layer)+&#8221; \u5c42\u7b2c &#8220;+str(num_nw)+&#8221; \u4e2a\u795e\u7ecf\u5143\u7684\u6743\u91cd(\u5171&#8221;+str(len(w))+&#8221;\u4e2a\u8f93\u5165)\uff1a&#8221;)<\/div>\n<div>print(str(w))<\/div>\n<div>print(&#8220;\u7b2c &#8220;+str(layer)+&#8221; \u5c42\u7b2c &#8220;+str(num_nw)+&#8221; \u4e2a\u795e\u7ecf\u5143\u7684\u504f\u7f6e(\u5171&#8221;+str(len(b))+&#8221;\u4e2a\u8f93\u51fa)\uff1a&#8221;)<\/div>\n<div>print(str(b))<\/div>\n<div>print(&#8221; &#8220;)<\/div>\n<div>print(&#8221; &#8220;)<\/div>\n<div>defdefault_weight_initializer(self):<\/div>\n<div>&#8220;&#8221;&#8221;Initialize each weight using a Gaussian distribution with mean 0<\/div>\n<div>and standard deviation 1 over the square root of the number of<\/div>\n<div>weights connecting to the same neuron. Initialize the biases<\/div>\n<div>using a Gaussian distribution with mean 0 and standard<\/div>\n<div>deviation 1.<\/div>\n<div>Note that the first layer is assumed to be an input layer, and<\/div>\n<div>by convention we won&#8217;t set any biases for those neurons, since<\/div>\n<div>biases are only ever used in computing the outputs from later<\/div>\n<div>layers.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>self.biases = [np.random.randn(y, 1) for y inself.sizes[1:]]<\/div>\n<div>self.weights = [np.random.randn(y, x)\/np.sqrt(x)<\/div>\n<div>for x, y inzip(self.sizes[:-1], self.sizes[1:])]<\/div>\n<div>deflarge_weight_initializer(self):<\/div>\n<div>&#8220;&#8221;&#8221;Initialize the weights using a Gaussian distribution with mean 0<\/div>\n<div>and standard deviation 1. Initialize the biases using a<\/div>\n<div>Gaussian distribution with mean 0 and standard deviation 1.<\/div>\n<div>Note that the first layer is assumed to be an input layer, and<\/div>\n<div>by convention we won&#8217;t set any biases for those neurons, since<\/div>\n<div>biases are only ever used in computing the outputs from later<\/div>\n<div>layers.<\/div>\n<div>This weight and bias initializer uses the same approach as in<\/div>\n<div>Chapter 1, and is included for purposes of comparison. It<\/div>\n<div>will usually be better to use the default weight initializer<\/div>\n<div>instead.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>self.biases = [np.random.randn(y, 1) for y inself.sizes[1:]]<\/div>\n<div>self.weights = [np.random.randn(y, x)<\/div>\n<div>for x, y inzip(self.sizes[:-1], self.sizes[1:])]<\/div>\n<div>deffeedforward(self, a):<\/div>\n<div>&#8220;&#8221;&#8221;Return the output of the network if &#8220;a&#8220; is input.&#8221;&#8221;&#8221;<\/div>\n<div>for b, w inzip(self.biases, self.weights):<\/div>\n<div>a = sigmoid(np.dot(w, a)+b)<\/div>\n<div>return a<\/div>\n<div>defSGD(self, training_data, epochs, mini_batch_size, eta,<\/div>\n<div>lmbda=0.0,<\/div>\n<div>evaluation_data=None,<\/div>\n<div>monitor_evaluation_cost=False,<\/div>\n<div>monitor_evaluation_accuracy=False,<\/div>\n<div>monitor_training_cost=False,<\/div>\n<div>monitor_training_accuracy=False):<\/div>\n<div>&#8220;&#8221;&#8221;Train the neural network using mini-batch stochastic gradient<\/div>\n<div>descent. The &#8220;training_data&#8220; is a list of tuples &#8220;(x, y)&#8220;<\/div>\n<div>representing the training inputs and the desired outputs. The<\/div>\n<div>other non-optional parameters are self-explanatory, as is the<\/div>\n<div>regularization parameter &#8220;lmbda&#8220;. The method also accepts<\/div>\n<div>&#8220;evaluation_data&#8220;, usually either the validation or test<\/div>\n<div>data. We can monitor the cost and accuracy on either the<\/div>\n<div>evaluation data or the training data, by setting the<\/div>\n<div>appropriate flags. The method returns a tuple containing four<\/div>\n<div>lists: the (per-epoch) costs on the evaluation data, the<\/div>\n<div>accuracies on the evaluation data, the costs on the training<\/div>\n<div>data, and the accuracies on the training data. All values are<\/div>\n<div>evaluated at the end of each training epoch. So, for example,<\/div>\n<div>if we train for 30 epochs, then the first element of the tuple<\/div>\n<div>will be a 30-element list containing the cost on the<\/div>\n<div>evaluation data at the end of each epoch. Note that the lists<\/div>\n<div>are empty if the corresponding flag is not set.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>training_data_list = list(training_data)<\/div>\n<div>evaluation_data_list = list(evaluation_data)<\/div>\n<div>if evaluation_data:<\/div>\n<div>n_data = len(evaluation_data_list)<\/div>\n<div>n = len(training_data_list)<\/div>\n<div>evaluation_cost, evaluation_accuracy = [], []<\/div>\n<div>training_cost, training_accuracy = [], []<\/div>\n<div>print(&#8220;=================================================================&#8221;)<\/div>\n<div>print(&#8220;=================================================================&#8221;)<\/div>\n<div>loop = 0<\/div>\n<div>for j inrange(epochs):<\/div>\n<div>loop += 1<\/div>\n<div>print(&#8220;Time: &#8220;+str(time.strftime(&#8216;%Y-%m-%d %H:%M:%S&#8217;,time.localtime(time.time()))))<\/div>\n<div>random.shuffle(training_data_list)<\/div>\n<div>training_data = training_data_list<\/div>\n<div>evaluation_data = evaluation_data_list<\/div>\n<div>mini_batches = [<\/div>\n<div>training_data[k:k+mini_batch_size]<\/div>\n<div>for k inrange(0, n, mini_batch_size)]<\/div>\n<div>for mini_batch in mini_batches:<\/div>\n<div>self.update_mini_batch(<\/div>\n<div>mini_batch, eta, lmbda, len(training_data))<\/div>\n<div>print(&#8220;Epoch %s training complete&#8221;% j)<\/div>\n<div>if monitor_training_cost:<\/div>\n<div>cost = self.total_cost(training_data, lmbda)<\/div>\n<div>training_cost.append(cost)<\/div>\n<div>print(&#8220;Cost on training data: {}&#8221;.format(cost))<\/div>\n<div>if monitor_training_accuracy:<\/div>\n<div>accuracy = self.accuracy(training_data, convert=True)<\/div>\n<div>training_accuracy.append(accuracy)<\/div>\n<div>print(&#8220;Accuracy on training data: {} \/ {}&#8221;.format(<\/div>\n<div>accuracy, n))<\/div>\n<div>if monitor_evaluation_cost:<\/div>\n<div>cost = self.total_cost(evaluation_data, lmbda, convert=True)<\/div>\n<div>evaluation_cost.append(cost)<\/div>\n<div>print(&#8220;Cost on evaluation data: {}&#8221;.format(cost))<\/div>\n<div>if monitor_evaluation_accuracy:<\/div>\n<div>accuracy = self.accuracy(evaluation_data)<\/div>\n<div>evaluation_accuracy.append(accuracy)<\/div>\n<div>print(&#8220;Accuracy on evaluation data: {} \/ {}&#8221;.format(<\/div>\n<div>self.accuracy(evaluation_data), n_data))<\/div>\n<div>print(&#8220;\\n&#8221;)<\/div>\n<div>print(&#8220;=================================================================&#8221;)<\/div>\n<div>print(&#8220;=================================================================&#8221;)<\/div>\n<div>print(&#8221; &#8220;)<\/div>\n<div>layer = 1<\/div>\n<div>print(&#8220;\u8bad\u7ec3\u540e\u7684\u6743\u91cd\u548c\u504f\u7f6e\uff1a&#8221;)<\/div>\n<div>for lw, lb inzip(self.weights, self.biases):<\/div>\n<div>layer += 1<\/div>\n<div>num_nw = 0<\/div>\n<div>for w, b inzip(lw, lb):<\/div>\n<div>num_nw += 1<\/div>\n<div>print(&#8220;\u7b2c &#8220;+str(layer)+&#8221; \u5c42\u7b2c &#8220;+str(num_nw)+&#8221; \u4e2a\u795e\u7ecf\u5143\u7684\u6743\u91cd(\u5171&#8221;+str(len(w))+&#8221;\u4e2a\u8f93\u5165)\uff1a&#8221;)<\/div>\n<div>print(str(w))<\/div>\n<div>print(&#8220;\u7b2c &#8220;+str(layer)+&#8221; \u5c42\u7b2c &#8220;+str(num_nw)+&#8221; \u4e2a\u795e\u7ecf\u5143\u7684\u504f\u7f6e(\u5171&#8221;+str(len(b))+&#8221;\u4e2a\u8f93\u51fa)\uff1a&#8221;)<\/div>\n<div>print(str(b))<\/div>\n<div>print(&#8221; &#8220;)<\/div>\n<div>print(&#8221; &#8220;)<\/div>\n<div>print(&#8220;=================================================================&#8221;)<\/div>\n<div>print(&#8220;=================================================================&#8221;)<\/div>\n<div>print(&#8220;\u6bcf\u5c42\u6d4b\u8bd5\u7ed3\u679c\u7684\u8ba1\u7b97\u516c\u5f0f\uff1a (\u8f93\u51651*\u6743\u91cd1 + \u8f93\u51652*\u6743\u91cd2 + \u8f93\u51653*\u6743\u91cd3 + &#8230;) + \u504f\u7f6e &#8220;)<\/div>\n<div>print(&#8220;a1*w11&#8212;|&#8221;)<\/div>\n<div>print(&#8220;a2*w12&#8212;|+b1&#8212;|&#8221;)<\/div>\n<div>print(&#8220;a3*w13&#8212;| |&#8221;)<\/div>\n<div>print(&#8220;&#8230;&#8230;&#8212;| |-output&#8221;)<\/div>\n<div>print(&#8220;a1*w21&#8212;| |&#8221;)<\/div>\n<div>print(&#8220;a2*w22&#8212;|+b2&#8212;|&#8221;)<\/div>\n<div>print(&#8220;a3*w23&#8212;|&#8221;)<\/div>\n<div>print(&#8220;&#8230;&#8230;&#8212;|&#8221;)<\/div>\n<div>print(&#8220;Time: &#8220;+str(time.strftime(&#8216;%Y-%m-%d %H:%M:%S&#8217;,time.localtime(time.time()))))<\/div>\n<div>return evaluation_cost, evaluation_accuracy, \\<\/div>\n<div>training_cost, training_accuracy<\/div>\n<div>defupdate_mini_batch(self, mini_batch, eta, lmbda, n):<\/div>\n<div>&#8220;&#8221;&#8221;Update the network&#8217;s weights and biases by applying gradient<\/div>\n<div>descent using backpropagation to a single mini batch. The<\/div>\n<div>&#8220;mini_batch&#8220; is a list of tuples &#8220;(x, y)&#8220;, &#8220;eta&#8220; is the<\/div>\n<div>learning rate, &#8220;lmbda&#8220; is the regularization parameter, and<\/div>\n<div>&#8220;n&#8220; is the total size of the training data set.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>nabla_b = [np.zeros(b.shape) for b in self.biases]<\/div>\n<div>nabla_w = [np.zeros(w.shape) for w in self.weights]<\/div>\n<div>for x, y in mini_batch:<\/div>\n<div>delta_nabla_b, delta_nabla_w = self.backprop(x, y)<\/div>\n<div>nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]<\/div>\n<div>nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]<\/div>\n<div>self.weights = [(1-eta*(lmbda\/n))*w-(eta\/len(mini_batch))*nw<\/div>\n<div>for w, nw inzip(self.weights, nabla_w)]<\/div>\n<div>self.biases = [b-(eta\/len(mini_batch))*nb<\/div>\n<div>for b, nb inzip(self.biases, nabla_b)]<\/div>\n<div>defbackprop(self, x, y):<\/div>\n<div>&#8220;&#8221;&#8221;Return a tuple &#8220;(nabla_b, nabla_w)&#8220; representing the<\/div>\n<div>gradient for the cost function C_x. &#8220;nabla_b&#8220; and<\/div>\n<div>&#8220;nabla_w&#8220; are layer-by-layer lists of numpy arrays, similar<\/div>\n<div>to &#8220;self.biases&#8220; and &#8220;self.weights&#8220;.&#8221;&#8221;&#8221;<\/div>\n<div>nabla_b = [np.zeros(b.shape) for b in self.biases]<\/div>\n<div>nabla_w = [np.zeros(w.shape) for w in self.weights]<\/div>\n<div># feedforward<\/div>\n<div>activation = x<\/div>\n<div>activations = [x] # list to store all the activations, layer by layer<\/div>\n<div>zs = [] # list to store all the z vectors, layer by layer<\/div>\n<div>for b, w inzip(self.biases, self.weights):<\/div>\n<div>z = np.dot(w, activation)+b<\/div>\n<div>zs.append(z)<\/div>\n<div>activation = sigmoid(z)<\/div>\n<div>activations.append(activation)<\/div>\n<div># backward pass<\/div>\n<div>delta = (self.cost).delta(zs[-1], activations[-1], y)<\/div>\n<div>nabla_b[-1] = delta<\/div>\n<div>nabla_w[-1] = np.dot(delta, activations[-2].transpose())<\/div>\n<div># Note that the variable l in the loop below is used a little<\/div>\n<div># differently to the notation in Chapter 2 of the book. Here,<\/div>\n<div># l = 1 means the last layer of neurons, l = 2 is the<\/div>\n<div># second-last layer, and so on. It&#8217;s a renumbering of the<\/div>\n<div># scheme in the book, used here to take advantage of the fact<\/div>\n<div># that Python can use negative indices in lists.<\/div>\n<div>for l inrange(2, self.num_layers):<\/div>\n<div>z = zs[-l]<\/div>\n<div>sp = sigmoid_prime(z)<\/div>\n<div>delta = np.dot(self.weights[-l+1].transpose(), delta) * sp<\/div>\n<div>nabla_b[-l] = delta<\/div>\n<div>nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())<\/div>\n<div>return (nabla_b, nabla_w)<\/div>\n<div>defaccuracy(self, data, convert=False):<\/div>\n<div>&#8220;&#8221;&#8221;Return the number of inputs in &#8220;data&#8220; for which the neural<\/div>\n<div>network outputs the correct result. The neural network&#8217;s<\/div>\n<div>output is assumed to be the index of whichever neuron in the<\/div>\n<div>final layer has the highest activation.<\/div>\n<div>The flag &#8220;convert&#8220; should be set to False if the data set is<\/div>\n<div>validation or test data (the usual case), and to True if the<\/div>\n<div>data set is the training data. The need for this flag arises<\/div>\n<div>due to differences in the way the results &#8220;y&#8220; are<\/div>\n<div>represented in the different data sets. In particular, it<\/div>\n<div>flags whether we need to convert between the different<\/div>\n<div>representations. It may seem strange to use different<\/div>\n<div>representations for the different data sets. Why not use the<\/div>\n<div>same representation for all three data sets? It&#8217;s done for<\/div>\n<div>efficiency reasons &#8212; the program usually evaluates the cost<\/div>\n<div>on the training data and the accuracy on other data sets.<\/div>\n<div>These are different types of computations, and using different<\/div>\n<div>representations speeds things up. More details on the<\/div>\n<div>representations can be found in<\/div>\n<div>mnist_loader.load_data_wrapper.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>if convert:<\/div>\n<div>results = [(np.argmax(self.feedforward(x)), np.argmax(y))<\/div>\n<div>for (x, y) in data]<\/div>\n<div>else:<\/div>\n<div>results = [(np.argmax(self.feedforward(x)), y)<\/div>\n<div>for (x, y) in data]<\/div>\n<div>returnsum(int(x == y) for (x, y) in results)<\/div>\n<div>deftotal_cost(self, data, lmbda, convert=False):<\/div>\n<div>&#8220;&#8221;&#8221;Return the total cost for the data set &#8220;data&#8220;. The flag<\/div>\n<div>&#8220;convert&#8220; should be set to False if the data set is the<\/div>\n<div>training data (the usual case), and to True if the data set is<\/div>\n<div>the validation or test data. See comments on the similar (but<\/div>\n<div>reversed) convention for the &#8220;accuracy&#8220; method, above.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>data_list = list(data)<\/div>\n<div>cost = 0.0<\/div>\n<div>for x, y in data:<\/div>\n<div>a = self.feedforward(x)<\/div>\n<div>if convert: y = vectorized_result(y)<\/div>\n<div>cost += self.cost.fn(a, y)\/len(data_list)<\/div>\n<div>cost += 0.5*(lmbda\/len(data_list))*sum(<\/div>\n<div>np.linalg.norm(w)**2 for w in self.weights)<\/div>\n<div>return cost<\/div>\n<div>defsave(self, filename):<\/div>\n<div>&#8220;&#8221;&#8221;Save the neural network to the file &#8220;filename&#8220;.&#8221;&#8221;&#8221;<\/div>\n<div>data = {&#8220;sizes&#8221;: self.sizes,<\/div>\n<div>&#8220;weights&#8221;: [w.tolist() for w inself.weights],<\/div>\n<div>&#8220;biases&#8221;: [b.tolist() for b inself.biases],<\/div>\n<div>&#8220;cost&#8221;: str(self.cost.__name__)}<\/div>\n<div>f = open(filename, &#8220;w&#8221;)<\/div>\n<div>json.dump(data, f)<\/div>\n<div>f.close()<\/div>\n<div>#### Loading a Network<\/div>\n<div>def load(filename):<\/div>\n<div>&#8220;&#8221;&#8221;Load a neural network from the file &#8220;filename&#8220;. Returns an<\/div>\n<div>instance of Network.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>f = open(filename, &#8220;r&#8221;)<\/div>\n<div>data = json.load(f)<\/div>\n<div>f.close()<\/div>\n<div>cost = getattr(sys.modules[__name__], data[&#8220;cost&#8221;])<\/div>\n<div>net = Network(data[&#8220;sizes&#8221;], cost=cost)<\/div>\n<div>net.weights = [np.array(w) for w in data[&#8220;weights&#8221;]]<\/div>\n<div>net.biases = [np.array(b) for b in data[&#8220;biases&#8221;]]<\/div>\n<div>return net<\/div>\n<div>#### Miscellaneous functions<\/div>\n<div>def vectorized_result(j):<\/div>\n<div>&#8220;&#8221;&#8221;Return a 10-dimensional unit vector with a 1.0 in the j&#8217;th position<\/div>\n<div>and zeroes elsewhere. This is used to convert a digit (0&#8230;9)<\/div>\n<div>into a corresponding desired output from the neural network.<\/div>\n<div>&#8220;&#8221;&#8221;<\/div>\n<div>e = np.zeros((10, 1))<\/div>\n<div>e[j] = 1.0<\/div>\n<div>return e<\/div>\n<div>def sigmoid(z):<\/div>\n<div>&#8220;&#8221;&#8221;The sigmoid function.&#8221;&#8221;&#8221;<\/div>\n<div>return1.0\/(1.0+np.exp(-z))<\/div>\n<div>def sigmoid_prime(z):<\/div>\n<div>&#8220;&#8221;&#8221;Derivative of the sigmoid function.&#8221;&#8221;&#8221;<\/div>\n<div>return sigmoid(z)*(1-sigmoid(z))<\/div>\n<div>def test():<\/div>\n<div>import mnist_loader<\/div>\n<div>training_data, validation_data, test_data = mnist_loader.load_data_wrapper()<\/div>\n<div># net = Network([784, 30, 10], cost=QuadraticCost)<\/div>\n<div>net = Network([784, 30, 10], cost=CrossEntropyCost)<\/div>\n<div># net.large_weight_initializer()<\/div>\n<div>net.default_weight_initializer()<\/div>\n<div>net.print_init_bias_weight()<\/div>\n<div># net.SGD(training_data, 30, 10, 0.5, evaluation_data=test_data,<\/div>\n<div>net.SGD(training_data, 5, 10, 0.5, evaluation_data=test_data,<\/div>\n<div>monitor_evaluation_cost=True, monitor_evaluation_accuracy=True, monitor_training_cost=True, monitor_training_accuracy=True)<\/div>\n<div>net.save(&#8220;network2_save.dat&#8221;)<\/div>\n<div># \u5982\u679c\u505c\u6b62\u4e86\uff0c\u8981\u63a5\u7740\u518d\u8bad\u7ec3<\/div>\n<div>print(&#8220;######################################################################################################&#8221;)<\/div>\n<div>print(&#8220;########################################## \u65b0\u7684\u4e00\u8f6e\u6d4b\u8bd5\uff1a##############################################&#8221;)<\/div>\n<div>time.sleep(3)<\/div>\n<div>training_data, validation_data, test_data = mnist_loader.load_data_wrapper()<\/div>\n<div>net = load(&#8220;network2_save.dat&#8221;)<\/div>\n<div># net.default_weight_initializer() #\u4e0d\u8981\u518d\u521d\u59cb\u5316\u4e86<\/div>\n<div>net.print_init_bias_weight()<\/div>\n<div>net.SGD(training_data, 5, 10, 0.5, evaluation_data=test_data,<\/div>\n<div>monitor_evaluation_cost=True, monitor_evaluation_accuracy=True, monitor_training_cost=True, monitor_training_accuracy=True)<\/div>\n<div>net.save(&#8220;network2_save.dat&#8221;)<\/div>\n<div>if __name__ == &#8216;__main__&#8217;:<\/div>\n<div>test()<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u300a\u795e\u7ecf\u7f51\u7edc\u4e0e\u6df1\u5ea6\u5b66\u4e60\u300b\uff08Michael Nielsen\u8457\uff09\u4e2d\u7684\u4ee3\u7801\u662f\u57fa\u4e8epython2.7\u7684\uff0c\u4e0b\u9762\u4e3a\u79fb\u690d\u5230py &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[443],"tags":[727,108,446,447],"class_list":["post-986","post","type-post","status-publish","format-standard","hentry","category-443","tag-network2","tag-python","tag-446","tag-447"],"views":2446,"_links":{"self":[{"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/986","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=986"}],"version-history":[{"count":1,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/986\/revisions"}],"predecessor-version":[{"id":988,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/986\/revisions\/988"}],"wp:attachment":[{"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=986"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=986"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=986"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}