В этом случае второй RNN сворачивает последовательность в один вектор, потому что по умолчанию return_sequences=False
. Чтобы модель возвращала последовательности и запускала плотный слой по каждому временному шагу отдельно, просто добавьте return_sequences=True
ко второму RNN:
x = Bidirectional(LSTM(n_hid, return_sequences=True, dropout=0.5, recurrent_dropout=0.2))(x)
Плотные слои автоматически применяются к последнему измерению, поэтому нет необходимости изменять форму после этого.
Первая опция принесет значительные издержки. Я определил свое собственное управление полем списка, полученное из класса поля списка, и выполнил переопределение loadpostback данных:
public class CustomListBox : ListBox
{
protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
{
return true;
}
}
Используя это вместо регулярного поля списка в моем пользовательском элементе управления решил проблему, однако есть ли какие-либо риски, связанные с моим подходом?
Проблема состоит в том, что сохраненное состояние отображения списка и данных, полученных на обратной передаче, не соответствует. Проблема проверки события наиболее вероятна только одна из возможных проблем, которые могли бы появиться из-за этого подхода. Архитектура веб-форм не позволяет этот вид использования и, скорее всего, будет больше проблем с этим подходом, даже если Вы успешно выполнитесь для предотвращения проблемы проверки события. У Вас есть несколько альтернатив:
1) Самое простое должно сделать логику свопинга на сервере вместо того, чтобы использовать JavaScript. Таким образом, состояние отображения будет сохранено между обратными передачами, и добавленные издержки нескольких распространений в прямом и обратном направлениях к серверу не могли бы быть проблемой.
2) Если несколько распространений в прямом и обратном направлениях к серверу являются проблемой, запишите управление сервером, которое обрабатывает свое собственное состояние отображения. Это - конечно, много привлекательного подхода.
3) Подход второго плана мог быть должен использовать два простых списка HTML (просто пишут теги HTML, не используя средства управления asp.net), и ведите на стороне клиента из JavaScript список идентификатора в скрытом поле. На сообщении назад просто анализируют скрытое поле и извлекают игнорирование идентификатора списки HTML.
Я пошел бы с 1, если нет СЕРЬЕЗНЫХ аргументов против него.
Несколько возможных вариантов:
Если возможно, отключите ViewState в двух списках. Без ViewState сервер не будет знать то, чем были исходные значения, и следовательно не будет ошибка. С этим подходом Вы должны будете повторно заполнить списки (из-за отсутствия ViewState) и, возможно, должны отследить выбор вручную - или должны будете заполнить списки во время фазы OnInit.
Выключите проверку события (если Вы можете),
Заполните оба списка полностью на стороне сервера и используйте клиентский сценарий (JavaScript) для удаления записей из двух списков как требуется.
Случайно, Вы уже попробовали это? Сделайте это каждый раз, когда Вы унавоживаете со списком всегда.
document.getElementById("listbox").selectedIndex = -1;
Это жалуется, потому что выбранный пункт в списке не присутствовал в списке, когда это было представлено. Рассмотрите использование PageMethods через Ajax для возвращения данных к форме вместо PostBack. Или используйте неэлементы управления вводом для содержания данных - как незаказанные списки, между которыми Вы перемещаете элементы списка назад и вперед. Можно поместить GUID в скрытые промежутки в элементе списка, где можно достигнуть их в случае необходимости.