У меня возникла проблема с обновлением изображений на полимерной странице. Мой элемент выглядит следующим образом:
import { html, LitElement, property } from 'lit-element';
import { connect } from 'pwa-helpers/connect-mixin.js';
// These are the shared styles needed by this element.
import { SharedStyles } from '../../styles/shared-styles.js';
// This element is connected to the Redux store.
import { store, RootState } from '../../store.js';
class TFJSItem extends connect(store)(LitElement) {
@property({type: Number})
private _prediction = 0;
static styles = SharedStyles;
protected render() {
console.info(this._prediction);
return html`
<section>
<h2>TFJS</h2>
<p>${this._prediction}</p>
</section>
`;
}
// This is called every time something is updated in the store.
stateChanged(state: RootState) {
console.info(state.network!.prediction);
this._prediction = state.network!.prediction;
}
}
window.customElements.define('tfjs-item', TFJSItem);
У меня есть скрипт, работающий на 1000 итераций, который отправляет действие в редукс для обновления числа, хранящегося в network.prediction. Однако число, отображаемое в элементах, обновляется только один раз, после последнего изменения состояния. Однако, поскольку я хочу, чтобы это был номер, работающий в реальном времени, я хочу, чтобы каждое изменение записывалось.
Странно то, что второй console.info() выполняется для каждого изменения, однако рендер вызывается только один раз.
Данные поступают из процесса обучения tfjs. Я хочу обновлять прогноз каждый раз, когда делается новая итерация:
import * as tf from '@tensorflow/tfjs';
import * as d from './data';
import * as m from './model';
import { store } from '../store.js';
import { newPrediction } from '../actions/network.js';
export class Training {
model: m.Model;
data: d.Data;
iterations: number;
constructor(model: m.Model, data: d.Data) {
this.model = model;
this.model.model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
this.data = data;
this.iterations = 0;
}
start() {
var this_ = this;
if (this.iterations < 1000) {
this.iterate();
}
}
iterate() {
this.iterations++;
tf.tidy(() => {
const prediction = this.model.model.predict(tf.tensor2d([5], [1, 1]) as tf.Tensor) as tf.Tensor<tf.Rank>;
store.dispatch(newPrediction(prediction));
this.model.model.trainOnBatch(this.data.xs, this.data.ys);
});
}
}
Спасибо вам за эту информацию! Теперь я жду 1 мс после каждой итерации следующим образом: start() { var this_ = this; if (this.iterations < 1000) { this.iterate(); setTimeout (function() { this_.start(); }, 1); } }
Вы хотите опубликовать это как ответ? Тогда я могу отметить это как правильное.
Еще одна возможная проблема: ваш тренер TFJS должен периодически вызывать await tf.nextFrame(), чтобы передать управление, чтобы избежать зависания пользовательского интерфейса. Обычно это происходит автоматически при использовании LayersModel.fit() и LayersModel.fitDataset(), но проверьте аргумент yieldEvery, чтобы настроить поведение (js.tensorflow.org/api/latest/#tf.LayersModel.fit).
Хорошо, я не ожидал, что это будет связано с тензорным потоком. Однако сейчас я добавлю код тензорного потока, так как вы указали мне это направление. Я не использую model.fit(), так как хочу контролировать, когда будет выполняться итерация в будущем (остановка/продолжение/пошаговое выполнение итераций).






LitElement пакетно вызывает render() (фактически весь конвейер обновлений). Ожидается, что если вы много обновляете состояние в одной задаче, будет только один вызов render().
Как правило, более быстрый рендеринг на самом деле не будет отображать что-либо чаще на экране, потому что и синхронные функции, и микрозадачи блокируют рисование, поэтому браузер в любом случае будет рисовать экран только после всех обновлений.
вы ждете некоторое время (setTimeout или эквивалент) между отправкой каждого действия в избыточность? я знаю, что Redux может пакетно обновлять состояние, поэтому вы можете увидеть последнее, только если они слишком близко друг к другу