минимизация потерь в tenorflow.js для нейронной сети с прямой связью - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь создать пример нейронной сети с прямой связью в tenorflow.js, изначально используя небольшой набор данных (только для POC).Есть 5 входных узлов и один выходной узел.Данные относятся к жилью, где есть несколько входных данных, и мы прогнозируем цену.

x_train:
[ [ 79545.45857, 5.682861322, 7.009188143, 4.09, 23086.8005 ],
  [ 79248.64245, 6.002899808, 6.730821019, 3.09, 40173.07217 ],
  [ 61287.06718, 5.86588984, 8.51272743, 5.13, 36882.1594 ],
  [ 63345.24005, 7.188236095, 5.586728665, 3.26, 34310.24283 ],
  [ 59982.19723, 5.040554523, 7.839387785, 4.23, 26354.10947 ],
...
] 

y_train
[ [ 1059033.558 ],
  [ 1505890.915 ],
  [ 1058987.988 ],
  [ 1260616.807 ],
  [ 630943.4893 ],
...
]

const model = tf.sequential();
const config_hidden = {
        inputShape: [5],
        activation: 'sigmoid',
        units: 6
    }

const config_output = {
    units: 1,
    activation: 'sigmoid'
}

const hidden = tf.layers.dense(config_hidden);
const output = tf.layers.dense(config_output);

model.add(hidden);
model.add(output);

const optimizer = tf.train.sgd(0.5);

const config = {
    optimizer: optimizer,
    loss: 'meanSquaredError',
    metrics: ['accuracy']
}

model.compile(config);

train_data().then(function () {
    console.log('Training is Complete');
}

async function train_data() {
    const options = {
        shuffle: true,
        epochs: 10,
        batch_size: 100,
        validationSplit: 0.1
    }

    for (let i = 0; i < 10; i++) {
        const res = await model.fit(xs, ys, options);
        console.log(res.history.loss[0]);
    }
}

Модель прекрасно компилируется.Но потери при обучении модели огромны

Model Successfully Compiled
Epoch 1 / 10
eta=0.0 ====================================================================>
1058ms 235us/step - acc=0.00 loss=1648912629760.00 val_acc=0.00 val_loss=1586459705344.00
Epoch 2 / 10
eta=0.0 ====================================================================>
700ms 156us/step - acc=0.00 loss=1648913285120.00 val_acc=0.00 val_loss=1586459705344.00
Epoch 3 / 10
eta=0.0 ====================================================================>
615ms 137us/step - acc=0.00 loss=1648913022976.00 val_acc=0.00 val_loss=1586459705344.00
Epoch 4 / 10
eta=0.0 ====================================================================>
852ms 189us/step - acc=0.00 loss=1648913285120.00 val_acc=0.00 val_loss=1586459705344.00

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

xs = xs.div(xs.mean(0));

x_train
[[1.1598413, 0.9507535, 1.003062 , 1.0272969, 0.6384002],
     [1.1555134, 1.0042965, 0.9632258, 0.7761241, 1.1108726],
     [0.8936182, 0.9813745, 1.2182286, 1.2885166, 1.0198718],
     ...,

Нет больших изменений в потере

Model Successfully Compiled
Epoch 1 / 10
eta=0.0 ====================================================================>
841ms 187us/step - acc=0.00 loss=1648912760832.00 val_acc=0.00 val_loss=1586459705344.00
Epoch 2 / 10
eta=0.0 ====================================================================>
613ms 136us/step - acc=0.00 loss=1648913154048.00 val_acc=0.00 val_loss=1586459705344.00
Epoch 3 / 10
eta=0.0 ====================================================================>
646ms 144us/step - acc=0.00 loss=1648913022976.00 val_acc=0.00 val_loss=1586459705344.00

Затем я также нормализовал вывод,

ys = ys.div(1000000);

Model Successfully Compiled
Epoch 1 / 10
eta=0.0 ====================================================================>
899ms 200us/step - acc=0.00 loss=0.202 val_acc=0.00 val_loss=0.161
Epoch 2 / 10
eta=0.0 ====================================================================>
667ms 148us/step - acc=0.00 loss=0.183 val_acc=0.00 val_loss=0.160
Epoch 3 / 10
eta=0.0 ====================================================================>
609ms 135us/step - acc=0.00 loss=0.182 val_acc=0.00 val_loss=0.159

Это привело к снижению потерь до десятичных цифр.Однако видно, что даже выполнение 10000 итераций для данных обучения существенно не уменьшает потери.Например,

Epoch 8 / 10
eta=0.0 ====================================================================>
502ms 112us/step - acc=0.00 loss=0.181 val_acc=0.00 val_loss=0.158
Epoch 9 / 10
eta=0.0 ====================================================================>
551ms 122us/step - acc=0.00 loss=0.181 val_acc=0.00 val_loss=0.158
Epoch 10 / 10
eta=0.0 ====================================================================>
470ms 104us/step - acc=0.00 loss=0.181 val_acc=0.00 val_loss=0.158
0.18076679110527039

Наконец, потери начинаются с отметки 0,202 и снижаются до отметки 0,180.Это приводит к неправильным прогнозам.

Это очень распространенный сценарий.Несколько входов имеют значения в разных диапазонах (например, данные корпуса, как указано выше).Несколько входов передаются в прямую нейронную сеть.Ожидается только один выход (цена в данном случае).

Вопросы: 1. Что я делаю не так в коде выше?2. Правильно ли я нормализую данные?3. Использую ли я правильную функцию потерь / оптимизатор / скорость обучения / активацию и т. Д. 4. Как узнать, хорошо ли работает модель 5. Есть ли какой-либо другой способ сделать это в tenorflow.js?

1 Ответ

1 голос
/ 07 мая 2019

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

  1. Удалить сигмовидную активацию с выхода.Сигмовидная функция сдавливает входы между 0 и 1, поэтому она не предназначена для регрессии.Ваш последний слой не нуждается в активации.

  2. Ваша скорость обучения слишком высока, поэтому я сомневаюсь, что алгоритм обучения сможет сойтись.Начните со значений около 0,001 - 0,01 и т. Д. И отрегулируйте их при необходимости.

  3. Нет, вы неправильно нормализуете.Как правило, данные нормированы на среднее значение, равное нулю, и стандартное отклонение, равное единице.Это делается для каждого столбца объекта с использованием среднего значения и стандартного отклонения только этого столбца, а не всех данных.Например, формула i в столбце признаков x выглядит следующим образом: (x_i - x.mean()) / x.std().(Я не знаю javascript)

  4. Метрика производительности, которую вы указали, «точность», предназначена для классификации, а не для регрессии, и будет бессмысленной (если она даже будет указана).Минимизация среднеквадратичной или абсолютной квадратичной ошибки - лучший способ количественной оценки производительности модели.

...