Я скачал код для CoreMLBERT, оптимизированный для ответа на вопрос . Мне нужно масштабировать его для более крупного текста, веб-сайт рекомендовал два метода, используя механизм поиска или сегментируя текст, и выводя прогноз для каждого раздела. Я выбрал второй вариант, однако мой алгоритм, похоже, выводит ответ только из первой сегментации текста.
Я также включил текст, который использовал для проверки ниже, к вопросу: «Что делаетХанская академия "привела бы к ответу:" желуди "
import CoreML
class BERT {
/// The underlying Core ML Model.
let bertModel = BERTQAFP16()
/// Finds an answer to a given question by searching a document's text.
///
/// - parameters:
/// - question: The user's question about a document.
/// - document: The document text that (should) contain an answer.
/// - returns: The answer string or an error descripton.
/// - Tag: FindAnswerForQuestionInDocument
func findAnswer(for question: String, in document: String) -> Substring {
// Prepare the input for the BERT model.
//My own function, which works fine in terms of splitting the text, only the prediction is the problem.
let textArray = split(maxTokens: BERTInput.maxTokens, documentString: document)
print("The amount of sections in text array is:")
print(textArray.count)
//Slightly edited bertInput to take in more than 384 tokens
let bertInputOG = BERTInputOG(documentString: document, questionString: question)
var startLogitsArray = [Double]()
var endLogitsArray = [Double]()
var topStartIndices = [Int]()
var topEndIndices = [Int]()
for i in 0...(textArray.count-1){
let bertInput = BERTInput(documentString: textArray[i], questionString: question)
// The MLFeatureProvider that supplies the BERT model with its input MLMultiArrays.
let modelInput = bertInput.modelInput!
// Make a prediction with the BERT model.
guard let prediction = try? bertModel.prediction(input: modelInput) else {
return "I don't have an answer. Ask your teacher this question *Beep*."
}
// Analyze the output form the BERT model.
//I'm assuming the error is here somewhere
//Taking the logits and indexes for each section, then adding it to the main array for later
let startlogits = bestLogitsIndices(from: prediction, in: bertInput.documentRange)!.startLogitsOfDoc
let endlogits = bestLogitsIndices(from: prediction, in: bertInput.documentRange)!.endLogitsOfDoc
let startindexes = bestLogitsIndices(from: prediction, in: bertInput.documentRange)!.topStartIndices
let endindexes = bestLogitsIndices(from: prediction, in: bertInput.documentRange)!.topEndIndices
for j in 0...(startlogits.count-1){
startLogitsArray.append((startlogits[j]))
endLogitsArray.append((endlogits[j]))
}
for k in 0..<(startindexes.count-1){
topStartIndices.append((startindexes[k]))
topEndIndices.append((endindexes[k]))
}
//Prediction for each section, just to see what was going on
let bestPair = findBestLogitPair(startLogits: startlogits,
bestStartIndices: startindexes,
endLogits: endlogits,
bestEndIndices: endindexes)
let documentTokens = bertInput.document.tokens
let answerStart = documentTokens[bestPair.start].startIndex
let answerEnd = documentTokens[bestPair.end].endIndex
let originalText = bertInput.document.original
print("The prediction for this section is:")
print(originalText[answerStart..<answerEnd])
print("\n")
}
// Search for the highest valued logit pairing.
//Final prediction
let bestPair = findBestLogitPair(startLogits: startLogitsArray,
bestStartIndices: topStartIndices,
endLogits: endLogitsArray,
bestEndIndices: topEndIndices)
// Find the indices of the original string.
let documentTokens = bertInputOG.document.tokens
let answerStart = documentTokens[bestPair.start].startIndex
let answerEnd = documentTokens[bestPair.end].endIndex
// Return the portion of the original string as the answer.
let originalText = bertInputOG.document.original
return originalText[answerStart..<answerEnd]
}
}
Мой текст: Наш друг-белочка здесь любит собирать желуди, потому что, действительно, именно так он способен жить. И скажем, каждый день он собирает ровно три желудя. И вот что меня интересует, сколько желудей у него будет после пяти дней? Поэтому один из способов думать об этом - каждый день он может собрать группу из трех желудей. Таким образом, вы могли бы рассматривать это как, возможно, то, что он смог собрать в первый день. И затем во второй день он может собрать вторую группу из трех желудей. На третий день он может собрать еще одну группу из трех желудей. И каждый день столько же желудей он собирает. На четвертый день еще три. На пятый день еще три. И поэтому, если бы вам было любопытно, сколько всего желудей он собрал, ну, вы могли бы просто подсчитать их, или вы могли бы подумать, ну, у него есть пять групп по три желудя. Пять равных групп по три желудя. Таким образом, вы могли бы сказать пять групп по три желудя, три желудя. И поэтому общая сумма будет пять, мы можем рассматривать это как пять тройки. Теперь, пять тройок, вы можете рассматривать это как пять тройок, сложенных вместе. Три плюс три, плюс три, плюс три, плюс три. И если вы хотите рассчитать это, вы можете пропустить счет на три. Таким образом, это будет три, шесть, девять, 12, 15, потому что мы добавляем три, мы получаем шесть, мы добавляем еще три, мы получаем девять, мы добавляем еще три, мы получаем 12, мы добавляем еще три, мыдоберитесь до 15. Итак, это был бы способ узнать, что у вас 15 желудей, но мы начинаем касаться одной из самых фундаментальных идей во всей математике. Фактически, мы на самом деле применяем это, мы просто не использовали мир, и это, мы умножаем. Мы используем умножение. Все умножение - это понятие множественных равных групп чего-либо. Итак, вот один из способов выразить то, что мы только что сделали, это то, что мы просто, когда мы сказали пять по три, это то же самое, что и пять, и я собираюсь представить вам новый символ, пять раз три. Так что все эти вещи эквивалентны. Вы уже привыкли видеть равные группы и несколько одинаковых групп, и вы привыкли что-то добавлять несколько раз, и вы привыкли пропускать подсчет, и все это в некотором роде или форме, вы былиделать умножение. Поэтому, когда кто-то говорит пять раз по три, вы можете рассматривать это как пять групп по три, или вы можете рассматривать это как пять по три, или вы можете рассматривать это как три плюс три, плюс три, плюс три, или вы можете рассматривать это как 15Я оставлю тебя там. В Академии Хана много практики, чтобы проработать это и убедиться, что вы поняли основную идею. Но, как вы увидите, это, возможно, одна из самых полезных концепций, которую вы могли бы выучить за всю свою жизнь.