transformer--编码器2(前馈全连接层、规范化层、子层链接结构、编码器层、编码器)

news2024/11/18 11:33:27

前馈全连接层

什么是前馈全连接层:

在Transformer中前馈全连接层就是具有两层线性层的全连接网络

前馈全连接层的作用:

考虑注意力机制可能对复杂过程的拟合程度不够,通过增加两层网络来增强模型的能力

code

# 前馈全连接层
class PositionwiseFeedForward(nn.Module):
    def __init__(self, d_model, d_ff,drop=0.1) -> None:
        """ 
        d_mode :第一个线下层的输入维度
        d_ff   :隐藏层的维度
        drop   :

        """
        super(PositionwiseFeedForward,self).__init__()

        self.line1 = nn.Linear(d_model,d_ff)
        self.line2 = nn.Linear(d_ff,d_model)
        self.dropout = nn.Dropout(dropout)

    def forward(self,x):
        return self.line2(self.dropout(F.relu(self.line1(x))))

测试:

输出

ff_result.shape =  torch.Size([2, 4, 512])
ff_result =  tensor([[[-0.0589, -1.3885, -0.8852,  ..., -0.4463, -0.9892,  2.7384],
         [ 0.2426, -1.1040, -1.1298,  ..., -0.9296, -1.5262,  1.0632],
         [ 0.0318, -0.8362, -0.9389,  ..., -1.6359, -1.8531, -0.1163],
         [ 1.1119, -1.2007, -1.5487,  ..., -0.8869,  0.1711,  1.7431]],

        [[-0.2358, -0.9319,  0.8866,  ..., -1.2987,  0.2001,  1.5415],
         [-0.1448, -0.7505, -0.3023,  ..., -0.2585, -0.8902,  0.6206],
         [ 1.8106, -0.8460,  1.6487,  ..., -1.1931,  0.0535,  0.8415],
         [ 0.2669, -0.3897,  1.1560,  ...,  0.1138, -0.2795,  1.8780]]],
       grad_fn=<ViewBackward0>)

规范化层

规范化层的作用:

它是所有深层网络模型都需要的标准网络层,因为随着网络层数的增加,通过多层的计算后参数可能开始出现过大或过小的情况,这样可能会导致学习过程出现异常,模型可能收敛非常的慢,因此都会在一定层数后接规范化层进行数值的规范化,使其特征数值在合理范围内.

code

class LayerNorm(nn.Module):
    def __init__(self,features,eps=1e-6) -> None:
        # features 词嵌入的维度
        # eps 足够小的数据,防止除0,放到分母上
        super(LayerNorm,self).__init__()
        # 规范化层的参数,后续训练使用的
        self.w = nn.parameter(torch.ones(features))
        self.b = nn.Parameter(torch.zeros(features))
        self.eps = eps

    def forward(self, x):

        mean = x.mean(-1,keepdim=True)
        stddev = x.std(-1,keepdim=True)
        # * 代表对应位置进行相乘,不是点积
        return self.w*(x-mean)/(stddev,self.eps) + self.b

test

输出:

ln_result.shape =  torch.Size([2, 4, 512])
ln_result =  tensor([[[ 1.3255e+00,  7.7968e-02, -1.7036e+00,  ..., -1.3097e-01,
           4.9385e-01,  1.3975e-03],
         [-1.0717e-01, -1.8999e-01, -1.0603e+00,  ...,  2.9285e-01,
           1.0337e+00,  1.0597e+00],
         [ 1.0801e+00, -1.5308e+00, -1.6577e+00,  ..., -1.0050e-01,
          -3.7577e-02,  4.1453e-01],
         [ 4.2174e-01, -1.1476e-01, -5.9897e-01,  ..., -8.2557e-01,
           1.2285e+00,  2.2961e-01]],

        [[-1.3024e-01, -6.9125e-01, -8.4373e-01,  ..., -4.7106e-01,
           2.3697e-01,  2.4667e+00],
         [-1.8319e-01, -5.0278e-01, -6.6853e-01,  ..., -3.3992e-02,
          -4.8510e-02,  2.3002e+00],
         [-5.7036e-01, -1.4439e+00, -2.9533e-01,  ..., -4.9297e-01,
           9.9002e-01,  9.1294e-01],
         [ 2.8479e-02, -1.2107e+00, -4.9597e-01,  ..., -6.0751e-01,
           3.1257e-01,  1.7796e+00]]], grad_fn=<AddBackward0>)

子层连接结构

什么是子层连接结构:

如图所示,输入到每个子层以及规范化层的过程中,还使用了残差链接(跳跃连接),因此我们把这一部分结构整体叫做子层连接(代表子层及其链接结构),在每个编码器层中,都有两个子层,这两个子层加上周围的链接结构就形成了两个子层连接结构.

code

# 子层连接结构
class SublayerConnection(nn.Module):
    def __init__(self,size,dropout=0.1) -> None:
        """
        size : 词嵌入的维度
        """
        super(SublayerConnection,self).__init__()
        self.norm = LayerNorm(size)
        self.dropout = nn.Dropout(dropout)

    def forward(self, x, sublayer):
        # sublayer 子层结构或者函数
        # x+ 跳跃层
        return x+self.dropout(sublayer(self.norm(x)))

测试代码 放到最后

输出:

sc_result.sahpe =  torch.Size([2, 4, 512])
sc_result =  tensor([[[-1.8123e+00, -2.2030e+01,  3.1459e+00,  ..., -1.3725e+01,
          -6.1578e+00,  2.2611e+01],
         [ 4.1956e+00,  1.9670e+01,  0.0000e+00,  ...,  2.3616e+01,
           3.8118e+00,  6.4224e+01],
         [-7.8954e+00,  8.5818e+00, -7.8634e+00,  ...,  1.5810e+01,
           3.5864e-01,  1.8220e+01],
         [-2.5320e+01, -2.8745e+01, -3.6269e+01,  ..., -1.8110e+01,
          -1.7574e+01,  2.9502e+01]],

        [[-9.3402e+00,  1.0549e+01, -9.0477e+00,  ...,  1.5789e+01,
           2.6289e-01,  1.8317e+01],
         [-4.0251e+01,  1.5518e+01,  1.9928e+01,  ..., -1.4024e+01,
          -3.4640e-02,  1.8811e-01],
         [-2.6166e+01,  2.1279e+01, -1.1375e+01,  ..., -1.9781e+00,
          -6.4913e+00, -3.8984e+01],
         [ 2.1043e+01, -3.5800e+01,  6.4603e+01,  ...,  2.2372e+01,
           3.0018e+01, -3.0919e+01]]], grad_fn=<AddBackward0>)

编码器层

编码器层的作用:

作为编码器的组成单元,每个编码器层完成一次对输入的特征提取过程,即编码过程,如下图

code

# 编码器层
class EncoderLayer(nn.Module):
    def __init__(self,size,self_attn, feed_forward,dropout) -> None:
        """
        size : 词嵌入维度
        self_attn: 多头自注意力子层实例化对象
        fee_forward: 前馈全连接层网络

        """
        super(EncoderLayer,self).__init__()

        self.self_attn = self_attn
        self.feed_forward = feed_forward

        # 编码器中有两个子层结构,所以使用clone实现
        self.sublayer = clones(SublayerConnection(size, dropout),2)
        self.size = size

    def forward(self,x,mask):
        x = self.sublayer[0](x, lambda x: self_attn(x,x,x,mask))
        return self.sublayer[1](x,self.feed_forward)
    

测试代码放到最后

输出 

el_result.shape =  torch.Size([2, 4, 512])
el_result =  tensor([[[-1.4834e+01, -4.3176e+00,  1.2379e+01,  ..., -1.0715e+01,
          -6.8350e-01, -5.2663e+00],
         [-1.7895e+01, -5.9179e+01,  1.0283e+01,  ...,  9.7986e+00,
           2.2730e+01,  1.6832e+01],
         [ 5.0309e+00, -6.9362e+00, -2.6385e-01,  ..., -1.2178e+01,
           3.1495e+01, -1.9781e-02],
         [ 1.6883e+00,  3.9012e+01,  3.2095e-01,  ..., -6.1469e-01,
           3.8988e+01,  2.2591e+01]],

        [[ 4.8033e+00, -5.5316e+00,  1.4400e+01,  ..., -1.1599e+01,
           3.1904e+01, -1.4026e+01],
         [ 8.6239e+00,  1.3545e+01,  3.9492e+01,  ..., -8.3500e+00,
           2.6721e+01,  4.4794e+00],
         [-2.0212e+01,  1.6034e+01, -1.9680e+01,  ..., -4.7649e+00,
          -1.1372e+01, -3.3566e+01],
         [ 1.0816e+01, -1.7987e+01,  2.0039e+01,  ..., -4.7768e+00,
          -1.9426e+01,  2.7683e+01]]], grad_fn=<AddBackward0>)

编码器

编码器的作用:

编码器用于对输入进行指定的特征提取过程,也称为编码,由N个编码器层堆叠而成

code  

# 编码器
class Encoder(nn.Module):
    def __init__(self, layer,N) -> None:
        super(Encoder,self).__init__()

        self.layers = clones(layer,N)
        self.norm = LayerNorm(layer.size)
    def forward(self, x, mask):
        """forward函数的输入和编码器层相同,x代表上一层的输出,mask代表掩码张量"""
        # 首先就是对我们克隆的编码器层进行循环,每次都会得到一个新的x,
        # 这个循环的过程,就相当于输出的x经过了N个编码器层的处理,
        # 最后再通过规范化层的对象self.norm进行处理,最后返回结果
        for layre in self.layers:
            x = layre(x,mask)
        return self.norm(x)

测试代码在下面:

输出:

en_result.shape :  torch.Size([2, 4, 512])
en_result :  tensor([[[-2.7477e-01, -1.1117e+00,  6.1682e-02,  ...,  6.7421e-01,
          -6.2473e-02, -4.6477e-02],
         [-7.7232e-01, -7.6969e-01, -2.0160e-01,  ...,  2.6131e+00,
          -1.9882e+00,  1.3715e+00],
         [-1.4178e+00,  2.6184e-01,  1.1888e-01,  ..., -9.9172e-01,
           1.3337e-01,  1.3132e+00],
         [-1.3268e+00, -1.1559e+00, -1.1774e+00,  ..., -8.1548e-01,
          -2.8089e-02,  1.4730e-03]],

        [[-1.3472e+00,  4.4969e-01, -4.3498e-02,  ..., -9.8910e-01,
           7.4551e-02,  1.1824e+00],
         [-2.2395e-02,  3.1730e-01,  6.8652e-02,  ...,  4.3939e-01,
           2.8600e+00,  3.2169e-01],
         [-7.2252e-01, -7.6787e-01, -7.5412e-01,  ...,  6.3915e-02,
           1.2210e+00, -2.3871e+00],
         [ 1.6294e-02, -4.8995e-02, -2.2887e-02,  ..., -7.7798e-01,
           4.4148e+00,  1.7802e-01]]], grad_fn=<AddBackward0>)

测试代码

from inputs import Embeddings,PositionalEncoding
import numpy as np
import torch
import torch.nn.functional as F
import torch.nn as nn
import matplotlib.pyplot as plt
import math
import copy 

def subsequent_mask(size):
    """
    生成向后遮掩的掩码张量,参数size是掩码张量最后两个维度的大小,
    他们最好会形成一个方阵
    """
    attn_shape = (1,size,size)
    # 使用np.ones方法向这个形状中添加1元素,形成上三角阵
    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)

def attention(query, key, value, mask=None, dropout=None):
    """ 注意力机制的实现,输入分别是query、key、value,mask
        此时输入的query、key、value的形状应该是 batch * number_token * embeding
    """
    # 获取词嵌入的维度
    d_k = query.size(-1)
    # 根据注意力公示,将query和key的转置相乘,然后乘上缩放系数得到评分,这里为什么需要转置?
    # batch * number_token * embeding X batch * embeding * number_token = batch * number_token * number_token
    # 结果是个方阵
    scores = torch.matmul(query,key.transpose(-2,-1))/math.sqrt(d_k)

    # 判断是否使用mask
    if mask is not None:
        scores = scores.masked_fill(mask==0,-1e9)
    
    # scores 的最后一维进行softmax操作,为什么是最后一维?
    # 因为scores是方阵,每行的所有列代表当前token和全体token的相似度值,
    # 因此需要在列维度上进行softmax
    p_attn = F.softmax(scores,dim=-1) # 这个就是最终的注意力张量

    # 之后判断是否使用dropout 进行随机置0
    if dropout is not None:
        p_attn = dropout(p_attn)
    # 最后,根据公式将p_attn与value张量相乘获得最终的query注意力表示,同时返回注意力张量
    # 计算后的 维度是多少呢?
    # batch * number_token * number_token X batch * number_token * embeding = 
    # batch * number_token * embeding
    return torch.matmul(p_attn,value), p_attn

def clones(module, N):
    """用于生成相同网络层的克隆函数,N代表克隆的数量"""
    return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])

class MultiHeadedAttention(nn.Module):
    def __init__(self, head,embedding_dim,dropout=0.1) -> None:
        """ head 代表头的数量, embedding_dim 词嵌入的维度 """
        super(MultiHeadedAttention,self).__init__()

        # 因为多头是指对embedding的向量进行切分,因此头的数量需要整除embedding
        assert embedding_dim % head == 0

        # 计算每个头获得分割词向量维度d_k
        self.d_k = embedding_dim // head

        # 传入头数
        self.head = head

        # 获得线形层对象,因为线性层是不分割词向量的,同时需要保证线性层输出和词向量维度相同
        # 因此线形层权重是方阵
        self.linears = clones(nn.Linear(embedding_dim,embedding_dim),4)

        # 注意力张量
        self.attn = None

        # dropout
        self.dropout = nn.Dropout(p=dropout)

    def forward(self,query,key,value,mask=None):
        
        if mask is not None:
            # 拓展维度,因为有多头了
            mask = mask.unsqueeze(0)
        batch_size = query.size(0)

        # 输入先经过线形层,首先使用zip将网络层和输入数据连接一起,
        # 模型的输出利用view和transpose进行维度和形状的变换
        # (query,key,value) 分别对应一个线形层,经过线形层输出后,立刻对其进行切分,注意这里切分是对query经过线形层输出后进行切分,key经过线性层进行切分,value进行线性层进行切分,在这里才是多头的由来
        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))]

        # 将每个头的输出传入注意力层
        x,self.attn = attention(query,key,value,mask,self.dropout)
        # 得到每个头的计算结果是4维张量,需要进行形状的转换
        x = x.transpose(1,2).contiguous().view(batch_size,-1,self.head*self.d_k)
        return self.linears[-1](x)
    
# 前馈全连接层
class PositionwiseFeedForward(nn.Module):
    def __init__(self, d_model, d_ff,drop=0.1) -> None:
        """ 
        d_mode :第一个线下层的输入维度
        d_ff   :隐藏层的维度
        drop   :

        """
        super(PositionwiseFeedForward,self).__init__()

        self.line1 = nn.Linear(d_model,d_ff)
        self.line2 = nn.Linear(d_ff,d_model)
        self.dropout = nn.Dropout(dropout)

    def forward(self,x):
        return self.line2(self.dropout(F.relu(self.line1(x))))

# 规范化层
class LayerNorm(nn.Module):
    def __init__(self,features,eps=1e-6) -> None:
        # features 词嵌入的维度
        # eps 足够小的数据,防止除0,放到分母上
        super(LayerNorm,self).__init__()
        # 规范化层的参数,后续训练使用的
        self.w = nn.Parameter(torch.ones(features))
        self.b = nn.Parameter(torch.zeros(features))
        self.eps = eps

    def forward(self, x):

        mean = x.mean(-1,keepdim=True)
        stddev = x.std(-1,keepdim=True)
        # * 代表对应位置进行相乘,不是点积
        return self.w*(x-mean)/(stddev+self.eps) + self.b

# 子层连接结构
class SublayerConnection(nn.Module):
    def __init__(self,size,dropout=0.1) -> None:
        """
        size : 词嵌入的维度
        """
        super(SublayerConnection,self).__init__()
        self.norm = LayerNorm(size)
        self.dropout = nn.Dropout(dropout)

    def forward(self, x, sublayer):
        # sublayer 子层结构或者函数
        # x+ 跳跃层
        return x+self.dropout(sublayer(self.norm(x)))

# 编码器层
class EncoderLayer(nn.Module):
    def __init__(self,size,self_attn, feed_forward,dropout) -> None:
        """
        size : 词嵌入维度
        self_attn: 多头自注意力子层实例化对象
        fee_forward: 前馈全连接层网络

        """
        super(EncoderLayer,self).__init__()

        self.self_attn = self_attn
        self.feed_forward = feed_forward

        # 编码器中有两个子层结构,所以使用clone实现
        self.sublayer = clones(SublayerConnection(size, dropout),2)
        self.size = size

    def forward(self,x,mask):
        x = self.sublayer[0](x, lambda x: self_attn(x,x,x,mask))
        return self.sublayer[1](x,self.feed_forward)

# 编码器
class Encoder(nn.Module):
    def __init__(self, layer,N) -> None:
        super(Encoder,self).__init__()

        self.layers = clones(layer,N)
        self.norm = LayerNorm(layer.size)
    def forward(self, x, mask):
        """forward函数的输入和编码器层相同,x代表上一层的输出,mask代表掩码张量"""
        # 首先就是对我们克隆的编码器层进行循环,每次都会得到一个新的x,
        # 这个循环的过程,就相当于输出的x经过了N个编码器层的处理,
        # 最后再通过规范化层的对象self.norm进行处理,最后返回结果
        for layre in self.layers:
            x = layre(x,mask)
        return self.norm(x)



if __name__ == "__main__":

    # size = 5
    # sm = subsequent_mask(size)
    # print("sm: \n",sm.data.numpy())

    # plt.figure(figsize=(5,5))
    # plt.imshow(subsequent_mask(20)[0])
    # plt.waitforbuttonpress()

    # 词嵌入
    dim = 512
    vocab  =1000
    emb = Embeddings(dim,vocab)
    x = torch.LongTensor([[100,2,321,508],[321,234,456,324]])
    embr  =emb(x)
    print("embr.shape = ",embr.shape)
    # 位置编码
    pe = PositionalEncoding(dim,0.1) # 位置向量的维度是20,dropout是0
    pe_result = pe(embr)
    print("pe_result.shape = ",pe_result.shape)

    # 获取注意力值
    # query = key = value = pe_result 
    # attn,p_attn = attention(query,key,value)
    # print("attn.shape = ",attn.shape)
    # print("p_attn.shape = ",p_attn.shape)
    # print("attn: ",attn)
    # print("p_attn: ",p_attn)

    # # 带mask
    # mask = torch.zeros(2,4,4)
    # attn,p_attn = attention(query,key,value,mask)
    # print("mask attn.shape = ",attn.shape)
    # print("mask p_attn.shape = ",p_attn.shape)
    # print("mask attn: ",attn)
    # print("mask p_attn: ",p_attn)

    # 多头注意力测试
    head = 8
    embedding_dim = 512
    dropout = 0.2

    query = key = value = pe_result
    # mask 是给计算出来的点积矩阵使用的,这个矩阵是方阵,token
    mask = torch.zeros(8,4,4) 

    mha = MultiHeadedAttention(head,embedding_dim,dropout)
    mha_result = mha(query,key,value,mask)
    print("mha_result.shape = ",mha_result.shape)
    print("mha_result: ",mha_result)

    # 前馈全连接层 测试
    x = mha_result
    d_model  =512
    d_ff=128
    dropout = 0.2
    ff = PositionwiseFeedForward(d_model, d_ff, dropout)
    ff_result = ff(x)
    print("ff_result.shape = ",ff_result.shape)
    print("ff_result = ",ff_result)

    # 规范化层测试
    features = d_model = 512
    esp = 1e-6
    ln = LayerNorm(features,esp)
    ln_result = ln(ff_result)
    print("ln_result.shape = ",ln_result.shape)
    print("ln_result = ",ln_result)

    # 子层连接结构 测试
    size = 512
    dropout=0.2
    head=8
    d_model=512

    x = pe_result
    mask = torch.zeros(8,4,4)

    self_attn = MultiHeadedAttention(head,d_model,dropout)
    sublayer = lambda x:self_attn(x,x,x,mask) # 子层函数

    sc = SublayerConnection(size,dropout)
    sc_result = sc(x,sublayer)
    print("sc_result.sahpe = ", sc_result.shape)
    print("sc_result = ", sc_result)

    # 编码器层 测试
    size = 512
    dropout=0.2
    head=8
    d_model=512
    d_ff = 64

    x = pe_result
    mask = torch.zeros(8,4,4)

    self_attn = MultiHeadedAttention(head,d_model,dropout)
    ff = PositionwiseFeedForward(d_model,d_ff,dropout)
    mask = torch.zeros(8,4,4)

    el = EncoderLayer(size,self_attn,ff,dropout)
    el_result = el(x,mask)
    print("el_result.shape = ", el_result.shape)
    print("el_result = ", el_result)

    # 编码器测试
    size = 512
    dropout=0.2
    head=8
    d_model=512
    d_ff = 64

    c = copy.deepcopy
    x = pe_result
    

    self_attn = MultiHeadedAttention(head,d_model,dropout)
    ff = PositionwiseFeedForward(d_model,d_ff,dropout)
    # 编码器层不是共享的,因此需要深度拷贝
    layer= EncoderLayer(size,c(self_attn),c(ff),dropout)

    N=8
    mask = torch.zeros(8,4,4)

    en = Encoder(layer,N)
    en_result = en(x,mask)
    print("en_result.shape : ",en_result.shape)
    print("en_result : ",en_result)


    


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LNMP架构(搭建论坛+博客)

目录 一、LNMP架构概述 1、LNMP架构的概念 2、LNMP架构的优点 二、编译安装nginx软件 1、准备工作 1.1 关闭防火墙 1.2 安装依赖包 1.3 创建运行nginx用户 1.4 压缩包解压 2、编译与安装 3、添加nginx自启动文件 三、编译安装mysql软件 1、准备工作 1.1 安装mysq…

HTTPS的加密过程

文章目录 前言一、为什么需要加密&#xff1f;二、只用对称加密可以吗&#xff1f;三、只使用非对称加密四、双方都使用非对称加密五、使用非对称加密对称加密六、引入证书1.如何放防止数字证书被篡改&#xff1f;2.中间人有可能篡改该证书吗&#xff1f;3.中间人有可能掉包该证…

环境配置 |Jupyter lab/Jupyter Notebook 安装与设置

ipynb使用Jupyterlab/Jupyter Notebook 来编写Python程序时的文件,在使用时,可以现转换为标准的.py的python文件 1.Jupyter Lab 1.1.下载安装 环境&#xff1a;Linux pip install jupyterlab 1.2.使用 jupyter lab 点击后进入 1.3.jupyter lab更换内核 因为我的是在anac…

arm板运行程序时寻找动态库的路径设置

问题&#xff1a;error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file&#xff1f; 第一种方法---- 解决&#xff1a; ①复制需要用到的arm库到板子上。 ②pwd指令获取该库的绝对路径&#xff0c;把路径复制到/etc/ld.so.conf文件 ③输…

google最新大语言模型gemma本地化部署

Gemma是google推出的新一代大语言模型&#xff0c;构建目标是本地化、开源、高性能。 与同类大语言模型对比&#xff0c;它不仅对硬件的依赖更小&#xff0c;性能却更高。关键是完全开源&#xff0c;使得对模型在具有行业特性的场景中&#xff0c;有了高度定制的能力。 Gemma模…

网络传输基本流程(封装,解包)+图解(同层直接通信的证明),报头分离问题,协议定位问题,协议多路复用

目录 网络传输基本流程 引入 封装 过程梳理 图解 报文 解包 过程梳理 图解 -- 同层直接通信的证明 总结 解包时的报头分离问题 举例 -- 倒水 介绍 自底向上传输时的协议定位问题 介绍 解决方法 协议多路复用 介绍 优势 网络传输基本流程 引入 首先,我们明确…

Python学习 --- 面向对象

1.什么是对象 1.Python中创建类的关键字是 class 2.类的成员方法 1.函数是写在类外面的,方法则是写在类里面的 1.上面这一段代码中就展示了如何在方法中访问类的成员变量: self.成员变量名 3.魔术方法 魔术方法其实就是python中的类中的内置方法,下面这几个只是我们比较常…

02| JVM堆中垃圾回收的大致过程

如果一直在创建对象&#xff0c;堆中年轻代中Eden区会逐渐放满&#xff0c;如果Eden放满&#xff0c;会触发minor GC回收&#xff0c;创建对象的时GC Roots&#xff0c;如果存在于里面的对象&#xff0c;则被视为非垃圾对象&#xff0c;不会被此次gc回收&#xff0c;就会被移入…

深度神经网络联结主义的本质

一、介绍 在新兴的人工智能 (AI) 领域&#xff0c;深度神经网络 (DNN) 是一项里程碑式的成就&#xff0c;突破了机器学习、模式识别和认知模拟的界限。这一技术奇迹的核心是一个与认知科学本身一样古老的思想&#xff1a;联结主义。本文深入探讨了联结主义的基本原理&#xff0…

阿里云启动实例进入了急救模式解决办法

相关文档 问题描述 通过远程连接软件无法登录Linux实例&#xff0c;通过使用管理终端连接Linux实例远程连接时&#xff0c;发现系统进入到急救模式&#xff08;emergency mode&#xff09;&#xff0c;且出现报错。 CentOS实例报如下错误。 systemctl default to try again…

小(2)型土石坝安全监测设施配置详解

小(2)型土石坝的安全监测是确保大坝稳定、安全运行的重要环节。为此&#xff0c;合理配置安全监测设施显得尤为重要。以下是对小(2)型土石坝安全监测设施配置的详细介绍。 一、渗流量监测 渗流量是反映大坝安全状况的关键指标之一。为准确监测渗流量&#xff0c;我们采用仪器量…

PackagingTool_x64_v2.0.1.0图片转档打包二进制文件合并字库生成图片软件介绍

继去年12月份发布的打包软件PackagingTool v1.4.0.2之后&#xff0c;今年再度投入精力&#xff0c;完善了软件功能&#xff0c;同时开发了几个更加实用的工具&#xff0c;可助力UI界面的设计开发。当前最新版本为PackagingTool_x64_v2.0.1.0&#xff0c;该版本主界面如下&#…

php基础学习之错误处理(其二)

在实际应用中&#xff0c;开发者当然不希望把自己开发的程序的错误暴露给用户&#xff0c;一方面会动摇客户对己方的信心&#xff0c;另一方面容易被攻击者抓住漏洞实施攻击&#xff0c;同时开发者本身需要及时收集错误&#xff0c;因此需要合理的设置错误显示与记录错误日志 一…

全国夜间灯光指数数据、GDP密度分布、人口密度分布、土地利用数据、降雨量数据

引言 DMSP/OLS的1992-2013年全球遥感影像&#xff0c;包括三种非辐射定标的夜间灯光影像。三种全年平均影像分别是&#xff1a;无云观测频数影像、平均灯光影像和稳定灯光影像。目前地理遥感生态网可提供全国稳定灯光影像免费下载。稳定灯光影像是标定夜间平均灯光强度的年度栅…

java 大学生社团管理系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 大学生社团管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5…

概率基础——多元正态分布

概率基础——多元正态分布 介绍 多元正态分布是统计学中一种重要的多维概率分布&#xff0c;描述了多个随机变量的联合分布。在多元正态分布中&#xff0c;每个随机变量都服从正态分布&#xff0c;且不同随机变量之间可能存在相关性。本文将以二元标准正态分布为例&#xff0…

免费pr素材(漂亮的波浪图形动画背景视频素材)下载

10个漂亮的免费波浪图形动画pr素材&#xff0c;PR动态背景视频素材mogrt下载。 特点&#xff1a;Premiere Pro 2023或更高版本&#xff0c;超高清分辨率&#xff1a;38402160&#xff0c;每秒25帧的帧速率&#xff0c;包括教程视频。来自pr素材网&#xff0c;下载地址&#xff…

数字孪生与智慧交通的融合发展:推动交通行业数字化转型,构建智慧城市新生态

随着信息技术的快速发展和城市化进程的深入推进&#xff0c;交通行业正面临着前所未有的机遇与挑战。传统的交通管理模式已难以满足日益增长的交通需求&#xff0c;而数字化转型则成为了推动交通行业创新发展的必由之路。数字孪生技术作为一种前沿的信息技术手段&#xff0c;为…

Echarts图标初始化实例的时候传入的参数

一般我们初始化实例的时候都是这么写的 其实echarts.init()还可以传入另外两个选项&#xff0c; 第二个选项为主题色 分为深色主题以及浅色主题&#xff0c;默认为浅色主题&#xff0c;传入light 深色主题的话可以传入dark 第三个选项为option 但是用得比较多的是渲染器ren…

MySQL 使用 pt-archiver 删除数据

文章目录 前言1. 环境准备1.1 模拟造数1.2 工具安装 2. 删除数据2.1 批次删除表2.2 原理解析2.3 批处理思路 后记 前言 在线核心业务都会有日志表&#xff0c;随着业务持续运行&#xff0c;日志表每天都在增大&#xff0c;最后超过阈值触发空间使用率告警。DBA 处理空间告警时…