2016-12-06 10 views
1

私の質問は、このコードのごく一部にすぎませんが、私はそれを助けてくれます。それは、あなたがデータ構造を理解するためにバックステップする必要がある場合を除きこの減算はどのようにしてPythonで動作しますか?

import numpy as np 

    class Network(object): 

    def __init__(self, sizes): 
     """The list ``sizes`` contains the number of neurons in the 
     respective layers of the network. For example, if the list 
     was [2, 3, 1] then it would be a three-layer network, with the 
     first layer containing 2 neurons, the second layer 3 neurons, 
     and the third layer 1 neuron. The biases and weights for the 
     network are initialized randomly, using a Gaussian 
     distribution with mean 0, and variance 1. Note that the first 
     layer is assumed to be an input layer, and by convention we 
     won't set any biases for those neurons, since biases are only 
     ever used in computing the outputs from later layers.""" 
     self.num_layers = len(sizes) 
     self.sizes = sizes 
     self.biases = [np.random.randn(y, 1) for y in sizes[1:]] 
     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): 
      a = sigmoid(np.dot(w, a)+b) 
     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.""" 
     if test_data: n_test = len(test_data) 
     n = len(training_data) 
     for j in xrange(epochs): 
      random.shuffle(training_data) 
      mini_batches = [ 
       training_data[k:k+mini_batch_size] 
       for k in xrange(0, n, mini_batch_size)] 
      for mini_batch in mini_batches: 
       self.update_mini_batch(mini_batch, eta) 
      if test_data: 
       print "Epoch {0}: {1}/{2}".format(
        j, self.evaluate(test_data), n_test) 
      else: 
       print "Epoch {0} complete".format(j) 

    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 xrange(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)) 

は、コードのほとんどを無視(コードの説明を見るにはここからスクロールダウン)http://neuralnetworksanddeeplearning.com/chap1.html#implementing_our_network_to_classify_digitsから取られています。まず、の方法の中で、backpropメソッドの途中で、2つの値が渡されていることがわかります。どちらの値も配列です(出力時にこれを見ることができます。著者)。 cost_derivativeメソッドでは、2つの値を減算するだけですが、それは配列なので、どのように動作しますか?

私はPythonでこれを行うとき、私は当然のことながら、私はそれは彼らがnumpyの配列であるという事実である可能性がありと信じてエラー

a = [1,2,4] 
b = [5,6,7] 
print(a-b) 

を取得しますか?

はまた、同様の事はそれがあったかのように機能がそれを扱うにもかかわらず... zが配列でsigmoidsigmoid_prime機能、(これらの関数は配列として引数で呼ばれている場所を確認)で起こっています単一の価値...どのように機能するのですか?私はそれが配列内の各値に対してそれを行うと仮定します。

本質的に、私は期待していた機能を、アレイで動作する単一の値でしか動作していないと見ています。

すべての説明のために乾杯、私が投稿したリンクは少し説明があります。

答えて

1

output_activationsyはnumpy配列なので、減算が正しく機能します。 Numpyは、高速行列操作のためのPythonライブラリであり、numpy配列オーバーロード-は行列減算を実行します。

しかし、あなたの例では、[1,2,4]は数字の配列ではなくプレーンなpythonリストであり、-演算子はリストに定義されていません。あなたは二つのリスト引くとき

import numpy as np 

a = np.array([1,2,4]) 
b = np.array([5,6,7]) 
print(a-b) 
# [-4 -4 -3] 
+0

が理にかなっています。乾杯。 –

0

はい、それらはnumpy配列でスカラーではないため、エラーが発生しています。 代わりにnp.subtract(a、b)を使用します。ベクトルを減算しようとしていることを覚えておく必要があります。

+0

どのようにコードに入っていますが、np.substractを使用することはありませんが、 - ? –

+0

私はそれが彼がただの普通のpythonリストを宣言しているという事実によると推測しています –

+0

私は失敗した例で何をしているのでしょうか?助けをお祈りします。 –

2

:あなたがnumpyの配列を使用してリストを交換する場合は、あなたの出力は、より理にかなって

a = [1,2,4] 
b = [5,6,7] 
print(a-b) 

をPythonはそれらを引くしようとする機能__sub__を呼び出します。 Vanilla pythonの__sub__はリストを減算することはできず、リストオブジェクトには関数__sub__が含まれていないため、エラーが発生します。

あなたがnumpyの配列からリストを引く

a = [1,2,4] 
b = numpy.array([5,6,7]) 
print(a-b) 

バニラ__sub__はまだ失敗しますが、Pythonは任意のオブジェクト固有の__sub__機能を探し、numpyのののを見つけました。 Numpyは他のすべてのオブジェクトをnp.asarray()にラップし、それらをnumpy配列のように減算しようとします。リストは1D配列にマップされ、サイズは同じであるため、減算が機能し、出力として配列になります。

+0

はい、Pythonではオブジェクトに対して '__sub__'を定義して' -'演算子をオーバーロードできますが、Pythonの '__sub__'組み込み関数は認識していません。 'a-b'を書くと、pythonは' a .__ sub __(b) 'を呼び出そうとします。 「バニラ」__sub__'といったものはありません。 – ForeverWintr

関連する問題