Отображение и обновление прогресса модели во Flask - PullRequest
0 голосов
/ 11 мая 2019

Итак, у меня есть веб-приложение 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 , но я все еще не совсем уверен, как чтобы добиться этого, так как мне нужно, чтобы модель продолжила свою работу после обновления. Возможно, мне нужно запустить его в отдельном потоке или заблокировать процесс до получения сообщения от клиента?

...