numpy/cuda problem

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Hallo,
ich will die unten gezeigte Funktion über cuda auf der Grafikkarte ausführen lassen. Dabei bekomme ich diese Fehlermeldung:
Untyped global name 'isinstance': cannot determine Numba type of <class 'builtin_function_or_method'>

File "mnistcuda.py", line 57:
def multiply(self, n):
if isinstance(n, Matrix):
^
Weiß jemand was ich falsch mache und wie ich es besser machen kann?

Code: Alles auswählen

from numba import vectorize

@vectorize(['float32(float32, float32)'], target='cuda')
    def multiply(self, n):
        if isinstance(n, Matrix):
            # hadamard product
            self.data *= n.data
        else:
            # scalar product
            self.data *= n
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Fehlermeldung ist doch sehr deutlich: deinen selbstegschriebenen Datentypen kann numba nicht verknusen. Da du ja auf dem bestehst kann man da nichts machen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und noch eine Anmerkung: dein Dekorator ist komplett falsch. Du erklärst zwei floats miteinander verrechnen zu wollen. Die Realität könnte ja nun nicht weiter davon entfernt sein. Wenn du die Typdeklarationen nicht verstehst, benutze sie erst gar nicht, sondern direkt den “lazy” Modus. Dann fummelt python das selbst raus. Vorausgesetzt du verzichtest - wie jetzt schon im dritten Thema vorgeschlagen - auf deine sinnlose Matrix klasse.

https://numba.pydata.org/numba-doc/dev/ ... orize.html
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Ich habe jetzt das ganze so umgeschrieben das ich nicht mehr meine Klasse habe. Weiß jetzt allerdings nicht wo ich da das ganze jetzt implementier so das, dass ganze läuft ich hab echt schon einige Stellen und Konstellationen ausprobiert bekomme es aber nicht hin.

Code: Alles auswählen

def train(self, input_array, target_array):
        # generating the hidden outputs
        inputs = np.zeros((len(input_array), 1))
        for i in range(len(input_array)):
            inputs[i][0] = input_array[i]

        #multiplys weights input --> hidden * inputs
        hidden = np.zeros(((np.size(self.weights_ih, 1)), (np.size(inputs, 0))))
        hidden = np.dot(self.weights_ih, inputs)
        
        #add bias
        hidden += self.bias_h

        # activation function
        for val in np.nditer(hidden, op_flags=['readwrite']):
            val[...] = sigmoid(val)
        # hidden.map(relu)

        # generating the outputs output
        outputs = np.zeros(((np.size(self.weights_ho, 1)), (np.size(hidden, 0))))
        outputs = np.dot(self.weights_ho, hidden)
        outputs += self.bias_o

        for val in np.nditer(outputs, op_flags=['readwrite']):
            val[...] = sigmoid(val)
        #outputs.map(drelu)

        # convert output array to matrix object
        targets = np.zeros((len(target_array), 1))
        for i in range(len(target_array)):
            targets[i][0] = target_array[i]

        # calculate the error = targets - outputs
        output_errors = targets - outputs

        # calculate gradient = outputs * (1 - outputs)
        #gradients = Matrix.maps(outputs, dsigmoid)
        gradients = np.zeros(((np.size(outputs, 1)), (np.size(outputs, 0))))
        gradients = np.random.rand((np.size(outputs, 1)), (np.size(outputs, 0))) * 2 - 1
        data = np.fromiter((dsigmoid(x) for x in outputs), outputs.dtype, count=len(outputs))
        gradients = data.reshape(len(data), 1)
        # gradients = Matrix.maps(outputs, drelu)

        gradients *= output_errors
        gradients *= self.learning_rate

        # calculate deltas
        hidden_t = hidden.transpose()
        #multiplys gradients and hidden Transpose
        weight_ho_deltas = np.zeros(((np.size(gradients, 1)), (np.size(hidden_t, 0))))
        weight_ho_deltas = np.dot(gradients, hidden_t)

        # adjust the weights by deltas
        self.weights_ho += weight_ho_deltas
        # adjust the bias by its deltas (which is the gradients)
        self.bias_o += (gradients)

        # calculate the hidden layer errors
        who_t = self.weights_ho.transpose()
        hidden_errors = np.zeros(((np.size(who_t, 1)), (np.size(output_errors, 0))))
        hidden_errors = np.dot(who_t, output_errors)

        # calculate hidden gradient
        #hidden_gradient = Matrix.maps(hidden, dsigmoid)
        hidden_gradient = np.zeros(((np.size(hidden, 1)), (np.size(hidden, 0))))
        hidden_gradient = np.random.rand((np.size(hidden, 1)), (np.size(hidden, 0))) * 2 - 1
        data = np.fromiter((dsigmoid(x) for x in hidden), hidden.dtype, count=len(hidden))
        hidden_gradient = data.reshape(len(data), 1)
        # hidden_gradient = Matrix.maps(hidden, drelu)

        hidden_gradient *= hidden_errors
        hidden_gradient *= self.learning_rate

        # calculate input->hidden deltas
        inputs_t = inputs.transpose()
        #multiplys hidden_gradient and input Transpose
        weight_ih_deltas = np.zeros(((np.size(hidden_gradient, 1)), (np.size(inputs_t, 0))))
        weight_ih_deltas = np.dot(hidden_gradient, inputs_t)

        self.weights_ih += weight_ih_deltas
        # adjust the bias by its deltas (which is the gradient)
        self.bias_h += hidden_gradient
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@Hypec: ich weiß nicht, was der Ort, wo die Funktion stehen soll, damit zu tun hat, ob etwas funktioniert oder nicht. Welche konkreten Probleme hast Du denn?
Du solltest als erstes mal ein numpy-Tutorial durcharbeiten. Du brauchst nicht 0-Arrays erzeugen, wenn Du danach es wieder wegschmeißt, weil Du an die gleiche Variable das Ergebnis einer Rechnung bindest.
Die meisten Kommentare meinst Du auch nur zu brauchen, weil Du das, was da gemacht wird, viel zu kompliziert ausdrückst.

Wenn man alles unnötige weglöscht und für den Rest Numpy so benutzt, wie es gedacht ist, bleibt:

Code: Alles auswählen

def train(self, input_array, target_array):
        vsigmoid = np.vectorize(sigmoid)
        vdsigmoid = np.vectorize(dsigmoid)
        hidden = self.weights_ih.dot(input_array) + self.bias_h
        hidden = vsigmoid(hidden)
        outputs = self.weights_ho.dot(hidden) + self.bias_o
        outputs = vsigmoid(outputs)

        output_errors = target_array - outputs
        gradients = vdsigmoid(outputs) * output_errors * self.learning_rate

        weight_ho_deltas = gradients.dot(hidden.T)
        # adjust the weights by deltas
        self.weights_ho += weight_ho_deltasy
        # adjust the bias by its deltas (which is the gradients)
        self.bias_o += gradients

        hidden_errors = self.weights_ho.T.dot(output_errors)
        hidden_gradient = vdsigmoid(hidden) * hidden_errors * self.learning_rate
        weight_ih_deltas = hidden_gradient.dot(input_array.T)

        self.weights_ih += weight_ih_deltas
        # adjust the bias by its deltas (which is the gradient)
        self.bias_h += hidden_gradient
Da ich die Array-Dimensionen aber nicht kenne, kann es da noch ein paar Dimensionsfehler haben.
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Ich habe noch die Dimension von den Input und Target Arrays hinzufügen müssen aber anstonsten läuft der Code so. Aber noch eine frage so wie ich numpy vectorize verstanden habe läuft das jetzt nicht über die Grafikkarte oder hab ich das falsch verstanden?
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Also ich habe jetzt das ganze auch für ein Netzwerk mit 2 Hiddenlayern übernommen. Hat jemand eine Idee/Tipp für mich wie ich erstens das hier verbessere
inputs = np.zeros((len(input_array), 1))
for i in range(len(input_array)):
inputs[0] = input_array
und wie ich generell das Netzwerk verbessere?

Code: Alles auswählen

def __init__(self, i_nodes, h_1_nodes, o_nodes, h_2_nodes=0):
        self.input_nodes = i_nodes
        self.hidden_1_nodes = h_1_nodes
        self.hidden_2_nodes = h_2_nodes
        self.output_nodes = o_nodes
        
        self.weights_ih1 = np.random.rand(self.hidden_1_nodes, self.input_nodes) * 2 - 1
        
        self.bias_h1 = np.random.rand(self.hidden_1_nodes, 1) * 2 - 1
        self.bias_o = np.random.rand(self.output_nodes, 1) * 2 - 1
        
        if self.hidden_2_nodes > 0:
            self.weights_h1h2 = np.random.rand(self.hidden_2_nodes, self.hidden_1_nodes) * 2 - 1
            self.weights_h2o = np.random.rand(self.output_nodes, self.hidden_2_nodes) * 2 - 1

            self.bias_h2 = np.random.rand(self.hidden_2_nodes, 1) * 2 - 1
        else:
            self.weights_ho = np.random.rand(self.output_nodes, self.hidden_1_nodes) * 2 - 1
        self.learning_rate = 0.03

    def predict(self, input_array):
        vsigmoid = np.vectorize(sigmoid)
        vdsigmoid = np.vectorize(dsigmoid)
        inputs = np.zeros((len(input_array), 1))
        for i in range(len(input_array)):
            inputs[i][0] = input_array[i]

        hidden_1 = self.weights_ih1.dot(inputs) + self.bias_h1
        hidden_1 = vsigmoid(hidden_1)

        if self.hidden_2_nodes > 0:
            hidden_2 = self.weights_h1h2.dot(hidden_1) + self.bias_h2
            hidden_2 = vsigmoid(hidden_2)

            outputs = self.weights_h2o.dot(hidden_2) + self.bias_o
            outputs = vsigmoid(outputs)
        else:
            outputs = self.weights_ho.dot(hidden_1) + self.bias_o
            outputs = vsigmoid(outputs)

        return list(outputs.flat)

    def train(self, input_array, target_array):
        vsigmoid = np.vectorize(sigmoid)
        vdsigmoid = np.vectorize(dsigmoid)
        inputs = np.zeros((len(input_array), 1))
        for i in range(len(input_array)):
            inputs[i][0] = input_array[i]
        targets = np.zeros((len(target_array), 1))
        for i in range(len(target_array)):
            targets[i][0] = target_array[i]
        hidden_1 = self.weights_ih1.dot(inputs) + self.bias_h1
        hidden_1 = vsigmoid(hidden_1)

        if self.hidden_2_nodes > 0:
            hidden_2 = self.weights_h1h2.dot(hidden_1) + self.bias_h2
            hidden_2 = vsigmoid(hidden_2) 

            outputs = self.weights_h2o.dot(hidden_2) + self.bias_o
        else:
            outputs = self.weights_ho.dot(hidden_1) + self.bias_o
        outputs = vsigmoid(outputs)

        output_errors = targets - outputs
        gradients_o = vdsigmoid(outputs) * output_errors * self.learning_rate

        if self.hidden_2_nodes > 0:
            weight_h2o_deltas = gradients_o.dot(hidden_2.transpose())
            # adjust the weights by deltas
            self.weights_h2o += weight_h2o_deltas
            # adjust the bias by its deltas (which is the gradients)
            self.bias_o += gradients_o

            hidden_2_errors = self.weights_h2o.T.dot(output_errors)
            hidden_1_errors = self.weights_h1h2.T.dot(hidden_2_errors)
            hidden_1_gradient = vdsigmoid(hidden_1) * hidden_1_errors * self.learning_rate
            hidden_2_gradient = vdsigmoid(hidden_2) * hidden_2_errors * self.learning_rate
            weight_ih_deltas = hidden_1_gradient.dot(inputs.transpose())

            self.weights_ih1 += weight_ih_deltas
            # adjust the bias by its deltas (which is the gradient)
            self.bias_h1 += hidden_1_gradient
        else: 
            weight_ho_deltas = gradients_o.dot(hidden_1.transpose())
            # adjust the weights by deltas
            self.weights_ho += weight_ho_deltas
            # adjust the bias by its deltas (which is the gradients)
            self.bias_o += gradients_o

            hidden_1_errors = self.weights_ho.T.dot(output_errors)
            hidden_1_gradient = vdsigmoid(hidden_1) * hidden_1_errors * self.learning_rate
            weight_ih_deltas = hidden_1_gradient.dot(inputs.transpose())

            self.weights_ih1 += weight_ih_deltas
            # adjust the bias by its deltas (which is the gradient)
            self.bias_h1 += hidden_1_gradient
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@Hypec: in dem Du es komplett weg läßt, wie ich.
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Code: Alles auswählen

  File "mnist4.0.py", line 321, in <module>
    main()
  File "mnist4.0.py", line 305, in main
    train(nn, epochs=epochs, batch_size=batch_size)
  File "mnist4.0.py", line 266, in train
    neuralnet.train(images[counter_rand].data, images[counter_rand].target)
  File "mnist4.0.py", line 94, in train
    weight_ho_deltas = gradients_o.dot(hidden_1.transpose())
ValueError: shapes (10,10) and (1,32) not aligned: 10 (dim 1) != 1 (dim 0)
Diese Fehlermeldung bekomme ich, wenn ich es weglasse. Also der Teil ist notwendig, mir ist jedoch auch bewusst das er in der Form nicht gut ist.
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Irgendwie passen die shapes überhaupt nicht, was ist denn nun input_array?
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

das input_array ist ein 28x28 pixel großes Bild, hat also insgesamt 784 Zahlen. Es ist der mnist Datensatz.
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Das kann nicht sein, denn sonst würde Deine `input`-Kopiererei einen Fehler werfen.
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Hier ein Code der das ganze ausgibt und darunter der Output. (Der Fehler ist gewohlt da sonst das ganze 60000 mal durchlaufen würde.)

Code: Alles auswählen

inputs = np.zeros((len(input_array), 1))
        print(len(input_array))
        for i in range(len(input_array)):
            inputs[i][0] = input_array[i]
        print(len(inputs))
        targets = np.zeros((len(target_array), 1))
        for i in range(len(target_array)):
            targets[i][0] = target_array[i]
        hidden_4 = self.weights_ih1.dot(inputs) + self.bias_h1
        hidden_1 = vsigmoid(hidden_1)

Code: Alles auswählen

784
784

Traceback (most recent call last):
  File "mnist4.0.py", line 323, in <module>
    main()
  File "mnist4.0.py", line 307, in main
    train(nn, epochs=epochs, batch_size=batch_size)
  File "mnist4.0.py", line 268, in train
    neuralnet.train(images[counter_rand].data, images[counter_rand].target)
  File "mnist4.0.py", line 65, in train
    hidden_1 = vsigmoid(hidden_1)
UnboundLocalError: local variable 'hidden_1' referenced before assignment
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Also willst Du nur aus irgend einem Grund ein 2d-Array aus Deinem Vektor haben:

Code: Alles auswählen

input = np.atleast_2d(input_array).T
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Naja das ist ja nicht irgendein Grund, anderst Funktioniert es ja offensichtlich nicht.
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Das liegt aber nur daran, dass an anderer Stelle wieder irgend etwas mit den Dimensionen nicht ganz passt.
Antworten