Как исправить ошибку «TypeError: массивы объектов в настоящее время не поддерживаются» в numpy python 3 (умножение матриц) - PullRequest
0 голосов
/ 31 декабря 2018

Я пытаюсь сделать свою собственную нейронную сеть "библиотекой" (если можно так назвать) для себя, так как я хобби изучаю их.

Я написал этот код, который делаетраспространяемая нейронная сеть, передавая ей структуру желаемой сети, и она работала довольно хорошо.

Но тогда, когда я попытался дать модели другое количество узлов, код BUGGED

Я уже пытался отредактировать количество узлов в каждом слое и посмотреть, куда меня это приведет, и я узнал, что я получаю только эту ошибкукогда первый и второй слой имеют одинаковое количество узлов в них, но выходной слой имеет разное количество.Я также попытался сделать матричное умножение структуры, которая выводит ошибку на бумаге, и это дало мне реальный результат (который я дважды проверял на достоверность много раз).Так что теперь я знаю, что это имеет отношение к практическому, а не теоретическому.Я думаю, что с умножением матриц явно что-то не так.

Функции скрипта

Мне нужно было включить эти функции в вопрос, чтобы вы могли лучше понять, как этокод работает.

is_iterable ()

Эта функция возвращает логическое значение, которое описывает, является ли ввод повторяемым

    def is_iterable(x):
        try:
            x[0]
            return True
        except:
            return False

blueprint ()

Thisфункция возвращает копию входного массива, но изменяет элементы, которые не могут быть повторены, на 0 *

    def blueprint(x):
        return [blueprint(e) if is_iterable(e) else 0 for e in x]

build ()

Эта функция принимает модель желаемой структуры нейронной сети в качестве входных данныхи выводит подходящие рандомизированные смещения и веса, разделенные на два разных массива. Функция randomize () возвращает копию входного массива, но изменяет элементы, которые не могут быть повторены, на случайные числа с плавающей запятой между -1 и 1.Функция build-weights () возвращает рандомизированные весовые коэффициенты на основе модели нейронной сети.

    def build(x):

        def randomize(x):
            return np.array([randomize(n) if type(n) is list else random.uniform(-1, 1) for n in x])

        def build_weighs(x):
            y = []
            for i, l in enumerate(x):
                if i == len(x) - 1:
                    break
                y.append([randomize(x[i + 1]) for n in l])
            return np.array(y)

        return (randomize(x), build_weighs(x))

apply_funcs ()

Эта функция применяет список функций к другому спискуфункции, а затем возвращает их.Если список функций содержит 0, элемент из другого списка, расположенный в том же месте, не будет применен ни к одной функции.

    def apply_funcs(x, f):
        y = x
        i = 0
        for xj, fj in zip(x, f):
            if fj == 0:
                y[i] = xj
            else:
                y[i] = fj(xj)
            i += 1
        return y

nn ()

Это класс длясоздание нейронной сети.Вы можете видеть, что у него есть функция с именем 'prop' для прямого распространения в сети.

    class nn:
        def __init__(self, structure, a_funcs=None):
            self.structure = structure
            self.b = np.array(structure[0])
            self.w = np.array(structure[1])
            if a_funcs == None:
                a_funcs = blueprint(self.b)
            self.a_funcs = np.array(a_funcs).

        def prop(self, x):
            y = np.array(x)
            if y.shape != self.b[0].shape:
                raise ValueError("The input needs to be intact with the Input Nodes\nInput: {} != Input Nodes: {}".format(blueprint(y), blueprint(self.b[0])))
            wi = 0
            # A loop through the layers of the neural network
            for i in range(len(self.b)):
                # This if statement is here so that the weights get applied in the right order
                if i != 0:
                    y = np.matmul(y, self.w[wi])
                    wi += 1
                # Applying the biases of layer i to the current information
                y = np.add(y, self.b[i])
                # Applying the activation functions to the current information
                y = apply_funcs(y, self.a_funcs[i])

            return y

Определение структуры нейронной сети и ее распространение

n содержит структуру, которая представляет собой трехслойную сеть, содержащую соответственно 2 узла, 2 узла и 3 узла.

    n = [[0] * 2, [0] * 2, [0] * 3]
    bot = nn(build(n))
    print(bot.prop([1] * 2))

Когда я сделаю это, я ожидаю, что код выведет массивтри полуслучайных числа, подобные этому:

    [-0.55889818  0.62762604  0.59222784]

, но вместо этого я получаю ошибку от numpy, говоря это:

    File "C:\Users\Black\git\Changbot\oper.py.py", line 78, in prop
        y = np.matmul(y, self.w[wi])
    TypeError: Object arrays are not currently supported

И самое странное в этом то, что (как я уже говорил ранее)) Я получаю эту ошибку только тогда, когда первый и второй слои имеют одинаковое количество узлов, но выходной слой имеет разное количество.Все остальное время я получаю ожидаемый результат ...

Теперь я снова проверил значения, которые вызывают эту ошибку, и я не вижу никаких объектов, кроме списка.Это то же самое, когда это не глючит ... Поэтому я добавил это выражение try-exc:

    try:
        y = np.matmul(np.array(y), self.w[wi])
    except TypeError:
        print("y:{}\nself.w[wi]:{}".format(y, self.w[wi]))

Затем выдает это:

    y:[1.6888437]
    self.w[wi]:[array([-0.19013173])]

, которое должно иметь возможность умножатьсядруг с другом я даже пытался скопировать вставив значения в интерпретатор и умножить их там, и это работает там ...

ПРИМЕЧАНИЕ: ЭТО ОЧЕНЬ ПЛОХОЙ ТЕСТ, КАК КОРОБКИ ПЕРЕДАЧНОЙ ПАСТЫ НЕ ДЕЛАЮТ 'Имеют те же типы в качестве фактических массивов

    np.matmul([1.6888437], [np.array([-0.19013173])])

Вывод для вышеупомянутого:

    [-0.32110277]

После просмотра ответов

Хорошо.Теперь я обнаружил, что объектные массивы dtype лежат в структуре нейронной сети, выполнив это в конце скрипта:

    print("STRUCTURE:{}".format(n))

Затем он выводит это:

    STRUCTURE:(array([array([0.6888437]), array([ 0.51590881, -0.15885684]),
   array([-0.4821665 ,  0.02254944, -0.19013173])], dtype=object), array([list([array([ 0.56759718, -0.39337455])]),
   list([array([-0.04680609,  0.16676408,  0.81622577]), array([ 0.00937371, -0.43632431,  0.51160841])])],
  dtype=object))

Исправление ошибки

Я могу понять из одного из ответов на этот пост, что np.array () пытается создать как можно больший размерный массив, и, в случае неудачи, возвращается к объекту dtype (или для некоторых комбинаций входных данных).выдает ошибку).

Объект dtype создается в функции build () , поэтому я попытался удалить все функции np.array () втот.На самом деле я удалил все это из всего сценария. И угадайте, что? Это сработало!1000 раз спасибо вам за вклады!

Кстати С Новым Годом

1 Ответ

0 голосов
/ 31 декабря 2018

Что касается тестирования копирования-вставки:

In [55]: np.matmul([1.6888437], [np.array([-0.19013173])])
Out[55]: array([-0.32110277])

Но это не то, что использует ваш код.Вместо этого мы должны сделать массивы, которые соответствуют в dtype.

In [59]: x = np.array([1.6888437]); y = np.array([np.array([-0.19013173]),None])[:1]
In [60]: x
Out[60]: array([1.6888437])
In [61]: y
Out[61]: array([array([-0.19013173])], dtype=object)

Я использовал забавный бизнес None, чтобы заставить его создать объект dtype, содержащий массив, который будет print иметь значение [array([-0.19013173])].

. Теперь я получаю вашу ошибку:

In [62]: np.matmul(x,y)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-62-b6212b061655> in <module>()
----> 1 np.matmul(x,y)

TypeError: Object arrays are not currently supported

Даже если все работает как с dot

In [66]: np.dot(x,y)
Out[66]: array([-0.32110277])

, вычисления с массивами dtype объекта выполняются медленнее.

Я не буду пытаться вычислитьпочему у вас есть массив dtype объекта на данный момент.Но я думаю, что вы должны избегать тех в коде, где скорость имеет значение.

Если вы создаете массив из массивов или списков, которые различаются по размеру, результатом, вероятно, будет объект типа d с меньшим числом измерений.np.array пытается создать как можно больший размерный массив, и в случае неудачи возвращается объект dtype (или для некоторых комбинаций входов возникает ошибка).

...