Содержание

Как стать суперсолдатом: спецназ раскрывает секреты физподготовки

Военные — особенные люди, подготовленные для выполнения самых сложных задач. Передовая техника, современное вооружение — основные, но не единственные средства, которыми достигается победа и выполнение приказа. Физическое здоровье и выносливость — вот качества современного российского военного, без которых невозможно нести службу и выполнять серьёзные боевые задачи. Тренировки на выносливость — едва ли не самый тяжелый вид тренировок, которые практикуются в российской армии, однако у каждого рода войск они помимо общих черт имеют и свои особенности.

Наследие

Советская школа тренировки выпускала выносливых суперлюдей. К службе в армии и спецназе в те времена предъявлялись достаточно жесткие требования. Результат не заставлял себя долго ждать: советские солдаты, десантники и спецназовцы лихо совершали многокилометровые марш-броски в полной выкладке и на коротких дистанциях даже умудрялись не сбить дыхания. По рассказам инструкторов, своими руками делающих из обычных парней сверхвыносливых бойцов, бег — основа любой физподготовки.

«Ты может не иметь чёрный пояс по каратэ-до, но бегать быстро и долго ты обязан», — рассказывает в интервью телеканалу «Звезда» инструктор по физподготовке и обладатель крапового берета Виктор Иванников.

По словам Иванникова, тренировать дыхание и общую выносливость лучше всего именно занимаясь бегом. Каждый день.

«Это касается и армейских подразделений, и спецназа. Стрелять солдата научат, а бегать нужно учиться самому. Это тяжело, это трудно, но если день за днем тренировать организм, то через пару месяцев гарантированно войдёшь в ритм и будешь дальше совершенствовать тело, а с ним и дух», — заявил спецназовец.

«Краповый берет» также поделился любопытным фактом — тренировку своих бойцов (одного из подразделений внутренних войск) он проводит еще по старой, советской системе. Не потому, что новых систем не придумано, а потому, что старая система работает. Ее лишь пришлось немного улучшить. В частности, по рассказам спецназовца, из Советского Союза и пришла рекомендация для солдат, которая помогает повысить общую выносливость организма при беге. Достигается такое физическое состояние, по слова Виктора Иванникова, очень просто.

«При беге старайтесь делать короткий шаг. При коротком шаге мышцы таза будут не так нагружены. Неторопливость — тоже один из ключевых факторов хорошего длительного бега и тренировки на выносливость. Старайтесь не рвать с места, а рассчитывать силы, дозируя их на всю дистанцию пути», — рассказывает профессионал.

Также, по словам «крапового берета», большую роль играет и обувь.

«Курсантов своих я каждый раз начинаю гонять в «кирзачах» — тяжелых армейских сапогах, которые сейчас уже не носят. Побегав в них недели две, в «берцах» обычный призывник начинает бегать на уровне спортсмена-любителя, а дальше — по накатанной. Ежедневные тренировки и занятия. Вот вам простой секрет выносливости из прошлого. Можете для разнообразия, после двух-трех недель занятий нагружать себя «блинами» от штанги из спортзала. Начинайте с грузов массой пять кг, и увеличивайте вплоть до веса в 30 кг — столько в среднем весит снаряжение бойца спецназа», — советует Иванников.

Дыхание

Особо важным, по признаниям как действующих спецназовцев, так и инструкторов, в тренировке на выносливость является дыхание.

«Без хорошего дыхания ни один человек выносливым не станет», — рассказал телеканалу «Звезда» инструктор Константин Звонарев.

Тренировкой дыхания, по словам специалиста, в подразделениях специального назначения Минобороны, федеральных служб, занимаются постоянно. Отдельные подразделения, по словам Звонарёва, почти постоянно забрасывают в высокогорные районы с ежедневными марш-бросками.

«В 58-й армии есть одно подразделение, не буду говорить, какое. Секрет хорошей физподготовки бойцов этого подразделения в том, что они постоянно тренируются, пробегая дистанции уже со снаряжением в условиях так называемого «тяжелого», разреженного воздуха. Высокие горы — лучший тренер. Инструктор, который бежит вместе с отрядом, постоянно контролирует дыхание бойцов, постоянно подсказывает, как правильно нужно это делать», — рассказывает эксперт.

Достичь идеального понимания своего собственного тела, по словам инструкторов, можно массой способов, однако, дыхательную часть освоить можно так: бег с нагрузкой в 10-12 кг и дыхание только через нос. Два коротких вдоха и два коротких выдоха. Такая схема, по признаниям инструкторов и действующих сотрудников, обеспечивает идеальное количество воздуха в легких и облегчает процесс бега, попутно обеспечивая непрерывное дыхание и практически полное отсутствие одышки.

Тренировка спецназа ГРУ

Сверхнагрузки для сверхлюдей, по признаниям самих разведчиков,  это нормально.

«Главное, что это работает. О том, что это тяжело, мы уже не вспоминаем. Тренировка вызывает привыкание, и без нагрузок уже не можешь жить», — рассказывает один из бойцов российского военного спецназа.

Выносливость — едва ли не самое важное для разведчика качество. Это гарантия выживания. Начинается самая обычная тренировка на выносливость в спецназе ГРУ примерно так: бег на дистанцию 10 километров, а иногда и на все 40 и даже 45. Временной норматив по преодолению дистанции в 10 км в полной выкладке (около 40 кг) — чуть меньше часа. Не успел — на следующий день километры, которые спецназовец не добежал, прибавляют к следующей дистанции. Еще одним важным упражнением, наряду с бегом, по словам российских «суперсолдат» является бег, чередующийся с переползаниями. Благодаря такой системе тренируются почти все группы мышц — шейные, спинные, а так же ноги и руки.

«Общая физическая выносливость среднестатистического бойца может повыситься после курса подготовки примерно вдвое», — рассказывает инструктор-спецназовец Олег Буровой.

«Однако тут следует учесть, что для спецназа такие нагрузки — постоянное явление. Отсюда и секрет выносливости. Когда тренируешь организм и тело каждый день, такие нагрузки становятся нормальными. Перефразируя известную поговорку, можно сказать, что повторение — мать подготовки», — добавляет он.

Именно в ГРУ служат самые подготовленные спецназовцы страны. Постоянные пробежки, нагрузки, рукопашный бой и общее пристальное внимание к физической подготовке — именно комплекс этих программ делает из курсантов и «срочников» матерых разведчиков. Такая тренировка, по словам инструкторов рязанского десантного училища, воспитывает «боевую злобу», которая зачастую помогает преодолевать военным определенные трудности, связанные с выполнением боевой задачи.

Стандартная круговая тренировка на выносливость длится примерно 40 минут. Порядок выполнения тренировки курсантами РВВДКУ следующий: бег  — 10 км, отдых — пять минут. Затем отжимания на пальцах — 20 раз, джамп (выпады) — 10 повторов. Упражнения делают с чередованием, по два подхода, после чего курсант должен практически до бессознательного состояния качать пресс. До тех пор, пока не кончатся силы.

Но главный секрет выносливости бойцов, как уверяют все без исключения специалисты, это не тяжесть физических нагрузок, а их регулярность. Военным с этим проще – у них распорядок дня расписан поминутно. А вот гражданскому человеку натренировать себя до уровня спецназовца сложно. Но можно. Главное – заставить себя выйти из дома.

Автор: Дмитрий Юров

Фото: voenpro.ru, armsofwar.ru

«Взрывная» тренировка спецназовцев ГРУ. Под силу далеко не каждому | Satisfy Hero

Главный смысл всех тренировок спецназа заключается в развитии силы и выносливости в бойце. Именно поэтому достаточно непросто найти среди спецназовцев каких-то перекачанных бодибилдеров. А вот ребят, которые выглядят очень даже подтянуто, при этом в силе могут с легкостью переплюнуть любого силача — запросто. 🏃 💣💪

Поэтому сегодня мы с вами поговорим о взрывных тренировках спецназа, но сразу предупрежу, что эти тренировки никак не подойдут для новичков. Скорее они смахивают на «попробуй так же». А теперь поподробнее!

№1. Бег

Этот бег не имеет ничего общего с привычным нам бегом в парке или на природе, или даже на беговых дорожках. Бег — это основа, скажем так, база тренировок спецназа ГРУ. И это не просто бег, а бег дистанцией в 10 км.

Более того, в процессе такого бега используется утяжеление до 50 кг. И если спецназовец справился с этой задачей, пробежав данную дистанцию за один час, это является хорошим результатом.

Можете также чередовать бег с переползаниями. Например, ползать через каждые 200 метров, тем самым усложняя себе задачу.

№2. Тренировка

А вы знали такой интересный факт, что основный принцип тренировок спецназовцев был взят еще со старой отечественной школы самбо? И благодаря такой жесткой тренировке, хорошо развивается выносливость, стойкость, физическая сила и подтяжка, а также развивается ненависть, что очень важно для спецназовцев.

И тут количество повторений отсутствует, так как тренировка продолжается до тех пор, пока боец просто не валится на пол, полностью обессиленный.

Другими словами, подобная тренировка напоминает круговую, когда все упражнения выполняются перед передышек и отдыхов.

Круг первый. Начинается круговая тренировка с первого круга, в котором присутствуют такие упражнения:

  • отжимания;
  • прыжки вверх из положения приседа;
  • отжимания;
  • опять джамп;
  • упражнения для пресса.

Последние упражнения для пресса выполняются на полную катушку, пока не остается сил вовсе.

На втором круге уже обычно присутствуют такие упражнения, как приседания, подтягивания, планка, в общем все, что только можно! В среднем один спецназовец должен пройти не менее 5-7 кругов такой жесткой тренировки.

№3. Рацион

Помимо серьезного подхода в тренировках, особое внимание стоит уделить и вопросу внимания. И хотя рацион особо ничем не отличается, в нем не присутствуют какие-то спортивные добавки и стероиды. И все же, если проанализировать меню спецназовца, то можно прийти к выводу, что в рационе присутствует достаточное количество белков, жиров и сложных для переваривания углеводов.

Так как тренировки достаточно жесткие, нету никакого смысла в низком содержании углеводов и жиров в рационе бойцов.

Вот и все, товарищи! Хотите выглядеть подтянуто и быть очень сильным? Не стремитесь к качалке! Тренируйте силу, выносливость и стойкость! И лайк не забудьте!

Как тренируется спецназ ГРУ. | Calisthenics

Спецназ ГРУ является одним из самых известных и можно сказать элитных воинских подразделений. Сотрудники Спецназа ГРУ выполняют одни из самых сложных и за частую секретных операций.

Попасть в данное подразделение могут только лучшие из лучших, для того чтобы попасть на службу в спецназ ГРУ, бойцам приходиться проходить жесточайший отбор. Иметь отличную физическую и психологическую подготовку. Быть готовыми к тяжелейшим последующим, каждодневным тренировкам, которые обычному человеку могут показаться чем то безумным и шокирующим.

Если внимательно посмотреть на бойцов данного подразделения можно заметить, что большинство из них не являются, какими то сверх накачанными. Большинство бойцов подразделения просто настоящие крепкие мужики среднего телосложения, которые с легкостью смогут уложить не одного накачанного «кабана» за раз. Они не стремятся накачать себе горы мышц. У них другие задачи натренировать свое тело на максимальную выносливость, подготовить его к самым жестким условиям, что бы уметь выполнять поставленные задачи не смотря на внешние факторы дождь, снег, жару или холод.

Кросс. Основой для бойца спецподразделения является тренировка ног и выносливости, лучшей тренировкой для этого служат каждодневные много километровые кроссы. До 10 км каждый день, независимо от погоды, грязь, слякоть не имеет значения. В среднем бойцам требуется около 1 часа на преодоление дистанции в 10 км с полной боевой выкладкой. Зачастую бег чередуется с переползанием это позволяет проработать большее количество мышц.

Круговая тренировка выносливости. Данная тренировка обеспечивает максимальную тренировку выносливости всего тела. Спустя 5-10 минут отдыха после 10 км кросса бойцы приступают к выполнению круговой тренировки. Выполняют обычно в среднем по 5 кругов отдых между кругами 5 минут. Круги могут выглядеть по разному и состоять из различных упражнений отжиманий, подтягиваний, приседаний. Стандартный круг выглядит примерно так.

Отжимания на кулаках 20 раз

Выпрыгивание из положения сидя 10 раз

Отжимания на кулаках 25 раз

Выпрыгивания 10 раз

Отжимания на пальцах 10 раз

Выпрыгивания 10 раз

Отжимания 30 раз

Пресс 50 раз

Рукопашный бой. Очень много времени уделяется рукопашному бою. Любой боец спецподразделения обязан в совершенстве владеть рукопашным боем и не только. Поскольку в бою ситуации бывают разные боец должен уметь использовать любые предметы и преимущества для победы над противником. Много времени уделяется ударной технике броскам, захватам. Зачастую новичков бросают в спарринг к уже опытным бойцам, которые далеко не сюсюкаются с новичками. За счет этого те учатся вырабатывать в себе агрессию и силу духа. Для тренировки силы удара используются упражнения с кувалдой и различные упражнения на взрывную силу.

Постоянная нагрузка в течении дня. Боец должен выполнять определенную норму упражнений каждый день, определенное число отжиманий, подтягиваний, выпрыгиваний. Не смог выполнить норму в первой половине дня, будешь обязан добить во второй, или даже после отбоя.

И это далеко не все, что приходиться переносить бойцам, для того чтобы стать служащими спецподразделений. Бойцы должны иметь буквально не человеческую выносливость, не спать до нескольких суток, голодать, но все равно быть способными выполнять поставленную задачу.

Спасибо за просмотр! Я буду вам крайне признателен, если вы подпишитесь на канал, поставите лайк и поделитесь в соц. сетях.

Тренировка спецназа ГРУ – Airsoft Power Play

Сергей Николаевич Бадюк рожденный 3 июля 1970 в Винницкой области, в 1988-1990 гг. прошел службу в бригаде спец. назначения спецназа ГРУ. Выпускник Высшей школы КГБ. Проходил службу в рядах ФСБ Российской Федерации, и сейчас тренировки спецназа ГРУ без Сергея Бадюка просто сложно представить.

Мастер спорта СССР в гиревом спорте, рукопашному бою, обладатель звания мастер боевых искусств России. Инструктор по рукопашному бою в Академии ФСБ России.

Попасть в спецназ не так просто. Получить пометку «Годен к ВДВ» можно, обладая развитым телосложением, желательно иметь разряд по бегу, стрельбе, парашютному спорту или рукопашному бою. Также приветствуется способность мыслить и быстро принимать решения в стрессовых ситуациях, так как ГРУ это в первую очередь разведка.

Сергей Николаевич Бадюк

Главное разведывательное управление Вооруженных Сил Российской Федерации было основано в 1918 году. Занимается любыми видами разведки, бюджет и численность бойцов и офицерского состава строго засекречены.

Спецназ ГРУ основан несколько позже – в 1950 году. Задачами подразделения является – разведка, контрразведка, уничтожение террористов, диверсионная деятельность. Эта боевая единица сыграла значительную роль в афганской войне. Является самой закрытой и, пожалуй, самой опасной единицей ВС России.

Осторожность

Главное качество разведчика – холодный расчет и ясный ум. Необходимо оценивать ситуацию и думать в первую очередь о выполнении задания и о сохранности своей группы, геройство идет уже в последних рядах. Так, например, во время ротации кадров мы обязательно спрашиваем у новобранца – почему он хочет стать спецназовцем? Если в ответ мы слышим что-то в духе – «Хочу стать героем», отправляем восвояси. При такой мотивации, героем он может стать только посмертно, загубив вместе с собой всю группу.

После того, как солдат, все-таки попал в спецназ, ему с первого же дня начинают вбивать, что он круче всех. Для этого годятся любые инструменты – слова, руки, ноги. Важно поверить в это, если не поверит – отправят служить в пехоту.

Служба в спецназе сильно выматывает – сутки напролет ты стреляешь, бегаешь, тебя постоянно бьют. Бьют, конечно, не «деды», никаких «принеси-постирай» тут нет. Просто с самого начала мы воспитываем в бойцах разведчиков – они по казарме должны передвигаться, как по заминированной вражеской территории. Тут и затрещину получить можно или на растяжку нарваться или еще чего, вот такие здесь шутки. Это не так дико, как может показаться. В боевых условиях никто с тобой честно играть не будет, тут главное – выжить и выполнить задачу, или же просто выполнить задачу – выбор есть всегда.

Также тут быстро отучают трогать незнакомые, чужие вещи – под брелоком, лежащим на столе, вполне может оказаться взрывпакет. Через несколько месяцев такой службы, не только на затылке глаза могут вырасти, но и спать ты будешь настолько чутко, что просыпаешься от одного взгляда.

Выносливость

Ноги десантника – его хлеб. С момента, когда группу засекли, примерно через 6 часов она уже будет уничтожена. Лично знаю случай, когда один боец, в боевых условиях сказал, что не может больше бежать. Группа оставила ему практически все боеприпасы и побежала дальше. Вот так рождаются новые герои. Можно не уметь мастерски владеть техникой рукопашного боя, но ты просто обязан бегать лучше скаковой лошади.

Метание камней – отличная тренировка, которая увеличит взрывную силу удара.

Первый месяц, солдаты спят по 4 часа, спали бы и меньше, но это уже не положено по уставу. Оставшееся время они занимаются, тренируются, другими словами – вкалывают. Подъем в 6 утра. Спокойно одеваются, умываются, делают утреннюю зарядку, никто никого не торопит и не гонит, но потом, одели ранцы и побежали. Бегут долго, с постоянными вводными заданиями – то засада, то стрельба, кувырки, гусиный шаг, переползания и прочие радости. После утренней пробежки – физическая подготовка, рукопашный бой, тактические занятия. И в таком темпе каждый день, иначе в спецназ не попасть.

После нескольких месяцев подготовки, степень натренированности бойцов проверят скачками. Группу солдат вывозят в лес на неделю, без провизии. Командиры сменяются дважды в сутки и гоняют солдат по лесу, практически не давая им ни отдыха, ни возможности поспать. Кто не выдержал – отправляется в пехоту. Так отсеивают, довольно много народа, что-то вроде экзамена.

Решительность

Лучшее средство для закалки решительности – рукопашный бой. Тренировки проходят примерно так: Одетого в защиту бойца. ставят в спарринг против более сильного, опытного противника и бьют. Так воспитывают бойцовский характер, решимость и силу воли. Это не неуставные отношения – боец имеет возможность отбиваться, точнее он просто обязан отбиваться.

Отличие подготовки рукопашного боя спецназа от большинства других подразделений в том, что наша цель – уничтожить, а не задержать противника. Поэтому и девиз наш звучит, как: «“Голыми руками дерутся только идиоты». Нас учат по возможности не драться голыми руками, а использовать все, что только можно – огнестрельное оружие, ножи, осколки, палки, даже свернутая газета может стать серьезным оружием.

Помимо обычной подготовке, в спецназе, также практикуют много «упражнений на дерзость». Например, у нас, было популярно упражнение с крысой. В умывальник загоняли большую крысу и заталкивали туда голого бойца. Когда крыса загнана в угол – она будет атаковать. Тут то и начинается настоящая жесть. Если ты смог убить голыми руками крысу, то человек тебе уже не страшен.

Агрессия

Агрессия – одна из главных составляющих подготовки бойца. Он должен своего сержанта бояться сильнее врага, бежать к врагу с ярко выраженным желанием его уничтожить. Во время занятий по рукопашке не обходится без крови, сержанты специально наносят травмы. Он должен привыкать к крови, должен не бояться травм, а в боевой ситуации вообще на них не отвлекаться, тогда останется жив. Под таким прессингом человек все знания впитывает как губка и все выученное за полгода останется с ним на всю жизнь. При подготовке стараются максимально приблизить условия к боевым, чтобы солдаты чувствовали угрозу жизни и были готовы идти до конца. Поэтому, чтобы успокоить трех пьяных десантников – вызывают целую роту ОМОНа.

Правда, мы признаем, есть и обратная сторона медали. У нас в стране нет центров реабилитации после армейки. Мы то свою задачу выполняем на отлично – готовим бойцов, они проходят службу, выполняют все нормативы и задачи, но, по возвращению домой, становятся не готовы к обычной мирной жизни.

Чистоплотность

Не думайте, что спецназовец это такая машина убийства, которой плевать на свое состояние, гигиену и в целом комфорт и чистоту. Это кардинально не так. У нас паранойя по поводу личной гигиены. Мы часто находимся вне своей части, в походных условиях, в лесу или еще где. Поэтому необходимо держать себя в чистоте в любых условиях. Любой солдат, прибывший в роту, первым делом обязан постирать форму и одеть чистую. В каких условиях бы ты ни был, приведи себя в порядок по окончании задания.

При ударах головой бьем строго в нос.

Возможно по этой причине, а может и всему виной психологический настрой, но я не припомню, чтобы кто-нибудь из моих сослуживцев болел. Была даже история, когда меня, еще молодого бойца, с рассеченной гранатометом головой, отнесли к реке, промыли рану и перевязали. Все! и никакой заразы.

Принципы тренировок

В силу профессии, большую часть времени, боец находится вне пункта постоянной дислокации. Но тренировки ведь никто не отменял, поэтому приходится использовать любые доступные подручные средства.

Вот ежедневные тренировки, не эти новомодные, рассчитанные на несколько недель. Тут тебе придется заниматься минимум год. Я, когда пришел в армию весил 86 килограмм, спустя же всего три месяца, встав на весы, я был немного озадачен – 103 килограмма. И занимался я исключительно по этой программе. И пару слов о диете, она довольно проста – ешь побольше.

Подготовка держится на четырех столбах:

1. Бег и переползания. Ежедневно, необходимо пробегать 10 км. Иногда, по воскресеньям тренировку делают разнообразнее – 40 км. Но, пока ты еще не в армии, так и быть, можешь отдыхать в воскресенье. Обычный боец спецназа преодолевает 10 км менее чем за час, и это таща на себе 50 кг экипировки. Бег нужно чередовать с переползаниями – они отлично прорабатывают все группы мелких мышц;

2. Круговая тренировка. Тренировка была позаимствована у школы бокса и самбо СССР. Она увеличивает выносливость, силу и вызывает злобу к начальству. Повторы в любом упражнении определяются по настроению сержанта. Но для тебя, сгодится и 40-минутная тренировка, после 10 км пробежки. Отдых между кругами около 5 минут.

Один круг выглядит так:

  • Отжимания на пальцах (20 повторов)
  • Джамп (10 повторов)
  • Отжимания на кулаках (30 повторов)
  • Джамп (10 повторов)
  • Отжимания на пальцах (5 повторов)
  • Джамп (10 повторов)
  • Отжимания на кулаках (30 повторов)
  • В конце каждого круга качаем пресс до отказа. Также можно добавить метание камней.

3. Постоянная нагрузка. Каждый день, ты должен делать определенное количество отжиманий на кулаках, качать пресс, подтягиваться и т.д., причем число повторений каждый день должно расти.

4. Рукопашный бой. Тут важно выработать хороший, взрывной боковой удар. На прямых особо не сосредотачиваемся, потому как их очень сложно научиться бить сильно. Я за всю свою службу не видел ни одного бойца, который в полной мере бы овладел этой техникой. Поэтому используем боковые, благо их разновидностей и вариантов существует очень много. Сначала наносится удар в горло. В ближнем бою работаем локтями. Силу тренируем упражнением с кувалдой. Вся техника владения ногами сводится к удару в пах – тут вам не ринг. При ударах головой бьем строго в нос.

Естественно, чтобы так делать, ты долен сам отжиматься раз в пять больше бойца.

Примерно так, начинается каждое утро десантника.

А это иллюстрация к тому, что необходимо поддерживать состояние прессинга для солдат.

Джампы. Выпрыгивание вверх с хлопком – хорошо укрепляет икры и голеностоп, это позволит тебе бежать как скаковой лошади.

Упражнения с ремнем. Как я и говорил, используются все подручные средства. Пытайся разорвать его – справа, слева, сзади. Выполнять после круговой тренировки.

Кувалдой мы тренируем мощь и силу удара. Кувалду лучше брать с металлической сварной ручкой, она и тяжелее будет, и с черенка не слетит. Упражнения выполнять такие: удар сверху, удар справа, удар слева. Так ты включишь в работу все мышцы. На каждое упражнение по 3 подхода и по 10 повторов.

Рекомендуем купить

В этой статье мы рассказали о тренировках бойцов ГРУ, вы также можете прочесть о том как тренируется украинский спецназ, и узнать о тренировках ФСБ. Если вам понравился материал, поставьте лайк и поделитесь статьей с друзьями! Спасибо.

Открытая тренировка в зале единоборств для всех желающих — Кудо-клуб «Прайд»

О себе

«в кудо мы приобретаем самоконтроль над своими чувствами и эмоциями, если ты умеешь управлять своими эмоциями, то ты хозяин своей жизни»

Илья, привет! Расскажи немного о себе, чем вообще ты любишь заниматься?

Я частный репетитор по химии. Я из города Костромы, мне 32 года.

Люблю музыку, я ее слушаю, сочиняю, пишу песни и т.д. Люблю фильмы про единоборства, так как они настоящие, и они мотивируют. Люблю путешествовать, и у меня есть маленькая мечта – заработать денег и посетить все континенты и познакомиться со всеми основными культурами мира.

Что, на твой взгляд, самое важное в отношениях с людьми?

Нужно относиться к людям так, как к самому себе, или даже лучше. Нужно учиться слушать их, вникать в их проблемы, учиться общаться, помогать, находить нужные слова. Обогащать свой внутренний мир и видеть внутренний мир других людей.

Что мешает тебе жить, а что помогает?

Мешает жить лень, желание отдыхать, ничего не делать, мешает страх неудач. Помогает жить вера, вера в Бога, в себя, в людей

Как ты изменился после того как начал заниматься кудо?

Я стал сильнее, мудрее, мастеровитее, я переборол страх. И я кое что понял, что когда ты побеждаешь страх, то все двери и возможности по сути открываются для тебя. И в голове становится чище. Когда мысли очищаются от всех проблем, ты можешь взглянуть на вещи под другим углом, увидеть то, чего ты раньше не видел, найти правильное решение. Также появляется уважение к людям, к одноклубникам, учителю, соперникам. Уважение за помощь, за бой, за беседы, за благодарность.

Недавно я был в магазине с детьми, где одна парочка мне нахамила откровенно говоря, я просто им ответил словами без грубости. Несколько лет назад я бы им такого наговорил, да еще в тыкву бы дал, но какой пример бы я подал своим детям. То есть в кудо мы еще приобретаем самоконтроль над своими чувствами и эмоциями, если ты умеешь управлять своими эмоциями, то ты хозяин своей жизни, по сути, и также можешь вести за собой других людей.

А вообще часто доводилось драться?

Приходилось много драться на улице, в общежитии, в клубах, в школе. Но после того как я начал заниматься спортом я ни разу ни с кем не дрался.

Вообще, это забавно, что когда ты приобретаешь силу и навыки, то уже не дерешься, а дерешься тогда, когда ты по сути еще не умеешь драться, а когда умеешь, тебе уже этого не надо.

Нарезка с выступлений на соревнованиях по кудо

Кто тебя поддерживает в стремлении добиться успехов в кудо?

Мой брат ездит со мной на все соревнования практически, за что я ему очень благодарен. Также поддерживает очень наш сенсей Максим Александрович, в плане подготовки и настроя. Поддерживает вся команда, все одноклубники. Жена на соревнования отпускает, что тоже хорошо!

О кудо

Почему ты выбрал именно кудо?

Раньше я немного занимался боксом, потом решил поменять вид спорта, так как хотелось еще и ногами научиться бить и владеть навыками борьбы. При этом получать минимум увечий, так как на боксе и по голове хорошо прилетало, и зубы крошились.

Я очень долго просматривал ролики на ютубе, анализировал (сравнивал) разные боевые искусства, потом увидел кудо, проанализировал, и понял, что это идеальный вариант для меня

Какими получились твои первые шаги в кудо?

Вначале было непросто, потому что не было растяжки, все получалось коряво, борьба – это было просто выживание, стремление просто не попасться на прием. Еще было немного страшно, когда приходишь на спарринги с большими и опытными дядями, которые особо не жалели и не глядели на твой цвет пояса, били, так сказать, от души

Опиши свое самое большое достижение и самый впечатляющий провал?

Самое большое достижение – это то, что я сдал дан-тест на черный пояс 1 дан.

Самый большой провал, когда на соревнованиях я пропустил двойку,в глазах темнота, в голове будильник звенит, и так 5 секунд наверно, потом я пришел в себя, я стою на ногах, все нормально. Оказалось, я убежал куда-то далеко к судьям за татами, мой соперник на татами, я сделал вид, что ничего не было, все нормально, и дальше пошел биться. Для меня это был провал, хотя со стороны казалось, будто бы ничего и не было.

Сколько времени ты посвящаешь тренировкам?

Если просто обычный режим для поддержания формы – это 6 часов (3 тренировки) в неделю. Если идет подготовка к соревнованиям – это может быть и 20 часов в неделю (1-2 тренировки в день)

Какие советы можешь дать тем, кто только начинает заниматься кудо?

Многие приходят, думают, блин, куда я попал, потому что это реально трудный и тяжелый вид спорта, и самый главный фактор – это шлем. В шлеме тяжело дышать, и многие просто не могут долго тренироваться в шлеме, а кто-то просто не может вообще в нем тренироваться. Но постепенно привыкаешь, организм адаптируется. Поэтому хочу пожелать не сдаваться и тренироваться — это тяжелый путь, но чем путь тяжелее, тем легче преодолевать преграды на нем.

Почему полезно заниматься кудо и какие у тебя есть свои секреты, фишки?

Полезно заниматься кудо тем, что, работая в шлеме, вы приучаете свой организм работать в высоком режиме в состоянии небольшой гипоксии – дефицита кислорода. Тем самым, вы повышаете выносливость, вы снижаете степень окисления клеток, замедляете старение. Особенность состоит в том, что вы не прекращаете подачу кислорода, что по сути вредно, а просто ее ограничиваете.

Моя методика тренировки подойдет не всем, например, для повышения выносливости я бегал в шлеме по этажам – это упражнение я назвал «100 этажей». Все просто — пробежать 100 этажей в шлеме. 5 подходов по 20 этажей за раз.

Еще упражение у меня есть «100 связок» — в шлеме бьете по мешку 100 комбинаций без пауз, заканчивая каждую комбинацию ударом ноги, 3-4 удара в каждой комбинации. Этим упражнением нарабатываются выносливость и нейронные связки, потом вы будете выбрасывать эти комбинации в бою без мыслей.

Сформулируй, в нескольких предложениях, кудо — что это за вид спорта? Почему следует отдать ребенка в секцию кудо или прийти в зал самому?

Кудо – это эффективный вид спорта, защищенный, и очень разнообразный, очень либеральный, так как в нем нет рамок. Вы можете учиться бесконечно, и вносить туда своего сколько угодно, и никто вам слова не скажет, главное, соблюдайте правила на соревнованиях, и владейте базовыми техниками.

Отдать ребенка в кудо стоит потому, что на кудо он будет защищен. Есть полностью закрытый шлем, есть защита груди, голени, рук. Он станет сильным, у него будет правильное окружение, друзья, он будет увлечен, и у него появиться важная цель – стать сильным, чтобы защищать свою семью и своих близких. Сильный человек – не тот, у кого много мышц, а у кого сильный дух и воля. В кудо это главное, и оно приходит со временем к каждому, кто идет по этому пути.

 

Боевая подготовка Спецназа / Арсенал-Инфо.рф

Основную массу времени воин-спецназовец находится вне пунктов постоянной дислокации. Соответственно, вся физподготовка основана на том, чтобы использовать при тренировках подручные средства. Главное в тренировке – развитие выносливости и сохранение силовых качеств как можно дольше. Итак, тренировки ежедневные; курс не рассчитан, как обычно, на шесть или восемь недель – работать надо будет минимум год. Диета у спецназовца одна – есть побольше.

Подготовка бойца зиждется на четырех столпах:

1. Пробежка и переползания

10 км каждый день. По воскресеньям у нас иногда устраивают «спортивный праздник» – пробежать 40 км. Но, пока человек не в армии, в воскресенье может отдыхать. Боец пробегает 10 км меньше чем за час с полной выкладкой (дополнительные 50 кг). Бег надо чередовать с переползаниями. Они хорошо прорабатывают мелкие группы мышц и связки. Есть три способа: по-пластунски, на спине и прохождение минного поля (боец лег, руками прощупал неровности, подтянулся вперед, снова прощупал неровности; если что-то на поверхности вызывает подозрение – смещается в сторону).

2. Круговая тренировка

Прежде чем наступать на солдата, офицер должен сам отжиматься в пять раз больше него.

В Рязанском воздушно-десантном училище на спецкафедре физподготовки доказали, что высочайший уровень силовой выносливости дает именно круговая тренировка. Принцип был заимствован у советской школы бокса и самбо. Круговая тренировка развивает выносливость, взрывную силу, «сушит» и воспитывает злобу к начальству. Количество повторов в любом упражнении – пока сержант не заскучает.

Стандартная же тренировка занимает 40 минут. После упомянутой 10-километровой пробежки отдых 5 минут, затем снова 5–6 кругов, в которых упражнения выполняются друг за другом без отдыха. Отдых между кругами – 5 минут. Стандартный круг спецназовца выглядит так:

• Отжимания на пальцах (20 повторов)

• Джамп – выпрыгивания вверх из положения сидя с хлопком (10 повторов)

• Отжимания на кулаках (30 повторов)

• Джамп (10 повторов)

• Отжимания на пальцах (5 повторов)

• Джамп (10 повторов)

• Отжимания на кулаках (30 повторов)

Можно также включить в тренировку метание камней.

3. Постоянная нагрузка

Принцип в армии один – постоянная ежедневная нагрузка. То есть в день боец должен делать определенное (постоянно растущее) число отжиманий на кулаках, определенное число раз качать пресс, подтягиваться широким хватом и т. д. Не можешь сделать это за одну тренировку – набери сумму за день. Это и есть постоянная боевая готовность.

4. Рукопашный бой

Руки

Боковой левый и боковой правый из боксерской техники. Прямые удары – очень трудно научить бить сильно. Такой удар требует высочайшего уровня подготовки. Спецназ же исходит из того, что надо быстро и хорошо подготовить бойца. Поскольку ограничений нет, под этот боковой удар можно подвести кучу разновидностей и вариантов. Наносится он с любых позиций и ракурсов. Причем желательно сначала нанести противнику удар в горло. В ближнем бою – локтями. Нокаутирующую силу удара тренируют упражнениями с кувалдой.

Ноги

Приемы ногами в спецназе сводятся к одному – сильный удар в пах. Тут вам не спортплощадка.

Голова

Голову включают (а мозг на время выключают) в ближнем бою. Бьют верхней лобной частью исключительно в нос. При захвате сзади бьют в нос затылком.

Сваливание

Для этого тренируются сила и хват. Свалил противника за счет силы рук – бей по затылку, как по футбольному мячу, или наступай на горло.

Страница не найдена

17.03.2021
День войск Национальной Гвардии Российской Федерации

Ко Дню Национальной Гвардии России военторг Военпро расширил свой ассортимент оригинальными подарками и сувенирами с…

26.01.2021
Дарите мужчинам на 23 февраля неординарные подарки!

На сайте нашего интернет-военторга вы сможете подобрать к 23 февраля подарки для мужчин всех возрастов, с разными…

27.12.2020
Новогодние подарки наложенным платежом

Магазин подарков…

23.12.2020
Поздравляем пожарных и спасателей МЧС России!

В военторге Военпро вы можете купить юбилейные медали, береты, флаги, футболки и другие товары с символикой пожарных и…

17.12.2020
Подарки ФСБ для чекистов

Лучшие подарки ФСБ для настоящих чекистов от крупнейшего производителя атрибутики для спецслужб и армии…

07.12.2020
РВСН – история и современность

Рассказ о РВСН, история которых прочно связана с развитием баллистических ракет и…

02.12.2020
Снаряжение для Кавказа

Сегодня все представители армянской нации сплотились как монолит. Каждый армянин, представитель диаспор в любой стране…

Иллюстрированное руководство по LSTM и ГРУ: пошаговое объяснение | автор: Майкл Фи

Привет и добро пожаловать в иллюстрированное руководство по долговременной краткосрочной памяти (LSTM) и закрытым рекуррентным модулям (GRU). Я Майкл, и я инженер по машинному обучению в сфере голосового помощника AI.

В этом посте мы начнем с интуиции, лежащей в основе LSTM и ГРУ. Затем я объясню внутренние механизмы, которые позволяют LSTM и ГРУ так хорошо работать. Если вы хотите понять, что происходит под капотом этих двух сетей, тогда этот пост для вас.

Вы также можете посмотреть видеоверсию этого поста на YouTube, если хотите.

Рекуррентные нейронные сети страдают от кратковременной памяти. Если последовательность достаточно длинная, им будет трудно переносить информацию с более ранних временных шагов на более поздние. Поэтому, если вы пытаетесь обработать абзац текста, чтобы сделать прогнозы, RNN может упустить важную информацию с самого начала.

Во время обратного распространения рекуррентные нейронные сети страдают от проблемы исчезающего градиента.Градиенты — это значения, используемые для обновления весов нейронных сетей. Проблема исчезающего градиента заключается в том, что градиент уменьшается по мере его распространения во времени. Если значение градиента становится очень маленьким, это не способствует слишком большому обучению.

Правило обновления градиента

Итак, в повторяющихся нейронных сетях слои, которые получают небольшое обновление градиента, перестают обучаться. Обычно это более ранние слои. Таким образом, поскольку эти слои не обучаются, RNN могут забыть то, что они видели, в более длинных последовательностях, таким образом обладая кратковременной памятью.Если вы хотите узнать больше о механике рекуррентных нейронных сетей в целом, вы можете прочитать мой предыдущий пост здесь.

LSTM и GRU были созданы как решение для краткосрочной памяти. У них есть внутренние механизмы, называемые воротами, которые могут регулировать поток информации.

Эти ворота могут узнать, какие данные в последовательности важно сохранить или выбросить. Таким образом, он может передавать соответствующую информацию по длинной цепочке последовательностей, чтобы делать прогнозы. Почти все современные результаты, основанные на рекуррентных нейронных сетях, достигаются с этими двумя сетями.LSTM и GRU можно найти в распознавании речи, синтезе речи и генерации текста. Вы даже можете использовать их для создания подписей к видео.

Хорошо, поэтому к концу этого поста вы должны иметь твердое представление о том, почему LSTM и GRU хороши для обработки длинных последовательностей. Я собираюсь подойти к этому с помощью интуитивно понятных объяснений и иллюстраций и по возможности избегать математики.

Хорошо, давайте начнем с мысленного эксперимента. Допустим, вы просматриваете отзывы в Интернете, чтобы определить, хотите ли вы купить хлопья Life (не спрашивайте меня, почему).Вы сначала прочтете обзор, а затем определите, кто считает его хорошим или плохим.

Когда вы читаете обзор, ваш мозг подсознательно запоминает только важные ключевые слова. Вы можете подобрать такие слова, как «восхитительный» и «идеально сбалансированный завтрак». Вас не особо интересуют такие слова, как «это», «дал», «все», «должен» и т. Д. Если на следующий день друг спросит вас, что говорится в обзоре, вы, вероятно, не запомните это слово в слово. . Вы, возможно, помните основные моменты, вроде «обязательно буду покупать снова».Если вы очень похожи на меня, другие слова исчезнут из памяти.

И это, по сути, то, что делают LSTM или GRU. Он может научиться хранить только релевантную информацию, чтобы делать прогнозы, и забывать нерелевантные данные. В данном случае слова, которые вы запомнили, заставили вас судить, что это хорошо.

Чтобы понять, как LSTM или GRU достигают этого, давайте рассмотрим повторяющуюся нейронную сеть. RNN работает следующим образом; Первые слова преобразуются в машиночитаемые векторы. Затем RNN обрабатывает последовательность векторов один за другим.

Последовательность обработки по очереди

При обработке предыдущее скрытое состояние передается на следующий шаг последовательности. Скрытое состояние действует как память нейронных сетей. Он содержит информацию о предыдущих данных, которые сеть видела раньше.

Передача скрытого состояния на следующий временной шаг

Давайте посмотрим на ячейку RNN, чтобы увидеть, как вы рассчитываете скрытое состояние. Во-первых, вход и предыдущее скрытое состояние объединяются для формирования вектора. Этот вектор теперь имеет информацию о текущем и предыдущих входах.Вектор проходит активацию tanh, и на выходе появляется новое скрытое состояние или память сети.

RNN Cell

Активация tanh

Активация tanh используется для помощи в регулировании значений, передаваемых по сети. Функция tanh сжимает значения, чтобы они всегда находились в диапазоне от -1 до 1.

Tanh сжимает значения в диапазоне от -1 до 1

Когда векторы проходят через нейронную сеть, они претерпевают множество преобразований из-за различных математических операций. Итак, представьте себе значение, которое продолжает умножаться на, скажем, 3 .Вы можете увидеть, как некоторые значения могут взорваться и стать астрономическими, в результате чего другие значения будут казаться незначительными.

векторные преобразования без tanh

Функция tanh гарантирует, что значения остаются между -1 и 1, таким образом регулируя вывод нейронной сети. Вы можете видеть, как те же значения сверху остаются между границами, разрешенными функцией tanh.

векторных преобразований с помощью tanh

Итак, это RNN. У него очень мало внутренних операций, но он работает довольно хорошо при определенных обстоятельствах (например, короткие последовательности).RNN использует намного меньше вычислительных ресурсов, чем его усовершенствованные варианты, LSTM и GRU.

LSTM имеет такой же поток управления, что и рекуррентная нейронная сеть. Он обрабатывает данные, передавая информацию по мере ее распространения. Различия заключаются в операциях внутри ячеек LSTM.

Ячейка LSTM и ее операции

Эти операции используются, чтобы позволить LSTM сохранить или забыть информацию. Теперь рассмотрение этих операций может стать немного утомительным, поэтому мы рассмотрим их шаг за шагом.

Основная концепция

Основная концепция LSTM — это состояние ячейки и ее различные ворота. Состояние ячейки действует как транспортная магистраль, которая передает относительную информацию по всей цепочке последовательности. Вы можете думать об этом как о «памяти» сети. Теоретически состояние ячейки может нести важную информацию на протяжении всей обработки последовательности. Таким образом, даже информация из более ранних временных шагов может перейти к более поздним временным шагам, уменьшая влияние кратковременной памяти.По мере того, как состояние ячейки продолжает свой путь, информация добавляется или удаляется из состояния ячейки через шлюзы. Ворота — это разные нейронные сети, которые решают, какая информация разрешена о состоянии ячейки. Гейтс может узнать, какую информацию важно сохранить или забыть во время тренировки.

Сигмоид

Gates содержит сигмовидные активации. Активация сигмовидной кишки похожа на активацию tanh. Вместо того, чтобы сжимать значения от -1 до 1, он сжимает значения от 0 до 1. Это помогает обновить или забыть данные, потому что любое число, умноженное на 0, равно 0, в результате чего значения исчезают или «забываются».«Любое число, умноженное на 1, является тем же значением, поэтому это значение остается неизменным или« сохраняется ». Сеть может узнать, какие данные не важны, поэтому их можно забыть или какие данные важно сохранить.

Сигмоид сжимает значения между 0 и 1

Давайте углубимся в то, что делают различные ворота, не так ли? Итак, у нас есть три разных шлюза, которые регулируют поток информации в ячейке LSTM. Забытый вентиль, входной вентиль и выходной вентиль.

Забыть ворота

Во-первых, у нас есть ворота забвения.Эти ворота решают, какую информацию следует выбросить или оставить. Информация из предыдущего скрытого состояния и информация из текущего входа передаются через сигмоидальную функцию. Значения находятся в диапазоне от 0 до 1. Чем ближе к 0, тем лучше все забыть, а чем ближе к 1, тем лучше.

Забыть операции с воротами

Входные ворота

Для обновления состояния ячейки у нас есть входные ворота. Сначала мы передаем предыдущее скрытое состояние и текущий ввод в сигмоидальную функцию. Это решает, какие значения будут обновлены, путем преобразования значений между 0 и 1.0 означает не важно, а 1 означает важно. Вы также передаете скрытое состояние и текущий ввод в функцию tanh, чтобы сжать значения от -1 до 1, чтобы помочь регулировать сеть. Затем вы умножаете выход tanh на выход сигмоида. Выход сигмоида решит, какая информация важна для выхода tanh.

Операции входного шлюза

Состояние ячейки

Теперь у нас должно быть достаточно информации для вычисления состояния ячейки. Во-первых, состояние ячейки точечно умножается на вектор забывания.Это имеет возможность отбрасывать значения в состоянии ячейки, если оно умножается на значения, близкие к нулю. Затем мы берем выходные данные из входного вентиля и выполняем точечное сложение, которое обновляет состояние ячейки до новых значений, которые нейронная сеть считает релевантными. Это дает нам новое состояние клетки.

Расчет состояния ячейки

Выходной вентиль

Наконец, у нас есть выходной вентиль. Выходной вентиль решает, каким должно быть следующее скрытое состояние. Помните, что скрытое состояние содержит информацию о предыдущих входах.Скрытое состояние также используется для прогнозов. Сначала мы передаем предыдущее скрытое состояние и текущий ввод в сигмовидную функцию. Затем мы передаем недавно измененное состояние ячейки в функцию tanh. Мы умножаем выход tanh на выход сигмоида, чтобы решить, какую информацию должно нести скрытое состояние. Выход — скрытое состояние. Затем новое состояние ячейки и новое скрытое состояние переносятся на следующий временной шаг.

Операции выходного шлюза

Чтобы просмотреть, вентиль Забытия решает, что важно сохранить от предыдущих шагов.Входной вентиль решает, какая информация актуальна для добавления из текущего шага. Выходной вентиль определяет, каким должно быть следующее скрытое состояние.

Демонстрация кода

Для тех из вас, кто лучше разбирается в коде, вот пример использования псевдокода Python.

псевдокод python

1. Сначала объединяются предыдущее скрытое состояние и текущий ввод. Назовем его комбайном .
2. Комбайн загружается в забойный слой. Этот слой удаляет нерелевантные данные.
4. Слой-кандидат создается с помощью комбайна . Кандидат содержит возможные значения для добавления к состоянию ячейки.
3. Комбайн также попадает во входной слой. Этот уровень решает, какие данные от кандидата следует добавить в новое состояние ячейки.
5. После вычисления слоя забывания, слоя-кандидата и входного слоя состояние ячейки вычисляется с использованием этих векторов и предыдущего состояния ячейки.
6. Затем вычисляется результат.
7. Точечное умножение вывода и нового состояния ячейки дает нам новое скрытое состояние.

Вот и все! Поток управления в сети LSTM — это несколько тензорных операций и цикл for. Вы можете использовать скрытые состояния для прогнозов. Комбинируя все эти механизмы, LSTM может выбирать, какую информацию необходимо запомнить или забыть во время обработки последовательности.

Итак, теперь мы знаем, как работает LSTM, давайте кратко рассмотрим ГРУ. GRU — это новое поколение рекуррентных нейронных сетей, очень похожее на LSTM. ГРУ избавилось от состояния ячейки и использовало скрытое состояние для передачи информации.У него также есть только два гейта, вентиль сброса и вентиль обновления.

Ячейка GRU и ее ворота

Шлюз обновления

Шлюз обновления действует аналогично шлюзу забывания и входу LSTM. Он решает, какую информацию выбросить и какую новую добавить.

Шлюз сброса

Шлюз сброса — это еще один шлюз, используемый для определения того, сколько прошлой информации следует забыть.

А это ГРУ. В ГРУ меньше тензорных операций; поэтому они обучаются немного быстрее, чем LSTM.Неизвестно, какой из них лучше. Исследователи и инженеры обычно пытаются определить, какой из них лучше подходит для их варианта использования.

Подводя итог, можно сказать, что RNN хороши для обработки данных последовательности для предсказаний, но страдают от кратковременной памяти. LSTM и GRU были созданы как метод уменьшения кратковременной памяти с помощью механизмов, называемых воротами. Гейты — это просто нейронные сети, которые регулируют поток информации, проходящей через цепочку последовательностей. LSTM и GRU используются в самых современных приложениях глубокого обучения, таких как распознавание речи, синтез речи, понимание естественного языка и т. Д.

Если вы хотите углубиться, вот ссылки на некоторые фантастические ресурсы, которые могут дать вам другой взгляд на понимание LSTM и GRU. Этот пост был сильно вдохновлен ими.

Recurrent Neural Network Tutorial, Part 4 – Implementing a GRU/LSTM RNN with Python and Theano

http: // colah .github.io / posts / 2015-08-Understanding-LSTMs /

Мне было очень весело писать этот пост, поэтому дайте мне знать комментарии, если это было полезно, или что вы хотели бы видеть в следующем.И как всегда, спасибо за чтение!

Посетите michaelphi.com, чтобы найти больше подобного контента.

Понимание сетей GRU. В этой статье я постараюсь дать… | Симеон Костадинов

В этой статье я постараюсь дать довольно простое и понятное объяснение одного действительно интересного типа нейронной сети. Представлено Cho, et al. В 2014 году GRU (Gated Recurrent Unit) стремится решить проблему исчезающего градиента , которая поставляется со стандартной рекуррентной нейронной сетью.GRU также можно рассматривать как разновидность LSTM, потому что оба они спроектированы одинаково и в некоторых случаях дают одинаково отличные результаты. Если вы не знакомы с рекуррентными нейронными сетями, рекомендую прочитать мое краткое введение. Чтобы лучше понять LSTM, многие рекомендуют статью Кристофера Олаха. Я бы также добавил этот документ, который дает четкое различие между GRU и LSTM.

Как работают ГРУ?

Как упоминалось выше, ГРУ являются улучшенной версией стандартной рекуррентной нейронной сети.Но что делает их такими особенными и эффективными?

Чтобы решить проблему исчезающего градиента стандартной RNN, ГРУ использует так называемый вентиль обновления и вентиль сброса . По сути, это два вектора, которые определяют, какую информацию нужно передать на выход. Их особенность заключается в том, что их можно обучить хранить информацию давних времен, не стирая ее во времени и не удаляя информацию, не имеющую отношения к прогнозу.

Чтобы объяснить математику, лежащую в основе этого процесса, мы рассмотрим отдельный блок из следующей рекуррентной нейронной сети:

Рекуррентная нейронная сеть с закрытым рекуррентным блоком

Вот более подробная версия этого единственного GRU:

Блокируемый рекуррентный блок

Во-первых, давайте введите обозначения:

Если вы не знакомы с приведенной выше терминологией, я рекомендую посмотреть эти учебные пособия о функциях «сигмоида» и «tanh» и работе с «произведением Адамара».

№1. Строб обновления

Мы начинаем с вычисления строба обновления z_t для временного шага t по формуле:

Когда x_t подключается к сетевому модулю, он умножается на собственный вес W (z) . То же самое касается h_ (t-1) , который содержит информацию для предыдущих единиц t-1 и умножается на собственный вес U (z). Оба результата суммируются, и применяется сигмовидная функция активации для сжатия результата между 0 и 1.Следуя приведенной выше схеме, мы имеем:

Шлюз обновления помогает модели определить, сколько прошлой информации (из предыдущих временных шагов) необходимо передать в будущее. Это действительно мощно, потому что модель может решить скопировать всю информацию из прошлого и устранить риск исчезновения проблемы градиента. Позже мы увидим использование шлюза обновления. А пока запомните формулу для z_t .

№ 2. Сбросить вентиль

По сути, этот вентиль используется из модели, чтобы решить, какую часть прошлой информации нужно забыть .Для его расчета мы используем:

Эта формула аналогична формуле для шлюза обновления. Разница заключается в весе и использовании ворот, что немного заметит. На схеме ниже показано, где находится вентиль сброса:

Как и раньше, мы подключаем h_ (t-1) — синюю линию и x_t — фиолетовую линию , умножаем их на их соответствующие веса, суммируем результаты и применяем сигмовидная функция.

№ 3. Текущее содержимое памяти

Давайте посмотрим, как именно ворота повлияют на конечный результат.Во-первых, мы начнем с использования ворот сброса. Мы вводим новое содержимое памяти, которое будет использовать шлюз сброса для хранения соответствующей информации из прошлого. Он рассчитывается следующим образом:

  1. Умножьте входные данные x_t на вес W и h_ (t-1) на вес U.
  2. Вычислите произведение Адамара (поэлементно) между сброс затвора р_т и Ух_ (т-1). Это определит, что нужно удалить из предыдущих временных шагов.Допустим, у нас есть задача анализа настроений для определения мнения о книге на основе написанной им рецензии. Текст начинается со слов «Это фантастическая книга, которая иллюстрирует…», а после пары абзацев заканчивается словами «Мне не очень понравилась книга, потому что я думаю, что в ней отражено слишком много деталей». Чтобы определить общий уровень удовлетворенности книгой, нам понадобится только последняя часть обзора. В этом случае, когда нейронная сеть приближается к концу текста, она научится присваивать вектор r_t близким к 0, стирая прошлое и сосредотачиваясь только на последних предложениях.
  3. Суммируйте результаты шагов 1 и 2.
  4. Примените нелинейную функцию активации tanh .

Вы можете ясно видеть шаги здесь:

Мы выполняем поэлементное умножение h_ (t-1) — синяя линия и r_t — оранжевая линия , а затем суммируем результат — розовая линия с вход x_t — фиолетовая линия . Наконец, tanh используется для получения h’_t — ярко-зеленой линии .

№ 4.Последняя память на текущем временном шаге

На последнем шаге сети необходимо вычислить h_t — вектор, который содержит информацию для текущего блока и передает ее в сеть. Для этого необходим шлюз обновления. Он определяет, что собирать из текущего содержимого памяти — h’_t , а что из предыдущих шагов — h_ (t-1) . Это делается следующим образом:

  1. Примените поэлементное умножение к шлюзу обновления z_t и h_ (t-1).
  2. Примените поэлементное умножение к (1-z_t), и h’_t.
  3. Просуммируйте результаты шагов 1 и 2.

Давайте рассмотрим пример рецензии на книгу. На этот раз наиболее актуальная информация располагается в начале текста. Модель может научиться устанавливать вектор z_t близким к 1 и сохранять большую часть предыдущей информации. Поскольку z_t будет близко к 1 на этом временном шаге, 1-z_t будет близко к 0, что будет игнорировать большую часть текущего контента (в этом случае последняя часть обзора, которая объясняет сюжет книги), который не имеет отношения к нашему прогнозу.

Вот иллюстрация, которая подчеркивает вышеприведенное уравнение:

Далее вы можете увидеть, как z_t — зеленая линия используется для расчета 1-z_t , который в сочетании с h’_t — ярко-зеленой линией, дает результат в виде темно-красной линии . z_t также используется с h_ (t-1) — синей линией в поэлементном умножении. Наконец, h_t — синяя линия является результатом суммирования выходных сигналов, соответствующих яркой и темно-красной линиям .

Стробируемый рекуррентный блок (GRU) с PyTorch

Вы слышали о ГРУ?

Стробируемый рекуррентный блок (GRU) является младшим братом более популярной сети с долгой кратковременной памятью (LSTM), а также типом рекуррентной нейронной сети (RNN). Как и его собрат, ГРУ способны эффективно сохранять долгосрочные зависимости в последовательных данных. Кроме того, они могут решить проблему «кратковременной памяти», от которой страдают обычные RNN.

Принимая во внимание наследие рекуррентных архитектур в моделировании и прогнозировании последовательностей, GRU находится на пути к тому, чтобы затмить своего старшего брата благодаря своей превосходной скорости при достижении аналогичной точности и эффективности.

В этой статье мы рассмотрим концепции, лежащие в основе ГРУ, и сравним механизмы ГРУ и LSTM. Мы также рассмотрим различия в производительности этих двух вариантов RNN. Если вы не знакомы с RNN или LSTM, вы можете просмотреть мои предыдущие сообщения по этим темам:

Готовы создавать, обучать и развертывать ИИ?

Начните работу с совместной платформой искусственного интеллекта FloydHub бесплатно
Попробовать FloydHub бесплатно

Что такое ГРУ?

Стробируемый рекуррентный блок (GRU), как следует из названия, является вариантом архитектуры RNN и использует стробирующие механизмы для контроля и управления потоком информации между ячейками в нейронной сети.ГРУ были введены только в 2014 году Чо и др. и может считаться относительно новой архитектурой, особенно по сравнению с широко распространенной LSTM, предложенной в 1997 году Зеппом Хохрайтером и Юргеном Шмидхубером.

Общая структура в ячейке ГРУ

Структура ГРУ позволяет ему адаптивно фиксировать зависимости от больших последовательностей данных, не отбрасывая информацию из более ранних частей последовательности. Это достигается за счет стробирующих устройств , подобных тем, которые используются в LSTM, которые решают проблему исчезающего / увеличивающегося градиента традиционных RNN.Эти шлюзы несут ответственность за регулирование информации, которая должна храниться или отбрасываться на каждом временном шаге. Позже в этой статье мы подробно рассмотрим, как работают эти ворота и как они преодолевают указанные выше проблемы.

GRU следуют тому же потоку, что и типичный RNN

За исключением своих внутренних механизмов стробирования, GRU функционирует точно так же, как RNN, где последовательные входные данные потребляются ячейкой GRU на каждом временном шаге вместе с памятью или иначе известны как скрытое состояние .Затем скрытое состояние повторно вводится в ячейку RNN вместе со следующими входными данными в последовательности. Этот процесс продолжается как релейная система, производя желаемый выходной сигнал.

Но как это на самом деле работает? Внутренняя работа ГРУ

Способность ГРУ удерживать долгосрочные зависимости или память проистекает из вычислений в ячейке ГРУ для создания скрытого состояния. В то время как LSTM имеют два разных состояния, передаваемых между ячейками — состояние ячейки и скрытое состояние , которые несут долгую и краткосрочную память, соответственно, — ГРУ имеют только одно скрытое состояние, передаваемое между временными шагами.Это скрытое состояние способно одновременно удерживать как долгосрочные, так и краткосрочные зависимости из-за механизмов стробирования и вычислений, через которые проходят скрытое состояние и входные данные.

GRU против LSTM

Ячейка GRU содержит только два шлюза: ворота обновления и ворота сброса . Подобно воротам в LSTM, эти ворота в ГРУ обучены , чтобы выборочно отфильтровывать любую не относящуюся к делу информацию, сохраняя при этом то, что полезно.Эти вентили по существу являются векторами, содержащими значения от 0 до 1 , которые будут умножены на входные данные и / или скрытое состояние. Значение 0 в векторах вентилей указывает, что соответствующие данные во входном или скрытом состоянии не важны и, следовательно, будут возвращены как ноль. С другой стороны, значение 1 в векторе затвора означает, что соответствующие данные важны и будут использоваться.

В остальной части статьи я буду использовать термины gate и vector как синонимы, поскольку они относятся к одному и тому же.

Структура подразделения ГРУ показана ниже.

Внутреннее устройство ячейки ГРУ

Хотя структура может выглядеть довольно сложной из-за большого количества соединений, механизм, стоящий за ней, можно разбить на три основных этапа.

Reset Gate

На первом этапе мы создадим ворота Reset . Этот вентиль выводится и рассчитывается с использованием как скрытого состояния из предыдущего временного шага, так и входных данных на текущем временном шаге.

Reset Gate Flow

Математически это достигается путем умножения предыдущего скрытого состояния и токового входа на их соответствующие веса и их суммирования перед передачей суммы через сигмоидную функцию . Функция сигмоида , , , преобразует значения, чтобы они попадали между 0 и 1 , позволяя вентилю фильтровать между менее важной и более важной информацией на последующих этапах.

$$ gate_ {reset} = \ sigma (W_ {input_ {reset}} \ cdot x_t + W_ {hidden_ ​​{reset}} \ cdot h_ {t-1}) $$

Когда вся сеть обучается через обратного распространения, веса в уравнении будут обновлены, так что вектор научится сохранять только полезные функции.

Предыдущее скрытое состояние сначала умножается на обучаемый вес, а затем подвергается поэлементному умножению (произведение Адамара) на вектор сброса . Эта операция решит, какая информация из предыдущих временных шагов должна быть сохранена вместе с новыми входными данными. В то же время текущий вход также будет умножен на обучаемый вес перед суммированием с произведением вектора сброса и предыдущего скрытого состояния выше. Наконец, нелинейная функция активации tanh будет применена к окончательному результату, чтобы получить r в приведенном ниже уравнении.

$$ r = tanh (gate_ {reset} \ odot (W_ {h_1} \ cdot h_ {t-1}) + W_ {x_1} \ cdot x_t) $$

Обновить Gate

Далее мы необходимо создать ворота Update . Так же, как вентиль Reset , вентиль вычисляется с использованием предыдущего скрытого состояния и текущих входных данных.

Обновить поток ворот

И , , Обновить, , и , , сбросить , векторы ворот создаются с использованием той же формулы, но веса, умноженные на входное и скрытое состояние, уникальны для каждого элемента, что означает, что конечные векторы для каждого ворот разные.Это позволяет воротам служить своим конкретным целям.

$$ gate_ {update} = \ sigma (W_ {input_ {update}} \ cdot x_t + W_ {hidden_ ​​{update}} \ cdot h_ {t-1}) $$

Обновление вектор затем подвергнется поэлементному умножению с предыдущим скрытым состоянием , чтобы получить и в нашем уравнении ниже, которое будет использоваться для вычисления нашего окончательного результата позже.

$$ u = gate_ {update} \ odot h_ {t-1} $$

Вектор Update также будет использоваться в другой операции позже при получении нашего окончательного вывода.Цель шлюза Обновление здесь состоит в том, чтобы помочь модели определить, какая часть прошлой информации, хранящейся в предыдущем скрытом состоянии , должна быть сохранена для будущего.

Объединение выходов

На последнем этапе мы повторно используем шлюз Update и получим обновленное скрытое состояние .

Вычисления окончательного вывода

На этот раз мы будем использовать поэлементную инверсную версию того же вектора Update ( 1 — Update gate ) и выполнять поэлементное умножение с наш вывод из Reset gate, r .Цель этой операции состоит в том, чтобы шлюз Update определил, какая часть новой информации должна храниться в скрытом состоянии .

Наконец, результат вышеуказанных операций будет суммирован с нашим выводом из ворот Update на предыдущем шаге, u . Это даст нам новое и обновленное скрытое состояние .

$$ h_t = r \ odot (1-gate_ {update}) + u $$

Мы можем использовать это новое скрытое состояние в качестве вывода для этого временного шага, пропустив его через линейный слой активации.

Решение проблемы исчезающего / увеличивающегося градиента

Мы видели ворота в действии. Мы знаем, как они преобразуют наши данные. Теперь давайте рассмотрим их общую роль в управлении сетевой памятью и поговорим о том, как они решают проблему исчезающего / увеличивающегося градиента.

Как мы видели в механизмах выше, Reset gate отвечает за решение, какие части предыдущего скрытого состояния должны быть объединены с текущим входом с по предлагают новый скрытый государственный.

И вентиль обновления отвечает за определение того, какая часть из предыдущего скрытого состояния должна быть сохранена и какая часть нового предложенного скрытого состояния (полученного из шлюза сброса ) должна быть добавленным к окончательному скрытому состоянию . Когда шлюз обновления , , , сначала умножается на предыдущее скрытое состояние, сеть выбирает, какие части предыдущего скрытого состояния она будет хранить в своей памяти, отбрасывая остальные.Впоследствии он исправляет недостающих частей информации, когда он использует инверсию шлюза обновления для фильтрации предлагаемого нового скрытого состояния из шлюза сброса .

Это позволяет сети сохранять долгосрочных зависимостей . Шлюз обновления может выбрать сохранение большей части предыдущей памяти в скрытом состоянии, если значения вектора обновления близки к 1 без повторного вычисления или изменения всего скрытого состояния.

Проблема исчезающего / увеличивающегося градиента возникает во время обратного распространения при обучении RNN, особенно если RNN обрабатывает длинные последовательности или имеет несколько уровней. Градиент ошибки , вычисленный во время обучения, используется для обновления веса сети в правильном направлении и с правильной величиной. Однако этот градиент вычисляется с помощью правила цепочки , начиная с конца сети. Следовательно, во время обратного распространения градиенты будут непрерывно подвергаться матричному умножению и либо уменьшаться (исчезать), либо увеличиваться (взрываться) экспоненциально для длинных последовательностей.Слишком маленький градиент означает, что модель не будет эффективно обновлять свои веса, в то время как очень большие градиенты приводят к нестабильности модели.

Вентили в LSTM и GRU помогают решить эту проблему из-за аддитивного компонента вентилей Update . В то время как традиционные RNN всегда заменяют все содержимое скрытого состояния на каждом временном шаге, LSTM и GRU сохраняют большую часть существующего скрытого состояния, добавляя поверх него новый контент.Это позволяет распространять градиенты ошибок в обратном направлении, не исчезая или не увеличиваясь слишком быстро из-за операций сложения.

В то время как LSTM и GRU являются наиболее широко используемыми исправлениями вышеупомянутой проблемы, другим решением проблемы разноса градиентов является отсечение градиента . Отсечение устанавливает определенное пороговое значение для градиентов, что означает, что даже если градиент превышает заранее определенное значение во время обучения, его значение все равно будет ограничено установленным порогом.Таким образом, направление градиента остается неизменным, и изменяется только величина градиента.

Gradient Clipping — Ссылка на изображение: Ian Goodfellow et. al, «Deep Learning», MIT press, 2016

GRU vs LSTM

Мы разобрались с механикой ГРУ. Но как он соотносится со своим старым (и более популярным) собратом LSTM?

Что ж, оба были созданы для решения проблемы исчезающего / увеличивающегося градиента, с которой сталкивается стандартная RNN, и оба этих варианта RNN используют механизмы стробирования для управления потоком долгосрочных и краткосрочных зависимостей в сети.

А чем они разные?

  1. Структурные различия

Хотя и ГРУ, и LSTM содержат ворота, основное различие между этими двумя структурами заключается в количестве ворот и их конкретных ролях. Роль шлюза обновления в GRU очень похожа на входные ворота и Забудьте шлюзы в LSTM. Однако управление новым содержимым памяти , добавленным в сеть, в этих двух случаях отличается.

Сравнение структуры GRU VS LSTM

В LSTM, в то время как Забыть шлюз определяет, какую часть предыдущего состояния ячейки следует сохранить, входной шлюз определяет объем новой памяти , который будет добавлен. Эти два шлюза независимы друг от друга, что означает, что количество новой информации, добавляемой через входной шлюз , , , , полностью не зависит от информации, сохраняемой через шлюз , , Забыть, , .

Что касается ГРУ, шлюз обновления отвечает за определение того, какую информацию из предыдущей памяти следует сохранить, а также отвечает за управление новой добавляемой памятью. Это означает, что сохранение предыдущей памяти и добавление новой информации в память в GRU НЕ является независимым.

Еще одно ключевое различие между структурами — это отсутствие состояния ячейки в ГРУ, как упоминалось ранее.В то время как LSTM хранит свои долгосрочные зависимости в состоянии ячейки и краткосрочную память в скрытом состоянии, GRU хранит и то, и другое в одном скрытом состоянии. Однако с точки зрения эффективности хранения долгосрочной информации обе архитектуры доказали свою эффективность для достижения этой цели.

2. Разница в скоростях

GRU обучаются быстрее по сравнению с LSTM из-за меньшего количества весов и параметров, которые необходимо обновлять во время обучения. Это можно объяснить меньшим количеством ворот в ячейке ГРУ (два входа) по сравнению с тремя воротами LSTM.

В пошаговом руководстве по коду ниже в этой статье мы будем напрямую сравнивать скорость обучения LSTM и ГРУ в той же задаче.

3. Оценка производительности

Точность модели, измеряется ли она погрешностью или пропорцией правильных классификаций, обычно является основным фактором при принятии решения, какой тип модели использовать для задачи. И GRU, и LSTM являются вариантами RNNS и могут быть подключены взаимозаменяемо для достижения аналогичных результатов.

Проект: прогнозирование временных рядов с помощью ГРУ и LSTM

Мы узнали о теоретических концепциях, лежащих в основе ГРУ. Пришло время применить полученные знания на практике.

Мы будем реализовывать модель ГРУ в коде. Чтобы продолжить наше сравнение GRU-LSTM, мы также будем использовать модель LSTM для выполнения той же задачи. Мы оценим эффективность обеих моделей по нескольким показателям. Набор данных, который мы будем использовать, — это набор данных о почасовом потреблении энергии, который можно найти на Kaggle.Набор данных содержит данные о потреблении энергии в разных регионах США, записываемые ежечасно.

Вы можете запустить реализацию кода из этой статьи на FloydHub, используя их графические процессоры в облаке, щелкнув следующую ссылку и используя записную книжку main.ipynb :

Это значительно ускорит тренировочный процесс. Кроме того, вы можете специально посетить репозиторий GitHub.

Целью этой реализации является создание модели, которая может точно предсказать потребление энергии в следующий час с учетом исторических данных об использовании.Мы будем использовать модели GRU и LSTM для обучения на наборе исторических данных и оценки обеих моделей на невидимом тестовом наборе. Для этого мы начнем с выбора функций и предварительной обработки данных, а затем определим, обучим и, в конечном итоге, оценим модели.

Это будет последовательность операций нашего проекта.

Мы подробно рассмотрим каждый из этих шагов.

Мы будем использовать библиотеку PyTorch для реализации обоих типов моделей вместе с другими распространенными библиотеками Python, используемыми в аналитике данных.

  импорт ОС
время импорта

импортировать numpy как np
импортировать панд как pd
импортировать matplotlib.pyplot как plt

импортный фонарик
импортировать torch.nn как nn
из torch.utils.data import TensorDataset, DataLoader

из tqdm import tqdm_notebook
из sklearn.preprocessing import MinMaxScaler

# Определить корневой каталог данных
data_dir = "./data/"
  
  # Визуализируйте, как выглядят наши данные
pd.read_csv (каталог_данных + 'AEP_hourly.csv'). head ()
  

Пример данных

Всего у нас 12 .csv файлы, содержащие почасовые данные о тенденциях энергопотребления указанного выше формата ( ‘est_hourly.paruqet’ и ‘pjm_hourly_est.csv’ не используются). На следующем шаге мы будем читать эти файлы и предварительно обрабатывать эти данные в следующем порядке:

  • Получить временные данные для каждого отдельного временного шага и обобщить их.
    • Час дня, т. Е. 0-23
    • День недели т.е. 1–7
    • месяц, т.е. 1–12
    • День года, т. Е. 1 — 365
  • Масштабируйте данные до значений от 0 до 1
    • Алгоритмы, как правило, работают лучше или сходятся быстрее, когда функции имеют относительно одинаковый масштаб и / или близки к нормально распределенным
    • Масштабирование сохраняет форму исходного распределения и не снижает важность выбросов
  • Сгруппируйте данные в последовательности, которые будут использоваться в качестве входных данных для модели, и сохраните их соответствующие метки.
    • Длина последовательности или период ретроспективного анализа — это количество точек данных в истории, которые модель будет использовать для прогнозирования
    • Метка будет следующей точкой данных во времени после последней во входной последовательности
  • Разделите входные данные и метки на обучающие и тестовые наборы
  # Объекты масштабирования будут храниться в этом словаре, чтобы наши выходные тестовые данные из модели можно было повторно масштабировать во время оценки
label_scaler = {}

train_x = []
test_x = {}
test_y = {}

для файла в tqdm_notebook (os.listdir (каталог_данных)):
    # Пропуск файлов, которые мы не используем
    если файл [-4:]! = ".csv" или file == "pjm_hourly_est.csv":
        Продолжать
    
    # Сохранять CSV-файл в Pandas DataFrame
    df = pd.read_csv ('{} / {}'. формат (каталог_данных, файл), parse_dates = [0])
    # Обработка данных времени в подходящие форматы ввода
    df ['час'] = df.apply (лямбда x: x ['Datetime']. час, ось = 1)
    df ['dayofweek'] = df.apply (лямбда x: x ['Datetime']. dayofweek, axis = 1)
    df ['месяц'] = df.apply (лямбда x: x ['Datetime'].месяц, ось = 1)
    df ['dayofyear'] = df.apply (лямбда x: x ['Datetime']. dayofyear, axis = 1)
    df = df.sort_values ​​("Datetime"). drop ("Datetime", axis = 1)
    
    # Масштабирование входных данных
    sc = MinMaxScaler ()
    label_sc = MinMaxScaler ()
    data = sc.fit_transform (df.values)
    # Получение шкалы для этикеток (данных об использовании), чтобы вывод можно было повторно масштабировать до фактического значения во время оценки
    label_sc.fit (df.iloc [:, 0] .values.reshape (-1,1))
    label_scaler [файл] = label_sc
    
    # Определить период ретроспективного анализа и разделить входные данные / метки
    ретроспективный анализ = 90
    входы = np.нули ((len (data) -lookback, lookback, df.shape [1]))
    метки = np.zeros (len (данные) -просмотр)
    
    для i в диапазоне (ретроспективный анализ, len (данные)):
        входные данные [i-lookback] = данные [i-lookback: i]
        ярлыки [i-lookback] = данные [i, 0]
    input = inputs.reshape (-1, ретроспективный анализ, df.shape [1])
    label = labels.reshape (-1,1)
    
    # Разделить данные на части для обучения / тестирования и объединить все данные из разных файлов в единый массив
    test_portion = int (0,1 * len (входы))
    если len (train_x) == 0:
        train_x = входы [: - test_portion]
        train_y = ярлыки [: - test_portion]
    еще:
        train_x = np.объединить ((поезд_x, входы [: - test_portion]))
        train_y = np.concatenate ((train_y, label [: - test_portion]))
    test_x [файл] = (входы [-test_portion:])
    test_y [файл] = (ярлыки [-test_portion:])
  

Всего у нас 980 185 последовательностей обучающих данных.

Чтобы повысить скорость обучения, мы можем обрабатывать данные партиями, чтобы модели не приходилось так часто обновлять свои веса. Классы Torch Dataset и DataLoader полезны для разделения наших данных на пакеты и перетасовки их.

  batch_size = 1024
train_data = TensorDataset (torch.from_numpy (train_x), torch.from_numpy (train_y))
train_loader = DataLoader (train_data, shuffle = True, batch_size = batch_size, drop_last = True)
  

Мы также можем проверить, есть ли у нас графические процессоры, чтобы ускорить время обучения. Если вы используете FloydHub с графическим процессором для запуска этого кода, время обучения значительно сократится.

  # torch.cuda.is_available () проверяет и возвращает логическое значение True, если графический процессор доступен, иначе он вернет False
is_cuda = факел.cuda.is_available ()

# Если у нас есть доступный графический процессор, мы настроим наше устройство на графический процессор. Мы будем использовать эту переменную устройства позже в нашем коде.
если is_cuda:
    device = torch.device ("cuda")
еще:
    устройство = torch.device ("процессор")
  

Далее мы определим структуру моделей GRU и LSTM. Обе модели имеют одинаковую структуру, с той лишь разницей, что рекуррентный уровень (GRU / LSTM) и инициализация скрытого состояния. Скрытое состояние для LSTM — это кортеж, содержащий как состояние ячейки , так и скрытое состояние , тогда как GRU имеет только одно скрытое состояние.

  класс GRUNet (nn.Module):
    def __init __ (self, input_dim, hidden_dim, output_dim, n_layers, drop_prob = 0.2):
        super (GRUNet, сам) .__ init __ ()
        self.hidden_dim = скрытый_dim
        self.n_layers = n_layers
        
        self.gru = nn.GRU (input_dim, hidden_dim, n_layers, batch_first = True, dropout = drop_prob)
        self.fc = nn.Linear (hidden_dim, output_dim)
        self.relu = nn.ReLU ()
        
    def вперед (self, x, h):
        out, h = self.gru (x, h)
        out = self.fc (self.relu (out [:, - 1]))
        вернуться, ч
    
    def init_hidden (self, batch_size):
        вес = следующий (self.parameters ()). data
        hidden = weight.new (self.n_layers, batch_size, self.hidden_dim) .zero _ (). to (устройство)
        вернуться скрыто

класс LSTMNet (nn.Module):
    def __init __ (self, input_dim, hidden_dim, output_dim, n_layers, drop_prob = 0.2):
        super (LSTMNet, сам) .__ init __ ()
        self.hidden_dim = скрытый_dim
        self.n_layers = n_layers
        
        self.lstm = nn.LSTM (input_dim, hidden_dim, n_layers, batch_first = True, dropout = drop_prob)
        self.fc = nn.Linear (hidden_dim, output_dim)
        self.relu = nn.ReLU ()
        
    def вперед (self, x, h):
        out, h = self.lstm (x, h)
        out = self.fc (self.relu (out [:, - 1]))
        вернуться, ч
    
    def init_hidden (self, batch_size):
        вес = следующий (self.parameters ()). data
        hidden = (weight.new (self.n_layers, batch_size, self.hidden_dim) .zero _ (). to (устройство),
                  масса.новый (self.n_layers, batch_size, self.hidden_dim) .zero _ (). to (устройство))
        вернуться скрыто
  

Процесс обучения определен в функции ниже, поэтому мы можем воспроизвести его для обеих моделей. Обе модели будут иметь одинаковое количество измерений в скрытом состоянии и слоях, обучены за одинаковое количество эпох и со скоростью обучения , а также обучены и протестированы на одном и том же наборе данных.

С целью сравнения производительности обеих моделей мы будем отслеживать время, необходимое для обучения модели, и в конечном итоге сравнивать окончательную точность обеих моделей на тестовом наборе.n \ frac {| F_t — A_t |} {(| F_t + A_t |) / 2} $$

  def train (train_loader, learn_rate, hidden_dim = 256, EPOCHS = 5, model_type = "GRU"):
    
    # Установка общих гиперпараметров
    input_dim = next (iter (train_loader)) [0] .shape [2]
    output_dim = 1
    n_layers = 2
    # Создание экземпляров моделей
    если model_type == "GRU":
        model = GRUNet (размер_входа, скрытый_дим, размер_выхода, n_layers)
    еще:
        model = LSTMNet (размер_входа, размер_крытого_дима, размер_вывода, n_слоев)
    model.to (устройство)
    
    # Определение функции потерь и оптимизатора
    критерий = nn.MSELoss ()
    optimizer = torch.optim.Adam (model.parameters (), lr = learn_rate)
    
    model.train ()
    print ("Начало обучения {} модели" .format (model_type))
    epoch_times = []
    # Начать цикл обучения
    для эпохи в диапазоне (1, EPOCHS + 1):
        start_time = time.clock ()
        h = model.init_hidden (размер партии)
        avg_loss = 0.
        counter = 0
        для x метка в train_loader:
            счетчик + = 1
            если model_type == "GRU":
                ч = ч. данные
            еще:
                h = кортеж ([e.данные для е в ч])
            model.zero_grad ()
            
            out, h = модель (x.to (устройство) .float (), h)
            потеря = критерий (out, label.to (устройство) .float ())
            loss.backward ()
            optimizer.step ()
            avg_loss + = loss.item ()
            если счетчик% 200 == 0:
                print ("Эпоха {} ...... Шаг: {} / {} ....... Средняя потеря для эпохи: {}". format (эпоха, счетчик, len (train_loader), avg_loss / counter) )
        current_time = время.clock ()
        print ("Эпоха {} / {} Готово, Полная потеря: {}".формат (эпоха, EPOCHS, avg_loss / len (train_loader)))
        print ("Общее прошедшее время: {} секунд" .format (str (current_time-start_time)))
        epoch_times.append (current_time-start_time)
    print ("Общее время обучения: {} секунд" .format (str (sum (epoch_times))))
    модель возврата

def оценить (модель, test_x, test_y, label_scaler):
    model.eval ()
    выходы = []
    target = []
    start_time = time.clock ()
    для i в test_x.keys ():
        inp = torch.from_numpy (np.array (test_x [i]))
        labs = фонарик.from_numpy (np.array (test_y [i]))
        h = model.init_hidden (inp.shape [0])
        out, h = модель (inp.to (устройство) .float (), h)
        outputs.append (label_scaler [i] .inverse_transform (out.cpu (). detach (). numpy ()). reshape (-1))
        targets.append (label_scaler [i] .inverse_transform (labs.numpy ()). reshape (-1))
    print ("Время оценки: {}". format (str (time.clock () - start_time)))
    sMAPE = 0
    для i в диапазоне (len (выходы)):
        sMAPE + = np.mean (abs (выходы [i] -targets [i]) / (цели [i] + output [i]) / 2) / len (выходы)
    print ("sMAPE: {}%".формат (sMAPE * 100))
    возвращаемые выходы, цели, sMAPE
  
  lr = 0,001
gru_model = поезд (train_loader, lr, model_type = "GRU")
Lstm_model = поезд (train_loader, lr, model_type = "LSTM")
  
  [Out]: Начало обучения модели ГРУ.
       Эпоха 1 ...... Шаг: 200/957 ....... Средняя потеря для эпохи: 0.0070570480596506965
       Эпоха 1 ...... Шаг: 400/957 ....... Средняя потеря для эпохи: 0.003

58837413135 Эпоха 1 ...... Шаг: 600/957 ....... Средняя потеря для эпохи: 0.0027501484048358784 Эпоха 1 ...... Шаг: 800/957 ....... Средняя потеря для эпохи: 0.0021489552696584723 Завершенная эпоха 1/5, общая потеря: 0,0018450273993545988 Истекшее время для эпохи: 78.02232400000003 секунды . . . Общее время обучения: 390,52727700000037 секунд Начало обучения модели LSTM Эпоха 1 ...... Шаг: 200/957 ....... Средняя потеря для эпохи: 0,013630141295143403 . . . Общее время обучения: 462.73371699999984 секунды

Как мы видим из времени обучения обеих моделей, наш младший брат абсолютно победил старшего по скорости. Модель ГРУ — явный победитель в этом аспекте; он завершил пять периодов обучения на 72 секунды быстрее, чем модель LSTM.

Перейдем к измерению точности обеих моделей, теперь мы будем использовать нашу функцию Assessment () и тестовый набор данных.

  gru_outputs, target, gru_sMAPE = оценить (gru_model, test_x, test_y, label_scaler)
  
  [Out]: время оценки: 1.98247

00012 sMAPE: 0,28081167222194775%

  lstm_outputs, цели, lstm_sMAPE = оценить (lstm_model, test_x, test_y, label_scaler)
  
  [Out]: время оценки: 2,602886000000126
       sMAPE: 0,27014616762377464%
  

Ааа. Интересно, правда? Хотя модель LSTM могла допускать меньшие ошибки и немного опережать модель GRU с точки зрения точности производительности, разница незначительна и, следовательно, неубедительна.

Другие тесты, сравнивающие обе эти модели, также не выявили явного победителя в отношении того, какая архитектура в целом лучше.

Наконец, давайте сделаем некоторые визуализации случайных наборов наших прогнозируемых выходных данных и фактических данных о потреблении.

  plt. Рисунок (figsize = (14,10))
plt.subplot (2,2,1)
plt.plot (gru_outputs [0] [- 100:], "-o", color = "g", label = "Прогноз")
plt.plot (цели [0] [- 100:], color = "b", label = "Actual")
plt.ylabel («Потребление энергии (МВт)»)
plt.legend ()

plt.подсюжет (2,2,2)
plt.plot (gru_outputs [8] [- 50:], "-o", color = "g", label = "Прогноз")
plt.plot (цели [8] [- 50:], color = "b", label = "Actual")
plt.ylabel («Потребление энергии (МВт)»)
plt.legend ()

plt.subplot (2,2,3)
plt.plot (gru_outputs [4] [: 50], "-o", color = "g", label = "Прогноз")
plt.plot (цели [4] [: 50], color = "b", label = "Actual")
plt.ylabel («Потребление энергии (МВт)»)
plt.legend ()

plt.subplot (2,2,4)
plt.plot (lstm_outputs [6] [: 100], "-o", color = "g", label = "Прогноз")
plt.plot (цели [6] [: 100], color = "b", label = "Actual")
plt.ylabel ('Энергопотребление (МВт)')
plt.legend ()
plt.show ()
  

Графики наших прогнозируемых результатов и фактических данных

Похоже, что модели в значительной степени успешны в прогнозировании тенденций энергопотребления. Хотя они все еще могут ошибаться в некоторых изменениях, таких как задержки в прогнозировании падения потребления, прогнозы очень близко соответствуют фактической линии на тестовом наборе. Это связано с характером данных о потреблении энергии и с тем фактом, что существуют закономерности и циклические изменения, которые модель может учесть.Для сложных задач прогнозирования временных рядов, таких как прогнозирование цен на акции или прогнозирование объема продаж, данные могут быть в значительной степени случайными или непредсказуемыми, и в таких случаях точность определенно будет ниже.

Помимо GRU

Как я уже упоминал в своей статье о LSTM, RNN и их варианты были заменены с годами в различных задачах NLP и больше не являются стандартной архитектурой NLP. Предварительно обученные модели преобразователей, такие как Google BERT, OpenAI GPT и недавно представленный XLNet, позволили получить современные тесты и результаты, а также представили перенос обучения для нисходящих задач в NLP.

На этом отпишусь обо всем, что касается ГРУ. Эта статья завершает мою серию статей, посвященных основам RNN; в будущем мы будем изучать более продвинутые концепции, такие как механизм внимания, трансформеры и современные достижения в области НЛП. Раздумывайте.


Особая благодарность Алессио за его ценные отзывы и советы, а также остальной части команды FloydHub за предоставление этой удивительной платформы и возможность внести свой вклад в сообщество глубокого обучения. Оставайся классным!


Призыв FloydHub для авторов ИИ

Хотите писать потрясающие статьи, как Габриэль, и сыграть свою роль на долгом пути к общему искусственному интеллекту? Мы ищем увлеченных писателей, чтобы создать лучший в мире блог для практического применения новаторского А.I. техники. FloydHub имеет большой охват в сообществе ИИ, и с вашей помощью мы можем вдохновить новую волну ИИ. Подайте заявку сейчас и присоединяйтесь к команде!


О Габриэле Лойе

Габриэль — энтузиаст искусственного интеллекта и веб-разработчик. В настоящее время он изучает различные области глубокого обучения — от обработки естественного языка до компьютерного зрения. Он всегда открыт для изучения нового, реализации или исследования новых идей и технологий. Вскоре он поступит в бакалавриат по бизнес-аналитике в вычислительной школе NUS, а в настоящее время проходит стажировку в финтех-стартапе PinAlpha.Габриэль также является писателем FloydHub AI. Вы можете связаться с Габриэлем в LinkedIn и GitHub.

9,1. Gated Recurrent Units (GRU) — погрузитесь в документацию Deep Learning 0.16.3

В Разделе 8.7 мы обсудили, как вычисляются градиенты в
РНС. В частности, мы обнаружили, что длинные произведения матриц могут приводить к
исчезающие или взрывающиеся градиенты. Давайте вкратце подумаем, что такое
На практике аномалии градиента означают:

Для решения этой проблемы был предложен ряд методов.Один из
самое раннее — долговременная кратковременная память [Hochreiter & Schmidhuber, 1997]
которые мы обсудим в разделе 9.2. Закрытый рекуррентный блок
(ГРУ) [Cho et al., 2014a] немного больше
оптимизированный вариант, который часто предлагает сопоставимую производительность и
значительно быстрее вычислить [Chung et al., 2014].
Из-за его простоты начнем с ГРУ.

9.1.1. Закрытое скрытое состояние¶

Ключевое различие между ванильными RNN и GRU заключается в том, что последние
поддержка стробирования скрытого состояния.Это означает, что мы посвятили
механизмы, когда скрытое состояние должно быть обновлено , а также когда оно
должно быть сбросить . Эти механизмы изучены, и они обращаются к
проблемы, перечисленные выше. Например, если первый токен имеет большой
важность мы научимся не обновлять скрытое состояние после первого
наблюдение. Точно так же мы научимся пропускать несущественные временные
наблюдения. Наконец, мы научимся сбрасывать скрытое состояние всякий раз, когда
нужный. Мы подробно обсудим это ниже.

9.1.1.1. Сбросить шлюз и обновить шлюз¶

Первое, что нам нужно представить, это вентиль сброса и
обновить ворота . Мы проектируем их как векторы с записями в
\ ((0, 1) \) такая, что мы можем выполнять выпуклые комбинации. {n \ times h} \) (количество скрытых
единицы: \ (h \)).{1 \ times h} \) — это
bias, а символ \ (\ odot \) — это (поэлементное) произведение Адамара
оператор. Здесь мы используем нелинейность в виде tanh, чтобы гарантировать, что
значения в скрытом состоянии кандидата остаются в интервале
\ ((- 1, 1) \).

Результат — кандидата , так как нам все еще нужно включить
действие шлюза обновления. По сравнению с (8.4.5),
теперь влияние предыдущих состояний можно уменьшить с помощью
поэлементное умножение \ (\ mathbf {R} _t \) и
\ (\ mathbf {H} _ {t-1} \) в (9.1.2). Когда записи
в вентиле сброса \ (\ mathbf {R} _t \) близки к 1, мы восстанавливаем
ванильный РНН, такой как в (8.4.5). Для всех записей
ворота сброса \ (\ mathbf {R} _t \), близкие к 0, кандидат
скрытое состояние является результатом MLP с \ (\ mathbf {X} _t \) в качестве
Вход. Таким образом, любое ранее существовавшее скрытое состояние сбрасывает до значений по умолчанию.

На рис. 9.1.2 показан вычислительный поток после применения
сброс ворот.

Рис. 9.1.2 Вычисление скрытого состояния кандидата в модели ГРУ.{n \ times h} \) просто старый
состояние \ (\ mathbf {H} _ {t-1} \) и насколько новый кандидат
Используется \ (\ tilde {\ mathbf {H}} _ t \). Ворота обновления
\ (\ mathbf {Z} _t \) можно использовать для этой цели, просто взяв
поэлементно выпуклые комбинации между обоими \ (\ mathbf {H} _ {t-1} \)
и \ (\ tilde {\ mathbf {H}} _ t \). Это приводит к окончательному обновлению
уравнение для ГРУ:

(9.1.3) ¶ \ [\ mathbf {H} _t = \ mathbf {Z} _t \ odot \ mathbf {H} _ {t-1} + (1 — \ mathbf {Z} _t) \ odot \ tilde { \ mathbf {H}} _ t. \]

Каждый раз, когда шлюз обновления \ (\ mathbf {Z} _t \) близок к 1, мы просто
сохранить старое состояние.В этом случае информация из
\ (\ mathbf {X} _t \) по существу игнорируется, эффективно пропуская время
шаг \ (t \) в цепочке зависимостей. Напротив, всякий раз, когда
\ (\ mathbf {Z} _t \) близко к 0, новое скрытое состояние
\ (\ mathbf {H} _t \) приближается к скрытому состоянию кандидата
\ (\ tilde {\ mathbf {H}} _ t \). Эти конструкции могут помочь нам справиться с
проблема исчезающего градиента в RNN и лучший захват зависимостей для
последовательности с большими шагами по времени. Например, если обновление
ворота были близки к 1 на всех временных шагах всего
подпоследовательности, старое скрытое состояние на временном шаге его начала будет
легко удерживаться и проходить до конца, независимо от длины
подпоследовательность.

На рис. 9.1.3 показан вычислительный поток после
обновление шлюза в действии.

Рис. 9.1.3 Вычисление скрытого состояния в модели ГРУ.

Таким образом, ГРУ имеют две следующие отличительные особенности:

9.1.2. Реализация с нуля¶

Чтобы лучше понять модель ГРУ, давайте реализуем ее
с нуля. Начнем с чтения набора данных машины времени, который мы использовали.
в разделе 8.5. Код для чтения набора данных:
нижеприведенный.

 из mxnet импорт np, npx
из mxnet.gluon import rnn
из d2l импортировать mxnet как d2l

npx.set_np ()

batch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine (размер_пакета, число_шагов)
 
 импортная горелка
из факела импорт нн
из d2l импортная горелка как d2l

batch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine (размер_пакета, число_шагов)
 
 импортировать тензорный поток как tf
из d2l импортировать тензорный поток как d2l

batch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine (размер_пакета, число_шагов)
 

9.1.2.1. Инициализация параметров модели¶

Следующим шагом является инициализация параметров модели. Рисуем гири
из распределения Гаусса со стандартным отклонением 0,01 и установить
смещение до 0. Гиперпараметр num_hiddens определяет количество
скрытые блоки. Мы инстанциируем все веса и смещения, относящиеся к
ворота обновления, ворота сброса, кандидатное скрытое состояние и выход
слой.

 def get_params (vocab_size, num_hiddens, устройство):
    num_inputs = num_outputs = словарный_размер

    def normal (форма):
        вернуть нп.random.normal (масштаб = 0,01, размер = форма, ctx = устройство)

    def three ():
        возврат (нормальный (
            (num_inputs, num_hiddens)), нормальный (
                (num_hiddens, num_hiddens)), np.zeros (num_hiddens,
                                                      ctx = устройство))

    W_xz, W_hz, b_z = three () # Обновить параметры гейта
    W_xr, W_hr, b_r = three () # Сбросить параметры гейта
    W_xh, W_hh, b_h = three () # Подходящие параметры скрытого состояния
    # Параметры выходного слоя
    W_hq = нормальный ((num_hiddens, num_outputs))
    b_q = np.нули (num_outputs, ctx = device)
    # Прикрепить градиенты
    params = [W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q]
    для параметра в параметрах:
        param.attach_grad ()
    вернуть параметры
 
 def get_params (vocab_size, num_hiddens, устройство):
    num_inputs = num_outputs = словарный_размер

    def normal (форма):
        вернуть torch.randn (размер = форма, устройство = устройство) * 0,01

    def three ():
        возврат (нормальный (
            (num_inputs, num_hiddens)), нормальный ((num_hiddens, num_hiddens)),
                факел.нули (num_hiddens, device = device))

    W_xz, W_hz, b_z = three () # Обновить параметры гейта
    W_xr, W_hr, b_r = three () # Сбросить параметры гейта
    W_xh, W_hh, b_h = three () # Подходящие параметры скрытого состояния
    # Параметры выходного слоя
    W_hq = нормальный ((num_hiddens, num_outputs))
    b_q = torch.zeros (num_outputs, device = device)
    # Прикрепить градиенты
    params = [W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q]
    для параметра в параметрах:
        param.requires_grad_ (Истина)
    вернуть параметры
 
 def get_params (vocab_size, num_hiddens):
    num_inputs = num_outputs = словарный_размер

    def normal (форма):
        вернуть tf.random.normal (форма = форма, стандартное отклонение = 0,01, среднее значение = 0,
                                dtype = tf.float32)

    def three ():
        return (tf.Variable (normal ((num_inputs, num_hiddens)),
                            dtype = tf.float32),
                tf.Variable (нормальный ((num_hiddens, num_hiddens)),
                            dtype = tf.float32),
                tf.Variable (tf.zeros (num_hiddens), dtype = tf.float32))

    W_xz, W_hz, b_z = three () # Обновить параметры гейта
    W_xr, W_hr, b_r = three () # Сбросить параметры гейта
    W_xh, W_hh, b_h = three () # Подходящие параметры скрытого состояния
    # Параметры выходного слоя
    W_hq = tf.Переменная (обычная ((num_hiddens, num_outputs)), dtype = tf.float32)
    b_q = tf.Variable (tf.zeros (num_outputs), dtype = tf.float32)
    params = [W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q]
    вернуть параметры
 

9.1.2.2. Определение модели¶

Теперь определим функцию инициализации скрытого состояния.
init_gru_state . Так же, как функция init_rnn_state , определенная в
В разделе 8.5 эта функция возвращает тензор с формой
(размер партии, количество скрытых блоков), значения которых нулевые.

 def init_gru_state (batch_size, num_hiddens, device):
    return (np.zeros (shape = (batch_size, num_hiddens), ctx = device),)
 
 def init_gru_state (batch_size, num_hiddens, device):
    return (torch.zeros ((batch_size, num_hiddens), device = device),)
 
 def init_gru_state (batch_size, num_hiddens):
    return (tf.zeros ((batch_size, num_hiddens)),)
 

Теперь мы готовы определить модель ГРУ. Его структура такая же, как
базовой ячейки RNN, за исключением того, что уравнения обновления более
сложный.

 def gru (входы, состояние, параметры):
    W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = параметры
    H, = состояние
    выходы = []
    для X входов:
        Z = npx.sigmoid (np.dot (X, W_xz) + np.dot (H, W_hz) + b_z)
        R = npx.sigmoid (np.dot (X, W_xr) + np.dot (H, W_hr) + b_r)
        H_tilda = np.tanh (np.dot (X, W_xh) + np.dot (R * H, W_hh) + b_h)
        H = Z * H + (1 - Z) * ​​H_тильда
        Y = np.dot (H, W_hq) + b_q
        outputs.append (Y)
    return np.concatenate (выходы, ось = 0), (H,)
 
 def gru (входы, состояние, параметры):
    W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = параметры
    H, = состояние
    выходы = []
    для X входов:
        Z = фонарик.сигмоид ((X @ W_xz) + (H @ W_hz) + b_z)
        R = torch.sigmoid ((X @ W_xr) + (H @ W_hr) + b_r)
        H_tilda = torch.tanh ((X @ W_xh) + ((R * H) @ W_hh) + b_h)
        H = Z * H + (1 - Z) * ​​H_тильда
        Y = H @ W_hq + b_q
        outputs.append (Y)
    вернуть torch.cat (выходы, dim = 0), (H,)
 
 def gru (входы, состояние, параметры):
    W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = параметры
    H, = состояние
    выходы = []
    для X входов:
        X = tf.reshape (X, [-1, W_xh.форма [0]])
        Z = tf.sigmoid (tf.matmul (X, W_xz) + tf.matmul (H, W_hz) + b_z)
        R = tf.sigmoid (tf.matmul (X, W_xr) + tf.matmul (H, W_hr) + b_r)
        H_tilda = tf.tanh (tf.matmul (X, W_xh) + tf.matmul (R * H, W_hh) + b_h)
        H = Z * H + (1 - Z) * ​​H_тильда
        Y = tf.matmul (H, W_hq) + b_q
        outputs.append (Y)
    return tf.concat (выходы, ось = 0), (H,)
 

9.1.2.3. Обучение и прогнозирование¶

Обучение и прогнозирование работают точно так же, как в
Раздел 8.5. После тренировки распечатываем недоумение
на обучающем наборе и предсказанной последовательности, следуя предоставленной
префиксы «путешественник во времени» и «путешественник» соответственно.

 vocab_size, num_hiddens, device = len (словар), 256, d2l.try_gpu ()
num_epochs, lr = 500, 1
model = d2l.RNNModelScratch (len (vocab), num_hiddens, device, get_params,
                            init_gru_state, gru)
d2l.train_ch8 (модель, train_iter, dictionary, lr, num_epochs, device)
 
 недоумение 1.1, 12548.7 токенов в секунду на графическом процессоре (0)
Путешествие во времени вы можете доказать, что черное есть белое, аргументируя это, сказал Филби
Путешествие: аргументом можно доказать, что черное есть белое, - сказал Филби
 
 vocab_size, num_hiddens, device = len (словар), 256, d2l.try_gpu ()
num_epochs, lr = 500, 1
model = d2l.RNNModelScratch (len (vocab), num_hiddens, device, get_params,
                            init_gru_state, gru)
d2l.train_ch8 (модель, train_iter, dictionary, lr, num_epochs, device)
 
 недоумение 1.1, 25223,3 токенов / сек на cuda: 0
путешественник во времени, так что о нем будет удобно говорить
Вы можете доказать, что черное есть белое, аргументируя это, сказал Филби
 
 vocab_size, num_hiddens, имя_устройства = len (
    словарь), 256, d2l.try_gpu () ._ имя_устройства
# определение стратегии обучения тензорного потока
стратегия = tf.distribute.OneDeviceStrategy (имя_устройства)
num_epochs, lr = 500, 1
с помощью strategy.scope ():
    model = d2l.RNNModelScratch (len (vocab), num_hiddens, init_gru_state, gru,
                                get_params)

d2l.train_ch8 (модель, train_iter, лексика, lr, num_epochs, стратегия)
 
 недоумение 1,1, 6850,4 токенов / сек на / GPU: 0
Путешествие во времени вы можете доказать, что черное есть белое, аргументируя это, сказал Филби
путешественник с легким приливом бодрости действительно
 

советов по обучению рекуррентных нейронных сетей

Некоторые практические приемы для обучения рекуррентных нейронных сетей:

Настройка оптимизации

  • Адаптивная скорость обучения. Мы обычно используем адаптивные оптимизаторы, такие как Adam
    (Kingma14) потому что они лучше справляются со сложными тренировками
    динамика рекуррентных сетей, простых градиентного спуска.
  • Градиентная обрезка. Распечатайте или постройте норму градиента, чтобы увидеть ее обычную
    диапазон, затем уменьшите градиенты, превышающие этот диапазон. Это предотвращает
    всплески градиентов, чтобы испортить параметры во время тренировки.
  • Нормализация убытка. Чтобы получить потери одинаковой величины в наборах данных,
    вы можете просуммировать условия потерь по последовательности и разделить их на максимальное
    длина последовательности.Это упрощает повторное использование гиперпараметров между
    эксперименты. Потери следует усреднить по партии.
  • Усеченное обратное распространение. Рекуррентные сети могут испытывать трудности
    изучение длинных последовательностей из-за исчезающих и шумных градиентов. Тренируйтесь на
    вместо этого перекрывающиеся фрагменты примерно из 200 шагов. Вы также можете постепенно
    увеличивайте длину блока во время тренировки. Сохранить скрытое состояние между
    границы чанка.
  • Длительное обучение. Особенно в языковом моделировании, небольшие улучшения
    потеря может иметь большое значение для воспринимаемого качества модели.Стоп
    тренировки, когда потери в обучении не улучшаются в течение нескольких эпох или
    потеря оценки начинает увеличиваться.
  • Многоступенчатая потеря. При обучении моделей генеративной последовательности существует
    компромисс между потерями в один шаг (принуждение учителя) и более длительным обучением
    воображаемые последовательности для соответствия цели
    (Chiappa17). Профессор форсинг
    (Goyal17) сочетает в себе два, но более сложен.

Структура сети

  • Стробируемый рекуррентный блок. GRU (Cho14) альтернативная память
    проектирование ячеек в LSTM. Я обнаружил, что часто достигается равное или лучшее
    производительность при использовании меньшего количества параметров и ускорении вычислений.
  • Нормализация слоев. Добавление нормализации слоя
    (Ba16) во все линейные отображения рекуррентной сети
    ускоряет обучение и часто улучшает конечные результаты. Несколько входов для
    то же отображение следует нормализовать отдельно, как это сделано в статье.
  • Сначала слои с прямой связью. Предварительная обработка ввода с прямой связью
    слои позволяют вашей модели проецировать данные в пространство с более легким
    временная динамика. Это может улучшить производительность задачи.
  • Составные повторяющиеся сети. Для рекуррентных сетей требуется квадратичное число
    веса в размере их слоя. Может быть более эффективно сложить два или три
    слои меньшего размера вместо одного большого. Вместо этого просуммируйте выходы всех слоев
    использовать только последний, аналогичный ResNet или DenseNet.

Параметры модели

  • Полученное начальное состояние. Инициализация скрытого состояния, так как нули могут вызвать
    большие потери для первых нескольких временных шагов, так что модель меньше фокусируется
    на фактической последовательности. Обучение начальному состоянию как переменной может улучшить
    производительность, как описано в этом посте.
  • Забудьте о смещении затвора. Повторяющейся сети может потребоваться некоторое время, чтобы научиться
    запомнить информацию из последнего временного шага. Инициализировать смещения для LSTM
    по умолчанию забыть гейт до 1, чтобы запомнить больше. Точно так же инициализируйте смещения
    для сброса ворот ГРУ на -1.
  • Регуляризация. Если ваша модель переоснащается, используйте специальную регуляризацию
    методы для рекуррентных сетей. Например, периодическое прекращение учебы
    (Semeniuta16) или Zoneout
    (Крюгер 17).

Надеюсь, этот сборник советов будет вам полезен. Пожалуйста, не стесняйтесь писать дальше
предложения по списку и задавайте вопросы.

Вы можете использовать этот пост под открытым небом
CC BY-SA 3.0
лицензия и цитируется как:

 @misc {hafner2017rnntips,
  author = {Хафнер, Данижар},
  title = {Советы по обучению рекуррентных нейронных сетей},
  год = {2017},
  howpublished = {запись в блоге},
  url = {https: // danijar.ru / советы-тренировочные-повторяющиеся-нейронные-сети /}
}
 

LSTM и GRU — Начало работы с глубоким обучением: курс по рекуррентным нейронным сетям

Привет и добро пожаловать в это видео о сетях с долгосрочной краткосрочной памятью и закрытых рекуррентных модулях, LSTM и GRU для краткости. В этом видео мы поговорим о двух разных типах рекуррентных нейронных сетей, которые не страдают от проблемы исчезающих градиентов. Как вы видели, обычная реализация рекуррентной нейронной сети, где выходные данные возвращаются на вход, страдает фундаментальной проблемой исчезающих градиентов и не может фиксировать долгосрочные зависимости в последовательности.Это проблема, потому что мы хотели бы, чтобы наша RNN могла анализировать текст и отвечать на вопросы, которые включают отслеживание длинных последовательностей слов. Блестящая схема решения этой проблемы была предложена в конце 90-х и получила название «Сеть долгосрочной краткосрочной памяти».

Эта сеть состоит из ячеек, каждая из которых включает несколько операций. Давайте рассмотрим их подробнее. Первое отличие от ванильной РНС — наличие внутренней переменной состояния. Он передается от одной ячейки к другой и модифицируется операционными воротами.Первые ворота называются воротами забвения. Это сигмоидальный слой, который принимает выходной сигнал в момент времени t минус один и текущий вход в момент времени t, объединяет их в один тензор и затем применяет линейное преобразование, за которым следует сигмоид. Из-за сигмоида на выходе этого затвора будет число от нуля до единицы. Это число умножает внутреннее состояние, поэтому ворота называются воротами забвения. Если f sub t равно нулю, предыдущее внутреннее состояние будет полностью забыто. А если он один, то его пропустят и переделают.

Второй вентиль — входной вентиль. Входной вентиль принимает предыдущий выход и новый вход и пропускает их через другой сигмовидный слой, очень похожий на вентиль забывания. Как и в предыдущем случае, этот вентиль возвращает значение от нуля до единицы. Значение входного вентиля умножается на выход слоя-кандидата. Этот слой применяет касательную гиперболу к смеси ввода и предыдущего вывода, возвращая вектор-кандидат для добавления во внутреннее состояние. Например, если мы строим языковую модель, этот шлюз будет контролировать, какие новые соответствующие функции нужно включить во внутреннее состояние.Внутреннее состояние обновляется с помощью этого правила, предыдущее состояние умножается на вентиль забывания и затем добавляется к доле нового кандидата, разрешенной входным вентилем. Наконец, у нас есть выходной вентиль.

Этот вентиль контролирует, какая часть внутреннего состояния проходит через выход, и работает аналогично другим вентилям. Итак, давайте резюмируем, как работает LSTM. У него три ворот, и все они работают одинаково. Они берут предыдущий выход и текущий вход, применяют линейное преобразование, а затем сигмовидную функцию активации.Поскольку эти три логических элемента имеют независимые веса и смещения, сеть узнает, какую часть прошлых выходных данных сохранить, какую часть текущих входных данных сохранить и какую часть внутреннего состояния отправить на выход. Остальные три компонента модуля LSTM — это внутреннее состояние, которое передается от одной итерации к следующей в виде конвейерной ленты, слой tanh, генерирующий входные данные кандидата для добавления во внутреннее состояние, и преобразование tanh внутреннего состояния. прежде, чем он попадет на выходной вентиль.Довольно просто. Эта формулировка рекуррентной нейронной сети хороша тем, что не страдает от проблемы исчезающего градиента.

И, следовательно, его можно использовать для решения более сложных задач, таких как, например, ответы на вопросы. Наконец, мы упомянули более простую версию LSTM под названием GRU или Gated Recurrent Unit. Этот модуль похож на LSTM, но упрощает его несколькими способами. Во-первых, он не передает две отдельные переменные, внутреннее состояние и выход. Он только передает вывод на следующую итерацию.Во-вторых, у него всего два ворот вместо трех. Первый вентиль управляет смешиванием предыдущего вывода с текущим вводом, и микс подается на слой tanh для вывода. Другой вентиль управляет смешиванием предыдущего выхода с текущим выходом. Посмотрите внимательно на последнюю формулу в последней строке. Разве это не знакомо? Да, это снова EWMA. Это экспоненциально взвешенная скользящая средняя. GRU применяет EWMA для фильтрации необработанного вывода, h тильда sub t, с дробной частью zed sub t, которая извлекается из обучающего набора.В заключение, в этом видео мы представили LSTM (Long-Term Short-Term Memory Network) и объяснили, как она может научиться выборочно запоминать и забывать прошлую информацию. Мы также представили ГРУ, которое представляет собой более простую версию подразделения того же типа. Спасибо за просмотр и до встречи в следующем видео.

Десятиминутное введение в последовательное обучение в Керасе


Пт 29 сентября 2017

Франсуа Шоле

В учебных пособиях.

Примечание: это сообщение из 2017 года. См. Это руководство для получения последней версии кода, используемого здесь.

Я часто вижу этот вопрос — как реализовать последовательное обучение RNN в Keras?
Вот краткое введение.

Обратите внимание, что этот пост предполагает, что у вас уже есть некоторый опыт
с рекуррентными сетями и Keras.


Что такое последовательное обучение?

Последовательное обучение (Seq2Seq) касается обучающих моделей.
для преобразования последовательностей из одного домена (например,грамм. предложения на английском языке) к последовательностям в другом домене
(например, те же предложения, переведенные на французский).

  «кот сел на циновку» -> [модель Seq2Seq] -> «le chat etait assis sur le tapis»
  

Это можно использовать для машинного перевода или для ответов на вопросы (создание ответа на естественном языке на основе вопроса на естественном языке) —
в общем, это применимо в любое время, когда вам нужно сгенерировать текст.

Есть несколько способов справиться с этой задачей: с использованием RNN или одномерных сверток.Здесь мы сосредоточимся на RNN.

Тривиальный случай: когда входная и выходная последовательности имеют одинаковую длину

Когда и входные последовательности, и выходные последовательности имеют одинаковую длину, вы можете реализовать такие модели просто с
слой Keras LSTM или GRU (или их стек). Так обстоит дело в
этот пример сценария
который показывает, как научить RNN научиться складывать числа, закодированные как строки символов:

Одним из недостатков этого подхода является то, что он предполагает, что можно сгенерировать цель [...t] задано ввод [... t] . В некоторых случаях это работает (например, добавление строк цифр), но не работает в большинстве случаев использования. В общем случае информация обо всей входной последовательности необходима для того, чтобы начать генерацию целевой последовательности.

Общий случай: каноническая последовательность-последовательность

В общем случае входные последовательности и выходные последовательности имеют разную длину (например, машинный перевод), и вся входная последовательность требуется для начала прогнозирования цели.Для этого требуется более продвинутая настройка, на которую люди обычно ссылаются, когда упоминают «модели от последовательности к последовательности» без какого-либо дополнительного контекста. Вот как это работает:

  • Уровень RNN (или его стек) действует как «кодировщик»: он обрабатывает входную последовательность и возвращает собственное внутреннее состояние.
    Обратите внимание, что мы отбрасываем выходы кодировщика RNN, только восстанавливая состояние.
    Это состояние будет служить «контекстом» или «условием» декодера на следующем этапе.
  • Другой уровень RNN (или его стек) действует как «декодер»:
    он обучен предсказывать следующие символы целевой последовательности,
    учитывая предыдущие символы целевой последовательности.В частности, он обучен превращать целевые последовательности в
    те же последовательности, но со смещением на один временной шаг в будущем,
    процесс обучения в данном контексте называется «принуждением учителя».
    Важно отметить, что кодировщик использует в качестве начального состояния векторы состояния от кодировщика,
    именно так декодер получает информацию о том, что он должен генерировать.
    Фактически, декодер учится генерировать целей [t + 1 ...]
    задано целей [... t] , обусловлено входной последовательностью .

В режиме вывода, т.е. когда мы хотим декодировать неизвестные входные последовательности, мы проходим немного другой процесс:

  • 1) Кодируйте входную последовательность в векторы состояния.
  • 2) Начните с целевой последовательности размера 1
    (только символ начала последовательности).
  • 3) Загрузите векторы состояния и целевую последовательность из 1 символа
    в декодер для прогнозирования следующего символа.
  • 4) Выберите следующий символ, используя эти предсказания.
    (мы просто используем argmax).
  • 5) Добавить выбранный символ в целевую последовательность
  • 6) Повторяйте, пока мы не сгенерируем символ конца последовательности или
    достигните предела символов.

Тот же самый процесс может также использоваться для обучения сети Seq2Seq без «принудительного принуждения учителя», то есть путем повторного ввода предсказаний декодера в декодер.

Пример Keras

Проиллюстрируем эти идеи реальным кодом.

В нашем примере реализации мы будем использовать набор данных пар английских предложений и их французского перевода, который вы можете скачать с сайта manythings.org / anki. Загружаемый файл называется fra-eng.zip . Мы реализуем модель «последовательность-последовательность» на уровне символов , обрабатывая входной символ за символом и генерируя вывод посимвольно. Другой вариант — модель на уровне слов, которая обычно более распространена для машинного перевода. В конце этого поста вы найдете некоторые заметки о превращении нашей модели в модель на уровне слов с использованием Embedding слоев.

Полный сценарий для нашего примера можно найти на GitHub.

Вот краткое изложение нашего процесса:

  • 1) Превратите предложения в 3 массива Numpy, encoder_input_data , decoder_input_data , decoder_target_data :
    • encoder_input_data — это 3D-массив формы 90_english_rac
      содержащий горячую векторизацию английских предложений.
    • decoder_input_data — это трехмерный массив формы (num_pairs, max_french_sentence_length, num_french_characters)
      содержит горячую векторизацию французских предложений.
    • decoder_target_data то же самое, что decoder_input_data , но смещено на один временной шаг .
      decoder_target_data [:, t,:] будет таким же, как decoder_input_data [:, t + 1,:] .
  • 2) Обучите базовую модель Seq2Seq на основе LSTM для прогнозирования decoder_target_data
    задано encoder_input_data и decoder_input_data .
    В нашей модели используется принуждение учителя.
  • 3) Расшифруйте несколько предложений, чтобы убедиться, что модель работает (т.е. повернуть образцы из encoder_input_data
    в соответствующие образцы из decoder_target_data ).

Поскольку процесс обучения и процесс вывода (декодирования предложений) сильно различаются, мы используем разные
модели для обоих, хотя все они используют одни и те же внутренние слои.

Это наша обучающая модель. Он использует три ключевые особенности Keras RNN:

  • Аргумент конструктора return_state , конфигурирующий уровень RNN для возврата списка, в котором
    первая запись — это выходы, а следующие записи — внутренние состояния RNN.Это используется для восстановления состояний кодировщика.
  • Аргумент вызова inital_state , определяющий начальное состояние (я) RNN.
    Это используется для передачи состояний кодировщика декодеру в качестве начальных состояний.
  • Аргумент конструктора return_sequences , настраивающий RNN для возврата его полного
    последовательность выходных данных (вместо только последнего выхода, что является поведением по умолчанию).
    Это используется в декодере.
  от keras.модели импорт модели
из keras.layers import Input, LSTM, Dense

# Определить входную последовательность и обработать ее.
encoder_inputs = Вход (shape = (None, num_encoder_tokens))
кодировщик = LSTM (latent_dim, return_state = True)
encoder_outputs, state_h, state_c = encoder (encoder_inputs)
# Мы отбрасываем `encoder_outputs` и сохраняем только состояния.
encoder_states = [state_h, state_c]

# Настроить декодер, используя `encoder_states` в качестве начального состояния.
decoder_inputs = Вход (shape = (None, num_decoder_tokens))
# Мы настраиваем наш декодер на возврат полных выходных последовательностей,
# а также для возврата внутренних состояний.Мы не используем
# возвращаем состояния в обучающей модели, но мы будем использовать их для вывода.
decoder_lstm = LSTM (latent_dim, return_sequences = True, return_state = True)
decoder_outputs, _, _ = decoder_lstm (decoder_inputs,
                                     initial_state = encoder_states)
decoder_dense = плотный (num_decoder_tokens, активация = 'softmax')
decoder_outputs = decoder_dense (decoder_outputs)

# Определите модель, которая повернется
# `encoder_input_data` &` decoder_input_data` в `decoder_target_data`
model = Модель ([encoder_inputs, decoder_inputs], decoder_outputs)
  

Мы обучаем нашу модель в две линии, отслеживая потери на удерживаемом наборе из 20% образцов.

  # Выполнить обучение
model.compile (optimizer = 'rmsprop', loss = 'category_crossentropy')
model.fit ([encoder_input_data, decoder_input_data], decoder_target_data,
          batch_size = размер_пакета,
          эпохи = эпохи,
          validation_split = 0,2)
  

Примерно через час работы с процессором MacBook мы готовы к заключению. Чтобы расшифровать тестовое предложение, повторно:

  • 1) Кодировать входное предложение и получить начальное состояние декодера
  • 2) Выполните один шаг декодера с этим начальным состоянием и маркером «начала последовательности» в качестве цели.На выходе будет следующий целевой символ.
  • 3) Добавьте предсказанный целевой символ и повторите.

Вот наша установка вывода:

  encoder_model = Модель (encoder_inputs, encoder_states)

decoder_state_input_h = Вход (shape = (latent_dim,))
decoder_state_input_c = Вход (shape = (latent_dim,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_outputs, state_h, state_c = decoder_lstm (
    decoder_inputs, initial_state = decoder_states_inputs)
decoder_states = [state_h, state_c]
decoder_outputs = decoder_dense (decoder_outputs)
decoder_model = Модель (
    [decoder_inputs] + decoder_states_inputs,
    [decoder_outputs] + decoder_states)
  

Мы используем его для реализации цикла вывода, описанного выше:

  def decode_sequence (input_seq):
    # Кодировать ввод как векторы состояния.State_value = encoder_model.predict (input_seq)

    # Сгенерировать пустую целевую последовательность длиной 1.
    target_seq = np.zeros ((1, 1, num_decoder_tokens))
    # Заполните первый символ целевой последовательности начальным символом.
    target_seq [0, 0, target_token_index ['\ t']] = 1.

    # Цикл выборки для пакета последовательностей
    # (для упрощения здесь предполагается партия размером 1).
    stop_condition = Ложь
    decoded_sentence = ''
    пока не stop_condition:
        output_tokens, h, c = модель_декодера.предсказывать(
            [target_seq] + state_value)

        # Образец токена
        sampled_token_index = np.argmax (output_tokens [0, -1,:])
        sampled_char = reverse_target_char_index [sampled_token_index]
        decoded_sentence + = sampled_char

        # Условие выхода: либо достигнуть максимальной длины
        # или найдите стоп-символ.
        если (sampled_char == '\ n' или
           len (decoded_sentence)> max_decoder_seq_length):
            stop_condition = Верно

        # Обновить целевую последовательность (длиной 1).target_seq = np.zeros ((1, 1, num_decoder_tokens))
        target_seq [0, 0, sampled_token_index] = 1.

        # Обновить состояния
        State_value = [h, c]

    вернуть decoded_sentence
  

Мы получаем хорошие результаты — неудивительно, поскольку мы декодируем образцы, взятые из обучающего теста.

  Входное предложение: Будьте вежливы.
Расшифрованная фраза: Soyez gentil!
-
Входное предложение: Брось!
Расшифрованный приговор: Laissez tomber!
-
Входное предложение: Убирайся!
Расшифрованное предложение: Сортез!
  

На этом мы завершаем наше десятиминутное введение в модели «последовательность-последовательность» в Керасе.Напоминание: полный код этого скрипта можно найти на GitHub.

Список литературы


Часто задаваемые вопросы о бонусах

Что, если я хочу использовать уровень GRU вместо LSTM?

На самом деле это немного проще, потому что GRU имеет только одно состояние, тогда как LSTM имеет два состояния. Вот как адаптировать модель обучения для использования слоя GRU:

  encoder_inputs = Вход (shape = (None, num_encoder_tokens))
кодировщик = ГРУ (latent_dim, return_state = True)
encoder_outputs, state_h = encoder (encoder_inputs)

decoder_inputs = Вход (shape = (None, num_decoder_tokens))
decoder_gru = ГРУ (латентный_дим, return_sequences = Истина)
decoder_outputs = decoder_gru (decoder_inputs, initial_state = state_h)
decoder_dense = плотный (num_decoder_tokens, активация = 'softmax')
decoder_outputs = decoder_dense (decoder_outputs)
model = Модель ([encoder_inputs, decoder_inputs], decoder_outputs)
  

Что, если я хочу использовать модель на уровне слов с целочисленными последовательностями?

Что делать, если ваши входные данные представляют собой целочисленные последовательности (например,грамм. представляющие последовательности слов, закодированные по их индексу в словаре)? Вы можете встроить эти целочисленные токены через слой Embedding . Вот как:

  # Определите входную последовательность и обработайте ее.
encoder_inputs = Вход (форма = (Нет,))
x = Встраивание (num_encoder_tokens, latent_dim) (encoder_inputs)
x, state_h, state_c = LSTM (latent_dim,
                           return_state = Истина) (x)
encoder_states = [state_h, state_c]

# Настроить декодер, используя `encoder_states` в качестве начального состояния.decoder_inputs = Вход (форма = (Нет,))
x = Встраивание (num_decoder_tokens, latent_dim) (decoder_inputs)
x = LSTM (latent_dim, return_sequences = True) (x, initial_state = encoder_states)
decoder_outputs = Плотный (num_decoder_tokens, Activation = 'softmax') (x)

# Определите модель, которая повернется
# `encoder_input_data` &` decoder_input_data` в `decoder_target_data`
model = Модель ([encoder_inputs, decoder_inputs], decoder_outputs)

# Скомпилировать и запустить обучение
model.compile (optimizer = 'rmsprop', loss = 'category_crossentropy')
# Обратите внимание, что decoder_target_data нужно закодировать в горячем режиме,
# вместо последовательностей целых чисел, таких как `decoder_input_data`!
модель.подходят ([encoder_input_data, decoder_input_data], decoder_target_data,
          batch_size = размер_пакета,
          эпохи = эпохи,
          validation_split = 0,2)
  

Что, если я не хочу использовать принуждение учителя для обучения?

В некоторых нишевых случаях вы не сможете использовать принуждение учителя, потому что у вас нет доступа к полным целевым последовательностям,
например если вы проводите онлайн-обучение на очень длинных последовательностях, где буферизация полных пар ввод-цель будет невозможна.В этом случае вы можете захотеть провести обучение, повторно вводя предсказания декодера во вход декодера, точно так же, как мы делали для логического вывода.

Вы можете достичь этого, построив модель, которая жестко кодирует выходной цикл повторной инжекции:

  от keras.layers import Lambda
из keras импортировать бэкэнд как K

# Первая часть без изменений
encoder_inputs = Вход (shape = (None, num_encoder_tokens))
кодировщик = LSTM (latent_dim, return_state = True)
encoder_outputs, state_h, state_c = encoder (encoder_inputs)
состояния = [state_h, state_c]

# Настроить декодер, который будет обрабатывать только один временной шаг за раз.decoder_inputs = Вход (shape = (1, num_decoder_tokens))
decoder_lstm = LSTM (latent_dim, return_sequences = True, return_state = True)
decoder_dense = плотный (num_decoder_tokens, активация = 'softmax')

all_outputs = []
входы = decoder_inputs
для _ в диапазоне (max_decoder_seq_length):
# Запускаем декодер на одном временном шаге
выходы, state_h, state_c = decoder_lstm (входы,
initial_state = состояния)
output = decoder_dense (выходы)
# Сохранить текущий прогноз (мы объединим все прогнозы позже)
all_outputs.добавить (выходы)
# Повторно вводим выходные данные как входные для следующей итерации цикла
# а также обновить состояния
входы = выходы
состояния = [state_h, state_c]

# Объединить все прогнозы
decoder_outputs = Лямбда (лямбда x: K.concatenate (x, axis = 1)) (all_outputs)

# Определить и скомпилировать модель, как раньше
model = Модель ([encoder_inputs, decoder_inputs], decoder_outputs)
model.compile (optimizer = 'rmsprop', loss = 'category_crossentropy')

# Подготовить входные данные декодера, которые содержат только начальный символ
# Обратите внимание, что мы могли бы сделать это константой, жестко закодированной в модели
decoder_input_data = np.