Beispiel #1
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
Beispiel #2
0
    def _calc_last_ksi(self, nn_y_list, sy):
        """
        计算最后一层 ksi
        :param nn_y_list: 神经网路计算的每一层结果
        :param sy: 训练样本的输出
        :return: 最后一层 ksi
        """

        # 1. 计算损失函数的偏导
        last_hop_y = nn_y_list[self._layer_count]
        loss_dy = self._loss.derivative_array(last_hop_y, sy)

        # 2. 计算最后一层 ksi
        nn_y_last = nn_y_list[self._layer_count - 1]
        row_last = len(nn_y_last)
        ksi_last = list()

        for i in range(0, row_last):
            # 计算ksi_last 的每个元素
            ksi_item = loss_dy[i][0] * self._last_hop_activation.derivative(last_hop_y, i) \
                       * self._activation.derivative(nn_y_last[i][0])

            ksi_last.append(ksi_item)

        ksi_last = list_2_matrix(ksi_last)

        return ksi_last
Beispiel #3
0
 def create_test_sample(self, ch):
     """
     创建测试样本(输入)
     :param ch: 测试样本字符
     :return: ch 的 one-hot 编码
     """
     sx = self._hanzi_encoder.encode(ch)
     sx = list_2_matrix(sx)
     return sx
Beispiel #4
0
    def create_sample(self):
        """
        创建样本
        :return: NULL
        """

        self._sx_list = list()
        self._sy_list = list()

        count = len(self._poem)

        for i in range(0, count - 1):
            sx = self._hanzi_encoder.encode(self._poem[i])
            sx = list_2_matrix(sx)
            self._sx_list.append(sx)

            sy = self._hanzi_encoder.encode(self._poem[i + 1])
            sy = list_2_matrix(sy)
            self._sy_list.append(sy)
Beispiel #5
0
    def _create_one_poem_sample(self, poem):
        """
        创建一首诗的训练样本
        :param poem: 一首诗
        :return: NULL
        """

        # 1. 先对这首诗做个预处理

        # 1.1 将 "\n" 替换为 “”
        poem = poem.replace("\n", "")

        # 1.2 最后加一个 END 字符
        poem = poem + HanziEncoder.END

        # 2. 构建样本

        # 2.1 初始化样本列表 sx_list, sy_list
        sx_list = list()
        sy_list = list()

        # 2.2 构建样本列表
        count = len(poem)

        for i in range(0, count - 1):
            sx = self._hanzi_encoder.encode(poem[i])
            sx = list_2_matrix(sx)
            sx_list.append(sx)

            sy = self._hanzi_encoder.encode(poem[i + 1])
            sy = list_2_matrix(sy)
            sy_list.append(sy)

        # 2.3 将样本列表加入样本分组
        self._sx_group.append(sx_list)
        self._sy_group.append(sy_list)
Beispiel #6
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)
Beispiel #7
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