I’m working on making an entity name recognition application using BERT Transformer where the input and visualization process is done using Plotly Dash. I am very confused what is wrong with my code. There are two problems that i experienced. At first, i thought the code that i made had worked because it could display the results on the bar chart when i input a text and click submit, but there is an error message “Callback error updating.figure” and secondly i can’t show result in pie chart. I think it’s just a minor error, but I still can’t find a way to solve this.
I would find it helpful and if someone could help me with this problem.
And my code for Layout is here:
# Define app
app = JupyterDash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
server = app.server
app.config['suppress_callback_exceptions']= True
colors = {"background": "#2D2D2D", "background_div": "white", 'text': 'white'}
app.layout = html.Div(style={'backgroundColor': colors['background']},
children=[
html.Div([
html.H2('Analyzing NER Indonesian Language (BERT Transformer)',
style={
'paddingTop': '30px',
'marginBottom': '30px',
'textAlign': 'center',
'color': colors['text']
}),
]),
html.Div(
dcc.Textarea(
id='text-input',
placeholder='Enter your text to be analyzed',
className='textarea',
style={
'width': '80%', 'height': 250, 'verticalAlign': 'top',
'fontFamily': 'Arial', 'fontColor': '#515151',
}
),
style={'display': 'flex', 'justifyContent': 'center'}
),
html.Div(
[html.Button(id='submit', n_clicks=0, children='Submit')],
style={'display': 'flex', 'justifyContent': 'center', 'marginTop': '20px'}),
html.Br(),
html.Div(
className="row",
children=[
html.Div(
className="six columns",
style={"width":600, "margin": 10, "marginLeft": '30px', 'display': 'inline-block'},
children=[
html.Div(
children=
dcc.Graph(id='piegraph')
)
]
),
html.Div(
className="six columns",
style={"width":700, "margin": 10, 'display': 'inline-block'},
children=html.Div(
children=
dcc.Graph(id='bargraph'),
)
)
]
),
]
)
My Code for Function is here:
def predictBar(text_input):
tokenized_sentence = tokenizer.encode(text_input)
input_ids = torch.tensor([tokenized_sentence]).cuda()
with torch.no_grad():
output = model(input_ids)
label_indices = np.argmax(output[0].to('cpu').numpy(),
axis=2)
# join split tokens
tokens = tokenizer.convert_ids_to_tokens(input_ids.to('cpu').numpy()[0])
new_tokens, new_labels = [], []
for token, label_idx in zip(tokens, label_indices[0]):
if token.startswith("##"):
new_tokens[-1] = new_tokens[-1] + token[2:]
else:
new_labels.append(tags_vals[label_idx])
new_tokens.append(token)
ner_data = {'Words':new_tokens,'Labels':new_labels}
fig_BAR = px.bar(ner_data, x="Words", y="Labels", orientation='h')
return fig_BAR
def predictPie(text_input):
tokenized_sentence = tokenizer.encode(text_input)
input_ids = torch.tensor([tokenized_sentence]).cuda()
with torch.no_grad():
output = model(input_ids)
label_indices = np.argmax(output[0].to('cpu').numpy(),
axis=2)
# join split tokens
tokens = tokenizer.convert_ids_to_tokens(input_ids.to('cpu').numpy()[0])
new_tokens, new_labels = [], []
for token, label_idx in zip(tokens, label_indices[0]):
if token.startswith("##"):
new_tokens[-1] = new_tokens[-1] + token[2:]
else:
new_labels.append(tags_vals[label_idx])
new_tokens.append(token)
ner_data = {'Words':new_tokens,'Labels':new_labels}
fig_PIE = px.pie(ner_data, values='Words', names='Labels')
return fig_PIE
and the callback code is here:
@app.callback(Output('piegraph', 'figure'),
[Input('submit', 'n_clicks')],
[State('text-input', 'value')])
def plot_pie(submit, text_input):
if submit is None:
# PreventUpdate prevents ALL outputs updating
raise dash.exceptions.PreventUpdate
fig_PIE = predictPIE(text_input)
return fig_PIE
@app.callback(Output('bargraph', 'figure'),
[Input('submit', 'n_clicks')],
[State('text-input', 'value')])
def plot_bar(submit, text_input):
if submit is None:
# PreventUpdate prevents ALL outputs updating
raise dash.exceptions.PreventUpdate
fig_BAR = predictBar(text_input)
return fig_BAR
I ran this using google colab with JupyterDash external mode.