Создание нейронной сети в керасе для умножения двух входных чисел - PullRequest
0 голосов
/ 13 мая 2018

Я играю с Keras v2.0.8 в Python v2.7 (бэкэнд Tensorflow) для создания небольших нейронных сетей, которые вычисляют простые арифметические функции (сложение, вычитание, умножение и т. Д.), И я немного запутался. Приведенный ниже код является моей сетью, которая генерирует случайный обучающий набор данных из целых чисел с соответствующими метками (два входа, добавленные вместе):

def create_data(low, high, examples):

    train_data = []
    label_data = []

    a = np.random.randint(low=low, high=high, size=examples, dtype='int')
    b = np.random.randint(low=low, high=high, size=examples, dtype='int')

    for i in range(0, examples):
        train_data.append([a[i], b[i]])
        label_data.append((a[i] + b[i]))

    train_data = np.array(train_data)
    label_data = np.array(label_data)

    return train_data, label_data

X, y = create_data(0, 500, 10000)

model = Sequential()
model.add(Dense(3, input_dim=2))
model.add(Dense(5, activation='relu'))
model.add(Dense(3, activation='relu'))
model.add(Dense(5, activation='relu'))
model.add(Dense(1, activation='relu'))

model.compile(optimizer='adam', loss='mean_squared_error', metrics=['accuracy'])
model.fit(X, y, epochs=10, batch_size=10)

test_data, _ = create_data(0, 500, 10)
results = model.predict(test_data, batch_size=2)

sq_error = []
for i in range(0, len(test_data)):
    print 'test value:', test_data[i], 'result:', results[i][0], 'error:',\
          '%.2f' %(results[i][0] - (test_data[i][0] + test_data[i][1]))
    sq_error.append((results[i][0] - (test_data[i][0] + test_data[i][1])))

print '\n total rmse error: ', sqrt(np.sum(np.array(sq_error)))

Это отлично тренируется и не дает неожиданных результатов. Однако, когда я создаю обучающие данные путем умножения двух входов вместе, потери модели для каждой эпохи остаются около 7 000 000 000, и модель не сходится вообще. Функция создания данных для этого выглядит следующим образом:

def create_data(low, high, examples):

    train_data = []
    label_data = []

    a = np.random.randint(low=low, high=high, size=examples, dtype='int')
    b = np.random.randint(low=low, high=high, size=examples, dtype='int')

    for i in range(0, examples):
        train_data.append([a[i], b[i]])
        label_data.append((a[i] * b[i]))

    train_data = np.array(train_data)
    label_data = np.array(label_data)

    return train_data, label_data 

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

У меня два вопроса:

1) Почему это так? Я предполагаю, что это как-то связано с основами нейронных сетей, но я не могу решить это.

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

Сетевая архитектура (2 - 3 - 5 - 3 - 5 - 1) сейчас довольно случайна. Я перепробовал много разных, меняющихся по слоям и нейронам, этот случайно оказался у меня на экране, когда я писал это, и получил 100% точность при добавлении двух входов.

1 Ответ

0 голосов
/ 14 мая 2018

Это связано с большими обновлениями градиента, вызванными большим количеством данных в обучении.При использовании нейронной сети вы должны сначала убедиться, что обучающие данные попадают в небольшой диапазон (обычно [-1,1] или [0,1]), чтобы помочь процессу оптимизации и предотвратить разрушительные обновления градиента.Поэтому сначала следует нормализовать данные.В этом случае одним хорошим кандидатом будет log-normalization .

Кстати, поправьте меня, если я ошибаюсь: я думаю, 'accuracy' как метрика в кератах используется в случаепроблемы классификации?А в задаче регрессии лучшим вариантом будет «средняя абсолютная ошибка» или 'mae'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...