【AI大模型】深入Transformer架构:编码器部分的实现与解析(上)

简介: 【AI大模型】深入Transformer架构:编码器部分的实现与解析(上)

学习目标

🍀 了解编码器中各个组成部分的作用.

🍀 掌握编码器中各个组成部分的实现过程.

🍔 编码器介绍

编码器部分: * 由N个编码器层堆叠而成 * 每个编码器层由两个子层连接结构组成 * 第一个子层连接结构包括一个多头自注意力子层和规范化层以及一个残差连接 * 第二个子层连接结构包括一个前馈全连接子层和规范化层以及一个残差连接

🍔 掩码张量

2.1 掩码张量介绍

  • 掩代表遮掩,码就是我们张量中的数值,它的尺寸不定,里面一般只有1和0的元素,代表位置被遮掩或者不被遮掩,至于是0位置被遮掩还是1位置被遮掩可以自定义,因此它的作用就是让另外一个张量中的一些数值被遮掩,也可以说被替换, 它的表现形式是一个张量.

2.2 掩码张量的作用

  • 在transformer中, 掩码张量的主要作用在应用attention(将在下一小节讲解)时,有一些生成的attention张量中的值计算有可能已知了未来信息而得到的,未来信息被看到是因为训练时会把整个输出结果都一次性进行Embedding,但是理论上解码器的的输出却不是一次就能产生最终结果的,而是一次次通过上一次结果综合得出的,因此,未来的信息可能被提前利用. 所以,我们会进行遮掩. 关于解码器的有关知识将在后面的章节中讲解.

2.3 生成掩码张量的代码分析

def subsequent_mask(size):
    """生成向后遮掩的掩码张量, 参数size是掩码张量最后两个维度的大小, 它的最后两维形成一个方阵"""
    # 在函数中, 首先定义掩码张量的形状
    attn_shape = (1, size, size)
    # 然后使用np.ones方法向这个形状中添加1元素,形成上三角阵, 最后为了节约空间, 
    # 再使其中的数据类型变为无符号8位整形unit8 
    subsequent_mask = np.triu(np.ones(attn_shape), k=1).astype('uint8')
    # 最后将numpy类型转化为torch中的tensor, 内部做一个1 - 的操作, 
    # 在这个其实是做了一个三角阵的反转, subsequent_mask中的每个元素都会被1减, 
    # 如果是0, subsequent_mask中的该位置由0变成1
    # 如果是1, subsequent_mask中的该位置由1变成0 
    return torch.from_numpy(1 - subsequent_mask)
  • np.triu演示:
>>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], k=-1)
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 0,  8,  9],
       [ 0,  0, 12]])
>>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], k=0)
array([[ 1,  2,  3],
       [ 0,  5,  6],
       [ 0,  0,  9],
       [ 0,  0, 0]])
>>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], k=1)
array([[ 0,  2,  3],
       [ 0,  0,  6],
       [ 0,  0,  0],
       [ 0,  0, 0]])
  • 输入实例:
# 生成的掩码张量的最后两维的大小
size = 5
  • 调用:
sm = subsequent_mask(size)
print("sm:", sm)
  • 输出效果:
# 最后两维形成一个下三角阵
sm: (0 ,.,.) = 
  1  0  0  0  0
  1  1  0  0  0
  1  1  1  0  0
  1  1  1  1  0
  1  1  1  1  1
[torch.ByteTensor of size 1x5x5]

2.4 掩码张量的可视化

plt.figure(figsize=(5,5))
plt.imshow(subsequent_mask(20)[0])
  • 输出效果:

  • 效果分析:
  • 通过观察可视化方阵, 黄色是1的部分, 这里代表被遮掩, 紫色代表没有被遮掩的信息, 横坐标代表目标词汇的位置, 纵坐标代表可查看的位置;
  • 我们看到, 在0的位置我们一看望过去都是黄色的, 都被遮住了,1的位置一眼望过去还是黄色, 说明第一次词还没有产生, 从第二个位置看过去, 就能看到位置1的词, 其他位置看不到, 以此类推.

2.5 掩码张量总结

  • 学习了什么是掩码张量:
  • 掩代表遮掩,码就是我们张量中的数值,它的尺寸不定,里面一般只有1和0的元素,代表位置被遮掩或者不被遮掩,至于是0位置被遮掩还是1位置被遮掩可以自定义,因此它的作用就是让另外一个张量中的一些数值被遮掩, 也可以说被替换, 它的表现形式是一个张量.
  • 学习了掩码张量的作用:
  • 在transformer中, 掩码张量的主要作用在应用attention(将在下一小节讲解)时,有一些生成的attetion张量中的值计算有可能已知量未来信息而得到的,未来信息被看到是因为训练时会把整个输出结果都一次性进行Embedding,但是理论上解码器的的输出却不是一次就能产生最终结果的,而是一次次通过上一次结果综合得出的,因此,未来的信息可能被提前利用. 所以,我们会进行遮掩. 关于解码器的有关知识将在后面的章节中讲解.
  • 学习并实现了生成向后遮掩的掩码张量函数: subsequent_mask
  • 它的输入是size, 代表掩码张量的大小.
  • 它的输出是一个最后两维形成1方阵的下三角阵.
  • 最后对生成的掩码张量进行了可视化分析, 更深一步理解了它的用途.

🍔 注意力机制

我们这里使用的注意力的计算规则:

3.1 注意力计算规则的代码分析

import torch.nn.functional as F
def attention(query, key, value, mask=None, dropout=None):
    """注意力机制的实现, 输入分别是query, key, value, mask: 掩码张量, 
       dropout是nn.Dropout层的实例化对象, 默认为None"""
    # 在函数中, 首先取query的最后一维的大小, 一般情况下就等同于我们的词嵌入维度, 命名为d_k
    d_k = query.size(-1)
    # 按照注意力公式, 将query与key的转置相乘, 这里面key是将最后两个维度进行转置, 再除以缩放系数根号下d_k, 这种计算方法也称为缩放点积注意力计算.
    # 得到注意力得分张量scores
    scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)
    # 接着判断是否使用掩码张量
    if mask is not None:
        # 使用tensor的masked_fill方法, 将掩码张量和scores张量每个位置一一比较, 如果掩码张量处为0
        # 则对应的scores张量用-1e9这个值来替换, 如下演示
        scores = scores.masked_fill(mask == 0, -1e9)
    # 对scores的最后一维进行softmax操作, 使用F.softmax方法, 第一个参数是softmax对象, 第二个是目标维度.
    # 这样获得最终的注意力张量
    p_attn = F.softmax(scores, dim = -1)
    # 之后判断是否使用dropout进行随机置0
    if dropout is not None:
        # 将p_attn传入dropout对象中进行'丢弃'处理
        p_attn = dropout(p_attn)
    # 最后, 根据公式将p_attn与value张量相乘获得最终的query注意力表示, 同时返回注意力张量
    return torch.matmul(p_attn, value), p_attn
  • tensor.masked_fill演示:
>>> input = Variable(torch.randn(5, 5))
>>> input 
Variable containing:
 2.0344 -0.5450  0.3365 -0.1888 -2.1803
 1.5221 -0.3823  0.8414  0.7836 -0.8481
-0.0345 -0.8643  0.6476 -0.2713  1.5645
 0.8788 -2.2142  0.4022  0.1997  0.1474
 2.9109  0.6006 -0.6745 -1.7262  0.6977
[torch.FloatTensor of size 5x5]
>>> mask = Variable(torch.zeros(5, 5))
>>> mask
Variable containing:
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
[torch.FloatTensor of size 5x5]
>>> input.masked_fill(mask == 0, -1e9)
Variable containing:
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
[torch.FloatTensor of size 5x5]
  • 输入参数:
# 我们令输入的query, key, value都相同, 位置编码的输出
query = key = value = pe_result
Variable containing:
( 0 ,.,.) = 
  46.5196  16.2057 -41.5581  ...  -16.0242 -17.8929 -43.0405
 -32.6040  16.1096 -29.5228  ...    4.2721  20.6034  -1.2747
 -18.6235  14.5076  -2.0105  ...   15.6462 -24.6081 -30.3391
   0.0000 -66.1486 -11.5123  ...   20.1519  -4.6823   0.4916
( 1 ,.,.) = 
 -24.8681   7.5495  -5.0765  ...   -7.5992 -26.6630  40.9517
  13.1581  -3.1918 -30.9001  ...   25.1187 -26.4621   2.9542
 -49.7690 -42.5019   8.0198  ...   -5.4809  25.9403 -27.4931
 -52.2775  10.4006   0.0000  ...   -1.9985   7.0106  -0.5189
[torch.FloatTensor of size 2x4x512]
  • 调用:
attn, p_attn = attention(query, key, value)
print("attn:", attn)
print("p_attn:", p_attn)
  • 输出效果:
# 将得到两个结果
# query的注意力表示:
attn: Variable containing:
( 0 ,.,.) = 
   12.8269    7.7403   41.2225  ...     1.4603   27.8559  -12.2600
   12.4904    0.0000   24.1575  ...     0.0000    2.5838   18.0647
  -32.5959   -4.6252  -29.1050  ...     0.0000  -22.6409  -11.8341
    8.9921  -33.0114   -0.7393  ...     4.7871   -5.7735    8.3374
( 1 ,.,.) = 
  -25.6705   -4.0860  -36.8226  ...    37.2346  -27.3576    2.5497
  -16.6674   73.9788  -33.3296  ...    28.5028   -5.5488  -13.7564
    0.0000  -29.9039   -3.0405  ...     0.0000   14.4408   14.8579
   30.7819    0.0000   21.3908  ...   -29.0746    0.0000   -5.8475
[torch.FloatTensor of size 2x4x512]
# 注意力张量:
p_attn: Variable containing:
(0 ,.,.) = 
  1  0  0  0
  0  1  0  0
  0  0  1  0
  0  0  0  1
(1 ,.,.) = 
  1  0  0  0
  0  1  0  0
  0  0  1  0
  0  0  0  1
[torch.FloatTensor of size 2x4x4]

3.2 带有mask的输入参数:

query = key = value = pe_result
# 令mask为一个2x4x4的零张量
mask = Variable(torch.zeros(2, 4, 4))
  • 调用:
attn, p_attn = attention(query, key, value, mask=mask)
print("attn:", attn)
print("p_attn:", p_attn)
  • 带有mask的输出效果:
# query的注意力表示:
attn: Variable containing:
( 0 ,.,.) = 
   0.4284  -7.4741   8.8839  ...    1.5618   0.5063   0.5770
   0.4284  -7.4741   8.8839  ...    1.5618   0.5063   0.5770
   0.4284  -7.4741   8.8839  ...    1.5618   0.5063   0.5770
   0.4284  -7.4741   8.8839  ...    1.5618   0.5063   0.5770
( 1 ,.,.) = 
  -2.8890   9.9972 -12.9505  ...    9.1657  -4.6164  -0.5491
  -2.8890   9.9972 -12.9505  ...    9.1657  -4.6164  -0.5491
  -2.8890   9.9972 -12.9505  ...    9.1657  -4.6164  -0.5491
  -2.8890   9.9972 -12.9505  ...    9.1657  -4.6164  -0.5491
[torch.FloatTensor of size 2x4x512]
# 注意力张量:
p_attn: Variable containing:
(0 ,.,.) = 
  0.2500  0.2500  0.2500  0.2500
  0.2500  0.2500  0.2500  0.2500
  0.2500  0.2500  0.2500  0.2500
  0.2500  0.2500  0.2500  0.2500
(1 ,.,.) = 
  0.2500  0.2500  0.2500  0.2500
  0.2500  0.2500  0.2500  0.2500
  0.2500  0.2500  0.2500  0.2500
  0.2500  0.2500  0.2500  0.2500
[torch.FloatTensor of size 2x4x4]

3.3 注意力机制总结

  • 学习并实现了注意力计算规则的函数: attention
  • 它的输入就是Q,K,V以及mask和dropout, mask用于掩码, dropout用于随机置0.
  • 它的输出有两个, query的注意力表示以及注意力张量.

🍔 多头注意力机制

4.1 多头注意力机制概念

  • 从多头注意力的结构图中,貌似这个所谓的多个头就是指多组线性变换层,其实并不是,我只有使用了一组线性变化层,即三个变换张量对Q,K,V分别进行线性变换,这些变换不会改变原有张量的尺寸,因此每个变换矩阵都是方阵,得到输出结果后,多头的作用才开始显现,每个头开始从词义层面分割输出的张量,也就是每个头都想获得一组Q,K,V进行注意力机制的计算,但是句子中的每个词的表示只获得一部分,也就是只分割了最后一维的词嵌入向量. 这就是所谓的多头,将每个头的获得的输入送到注意力机制中, 就形成多头注意力机制.

4.2 多头注意力机制结构图

4.3 多头注意力机制的作用

  • 这种结构设计能让每个注意力机制去优化每个词汇的不同特征部分,从而均衡同一种注意力机制可能产生的偏差,让词义拥有来自更多元的表达,实验表明可以从而提升模型效果.

4.4 多头注意力机制的代码实现

# 用于深度拷贝的copy工具包
import copy
# 首先需要定义克隆函数, 因为在多头注意力机制的实现中, 用到多个结构相同的线性层.
# 我们将使用clone函数将他们一同初始化在一个网络层列表对象中. 之后的结构中也会用到该函数.
def clones(module, N):
    """用于生成相同网络层的克隆函数, 它的参数module表示要克隆的目标网络层, N代表需要克隆的数量"""
    # 在函数中, 我们通过for循环对module进行N次深度拷贝, 使其每个module成为独立的层,
    # 然后将其放在nn.ModuleList类型的列表中存放.
    return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])
# 我们使用一个类来实现多头注意力机制的处理
class MultiHeadedAttention(nn.Module):
    def __init__(self, head, embedding_dim, dropout=0.1):
        """在类的初始化时, 会传入三个参数,head代表头数,embedding_dim代表词嵌入的维度, 
           dropout代表进行dropout操作时置0比率,默认是0.1."""
        super(MultiHeadedAttention, self).__init__()
        # 在函数中,首先使用了一个测试中常用的assert语句,判断h是否能被d_model整除,
        # 这是因为我们之后要给每个头分配等量的词特征.也就是embedding_dim/head个.
        assert embedding_dim % head == 0
        # 得到每个头获得的分割词向量维度d_k
        self.d_k = embedding_dim // head
        # 传入头数h
        self.head = head
        # 然后获得线性层对象,通过nn的Linear实例化,它的内部变换矩阵是embedding_dim x embedding_dim,然后使用clones函数克隆四个,
        # 为什么是四个呢,这是因为在多头注意力中,Q,K,V各需要一个,最后拼接的矩阵还需要一个,因此一共是四个.
        self.linears = clones(nn.Linear(embedding_dim, embedding_dim), 4)
        # self.attn为None,它代表最后得到的注意力张量,现在还没有结果所以为None.
        self.attn = None
        # 最后就是一个self.dropout对象,它通过nn中的Dropout实例化而来,置0比率为传进来的参数dropout.
        self.dropout = nn.Dropout(p=dropout)
    def forward(self, query, key, value, mask=None):
        """前向逻辑函数, 它的输入参数有四个,前三个就是注意力机制需要的Q, K, V,
           最后一个是注意力机制中可能需要的mask掩码张量,默认是None. """
        # 如果存在掩码张量mask
        if mask is not None:
            # 使用unsqueeze拓展维度
            mask = mask.unsqueeze(0)
        # 接着,我们获得一个batch_size的变量,他是query尺寸的第1个数字,代表有多少条样本.
        batch_size = query.size(0)
        # 之后就进入多头处理环节
        # 首先利用zip将输入QKV与三个线性层组到一起,然后使用for循环,将输入QKV分别传到线性层中,
        # 做完线性变换后,开始为每个头分割输入,这里使用view方法对线性变换的结果进行维度重塑,多加了一个维度h,代表头数,
        # 这样就意味着每个头可以获得一部分词特征组成的句子,其中的-1代表自适应维度,
        # 计算机会根据这种变换自动计算这里的值.然后对第二维和第三维进行转置操作,
        # 为了让代表句子长度维度和词向量维度能够相邻,这样注意力机制才能找到词义与句子位置的关系,
        # 从attention函数中可以看到,利用的是原始输入的倒数第一和第二维.这样我们就得到了每个头的输入.
        query, key, value = \
           [model(x).view(batch_size, -1, self.head, self.d_k).transpose(1, 2)
            for model, x in zip(self.linears, (query, key, value))]
        # 得到每个头的输入后,接下来就是将他们传入到attention中,
        # 这里直接调用我们之前实现的attention函数.同时也将mask和dropout传入其中.
        x, self.attn = attention(query, key, value, mask=mask, dropout=self.dropout)
        # 通过多头注意力计算后,我们就得到了每个头计算结果组成的4维张量,我们需要将其转换为输入的形状以方便后续的计算,
        # 因此这里开始进行第一步处理环节的逆操作,先对第二和第三维进行转置,然后使用contiguous方法,
        # 这个方法的作用就是能够让转置后的张量应用view方法,否则将无法直接使用,
        # 所以,下一步就是使用view重塑形状,变成和输入形状相同.
        x = x.transpose(1, 2).contiguous().view(batch_size, -1, self.head * self.d_k)
        # 最后使用线性层列表中的最后一个线性层对输入进行线性变换得到最终的多头注意力结构的输出.
        return self.linears[-1](x)
  • tensor.view演示:
>>> x = torch.randn(4, 4)
>>> x.size()
torch.Size([4, 4])
>>> y = x.view(16)
>>> y.size()
torch.Size([16])
>>> z = x.view(-1, 8)  # the size -1 is inferred from other dimensions
>>> z.size()
torch.Size([2, 8])
>>> a = torch.randn(1, 2, 3, 4)
>>> a.size()
torch.Size([1, 2, 3, 4])
>>> b = a.transpose(1, 2)  # Swaps 2nd and 3rd dimension
>>> b.size()
torch.Size([1, 3, 2, 4])
>>> c = a.view(1, 3, 2, 4)  # Does not change tensor layout in memory
>>> c.size()
torch.Size([1, 3, 2, 4])
>>> torch.equal(b, c)
False
  • torch.transpose演示:
>>> x = torch.randn(2, 3)
>>> x
tensor([[ 1.0028, -0.9893,  0.5809],
        [-0.1669,  0.7299,  0.4942]])
>>> torch.transpose(x, 0, 1)
tensor([[ 1.0028, -0.1669],
        [-0.9893,  0.7299],
        [ 0.5809,  0.4942]])
  • 实例化参数:
# 头数head
head = 8
# 词嵌入维度embedding_dim
embedding_dim = 512
# 置零比率dropout
dropout = 0.2
  • 输入参数:
# 假设输入的Q,K,V仍然相等
query = value = key = pe_result
# 输入的掩码张量mask
mask = Variable(torch.zeros(8, 4, 4))
  • 调用:
mha = MultiHeadedAttention(head, embedding_dim, dropout)
mha_result = mha(query, key, value, mask)
print(mha_result)
  • 输出效果:
tensor([[[-0.3075,  1.5687, -2.5693,  ..., -1.1098,  0.0878, -3.3609],
         [ 3.8065, -2.4538, -0.3708,  ..., -1.5205, -1.1488, -1.3984],
         [ 2.4190,  0.5376, -2.8475,  ...,  1.4218, -0.4488, -0.2984],
         [ 2.9356,  0.3620, -3.8722,  ..., -0.7996,  0.1468,  1.0345]],
        [[ 1.1423,  0.6038,  0.0954,  ...,  2.2679, -5.7749,  1.4132],
         [ 2.4066, -0.2777,  2.8102,  ...,  0.1137, -3.9517, -2.9246],
         [ 5.8201,  1.1534, -1.9191,  ...,  0.1410, -7.6110,  1.0046],
         [ 3.1209,  1.0008, -0.5317,  ...,  2.8619, -6.3204, -1.3435]]],
       grad_fn=<AddBackward0>)
torch.Size([2, 4, 512])

4.5 多头注意力机制总结

  • 学习了什么是多头注意力机制:
  • 每个头开始从词义层面分割输出的张量,也就是每个头都想获得一组Q,K,V进行注意力机制的计算,但是句子中的每个词的表示只获得一部分,也就是只分割了最后一维的词嵌入向量. 这就是所谓的多头.将每个头的获得的输入送到注意力机制中, 就形成了多头注意力机制.
  • 学习了多头注意力机制的作用:
  • 这种结构设计能让每个注意力机制去优化每个词汇的不同特征部分,从而均衡同一种注意力机制可能产生的偏差,让词义拥有来自更多元的表达,实验表明可以从而提升模型效果.
  • 学习并实现了多头注意力机制的类: MultiHeadedAttention
  • 因为多头注意力机制中需要使用多个相同的线性层, 首先实现了克隆函数clones.
  • clones函数的输入是module,N,分别代表克隆的目标层,和克隆个数.
  • clones函数的输出是装有N个克隆层的Module列表.
  • 接着实现MultiHeadedAttention类, 它的初始化函数输入是h, d_model, dropout分别代表头数,词嵌入维度和置零比率.
  • 它的实例化对象输入是Q, K, V以及掩码张量mask.
  • 它的实例化对象输出是通过多头注意力机制处理的Q的注意力表示.

相关文章
|
24天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
16天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
20天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2577 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
18天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
3天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
2天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
163 2
|
20天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1576 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
22天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
973 14
|
3天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
219 2
|
17天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
734 9