Exemplo n.º 1
0
class AttentionWeight:
    def __init__(self):
        self.params, self.grads = [], []
        self.softmax = Softmax()
        self.cache = None

    def forward(self, hs, h):
        N, T, H = hs.shape

        hr = h.reshape(N, 1, H)  #.repeat(T, axis=1)
        t = hs * hr
        s = np.sum(t, axis=2)
        a = self.softmax.forward(s)

        self.cache = (hs, hr)
        return a

    def backward(self, da):
        hs, hr = self.cache
        N, T, H = hs.shape

        ds = self.softmax.backward(da)
        dt = ds.reshape(N, T, 1).repeat(H, axis=2)
        dhs = dt * hr
        dhr = dt * hs
        dh = np.sum(dhr, axis=1)

        return dhs, dh
class AttentionWeight:
    def __init__(self):
        self.params, self.grads = [], []
        self.softmax = Softmax()
        self.cache = None

    def forward(self, hs, h):
        """順伝搬

        Args:
            hs (ndarray): Encorderで取得した各単語ベクトルを連結した隠れベクトル
            h (ndarray): hsの最終単語に対応するベクトル

        Returns:
            a (ndarray): Attention用重みベクトル
        """
        N, T, H = hs.shape

        hr = h.reshape(N, 1, H).repeat(T, axis=1)
        t = hs * hr
        s = np.sum(t, axis=2)  # スコア(重み付き和)
        a = self.softmax.forward(s)

        self.cache = (hs, hr)
        return a

    def backward(self, da):
        """逆伝搬

        Args:
            da (ndarray): Attention用重みベクトルの誤差微分

        Returns:
            dhs: Encorderで取得した各単語ベクトルを連結した隠れベクトルの誤差微分
            dh: hsの最終単語に対応するベクトルの誤差微分
        """
        hs, hr = self.cache
        N, T, H = hs.shape

        ds = self.softmax.backward(da)
        dt = ds.reshape(N, T, 1).repeat(H, axis=2)  # Sumの逆伝搬はRepeat
        dhs = dt * hr
        dhr = dt * hs
        dh = np.sum(dhr, axis=1)  # Repeatの逆伝搬はSum

        return dhs, dh
Exemplo n.º 3
0
class AttentionWeight:
    '''
    Encoderの全系列の隠れ状態hs(N, T, H)と
    Decoderの現系列の隠れ状態h(N, H)とのドット積をとり、
    softmax関数にかけることで系列ごとのアライメントa(N, T)を
    出力するレイヤ
    '''

    def __init__(self):
        self.params, self.grads = [], []
        self.softmax = Softmax()
        self.cache = None

    def forward(self, hs, h):
        '''
        Decoderの隠れ状態h(N, H)をnp.repeatで(N, T, H)に拡張し、
        hsとのアダマール積を取ってHについて総和を取り、
        Softmax関数で正規化してアライメントa(N, T)を得る

        Parameters
        ----------
        hs : np.ndarray(N, T, H)
            Encoderの全系列の隠れ状態
        h : np.ndarray(N, H)
            Decoderの現系列の隠れ状態

        Returns
        -------
        np.ndarray(N, T)
            hsに対し、系列ごとの重みを示すアライメント
        '''

        N, T, H = hs.shape

        hr = h.reshape(N, 1, H)#.repeat(T, axis=1)
        t = hs * hr  # (N, T, H)
        s = t.sum(axis=2)
        a = self.softmax.forward(s)  # (N, T)

        self.cache = (hs, hr)
        return a

    def backward(self, da):
        '''
        sumの逆伝播はrepeat
        repeatの逆伝播はsum

        Parameters
        ----------
        da : np.ndarray(N, T)
            アライメントの勾配

        Returns
        -------
        dhs, dh : np.ndarray(N, T, H), np.ndarray(N, H)
            全系列の隠れ状態hsの勾配と系列の隠れ状態hの勾配
        '''
        hs, hr = self.cache
        N, T, H = hs.shape

        ds = self.softmax.backward(da)
        dt = ds.reshape(N, T, 1).repeat(H, axis=2)
        dhs = dt * hr  # (N, T, H)
        dhr = dt * hs  # (N, T, H)
        dh = dhr.sum(axis=1)  # (N, H)

        return dhs, dh