Я новичок в Tensorflow и машинном обучении.
Моя задача - предсказать тип ввода данной строки. Вот пример обучающих данных (с выводом, уже закодированным в горячем виде):
const training = [
{ x: '622-49-7314', y: [1,0,0,0] }, // "ssn"
{ x: '1234 Elm Street', y: [0,1,0,0] }, // "street-address"
{ x: '(419) 555-5555', y: [0,0,1,0] }, // "phone-number"
{ x: 'Jane Doe', y: [0,0,0,1] }, // "full-name"
{ x: 'José García', y: [0,0,0,1] }, // "full-name"
// ... and millions more examples...
]
Моя первая проблема - как закодировать ввод, поскольку это не типичная проблема текстового словаря (последовательность слов ) а точнее последовательность букв переменного размера .
Я пробовал 3 подхода к кодированию для входной строки:
Кодировка 1, стандартные вложения текста :
async function encodeData(data) {
const sentences = data.map(str => str.toLowerCase());
const model = await use.load();
const embeddings = await model.embed(sentences);
return embeddings;
}
Кодировка 2, дополненные буферы Юникода и нормализованная экспонента (softmax):
function encodeStr(str, pad = 512) {
let arr = Array.from(
new Int32Array(Buffer.from(str.padEnd(pad, '\0'), 'utf16le'))
);
const sum = arr.reduce((t, v) => t + Math.exp(v), 0);
arr = arr.map(el => Math.exp(el) / sum);
return arr;
}
Кодировка 3, местность, га sh, разбитый на шестнадцатеричный вектор длины 64 и нормализованную экспоненту (softmax):
const { Nilsimsa } = require('nilsimsa');
function encodeHash(str) {
const hash = new Nilsimsa(str).digest('hex'),
vals = hash.split(/(?<=^(?:.{2})+)(?!$)/).map(el => parseInt(el, 16));
const sum = vals.reduce((t, v) => t + Math.exp(v), 0),
normArr = vals.map(el => Math.exp(el) / sum);
return normArr;
}
Затем я использовал простую модель:
const inputSz = 512; // or 128 for encodeStr, or 32 for encodeHash
const outputSz = 4; // [0,0,0,0] - the size of the one-hot encoding (potentially could be >1000)
model.add(
tf.layers.dense({
inputShape: [inputSz],
activation: 'softmax',
units: outputSz
})
);
model.add(
tf.layers.dense({
inputShape: [outputSz],
activation: 'softmax',
units: outputSz
})
);
model.add(
tf.layers.dense({
inputShape: [outputSz],
activation: 'softmax',
units: outputSz
})
);
model.compile({
loss: 'meanSquaredError',
optimizer: tf.train.adam(0.06)
});
Что обучено так:
const trainingTensor = tf.tensor2d( data.map(_ => encodeInput(_.input)));
const [encodedOut, outputIndex, outSz] = encodeOutput(data.map(_ => _.output));
const outputData = tf.tensor2d(encodedOut);
const history = await model.fit(trainingTensor, outputData, { epochs: 50 });
Но результаты все очень плохие, в среднем потеря = 0,165 . Я пробовал разные конфиги, используя подходы выше, ie. «softmax» и «sigmoid» активации, более или менее плотные слои, но я просто не могу понять это.
- Какой лучший способ кодировать строки, которые не являются просто текстом?
- Каков правильный тип сети и конфигурация модели для этого типа классификации?
Любая помощь или какое-либо направление здесь будут оценены, как я могу не могу найти хороших примеров для обоснования моего решения.