implement demo interface;fix eval bug in ner webapp; beautify textline_rec code

pull/2/head
Kai Labusch 5 years ago
parent 3c12e5538a
commit 9560f70580

@ -385,6 +385,8 @@ def model_predict(dataloader, device, label_map, model):
temp_2.pop() # skip last token since its [SEP] temp_2.pop() # skip last token since its [SEP]
y_pred.append(temp_2) y_pred.append(temp_2)
break break
else:
y_pred.append(temp_2)
return y_pred return y_pred

@ -93,12 +93,16 @@ class NERPredictor:
features = [convert_examples_to_features(ex, self._label_to_id, self._max_seq_length, self._bert_tokenizer) features = [convert_examples_to_features(ex, self._label_to_id, self._max_seq_length, self._bert_tokenizer)
for ex in examples] for ex in examples]
assert len(sentences) == len(features)
data_loader = NerProcessor.make_data_loader(None, self._batch_size, self._local_rank, self._label_to_id, data_loader = NerProcessor.make_data_loader(None, self._batch_size, self._local_rank, self._label_to_id,
self._max_seq_length, self._bert_tokenizer, features=features, self._max_seq_length, self._bert_tokenizer, features=features,
sequential=True) sequential=True)
prediction_tmp = model_predict(data_loader, self._device, self._label_map, self._model) prediction_tmp = model_predict(data_loader, self._device, self._label_map, self._model)
assert len(sentences) == len(prediction_tmp)
prediction = [] prediction = []
for fe, pr in zip(features, prediction_tmp): for fe, pr in zip(features, prediction_tmp):
prediction.append((fe.tokens[1:-1], pr)) prediction.append((fe.tokens[1:-1], pr))
@ -185,125 +189,47 @@ def fulltext(ppn):
if row_data.text is None: if row_data.text is None:
continue continue
text += html.escape(str(row_data.text)) + '<br><br><br>' text += row_data.text + " "
ret = {'text': text, 'ppn': ppn} ret = {'text': text, 'ppn': ppn}
return jsonify(ret) return jsonify(ret)
@app.route('/digisam-tokenized/<ppn>') @app.route('/tokenized', methods=['GET', 'POST'])
def tokenized(ppn): def tokenized():
df = digisam.get(ppn)
if len(df) == 0:
return 'bad request!', 400
text = ''
for row_index, row_data in df.iterrows():
if row_data.text is None:
continue
sentences = tokenizer.parse_text(row_data.text)
for sen, _ in sentences:
text += html.escape(str(sen)) + '<br>' raw_text = request.json['text']
text += '<br><br><br>'
ret = {'text': text, 'ppn': ppn}
return jsonify(ret)
sentences = tokenizer.parse_text(raw_text)
@app.route('/ner-bert-tokens/<model_id>/<ppn>') result = [(sen, i) for i, (sen, _) in enumerate(sentences)]
def ner_bert_tokens(model_id, ppn):
df = digisam.get(ppn) return jsonify(result)
if len(df) == 0:
return 'bad request!', 400
text = '' @app.route('/ner-bert-tokens/<model_id>', methods=['GET', 'POST'])
for row_index, row_data in df.iterrows(): def ner_bert_tokens(model_id):
if row_data.text is None: raw_text = request.json['text']
continue
sentences = tokenizer.parse_text(row_data.text) sentences = tokenizer.parse_text(raw_text)
prediction = predictor_store.get(model_id).classify_text(sentences) prediction = predictor_store.get(model_id).classify_text(sentences)
for tokens, word_predictions in prediction: output = []
for token, word_pred in zip(tokens, word_predictions):
text += html.escape("{}({})".format(token, word_pred))
text += '<br>'
text += '<br><br><br>'
ret = {'text': text, 'ppn': ppn}
return jsonify(ret)
@app.route('/digisam-ner/<model_id>/<ppn>')
def digisam_ner(model_id, ppn):
df = digisam.get(ppn)
if len(df) == 0:
return 'bad request!', 400
text = ''
for row_index, row_data in df.iterrows():
if row_data.text is None:
continue
sentences = tokenizer.parse_text(row_data.text)
prediction = predictor_store.get(model_id).classify_text(sentences)
for tokens, word_predictions in prediction: for tokens, word_predictions in prediction:
last_prediction = 'O' output_sentence = []
for token, word_pred in zip(tokens, word_predictions): for token, word_pred in zip(tokens, word_predictions):
if token == '[UNK]': output_sentence.append({'token': html.escape(token), 'prediction': word_pred})
continue
if not token.startswith('##'):
text += ' '
token = token[2:] if token.startswith('##') else token output.append(output_sentence)
if word_pred != 'X':
last_prediction = word_pred
if last_prediction == 'O':
text += html.escape(token)
elif last_prediction.endswith('PER'):
text += '<font color="red">' + html.escape(token) + '</font>'
elif last_prediction.endswith('LOC'):
text += '<font color="green">' + html.escape(token) + '</font>'
elif last_prediction.endswith('ORG'):
text += '<font color="blue">' + html.escape(token) + '</font>'
text += '<br>'
text += '<br><br><br>'
ret = {'text': text, 'ppn': ppn}
return jsonify(ret) return jsonify(output)
@app.route('/ner/<model_id>', methods=['GET', 'POST']) @app.route('/ner/<model_id>', methods=['GET', 'POST'])

@ -35,9 +35,9 @@
<div class="form-group row ml-2"> <div class="form-group row ml-2">
<label for="task" class="col-sm-2 col-form-label">Task:</label> <label for="task" class="col-sm-2 col-form-label">Task:</label>
<select id="task" class="selectpicker col-md-auto" onchange="task_select()"> <select id="task" class="selectpicker col-md-auto" onchange="task_select()">
<option value="2">Wort- und Satztokenisierung</option> <option value="tokenize">Wort- und Satztokenisierung</option>
<option value="3" selected>Named Entity Recognition</option> <option value="ner" selected>Named Entity Recognition</option>
<option value="4">BERT Tokens</option> <option value="bert-tokens">BERT Tokens</option>
</select> </select>
</div> </div>
<div class="form-group row ml-2" id="model_select"> <div class="form-group row ml-2" id="model_select">
@ -48,8 +48,7 @@
<div class="form-group row ml-2"> <div class="form-group row ml-2">
<label for="inputtext" class="col-sm-2 col-form-label">Input text:</label> <label for="inputtext" class="col-sm-2 col-form-label">Input text:</label>
<!-- <input id="inputtext" class="col-sm-8" type="text" rows=10/> --> <textarea id="inputtext" class=" col-sm-8 form-control" rows="10" required></textarea>
<textarea id="inputtext" class=" col-sm-8 form-control" rows="3" required></textarea>
</div> </div>
<div class="form-group row ml-2"> <div class="form-group row ml-2">
@ -75,5 +74,6 @@
</div> </div>
<script src="js/ner.js"></script> <script src="js/ner.js"></script>
<script src="js/ner-demo.js"></script>
</body> </body>
</html> </html>

@ -0,0 +1,34 @@
$(document).ready(function(){
$('#nerform').submit(
function(e){
e.preventDefault();
var task = $('#task').val();
var model_id = $('#model').val();
var input_text = $('#inputtext').val()
do_task(task, model_id, input_text);
}
);
$.get( "/models")
.done(
function( data ) {
var tmp="";
$.each(data,
function(index, item){
selected=""
if (item.default) {
selected = "selected"
}
tmp += '<option value="' + item.id + '" ' + selected + ' >' + item.name + '</option>'
});
$('#model').html(tmp);
}
);
task_select()
});

@ -4,7 +4,31 @@ $(document).ready(function(){
$('#nerform').submit( $('#nerform').submit(
function(e){ function(e){
e.preventDefault(); e.preventDefault();
load_ppn();
var task = $('#task').val();
var model_id = $('#model').val();
var spinner_html =
`<div class="d-flex justify-content-center">
<div class="spinner-border align-center" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>`;
var ppn = $('#ppn').val()
$("#resultregion").html(spinner_html);
$.get( "/digisam-fulltext/" + ppn)
.done(function( data ) {
do_task(task, model_id, data.text)
})
.fail(
function() {
console.log('Failed.');
$("#resultregion").html('Failed.');
});
} }
); );
@ -41,115 +65,3 @@ $(document).ready(function(){
task_select() task_select()
}); });
function task_select() {
var task = $('#task').val();
if (task < 3) {
$('#model_select').hide()
}
else {
$('#model_select').show()
}
$("#resultregion").html("");
$("#legende").html("");
}
function load_ppn() {
var ppn = $('#ppn').val()
var text_region_html =
`<div class="card">
<div class="card-header">
Ergebnis:
</div>
<div class="card-block">
<div id="textregion" style="overflow-y:scroll;height: 65vh;"></div>
</div>
</div>`;
var legende_html =
`<div class="card">
<div class="card-header">
Legende:
<div class="ml-2" >[<font color="red">Person</font>]</div>
<div class="ml-2" >[<font color="green">Ort</font>]</div>
<div class="ml-2" >[<font color="blue">Organisation</font>]</div>
<div class="ml-2" >[keine Named Entity]</div>
</div>
</div>`;
var spinner_html =
`<div class="d-flex justify-content-center">
<div class="spinner-border align-center" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>`;
$("#legende").html("");
var task = $('#task').val();
var model_id = $('#model').val();
console.log("Task: " + task);
if (task == 1) {
$("#resultregion").html(spinner_html);
$.get( "/digisam-fulltext/" + ppn)
.done(function( data ) {
$("#resultregion").html(text_region_html)
$("#textregion").html(data.text)
})
.fail(
function() {
console.log('Failed.');
$("#resultregion").html('Failed.');
});
}
else if (task == 2) {
$("#resultregion").html(spinner_html);
$.get( "/digisam-tokenized/" + ppn,
function( data ) {
$("#resultregion").html(text_region_html)
$("#textregion").html(data.text)
}).fail(
function() {
console.log('Failed.')
$("#resultregion").html('Failed.')
});
}
else if (task == 3) {
$("#resultregion").html(spinner_html);
$.get( "/digisam-ner/" + model_id + "/" + ppn,
function( data ) {
$("#resultregion").html(text_region_html)
$("#textregion").html(data.text)
$("#legende").html(legende_html)
}).fail(
function(a,b,c) {
console.log('Failed.')
$("#resultregion").html('Failed.')
});
}
else if (task == 4) {
$("#resultregion").html(spinner_html);
$.get( "/digisam-ner-bert-tokens/" + model_id + "/" + ppn,
function( data ) {
$("#resultregion").html(text_region_html)
$("#textregion").html(data.text)
}).fail(
function(a,b,c) {
console.log('Failed.')
$("#resultregion").html('Failed.')
});
}
}

@ -1,39 +1,9 @@
$(document).ready(function(){
$('#nerform').submit(
function(e){
e.preventDefault();
do_task();
}
);
$.get( "/models")
.done(
function( data ) {
var tmp="";
$.each(data,
function(index, item){
selected=""
if (item.default) {
selected = "selected"
}
tmp += '<option value="' + item.id + '" ' + selected + ' >' + item.name + '</option>'
});
$('#model').html(tmp);
}
);
task_select()
});
function task_select() { function task_select() {
var task = $('#task').val(); var task = $('#task').val();
if (task < 3) { if ((task != "ner") && (task != "bert-tokens")){
$('#model_select').hide() $('#model_select').hide()
} }
else { else {
@ -44,10 +14,9 @@ function task_select() {
$("#legende").html(""); $("#legende").html("");
} }
function do_task(task, model_id, input_text) {
function do_task() { var post_data = { "text" : input_text }
var input_text = $('#inputtext').val()
var text_region_html = var text_region_html =
`<div class="card"> `<div class="card">
@ -55,7 +24,7 @@ function do_task() {
Ergebnis: Ergebnis:
</div> </div>
<div class="card-block"> <div class="card-block">
<div id="textregion" style="overflow-y:scroll;height: 65vh;"></div> <div id="textregion" style="overflow-y:scroll;height: 55vh;"></div>
</div> </div>
</div>`; </div>`;
@ -79,31 +48,45 @@ function do_task() {
$("#legende").html(""); $("#legende").html("");
var task = $('#task').val(); if (task == "fulltext") {
var model_id = $('#model').val(); $("#resultregion").html(text_region_html)
$("#textregion").html(input_text)
// if (task == 2) { }
// $("#resultregion").html(spinner_html); else if (task == "tokenize") {
//
// $.get( "/digisam-tokenized/" + ppn,
// function( data ) {
// $("#resultregion").html(text_region_html)
// $("#textregion").html(data.text)
// }).fail(
// function() {
// console.log('Failed.')
// $("#resultregion").html('Failed.')
// });
// }
// else
//
if (task == 3) {
$("#resultregion").html(spinner_html); $("#resultregion").html(spinner_html)
post_data = { "text" : input_text } $.ajax(
{
url: "/tokenized",
data: JSON.stringify(post_data),
type: 'POST',
contentType: "application/json",
success:
function( data ) {
text_html = ""
data.forEach(
function(sentence) {
console.log(post_data) text_html += JSON.stringify(sentence)
text_html += '<br/>'
}
)
$("#resultregion").html(text_region_html)
$("#textregion").html(text_html)
$("#legende").html(legende_html)
}
,
error:
function(error) {
console.log(error);
}
})
}
else if (task == "ner") {
$("#resultregion").html(spinner_html)
$.ajax({ $.ajax({
url: "/ner/" + model_id, url: "/ner/" + model_id,
@ -141,43 +124,40 @@ function do_task() {
console.log(error); console.log(error);
} }
}); });
}
else if (task == "bert-tokens") {
$("#resultregion").html(spinner_html);
$.ajax(
{
url: "/ner-bert-tokens/" + model_id,
data: JSON.stringify(post_data),
type: 'POST',
contentType: "application/json",
success:
function( data ) {
text_html = ""
data.forEach(
function(sentence) {
sentence.forEach(
function(part) {
if (text_html != "") text_html += ' '
// $.post( "/ner/" + model_id, post_data).done( text_html += part.token + "(" + part.prediction + ")"
// function( data ) { })
// text_html += '<br/>'
// text_region_html = "" }
// data.forEach( )
// function(sentence) { $("#resultregion").html(text_region_html)
// sentence.forEach( $("#textregion").html(text_html)
// function(token) { $("#legende").html(legende_html)
// text_region_html += token.word + "(" + token.prediction + ") " }
// }) ,
// } error:
// ) function(error) {
// console.log(error);
// $("#resultregion").html(text_region_html) }
// $("#textregion").html(data.text) })
// $("#legende").html(legende_html) }
// }).fail(
// function(a,b,c) {
// console.log('Failed.')
// $("#resultregion").html('Failed.')
// });
}
// else
//
// if (task == 4) {
// $("#resultregion").html(spinner_html);
//
// $.get( "/digisam-ner-bert-tokens/" + model_id + "/" + ppn,
// function( data ) {
// $("#resultregion").html(text_region_html)
// $("#textregion").html(data.text)
// }).fail(
// function(a,b,c) {
// console.log('Failed.')
// $("#resultregion").html('Failed.')
// });
// }
} }

@ -35,10 +35,10 @@
<div class="form-group row ml-2"> <div class="form-group row ml-2">
<label for="task" class="col-sm-2 col-form-label">Task:</label> <label for="task" class="col-sm-2 col-form-label">Task:</label>
<select id="task" class="selectpicker col-md-auto" onchange="task_select()"> <select id="task" class="selectpicker col-md-auto" onchange="task_select()">
<option value="1">OCR-Text aus ALTO Datei</option> <option value="fulltext">OCR-Text aus ALTO Datei</option>
<option value="2">Wort- und Satztokenisierung</option> <option value="tokenize">Wort- und Satztokenisierung</option>
<option value="3" selected>Named Entity Recognition</option> <option value="ner" selected>Named Entity Recognition</option>
<option value="4">BERT Tokens</option> <option value="bert-tokens">BERT Tokens</option>
</select> </select>
</div> </div>
<div class="form-group row ml-2" id="model_select"> <div class="form-group row ml-2" id="model_select">
@ -72,6 +72,7 @@
</div> </div>
</div> </div>
<script src="js/ner.js"></script>
<script src="js/ner-ds-sbb.js"></script> <script src="js/ner-ds-sbb.js"></script>
</body> </body>
</html> </html>
Loading…
Cancel
Save