第十四周学习周报

目录

    • 摘要
    • Abstract
    • 1. LSTM的代码实现
    • 2. 序列到序列模型
    • 3. 梯度与方向导数
    • 总结

摘要

在上周的学习基础之上,本周学习的内容有LSTM的代码实现,通过对代码的学习进一步加深了对LSTM的理解。为了切入到transformer的学习,本文通过对一些应用例子的分析,阐述了什么是序列到序列(Seq2Seq)模型。序列到序列模型用于将一个序列(如文本,时间序列数据)转换为另一个序列。这种模型广泛应用于自然语言处理领域,特别是在机器翻译、文本摘要、对话系统和语音识别等任务中。序列到序列模型通常由Encoder和Decoder两部分组成。除此本周还回顾了梯度与方向导数的相关问题与数学推导。

Abstract

On the basis of last week’s learning,this week’s learning content includes the code implementation of LSTM, which further deepens the understanding of LSTM through the study of the code. In order to delve into the learning of transformers, this article explains what sequence to sequence (Seq2Seq) model is through the analysis of some application examples.The sequence to sequence model is used to transform a sequence (such as text, time series data) into another sequence. This model is widely used in the field of natural language processing, especially in tasks such as machine translation, text summarization, dialogue systems, and speech recognition. The sequence to sequence model usually consists of two parts: Encoder and Decoder. In addition, this week we also reviewed the related issues and mathematical derivations of gradients and directional derivatives.

1. LSTM的代码实现

在上周对LSTM的学习基础之上,本周通过对LSTM代码的学习进一步加深对LSTM的理解
(1)激活函数的实现
在LSTM中用到的激活函数为sigmoid()和tanh(),代码实现过程如下;

class SigmoidActivator(object):
    def forward(self, weighted_input):
        return 1.0 / (1.0 + np.exp(-weighted_input))

    def backward(self, output):
        return output * (1 - output)


class TanhActivator(object):
    def forward(self, weighted_input):
        return 2.0 / (1.0 + np.exp(-2 * weighted_input)) - 1.0

    def backward(self, output):
        return 1 - output * output

(2)LSTM的初始化
在构造函数的初始化中,只初始化了与forward计算相关的变量,与backward相关的变量没有初始化。这是因为构造LSTM对象的时候,我们还不知道它未来是用于训练(既有forward又有backward)还是推理(只有forward)。代码实现过程如下:

class LstmLayer(object):
    def __init__(self, input_width, state_width,
                 learning_rate):
        self.input_width = input_width
        self.state_width = state_width
        self.learning_rate = learning_rate
        # 门的激活函数
        self.gate_activator = SigmoidActivator()
        # 输出的激活函数
        self.output_activator = TanhActivator()
        # 当前时刻初始化为t0
        self.times = 0
        # 各个时刻的单元状态向量c
        self.c_list = self.init_state_vec()
        # 各个时刻的输出向量h
        self.h_list = self.init_state_vec()
        # 各个时刻的遗忘门f
        self.f_list = self.init_state_vec()
        # 各个时刻的输入门i
        self.i_list = self.init_state_vec()
        # 各个时刻的输出门o
        self.o_list = self.init_state_vec()
        # 各个时刻的即时状态c~
        self.ct_list = self.init_state_vec()
        # 遗忘门权重矩阵Wfh, Wfx, 偏置项bf
        self.Wfh, self.Wfx, self.bf = (
            self.init_weight_mat())
        # 输入门权重矩阵Wfh, Wfx, 偏置项bf
        self.Wih, self.Wix, self.bi = (
            self.init_weight_mat())
        # 输出门权重矩阵Wfh, Wfx, 偏置项bf
        self.Woh, self.Wox, self.bo = (
            self.init_weight_mat())
        # 单元状态权重矩阵Wfh, Wfx, 偏置项bf
        self.Wch, self.Wcx, self.bc = (
            self.init_weight_mat())

    def init_state_vec(self):
        '''
        初始化保存状态的向量
        '''
        state_vec_list = []
        state_vec_list.append(np.zeros(
            (self.state_width, 1)))
        return state_vec_list

    def init_weight_mat(self):
        '''
        初始化权重矩阵
        '''
        Wh = np.random.uniform(-1e-4, 1e-4,
                               (self.state_width, self.state_width))
        Wx = np.random.uniform(-1e-4, 1e-4,
                               (self.state_width, self.input_width))
        b = np.zeros((self.state_width, 1))
        return Wh, Wx, b

(3)LSTM的前向传播
代码实现如下:

    def forward(self, x):
        '''
        根据式1-式6进行前向计算
        '''
        self.times += 1
        # 遗忘门
        fg = self.calc_gate(x, self.Wfx, self.Wfh,
                            self.bf, self.gate_activator)
        self.f_list.append(fg)
        # 输入门
        ig = self.calc_gate(x, self.Wix, self.Wih,
                            self.bi, self.gate_activator)
        self.i_list.append(ig)
        # 输出门
        og = self.calc_gate(x, self.Wox, self.Woh,
                            self.bo, self.gate_activator)
        self.o_list.append(og)
        # 即时状态
        ct = self.calc_gate(x, self.Wcx, self.Wch,
                            self.bc, self.output_activator)
        self.ct_list.append(ct)
        # 单元状态
        c = fg * self.c_list[self.times - 1] + ig * ct
        self.c_list.append(c)
        # 输出
        h = og * self.output_activator.forward(c)
        self.h_list.append(h)

    def calc_gate(self, x, Wx, Wh, b, activator):
        '''
        计算门
        '''
        h = self.h_list[self.times - 1]  # 上次的LSTM输出
        net = np.dot(Wh, h) + np.dot(Wx, x) + b
        gate = activator.forward(net)
        return gate

从上面的代码我们可以看到,门的计算都是相同的算法,而门和的计算仅仅是激活函数不同。使用calc_gate方法减少了很多重复代码。
(4)LSTM的反向传播
与反向传播相关的内部状态变量是在调用backward方法之后才初始化的。这种延迟初始化的一个好处是,如果LSTM只是用来推理,那么就不需要初始化这些变量,节省了很多内存。

    def backward(self, x, delta_h, activator):
        '''
        实现LSTM训练算法
        '''
        self.calc_delta(delta_h, activator)
        self.calc_gradient(x)

算法主要由两部分组成,一部分使计算误差项,另一部分是梯度的计算。
计算误差项的对应代码如下:

    def calc_delta(self, delta_h, activator):
        # 初始化各个时刻的误差项
        self.delta_h_list = self.init_delta()  # 输出误差项
        self.delta_o_list = self.init_delta()  # 输出门误差项
        self.delta_i_list = self.init_delta()  # 输入门误差项
        self.delta_f_list = self.init_delta()  # 遗忘门误差项
        self.delta_ct_list = self.init_delta()  # 即时输出误差项

        # 保存从上一层传递下来的当前时刻的误差项
        self.delta_h_list[-1] = delta_h

        # 迭代计算每个时刻的误差项
        for k in range(self.times, 0, -1):
            self.calc_delta_k(k)

    def init_delta(self):
        '''
        初始化误差项
        '''
        delta_list = []
        for i in range(self.times + 1):
            delta_list.append(np.zeros(
                (self.state_width, 1)))
        return delta_list

    def calc_delta_k(self, k):
        '''
        根据k时刻的delta_h,计算k时刻的delta_f、
        delta_i、delta_o、delta_ct,以及k-1时刻的delta_h
        '''
        # 获得k时刻前向计算的值
        ig = self.i_list[k]
        og = self.o_list[k]
        fg = self.f_list[k]
        ct = self.ct_list[k]
        c = self.c_list[k]
        c_prev = self.c_list[k - 1]
        tanh_c = self.output_activator.forward(c)
        delta_k = self.delta_h_list[k]

        # 根据式9计算delta_o
        delta_o = (delta_k * tanh_c *
                   self.gate_activator.backward(og))
        delta_f = (delta_k * og *
                   (1 - tanh_c * tanh_c) * c_prev *
                   self.gate_activator.backward(fg))
        delta_i = (delta_k * og *
                   (1 - tanh_c * tanh_c) * ct *
                   self.gate_activator.backward(ig))
        delta_ct = (delta_k * og *
                    (1 - tanh_c * tanh_c) * ig *
                    self.output_activator.backward(ct))
        delta_h_prev = (
                np.dot(delta_o.transpose(), self.Woh) +
                np.dot(delta_i.transpose(), self.Wih) +
                np.dot(delta_f.transpose(), self.Wfh) +
                np.dot(delta_ct.transpose(), self.Wch)
        ).transpose()

        # 保存全部delta值
        self.delta_h_list[k - 1] = delta_h_prev
        self.delta_f_list[k] = delta_f
        self.delta_i_list[k] = delta_i
        self.delta_o_list[k] = delta_o
        self.delta_ct_list[k] = delta_ct

计算梯度的代码如下:

    def calc_gradient(self, x):
        # 初始化遗忘门权重梯度矩阵和偏置项
        self.Wfh_grad, self.Wfx_grad, self.bf_grad = (
            self.init_weight_gradient_mat())
        # 初始化输入门权重梯度矩阵和偏置项
        self.Wih_grad, self.Wix_grad, self.bi_grad = (
            self.init_weight_gradient_mat())
        # 初始化输出门权重梯度矩阵和偏置项
        self.Woh_grad, self.Wox_grad, self.bo_grad = (
            self.init_weight_gradient_mat())
        # 初始化单元状态权重梯度矩阵和偏置项
        self.Wch_grad, self.Wcx_grad, self.bc_grad = (
            self.init_weight_gradient_mat())

        # 计算对上一次输出h的权重梯度
        for t in range(self.times, 0, -1):
            # 计算各个时刻的梯度
            (Wfh_grad, bf_grad,
             Wih_grad, bi_grad,
             Woh_grad, bo_grad,
             Wch_grad, bc_grad) = (
                self.calc_gradient_t(t))
            # 实际梯度是各时刻梯度之和
            self.Wfh_grad += Wfh_grad
            self.bf_grad += bf_grad
            self.Wih_grad += Wih_grad
            self.bi_grad += bi_grad
            self.Woh_grad += Woh_grad
            self.bo_grad += bo_grad
            self.Wch_grad += Wch_grad
            self.bc_grad += bc_grad

        # 计算对本次输入x的权重梯度
        xt = x.transpose()
        self.Wfx_grad = np.dot(self.delta_f_list[-1], xt)
        self.Wix_grad = np.dot(self.delta_i_list[-1], xt)
        self.Wox_grad = np.dot(self.delta_o_list[-1], xt)
        self.Wcx_grad = np.dot(self.delta_ct_list[-1], xt)

    def init_weight_gradient_mat(self):
        '''
        初始化权重矩阵
        '''
        Wh_grad = np.zeros((self.state_width,
                            self.state_width))
        Wx_grad = np.zeros((self.state_width,
                            self.input_width))
        b_grad = np.zeros((self.state_width, 1))
        return Wh_grad, Wx_grad, b_grad

    def calc_gradient_t(self, t):
        '''
        计算每个时刻t权重的梯度
        '''
        h_prev = self.h_list[t - 1].transpose()
        Wfh_grad = np.dot(self.delta_f_list[t], h_prev)
        bf_grad = self.delta_f_list[t]
        Wih_grad = np.dot(self.delta_i_list[t], h_prev)
        bi_grad = self.delta_f_list[t]
        Woh_grad = np.dot(self.delta_o_list[t], h_prev)
        bo_grad = self.delta_f_list[t]
        Wch_grad = np.dot(self.delta_ct_list[t], h_prev)
        bc_grad = self.delta_ct_list[t]
        return Wfh_grad, bf_grad, Wih_grad, bi_grad, \
               Woh_grad, bo_grad, Wch_grad, bc_grad

(5)梯度下降算法的实现
在LSTM中我们使用梯度下降来更新权重,梯度下降的代码如下:

    def update(self):
        '''
        按照梯度下降,更新权重
        '''
        self.Wfh -= self.learning_rate * self.Whf_grad
        self.Wfx -= self.learning_rate * self.Whx_grad
        self.bf -= self.learning_rate * self.bf_grad
        self.Wih -= self.learning_rate * self.Whi_grad
        self.Wix -= self.learning_rate * self.Whi_grad
        self.bi -= self.learning_rate * self.bi_grad
        self.Woh -= self.learning_rate * self.Wof_grad
        self.Wox -= self.learning_rate * self.Wox_grad
        self.bo -= self.learning_rate * self.bo_grad
        self.Wch -= self.learning_rate * self.Wcf_grad
        self.Wcx -= self.learning_rate * self.Wcx_grad
        self.bc -= self.learning_rate * self.bc_grad

(6)梯度检查的实现
为了支持梯度检查,我们首先需要支持重置内部状态,实现的代码如下:

    def reset_state(self):
        # 当前时刻初始化为t0
        self.times = 0
        # 各个时刻的单元状态向量c
        self.c_list = self.init_state_vec()
        # 各个时刻的输出向量h
        self.h_list = self.init_state_vec()
        # 各个时刻的遗忘门f
        self.f_list = self.init_state_vec()
        # 各个时刻的输入门i
        self.i_list = self.init_state_vec()
        # 各个时刻的输出门o
        self.o_list = self.init_state_vec()
        # 各个时刻的即时状态c~
        self.ct_list = self.init_state_vec()

最后,实现梯度检查的代码如下:

def data_set():
    x = [np.array([[1], [2], [3]]),
         np.array([[2], [3], [4]])]
    d = np.array([[1], [2]])
    return x, d


def gradient_check():
    '''
    梯度检查
    '''
    # 设计一个误差函数,取所有节点输出项之和
    error_function = lambda o: o.sum()

    lstm = LstmLayer(3, 2, 1e-3)

    # 计算forward值
    x, d = data_set()
    lstm.forward(x[0])
    lstm.forward(x[1])

    # 求取sensitivity map
    sensitivity_array = np.ones(lstm.h_list[-1].shape,
                                dtype=np.float64)
    # 计算梯度
    lstm.backward(x[1], sensitivity_array, IdentityActivator())

    # 检查梯度
    epsilon = 10e-4
    for i in range(lstm.Wfh.shape[0]):
        for j in range(lstm.Wfh.shape[1]):
            lstm.Wfh[i, j] += epsilon
            lstm.reset_state()
            lstm.forward(x[0])
            lstm.forward(x[1])
            err1 = error_function(lstm.h_list[-1])
            lstm.Wfh[i, j] -= 2 * epsilon
            lstm.reset_state()
            lstm.forward(x[0])
            lstm.forward(x[1])
            err2 = error_function(lstm.h_list[-1])
            expect_grad = (err1 - err2) / (2 * epsilon)
            lstm.Wfh[i, j] += epsilon
            print
            'weights(%d,%d): expected - actural %.4e - %.4e' % (
                i, j, expect_grad, lstm.Wfh_grad[i, j])
    return lstm

在这里只对Wf进行了检查,运行结果如下所示:
在这里插入图片描述

2. 序列到序列模型

Transformer 是一个基于自注意力的序列到序列模型,与基于循环神经网络的序列到序列模型不同,其可以能够并行计算。
序列到序列模型输入和输出都是一个序列,输入与输出序列长度之间的关系有两种情况。
(1)输入跟输出的长度一样;
(2)机器决定输出的长度。
序列到序列模型有广泛的应用,通过以下的应用举例可以更好地了解序列到序列模型。

语音识别、机器翻译与语音翻译

语音识别:输入是声音信号,输出是语音识别的结果,即输入的这段声音信号所对应的文字。
机器翻译:机器输入一个语言的句子,输出另外一个语言的句子。输入句子的长度是N,输出句子的长度是 N′。
语音翻译:我们对机器说一句话,比如“machine learning”,机器直接把听到的英语的声音信号翻译成中文。
在这里插入图片描述
其中存在语音翻译的原因是,世界上有很多种语言可能根本没有文字,因此也就没有可以让机器先进行语音识别然后再进行机器翻译的训练资料。
以闽南语为例,,闽南语的文字不是很普及,一般人不一定能看懂。因此我们想做语音的翻译,对机器讲一句闽南语,它直接输出的是同样意思的白话文的句子,这样一般人就可以看懂。我们可以训练一个神经网络使输入的闽南语输出为可以听懂的白话。在这里插入图片描述
我们可以用视频网站上的带有中文字幕的乡土剧作为资料进行训练,在训练过程中可以忽略多噪声、音乐,乡土剧的字幕不一定跟声音能对应起来等因素的影响。

Text-To-Speech
输入文字、输出声音信号就是语音合成(Text-To-Speech)。
在这里插入图片描述
现在还没有真的做端到端的模型,以闽南语的语音合成为例,其使用的模型还是分成两阶,首先模型会先把白话文的文字转成闽南语的拼音,再把闽南语的拼音转成声音信号。从闽南语的拼音转成声音信号这一段是通过序列到序列模型 echotron 实现的。
聊天机器人
聊天机器人就是我们对它说一句话,它要给出一个回应。因为聊天机器人的输入输出都是文字,文字是一个向量序列,所以可用序列到序列的模型来做一个聊天机器人。我们可以收集大量的人为对话信息作为机器的训练资料。

问答任务
序列到序列模型在自然语言处理的领域的应用很广泛,而很多自然语言处理的任务都可以想成是问答(Question Answering,QA)的任务,例如:翻译、自动做摘要信息、情感分析等。所谓的问答就是给机器读一段文字,问机器一个问题,希望它可以给出一个正确的答案。
在这里插入图片描述

虽然各种自然语言处理的问题都能用序列到序列模型来解,但是对多数自然语言处理的任务或对多数的语音相关的任务而言,往往为这些任务定制化模型会得到更好的结果。针对各种不同的任务定制的模型往往比只用序列到序列模型的模型更好。
syntactic parsing
syntactic parsing给机器一段文字,机器要产生一个句法的分析树,即句法树。通过句法树告诉我们 deep 加 learning 合起来是一个名词短语,very 加 powerful 合起来是一个形容词短语,形容词短语加 is 以后会变成一个动词短语,动词短语加名词短语合起来是一个句子。
在这里插入图片描述
在句法分析的任务中,输入是一段文字,输出是一个树状的结构,而一个树状的结构可以看成一个序列,该序列代表了这个树的结构。

3. 梯度与方向导数

由于对梯度相关问题印象模糊,本次学习回顾了以下梯度与方向导数的概念以及相关推导。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

在本周,通过对LSTM代码实现的学习,进一步加深了对LSTM的理解。通过对梯度与方向导数相关概念的复习明白了梯度下降算法的原理。在下周我将进入transformer的相关学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/885119.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Docker】如何让docker容器正常使用nvidia显卡

首先确保宿主机正常安装了显卡驱动 nvidia-smi打印显卡信息如下: 安装nvidia-container-toolkit工具 sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit sudo systemctl restart docker运行如下命令测试显卡是否在容器内可用 …

如何去编写一个好的单元测试,通义灵码是如何快速生成单元测试?

本文首先讲述了什么是单元测试、单元测试的价值、一个好的单元测试所具备的原则,进而引入如何去编写一个好的单元测试,通义灵码是如何快速生成单元测试的。 通义灵码插件下载安装:通义灵码_智能编码助手_AI编程-阿里云 目录 什么是单元测试&…

产品管理- 互联网产品(5):运营知识与技能

了解运营 1、运营的基础是产品认清受众,切实解决问题、用户需求 2、运营活动贯穿产品的整个生命周期 3、找准用户,建立MVP 4、明确产品的应用场景。用户在何场景下基于何种需求使用产品?务必短流程 5、AARRR模型 6、运营管理流程类似产品管理…

如何获取钉钉webhook

第一步打开钉钉并登录 第二步创建团队 并且 添加自定义 机器人 即可获取webhook

MongoDB入门:安装及环境变量配置

一、安装MonggoDB Windows系统安装MongoDB 1、下载MongoDB安装包 访问MongoDB官方网站,选择与Windows系统相匹配的MongoDB Community Server版本进行下载。 Download MongoDB Community Server | MongoDB 2、安装MongoDB 双击下载好的安装包文件,根…

个人健康管理小程序(源码+参考文档+定制)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

5. 常用开源数据集快速导入Linux服务器(AutoDL)——深度学习·科研实践·从0到1

目录 1. 查找公开数据 2. 解压到自己的数据盘中 3. 解压常用指令 1. 查找公开数据 参考文档:AutoDL帮助文档-公开数据查找和导入 AutoDL提供了部分常用开源数据,供咱在实例中进行使用,免去下载上传的烦恼(直接解压到咱的服务…

网页WebRTC电话和软电话哪个好用?

关于WebRTC电话与软件电话哪个更好用,这实际上取决于多个因素,并没有一个绝对的答案。不过,我可以根据WebRTC技术的一些特点,以及与传统软件电话相比的优劣势,为你提供一个清晰的对比。 首先,让我们了解一下…

晶圆厂如何突破多网隔离实现安全稳定又快速的跨网域文件传输?

在当今数字化时代,晶圆厂作为高科技产业的核心,其生产效率和数据安全性直接影响到整个半导体行业的竞争力。晶圆厂内部网络通常被划分为多个安全域,如生产网络、研发网络、办公网络等,以确保数据安全和防止敏感信息泄露。然而&…

外设管控策略分享 | 如何进行USB外设管控?三款USB接口管控软件推荐!

USB外设,作为数据传输的重要媒介,既带来了便捷,也潜藏了风险。 如何有效进行USB外设管控,防止数据泄露,成为企业管理的重要课题。 本文将分享外设管控的策略,并推荐三款USB接口管控软件,助您构…

CSS宽度和高度

CSS 尺寸属性指的就是元素的宽度和高度属性,虽然说非常简单,但却是必须掌握的技能。CSS 中提供了 width、height、max-width、min- width、max-height 和 min-height 等几个属性来设置元素的宽度和高度,这些元素使用起来非常简单,…

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】 一、TFLM是什么?二、TFLM开源项目2.1 下载TFLM源代码2.2 TFLM基准测试说明2.3 TFLM基准测试命令 三、TFLM初步体验3.1 PC上运行Keyword基准测试3.2 PC上运行Person detection基准测试3.3 No module nam…

AIGC实践|AI助力文旅短视频创作全流程

前言: 受到央视《AI我中华》及各地文旅AI宣传片的启发,本次我将尝试使用AI辅助进行城市宣传片的创作探索。我将尽可能详细的展示使用AI辅助创作城市宣传片的全过程,从灵感捕捉到最终成品呈现。现在,让我们一同踏上这段充满创意的探…

如何部署北斗定位应用,基于国产自主架构LS2K1000LA-i处理器平台

北斗卫星导航系统(以下简称北斗系统)是着眼于国内经济社会发展需要,自主建设、独立运行的卫星导航系统。经过多年发展,北斗系统已成为面向全球用户提供全天候、全天时、高精度定位、导航与授时服务的重要新型基础设施。 图 1 北斗定位系统的应用优势 强可控:北斗系统是国…

本省第一所!新大学,揭牌!

9月26日,海南艺术职业学院举行揭牌仪式,标志着海南省第一所公办艺术类高等职业院校正式揭牌成立。海南省旅文厅党组成员、副厅长刘成出席揭牌仪式,省教育厅党组成员、副厅长邢孔政在揭牌仪式上宣读省人民政府同意设立海南艺术职业学院的批复。…

【C++单调队列】1438. 绝对差不超过限制的最长连续子数组|1672

本文时间知识点 C队列、双向队列 LeetCode1438. 绝对差不超过限制的最长连续子数组 给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。 如…

如何使用GLib的单向链表GSList

单向链表是一种基础的数据结构,也是一种简单而灵活的数据结构,本文讨论单向链表的基本概念及实现方法,并着重介绍使用GLib的GList实现单向链表的方法及步骤,本文给出了多个实际范例源代码,旨在帮助学习基于GLib编程的读…

基于SpringBoot大学生就业管理系统设计与实现

1.1 研究背景 科学技术日新月异的如今,计算机在生活各个领域都占有重要的作用,尤其在信息管理方面,在这样的大背景下,学习计算机知识不仅仅是为了掌握一种技能,更重要的是能够让它真正地使用到实践中去,以…

马丁格尔EA交易策略,昂首平台优化操作指南来了

在金融市场中,选择合适的交易工具和策略至关重要。在昂首平台,我们为您提供了多种高效交易策略,其中马丁格尔EA便是备受推崇的选择。下面我们将为您详细介绍如何在非活动阶段优化马丁格尔EA的操作,确保交易的安全与盈利。 1. 非活…

一、Spring Boot集成Spring Security之自动装配

Spring Boot集成Spring Security之自动装配介绍 一、实现功能及软件版本说明二、创建Spring Boot项目三、查看自动装配配置类四、自动装配配置类之SecurityAutoConfiguration1、SecurityAutoConfiguration部分源码2、主要作用3、SpringBootWebSecurityConfiguration3.1、Spring…