Как мне реализовать обратное распространение комплексной нейронной сети с помощью задачи mnist? - PullRequest
0 голосов
/ 16 апреля 2019

Я запустил следующий код, но точность была около 30%.

Как мне изменить код? например функция потери? сеть? и т.д.

В задаче радужной оболочки точность была более 90%.

# simple neural network of one complex valued neuron
# extended to use a periodic activation function
import numpy as np, numpy
# pandas for reading csv files
import pandas
# sklearn for splitting data into test/train sets
import sklearn.cross_validation
from keras.datasets import mnist

class neuralNetwork:

    def __init__(self, inputs, cats, periods):
        # number of inputs
        self.inputs = inputs

        # link weights matrix
        self.w = numpy.random.normal(0.0, pow(1.0, -0.5), (self.inputs + 1))
        self.w = numpy.array(self.w, ndmin=2, dtype='complex128')
        self.w += 1j * numpy.random.normal(0.0, pow(1.0, -0.5), (self.inputs + 1))

        # testing overrride
        #self.w = numpy.array([1.0 + 0.0j, 1.0 + 0.0j], ndmin=2, dtype='complex128')

        # number of output class categories
        self.categories = cats

        # todo periodicity
        self.periodicity = periods

        pass

    def z_to_class(self, z):
        # first work out the angle, but shift angle from [-pi/2, +pi.2] to [0,2pi]
        angle = numpy.mod(numpy.angle(z) + 2*numpy.pi, 2*numpy.pi)
        # from angle to category
        p = int(numpy.floor (self.categories * self.periodicity * angle / (2*numpy.pi)))
        p = numpy.mod(p, self.categories)
        return p

    def class_to_angles(self, c):
        # class to several angles due to periodicity, using bisector
        angles = (c + 0.5 + (self.categories * numpy.arange(self.periodicity))) / (self.categories * self.periodicity) * 2 * numpy.pi
        return angles

    def status(self):
        print ("w = ", self.w)
        print ("categories = ", self.categories)
        print ("periodicity = ", self.periodicity)
        pass

    def query(self, inputs_list):
        # add bias input
        inputs_list.append(1.0)

        # convert input to complex
        inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T
        #print("inputs = \n", inputs)

        # combine inputs, weighted
        z = numpy.dot(self.w, inputs)
        #print("z = ", z)

        # map to output classes
        o = self.z_to_class(z)
        #print("output = ", o)
        #print ("")
        return o

    def train(self, inputs_list, target):
        # add bias input
        inputs_list.append(1.0)
        #print(inputs_list)

        # convert inputs and outputs list to 2d array
        inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T
        #print(inputs)
        #exit()

        # combine inputs, weighted
        z = numpy.dot(self.w, inputs)[0]

        # desired angle from trainging set
        # first get all possible angles
        desired_angles = self.class_to_angles(target)

        # potential errors errors
        errors =  numpy.exp(1j*desired_angles) - z
        # select smallest error
        e = errors[numpy.argmin(numpy.abs(errors))]

        # dw = e * x.T / (x.x.T)
        dw = (e * numpy.conj(inputs.T)) / (self.inputs + 1)
        #print("dw = ", dw)
        self.w += dw
        #print("new self.w = ", self.w )
        #print("test new self.w with query = ", self.query(inputs.T))
        #print("--")
    pass

# create instance of neural network
number_of_inputs = 28 * 28 * 1
categories = 3
periods = 3

n = neuralNetwork(number_of_inputs, categories, periods)
n.status()

# train neural network
epochs = 10

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train[:10000]
y_train = y_train [:10000]
x_train = np.reshape(x_train, (-1, 28*28*1))
x_test = np.reshape(x_test, (-1, 28*28*1))

tmp_train_data = np.empty((0, 784))
tmp_label_data = np.empty((0))
for i in range(len(y_train)):
  if int(y_train[i]) < categories:
      tmp_train_data = np.append(tmp_train_data, [ (x_train[i]/255 * 0.99) + 0.01], axis=0)
      tmp_label_data = np.append(tmp_label_data, [y_train[i]], axis=0)

x_train = tmp_train_data
y_train = tmp_label_data

print("starting training")
for ep in range(epochs):
  print(str(ep) + ", done")
  for i in range (len(y_train)):
    n.train(x_train[i].tolist(), y_train[i].tolist())

# query after training
correct_count = 0
for i in range (len(y_train)):
  estimate = n.query(x_train[i].tolist())
  print(int(y_train[i]), estimate)
  if estimate == y_train[i]:
    correct_count += 1

print(correct_count)
print(len(y_train))
print ("performance = ", correct_count / len(y_train))

Этот код изменил следующее. http://makeyourownneuralnetwork.blogspot.com/2016/05/complex-valued-neural-networks.html#comment-form

Я пробовал несколько слоев, но и те не дали хорошего результата.

...