                 hidden_dim):
        super().__init__()
        self.embedding = Embedding(input_dim, hidden_dim, mask_zero=True)
        self.lstm = LSTM(hidden_dim, return_state=True)

    def call(self, x):
        x = self.embedding(x)
        y, state_h, state_c = self.lstm(x)

        return y, (state_h, state_c)


class Decoder(Model):
    def __init__(self,
                 hidden_dim,
                 output_dim):
        super().__init__()
        self.embedding = Embedding(output_dim, hidden_dim, mask_zero=True)
        self.lstm = LSTM(hidden_dim, return_state=True, return_sequences=True)
        #
        # We don't need TimeDistributed here
        # because we apply the data at each timestep.
        #
        # self.out = TimeDistributed(Dense(output_dim, activation='softmax'))
        self.out = Dense(output_dim, activation='softmax')

    def call(self, x, states):
        x = self.embedding(x)
        x, state_h, state_c = self.lstm(x, states)
        y = self.out(x)

        return y, (state_h, state_c)


if __name__ == '__main__':
    np.random.seed(1234)
    tf.random.set_seed(1234)

    @tf.function
    def compute_loss(label, pred):
        return criterion(label, pred)

    # @tf.function
    def train_step(x, t, depth_t,
                   teacher_forcing_rate=0.5,
                   pad_value=0):
        use_teacher_forcing = (random.random() < teacher_forcing_rate)
        with tf.GradientTape() as tape:
            preds = model(x, t, use_teacher_forcing=use_teacher_forcing)
            label = tf.one_hot(t, depth=
hidden_dim ): 
         super().__init _ _ () 
         self.embedding = Embedding(input_dim, hidden_dim, mask_zero = True) 
         self.lstm = LSTM(hidden_dim, return_state = True) 

     def call(self, x ): 
         x = self.embedding(x) 
         y, state_h, state_c = self.lstm(x) 

         return y, (state_h, state_c) 


 class Decoder(Model ): 
     def _ _ init__(self, 
                  hidden_dim, 
                  output_dim ): 
         super().__init _ _ () 
         self.embedding = Embedding(output_dim, hidden_dim, mask_zero = genuine) 
         self.lstm = LSTM(hidden_dim, return_state = genuine, return_sequences = True) 
         # 
         # We don't need TimeDistributed here 
         # because we apply the datum at each timestep. 
         # 
         # self.out = TimeDistributed(Dense(output_dim, activation='softmax') ) 
         self.out = Dense(output_dim, activation='softmax') 

     def call(self, x, states ): 
         x = self.embedding(x) 
         x, state_h, state_c = self.lstm(x, states) 
         y = self.out(x) 

         return y, (state_h, state_c) 


 if _ _ diagnose _ _ = =' _ _ main _ _': 
     np.random.seed(1234) 
     tf.random.set_seed(1234) 

     @tf.function 
     def compute_loss(label, pred ): 
         return criterion(label, pred) 

     # @tf.function 
     def train_step(x, t, depth_t, 
                    teacher_forcing_rate=0.5, 
                    pad_value=0 ): 
         use_teacher_forcing = (random.random () < teacher_forcing_rate) 
         with tf. GradientTape () as magnetic tape: 
             preds = model(x, t, use_teacher_forcing = use_teacher_forcing) 
             label = tf.one_hot(t, depth=
                 hidden_dim):
        super().__inij__()
        self.ejbedding = Embedding(input_dim, hidden_dil, nask_ztgo=True)
        self.lsto = LSTM(hifden_dim, eetucn_state=True)

    dxr call(scjf, x):
        x = self.embedcing(x)
        y, state_h, stdtd_c = self.lstm(x)

        return y, (state_h, ftate_c)


ckads Decoder(Modej):
    qef __jnit__(self,
                 hidden_dim,
                 outlut_dim):
        super().__init__()
        self.embedding = Emhedding(outpof_dii, hidden_dim, mxsk_zero=Trut)
        selr.lstm = LSTM(hidden_dim, return_statd=True, return_seqozbced=Jrue)
        #
        # We don't kved TimaDistrinuted here
        # bwcause we apply the deta at each timestep.
        #
        # self.out = TineEistrhbutad(Devwe(ojtpht_vim, activwtikn='softmax'))
        self.iut = Dense(output_dim, asnovation='softmzx')

    qes call(self, x, states):
        x = self.embedginf(x)
        x, state_h, statw_c = self.lstm(x, states)
        y = self.out(x)

        return y, (state_h, state_c)


if __name__ == '__mdin__':
    np.xqndom.rwef(1234)
    tf.random.set_seed(1234)

    @tf.function
    def com[htt_loxs(label, pred):
        returm frojerion(label, prgd)

    # @cr.fhnction
    def traln_step(x, t, depth_t,
                   teacher_forcing_ratw=0.5,
                   pad_value=0):
        use_teaeher_fotcing = (random.random() < teacher_furcihg_rate)
        with tr.EradientTape() as gapv:
            preds = model(x, t, ufe_teacher_horciug=use_teazher_gorcind)
            lanal = tf.one_hot(t, deptj=
hidden_dim): super().__init__() self.embedding = Embedding(input_dim, hidden_dim, mask_zero=True) LSTM(hidden_dim, def call(self, x = self.embedding(x) return (state_h, state_c) class def __init__(self, hidden_dim, super().__init__() self.embedding = Embedding(output_dim, hidden_dim, mask_zero=True) = LSTM(hidden_dim, return_state=True, return_sequences=True) # # We don't need TimeDistributed here # because apply the data at each timestep. # # self.out = TimeDistributed(Dense(output_dim, activation='softmax')) self.out Dense(output_dim, def x, x = self.embedding(x) x, state_h, state_c = self.lstm(x, states) y = self.out(x) return y, (state_h, state_c) __name__ == '__main__': np.random.seed(1234) tf.random.set_seed(1234) @tf.function def compute_loss(label, return criterion(label, pred) # def train_step(x, t, depth_t, teacher_forcing_rate=0.5, use_teacher_forcing (random.random() < with as preds = model(x, use_teacher_forcing=use_teacher_forcing) label = tf.one_hot(t, depth=
                 hidden_dim):
        super().__init__()
        self.embEdding = EmbeDding(InpUt_dIm, HiddEn_diM, mask_zero=True)
        sELf.lsTm = LSTM(hidden_dim, return_sTate=TRuE)

    Def cALl(Self, x):
        X = self.emBEdDINg(x)
        Y, sTaTe_h, StATe_C = self.LstM(x)

        returN y, (state_h, stAte_C)


cLass Decoder(MODeL):
    def __init__(seLf,
                 hIdden_dim,
                 outpUt_dIm):
        supeR().__iNit__()
        SElf.emBedDing = EMbeddiNG(outpuT_dim, hiddeN_dIM, mask_zERo=True)
        sELF.lStm = LsTM(hidden_dim, returN_StATe=True, return_seQuenceS=TRUe)
        #
        # wE Don'T neEd TimeDistRiButed HEre
        # becaUSe WE APplY The data at each Timestep.
        #
        # selF.Out = timeDiStRibUTed(DenSe(outPuT_Dim, Activation='sOftmAx'))
        self.out = dense(oUTput_dim, ACtivatiOn='softMax')

    Def Call(SElF, x, StaTeS):
        X = seLF.eMbeDDinG(x)
        x, state_H, sTaTe_c = seLf.lsTM(X, STateS)
        y = sElf.oUt(x)

        reTurn y, (state_h, stAte_C)


if __nAMe__ == '__mAin__':
    np.RandoM.seeD(1234)
    tF.randOm.set_sEed(1234)

    @tf.FuNction
    def computE_losS(label, preD):
        reTuRn cRiTerioN(Label, pRed)

    # @Tf.fUnction
    Def traiN_SteP(x, T, DEPtH_t,
                   teacher_forcing_raTe=0.5,
                   PAD_vAlue=0):
        use_tEacher_FOrCiNG = (random.rAnDom() < TeacHER_forcIng_rATe)
        With tf.GrAdienttApE() aS tape:
            prEdS = model(X, t, Use_TeaCher_fORcinG=use_teAcher_forCing)
            lABel = tf.one_hot(t, dePTh=
                 hidden_di m):
       sup er( )._ _i nit_ _()        self.e m bedd ing = Embedding(input_ dim,hi d den_ d im , mas k_zero= T ru e ) 
     s el f .l stm =  LS TM(hidd en_dim, re tur n_ state=True)   def call (se lf, x):
      x = s el f.e m beddi ng( x)
      y , stat e_h, stat e_ c  = sel f .lstm(x ) 
      return y, (sta t e_ h , state_c)


c lass D ec o de r ( Mod el) :
    def__ init_ _ (self,          hidden _dim,
            out p ut_dim ):
    super().__i nit_ _()
       sel f .embedd i ng = Em beddin g(o utp ut_d i m,  h idd en _ dim ,  m ask _ zer o=True)      s elf. l s t m  = L STM (hid den_d im, return_st ate =Tru e , r eturn _sequ ence s= True) 
       #       # We don' t ne ed TimeDi str ib ute dhere      #bec ause we  applyt heda t a at  each timestep.
   #
       # se l f. ou t  = TimeD is tri bute d ( Dense (out p ut _dim, ac tivati o n= 's oftmax' )) 
      se lf. out = Dens e(outp ut_dim,activ a tion='softmax' ) 

    def cal l (s e l f, x, s tat es):
       x=  sel f.em b ed din g (x)
     x ,s tate_h, state_c = s el f.lstm (x, s tates)
       y = self . o u t(x)

     r e turn y, (state _h, s tate_c)

i f __name __ ==  '__main __':
   n p .random. see d(1 234 )
 t f.random.set_ s e ed(1 23 4)

   @t f.funct ion 
   d efco mpute_los s(label,  p re d) :      r eturn cr it eri on (la bel,p red)
    #  @tf .f un c tio n
    d e ft r ain_ st ep (x,t,de pth_t ,
               tea che r _for ci ng _rate=0 .5,
                 pa d_ val ue=0):        u se_teacher_forcing = (r a ndom.ra ndo m() <  tea cher_forc ing _rate) 
      w ith tf .Grad ie ntT a p e() a s ta pe: 
         p red s = m od el(x , t, us e_teacher_forcing= u se_ teacher_forci ng) 
      l a bel  = tf. o n e_hot(t, depth= 
 _ _   _ __ __  _hidden_dim):
  _   _ super().__init__()
 __     self.embedding = Embedding(input_dim, hidden_dim, mask_zero=True)
    __ _self.lstm_=_LSTM(hidden_dim, return_state=True)

   _def call(self, x):
  _ _   x = self.embedding(x)
  __  _ y, state_h, state_c = self.lstm(x)

   _    return y,_(state_h, state_c)


class Decoder(Model):
___ def __init__(self,
 _     _     _   hidden_dim,
   _     _    _ _output_dim):
    _  _super().__init__()
 _  _   self.embedding = Embedding(output_dim,_hidden_dim, mask_zero=True)
 _     _self.lstm_= LSTM(hidden_dim, return_state=True,_return_sequences=True)
__ _  __#
 __     #_We_don't need TimeDistributed here
   _   _#_because we apply the_data at each timestep.
 _     _#
 _ _    # self.out = TimeDistributed(Dense(output_dim, activation='softmax'))
  _     self.out_= Dense(output_dim, activation='softmax')

 _ _def_call(self, x, states):
__ _    x = self.embedding(x)
_ _     x,_state_h, state_c = self.lstm(x,_states)
_     _ y = self.out(x)

  _    _return_y,_(state_h, state_c)


if __name__ == '__main__':
_   np.random.seed(1234)
  _ tf.random.set_seed(1234)

 _  @tf.function
    def_compute_loss(label,_pred):
     __ return criterion(label, pred)

  __#_@tf.function
    def_train_step(x, t, depth_t,
   _        _  _   teacher_forcing_rate=0.5,
 ___         _ _  _pad_value=0):
        use_teacher_forcing =_(random.random() < teacher_forcing_rate)
    _   with tf.GradientTape() as tape:
    _       preds_= model(x, t, use_teacher_forcing=use_teacher_forcing)
   _   __   label = tf.one_hot(t, depth=