Деление по нейронной сети; фиксированная стоимость, производимая каждый раз

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

import tensorflow as tf
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras import regularizers

num_train = 1000

X_train = np.random.rand(num_train, 2)
y_train_add = X_train[:, 0] + X_train[:, 1]

model_add = Sequential(
        [
            Dense(10),
            Dense(1)
            ]
        )

batch_size = 32
epochs = 100

model_add.compile(loss = 'mse', optimizer='adam')
model_add.fit(X_train, y_train_add, batch_size=batch_size, epochs=epochs, verbose = 1)

a = np.random.random((2000000,1))*100-50
b = np.random.random((100000,1))*10
x_train = np.append(a, b)
#This is because previously there had been severe inaccuracies near 0, which led to problems during division, so I increased the training data near zero
y_train = np.square(x_train)

model_sqr = Sequential(
        [
            Dense(8, activation = 'elu', kernel_regularizer = regularizers.l2(0.001), input_shape = (1,)),
            Dense(8, activation = 'elu', kernel_regularizer = regularizers.l2(0.001)),
            Dense(1)
            ]

        )

batch_size = 32
epochs = 100

model_sqr.compile(loss = 'mse', optimizer='adam')
model_sqr.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose = 1)

x = "n" 
while True:
    print("enter first num:")
    x = input()
    if x == "end":
        break

    print("Enter operation:")
    op= input()

    print("enter second num:")
    y = input()

    X = int(x)
    Y = int(y)
    Ydiv = np.reciprocal(Y)

    if op == "*":
        predicted_product = model_sqr.predict(model_add.predict(np.array([[X, Y]]))) - model_sqr.predict(np.array([X])) -  model_sqr.predict(np.array([Y]))
        print(predicted_product/2)
    elif op = = "/":
        predicted_quot = model_sqr.predict(model_add.predict(np.array([[X, Ydiv]]))) - model_sqr.predict(np.array([X])) -  model_sqr.predict(np.array([Ydiv]))
        print(predicted_quot/2)

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

Пытаясь понять, почему это происходит, я запустил, например, 25/5, изменив программу так, чтобы она отображала (25+(1/5))^2, 25^2 и (1/5)^2. слишком. Я получил значения 623,7364, 623,73645 и 0,24594116.

Чтобы понять, почему были получены эти значения и как их исправить, я вместе построил квадратную функцию (оранжевый) и свою модель нейронной сети для квадрата (синий):

Увеличение близко к 25;

Увеличение близко к 0;

Проблема в том, что промежуточные значения, которые я вижу, были предсказаны на основе графиков, это не те, которые я распечатал. Используя курсор, я мог видеть, например, что 25^2 было предсказано примерно как 624, (25+(1/5))^2 было предсказано примерно 634 и (1/5)^2 было предсказано как быть 0,42. Используя эти значения, вы получите приемлемый ответ, но значения, которые я распечатал, другие.

(1): Почему эти значения различны?

(2): Как я могу заставить модель делать приемлемые прогнозы, которые, по-видимому, дает график?

Можешь поделиться сюжетом крупным планом? те, которыми вы поделились, слишком уменьшены, чтобы с такой точностью определить их значение.

Benet Oriol 27.06.2024 08:12

@BenetOriol: Увеличенную версию какого из них вам нужна?

harry 27.06.2024 10:50

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

Benet Oriol 27.06.2024 17:57

@BenetOriol: Да, я использую один и тот же сохраненный файл .keras как для программы печати, так и для сценария. Сценарий, который я запускаю для отображения значений, на самом деле представляет собой отдельную программу, а не приведенную выше; он состоит только из импорта файла .keras, а затем цикла while в приведенном выше коде.

harry 28.06.2024 08:45

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

Ian Chu 28.06.2024 16:03

Попробуйте обучить модель на разном количестве выборок (1000, 10000, 50000 и т. д.) и проверьте, улучшается ли точность при увеличении количества выборок. Если повышение точности стабилизируется, вы можете добавить больше слоев и повторить попытку.

Ian Chu 28.06.2024 16:05

@IanChu: Количество обучающих примеров уже составило 2 100 000, поэтому я оставил его прежним и обучил их на модифицированной модели из пяти слоев: 16 нейронов в первых четырех и один в последнем. Теперь я получаю довольно точный набор значений из графика: 634,90, 624,85 и 0,1. Они должны дать значение, близкое к 5, но я все равно получаю разные значения для каждого из них, когда запускаю окончательный сценарий, и проблема небольшого фиксированного числа сохраняется. Что мне следует сделать, чтобы это исправить?

harry 29.06.2024 03:31

@harry, ты проверил мой ответ об использовании просто (Y * 1.0) в обратной функции?

michele sponchiado 03.07.2024 09:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
8
207
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, проблема в том, что когда вы выполняете обратное целочисленному значению Y, оно возвращает 0, поэтому вы всегда вычисляете произведение X на ноль.

Y = int(y)
Ydiv = np.reciprocal(Y) # Ydiv is zero because the reciprocal of a positive integer is zero

Я думаю, это основная причина, по которой ваша программа всегда возвращает один и тот же результат.

Чтобы преодолеть эту ситуацию, вы можете, например:

X = int(x)
Y = int(y)
Ydiv = np.reciprocal(Y * 1.0)
print("Ydiv")
print(Ydiv)
print(np.array([X]))
print(np.array([Ydiv]))

if op == "*":
    add_predict = model_add.predict(np.array([[X, Y]]))
    add = float(add_predict[0][0]);
    msqr = model_sqr.predict(np.array([add]));

    xsqr = model_sqr.predict(np.array([X]));

    ysqr = model_sqr.predict(np.array([Y]));
    predicted_product = msqr - xsqr - ysqr
    result = predicted_product[0][0] / 2.0
    print(f'result of {X} * {Y}: {result}')
elif op = = "/":
    add_predict = model_add.predict(np.array([[X, Ydiv]]))
    print("x + 1/y = ")
    print(add_predict)

    add = float(add_predict[0][0]);
    msqr = model_sqr.predict(np.array([add]));

    xsqr = model_sqr.predict(np.array([X]));

    ysqr = model_sqr.predict(np.array([Ydiv]));
    
    #predicted_quot = model_sqr.predict(model_add.predict(np.array([[X, Ydiv]]))) - model_sqr.predict(np.array([X])) -  model_sqr.predict(np.array([Ydiv]))
    predicted_quot = msqr - xsqr - ysqr
    print("result:")
    print(predicted_quot/2)
    print("---------")
    print("x + 1/y = ")
    print(add_predict)
    print(Ydiv)
    print("---------")
    print("(x + 1/y)^2 = ")
    print(msqr)
    print("---------")
    print("(x)^2 = ")
    print(xsqr)
    print("---------")
    print("(y)^2 = ")
    print(ysqr)
    print("---------")

Я выполнил вашу программу на 1000 циклов для деления x/y, дав результаты от 0 до 50, и ошибка между ожидаемым и прогнозируемым результатом кажется хорошей, просто есть смещение 0,5 для компенсации и некоторое расхождение для близких значений. до нуля

Что мне следует использовать вместо этого? Как я упоминал в предыдущем вопросе, Ydiv=1/Y выдает ValueError. np.power() делает то же самое. '

harry 02.07.2024 07:16

Я попробовал привести Y к типу float(y) и попробовал описанное выше, чтобы получить те же результаты.

harry 02.07.2024 07:29

Вы можете использовать, например. (см. исходный ответ для лучшего форматирования) Y = int(y) Ydiv = np.reciprocal(Y * 1.0) ... elif op = = "/": add_predict = model_add.predict(np.array([[X, Ydiv) ]])) add = float(add_predict[0][0]); msqr = model_sqr.predict(np.array([add])); xsqr = model_sqr.predict(np.array([X])); ysqr = model_sqr.predict(np.array([Ydiv])); предсказанный_quot = msqr - xsqr - ysqr

michele sponchiado 02.07.2024 09:01

Я добавил график результатов модели: его можно улучшить, но результаты кажутся нормальными.

michele sponchiado 02.07.2024 10:25

Я добавил в модуль добавления два вектора по 10 000 элементов: один с диапазоном 0 .. 1 и один с диапазоном 0 .. 50, 30 эпох. Аналогичным образом я добавил в модуль умножения два вектора по 40 000 элементов с тем же диапазоном, что и у модели добавления. Как вы сказали, повышение разрешения чисел от 0 до 1 должно повысить точность конечного результата. Наконец, я протестировал нашу модель, удалив приведение к int для x и y и используя пары x,y, чтобы деление x/y не превышало мой максимальный тренировочный диапазон 50, т. е. деление 25/0,1 = 250 выходит за пределы допустимого диапазона и не учитывается.

michele sponchiado 02.07.2024 11:40

Он по-прежнему выдает «ValueError: Исключение, возникшее при вызове Sequential.call(). Невозможно принять длину фигуры с неизвестным рангом». из-за строки «model_sqr.predict(np.array([Ydiv]))». Есть ли способ это исправить?

harry 04.07.2024 16:52

Привет, у меня возникла такая же ошибка при использовании вашего кода; он исчез после того, как я передал в квадратную модель переменную "add", взятую из model_add, как вы можете видеть в моем коде выше.

michele sponchiado 04.07.2024 17:02

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

harry 05.07.2024 11:12

Извините, я еще не пробовал часть умножения; Я посмотрю и сообщу тебе

michele sponchiado 05.07.2024 12:05

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

michele sponchiado 05.07.2024 12:11

Извините, не обращайте внимания на точность в моем предыдущем комментарии: в моем коде была ошибка копирования/вставки, я исправил ее, и модель, похоже, работает нормально.

michele sponchiado 05.07.2024 12:14

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

harry 05.07.2024 12:15

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

michele sponchiado 05.07.2024 12:17

Все в порядке, спасибо, просто ответь, когда будет время.

harry 05.07.2024 12:18

Другие вопросы по теме