예제 #1
0
파일: bp_nn_ex.py 프로젝트: 1801573781/wind
    def _bp_ksi(self, nn_y_list, ksi_list):
        """
        反向传播,计算:倒数第2层 ~ 第1层的 ksi
        :param nn_y_list: 神经网路计算的每一层结果
        :param ksi_list: 存储每一层的 ksi
        :return: NULL
        """

        # 反向传播
        for layer in range(self._layer_count - 2, -1, -1):
            # 1. 求解当前层激活函数的导数

            # 1.1 当前层神经网络的计算结果
            nn_y_cur = nn_y_list[layer]

            # 1.2 求导
            dy_cur_activiation = self._activation.derivative_array(nn_y_cur)

            # 1.3 将求导结果转化为对角矩阵
            diag_dy = np.diag(matrix_2_list(dy_cur_activiation))

            # 2. 下一层的 w 的转置
            w_next_T = (self._w_layer[layer + 1]).T

            # 3. 下一层的 ksi
            ksi_next = ksi_list[layer + 1]

            # 4. 计算当前层的 ksi: ksi_cur = diag_y * w_next_T, ksi_next
            ksi_cur = np.matmul(w_next_T, ksi_next)
            ksi_cur = np.matmul(diag_dy, ksi_cur)

            # 5. 将本层计算出的 ksi 加入到 ksi_list
            ksi_list[layer] = ksi_cur
예제 #2
0
    def _handle_lhr(self, lhr_y):
        """
        处理最后一跳修正后的输出
        :param lhr_y: 最后一跳修正后的输出
        :return: recurrent_flag,是否继续递归;recurrent_sx,如果递归,其 sx =  recurrent_sx
        """

        # 将矩阵 lhr_y 转成 list
        lst = matrix_2_list(lhr_y)

        # 解码
        ch = self._hanzi_encoder.decode(lst)

        # 如果 ch == END,那么结束递归
        if self._hanzi_encoder.is_end(ch):
            r_flag = False
            r_sx = None
        # 否则,递归下去
        else:
            # 将 ch 编码
            r_sx = self._hanzi_encoder.encode(ch)
            # 将 r_sx 转换为矩阵
            r_sx = list_2_matrix(r_sx)

            r_flag = True

        return r_flag, ch, r_sx
예제 #3
0
파일: rnn_ex.py 프로젝트: 1801573781/wind
    def _bptt(self, ksi_list, layer=0):
        """
        随时间反向传播(backpropagation through time, bttt),计算沿着时间轴的 eta_list
        :param ksi_list: 当前时间轴的每一层的 ksi 列表
        :param layer: 计算某一层的 bptt, layer 默认值是0
        :return: eta_list
        """

        # 1. 当前时刻
        cur_t = len(self._hidden_out_sequence)

        # 如果当前是 t0 时刻(cur_t = 1),则无须 bptt
        if cur_t <= 1:
            return None

        # 2. eta_list 初始化
        eta_list = [0] * (cur_t - 1)

        # 3. 按照时间反向传播,计算 eta

        # 3.1 eta_last,等于该层纵向的 ksi
        eta_last = ksi_list[layer]

        # 3.2 该层(layer)的 u 参数的转置(u.T)
        uT = self._u_layer[layer].T

        # 3.3 反向计算该层(layer)的 eta
        eta_pre = eta_last
        for t in range((cur_t - 2), -1, -1):
            # 本时刻隐藏层的输出
            hidden_out = self._hidden_out_sequence[t][layer]
            # 本时刻隐藏层输出的导数
            dh = self._activation.derivative_array(hidden_out)
            # 将导数变为对角线矩阵
            diag_dh = np.diag(matrix_2_list(dh))
            # 计算 eta
            eta = np.matmul(uT, eta_pre)
            eta = np.matmul(diag_dh, eta)

            # 存储 delta
            eta_list[t] = eta

            # 递归(循环)
            eta_pre = eta

        # 返回 eta_list
        return eta_list
예제 #4
0
    def predict_r(self, sx, py_list):
        """
        预测
        :param sx: 待预测的样本
        :param py_list: 预测结果
        :return: NULL
        """

        # 由于是递归调用,所以设置一个保护,防止死循环
        count = len(py_list)

        if count >= 30:
            return

        nn_y_list = self._calc_nn(sx)

        # 最后一层的 nn_y,才是神经网络的最终输出
        nn_y = nn_y_list[len(nn_y_list) - 1]

        # 最后一跳激活
        last_hop_y = self._last_hop_activation.active_array(nn_y)

        # 将矩阵转成 list
        last_hop_y = matrix_2_list(last_hop_y)

        # 将 list 修正一下
        RecurrentNN._revise(last_hop_y)

        # 解码
        ch = self._hanzi_encoder.decode(last_hop_y)

        # 将 ch 加入预测结果列表
        py_list.append(ch)

        # 如果 ch == END,那么结束递归
        if self._hanzi_encoder.is_end(ch):
            return
        # 否则,递归下去,继续预测
        else:
            # 将 ch 编码
            ec = self._hanzi_encoder.encode(ch)
            # 将 ec 转换为矩阵
            ec = list_2_matrix(ec)
            self.predict_r(ec, py_list)
예제 #5
0
    def _bptt(self, cur_t, ksi_list, layer=0):
        """
        随时间反向传播(backpropagation through time, bttt),计算沿着时间轴的 delta_list
        :param cur_t: 当前时刻
        :param ksi_list: 当前时间轴的每一层的 ksi 列表
        :param layer: 计算某一层的 bptt, layer 默认值是0
        :return: delta_list
        """

        # 如果当前是 t0 时刻(cur_t = 1),则无须 bptt
        if cur_t <= 1:
            return None

        # delta_list 初始化
        delta_list = [0] * (cur_t - 1)

        # delta 初始化
        delta = list_2_matrix(ksi_list[layer])

        # 获取该层(layer)的 u.T
        uT = self._u_layer[layer].T

        # 反向计算 delta
        for t in range((cur_t - 2), -1, -1):
            # 上一时刻的输出
            hidden_out_pre = self._hidden_out_sequence[t][layer]
            # 上一时刻输出的导数
            dh = self._activation.derivative_array(hidden_out_pre)
            # 将导数变为对角线矩阵
            diag_dh = np.diag(matrix_2_list(dh))
            # 计算 delta
            delta = np.matmul(uT, delta)
            delta = np.matmul(diag_dh, delta)

            # 存储 delta
            delta_list[t] = delta

        return delta_list