Итак, у меня есть веб-приложение Flask, которое генерирует изображения с помощью сценария, который инициализирует и запускает модель глубокого обучения (Style Transfer). Скрипт выводит результаты генерации каждые несколько итераций следующим образом:
run_st.py
def run_style_transfer(content_path,
style_path,
result_path,
loss_path,
exec_path,
...):
... model initialization ...
for i in range(num_iterations):
... generation and optimization logic...
if i % display_interval == 0:
print('Iteration: {}'.format(i))
print('Total loss: {:.4e}, '
'Style loss: {:.4e}, '
'Content loss: {:.4e}, '
'Time: {:.4f}s'.format(loss, style_score, content_score, time.time() - iter_start_time))
Моя текущая цель - показать напечатанные параметры на стороне клиента, обновляя их для каждого интервала отображения, чтобы показать прогресс генерации. HTML-шаблон, который должен быть обновлен, выглядит следующим образом:
style.html
<div id="style-status" class="form-group col-lg-12 text-center" style="display:none">
<h5>Current status:</h5>
<p id="cur_iter">Iteration: </p>
<p id="cur_closs">Content Loss: </p>
<p id="cur_sloss">Style Loss: </p>
<p id="cur_time">Iteration time: </p>
</div>
И представление для страницы, которая вызывает скрипт и отображает результаты, выглядит следующим образом:
views.py
@app.route('/style/<id>', methods=['GET', 'POST'])
@login_required
def style(id):
"""Renders the style page."""
if request.method == 'POST':
...
MODEL_PARAMS['content_path'] = "st_webservice/static/images/upload/content/" + file_names[0];
MODEL_PARAMS['style_path'] = "st_webservice/static/images/upload/style/" + file_names[1];
MODEL_PARAMS['result_path'] = "st_webservice/static/images/output/images/" + result_name;
MODEL_PARAMS['loss_path'] = "st_webservice/static/images/output/graphs/" + result_file_name + "_loss" + file_extension;
MODEL_PARAMS['exec_path'] = "st_webservice/static/images/output/graphs/" + result_file_name + "_time" + file_extension;
MODEL_PARAMS['num_iterations'] = int(request.form.get('iter-select'))
input_resolution = str(request.form.get('res-select')).split('x')
MODEL_PARAMS['img_w'] = int(input_resolution[0])
MODEL_PARAMS['img_h'] = int(input_resolution[1])
app.logger.info('Initiating style transfer model..')
app.logger.info('Selected image resolution: {}x{}'.format(MODEL_PARAMS['img_w'], MODEL_PARAMS['img_h']))
app.logger.info('Selected number of iterations: {}'.format(MODEL_PARAMS['num_iterations']))
try:
result_dict = run_style_transfer(**MODEL_PARAMS)
except TypeError:
message = "TypeError: Invalid model type or input image types."
app.logger.error(message)
return render_template('style.html', message=message)
except tf.errors.InvalidArgumentError:
message = "Invalid image resolution. Dimensions must be even and divisible numbers(ex. 512x256)."
app.logger.error(message)
return render_template('style.html', message=message)
...
return redirect(url_for('results', id=current_user.id))
return render_template('style.html', id=current_user.id)
И вот также обработка события JQuery для инициирования генерации после отправки формы:
$("#upload-form").submit(function () {
if ($('#val_message_style').text() == "" && $('#val_message_text').text() == "") {
$('#load').text('Generating image..');
$('#load').attr('disabled', 'disabled');
$('#gif').css('visibility', 'visible');
$('.err-mes').text('');
$('#style-status').show();
... Ajax request and update style-status information? ...
return true;
}
return false;
});
Я видел несколько примеров асинхронного обновления информации с использованием Ajax запросов или библиотек, таких как Celery и Socketio , но я все еще не совсем уверен, как чтобы добиться этого, так как мне нужно, чтобы модель продолжила свою работу после обновления. Возможно, мне нужно запустить его в отдельном потоке или заблокировать процесс до получения сообщения от клиента?