NLP自然語言處理04 transformer架構模擬實現

總體架構

輸入部分

代碼實現:

導包

# -*-coding:utf-8-*-
import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn as nn
# -*-coding:utf-8-*-
import copy
import torch.nn.functional as F
import math
位置編碼器部分
詞嵌入WordEmbedding

# todo 作用:輸入數據進行詞嵌入升維處理
class Embeddings(nn.Module):def __init__(self, vocab_size, embed_dim):super().__init__()# vocab_size:代表單詞的總個數self.vocab_size = vocab_size# embed_dim:代表詞嵌入維度self.embed_dim = embed_dim# 定義Embedding層self.embed = nn.Embedding(vocab_size, embed_dim)def forward(self, x):# x--》[batch_size, seq_len]return self.embed(x) * math.sqrt(self.embed_dim)
位置編碼模型PositionEncoding

# todo 作用:生成位置編碼矩陣,與輸入數據x進行融合,并輸出-->加入了位置編碼信息的詞嵌入張量
class PositionEncoding(nn.Module):def __init__(self, d_model, dropout_p, max_len=60):super().__init__()# d_model:代表詞嵌入維度self.d_model = d_model# dropout_p:代表隨機失活的系數self.dropout_p = dropout_p# max_len:代表最大句子長度self.max_len = max_len# 定義dropout層self.dropout = nn.Dropout(p=dropout_p)# 根據三角函數的公式實現位置的編碼# 定義位置編碼矩陣[max_len, d_model]-->[60, 512]pe = torch.zeros(max_len, d_model)# 定義位置列矩陣--》[max_len, 1]-->[60, 1]position = torch.arange(0, max_len).unsqueeze(dim=1)# 定義轉換矩陣:根據三角函數的計算公式,是其中的除了pos之外的系數(頻率)# temp_vec-->[256]temp_vec = torch.exp(torch.arange(0, d_model, 2) * -(math.log(10000)/d_model))# 根據三角函數的計算公式,計算角度:pos_vec-->[60, 256]pos_vec = position * temp_vec# 將奇數位用sin處理,偶數位用cos處理pe[:, 0::2] = torch.sin(pos_vec)pe[:, 1::2] = torch.cos(pos_vec)# 需要對上述的位置編碼結果升維:pe-->[1, max_len, d_model]-->[1, 60, 512]#todo  pe就是位置編碼矩陣 似乎每次結果一樣pe = pe.unsqueeze(dim=0)# pe位置編碼結果不隨著模型的訓練而更新,因此需要進行注冊到緩存區self.register_buffer('pe', pe)def forward(self, x):# x--》來自于embedding之后的結果--》[batch_size, seq_len, embed_dim]-->[2, 4, 512]# 將x和位置編碼的信息進行融合# todo x.size()[1]是指句子有多長pe就取出多長與x相加,pe的形狀為[1, max_len, d_model]-->[1, 4, 512]x = x + self.pe[:, :x.size()[1]]return self.dropout(x)

編碼器部分

掩碼矩陣部分:生成掩碼矩陣
# 生成一個下三角矩陣(sentence_mask)
def generate_triu(size):# a = np.triu(m=np.ones((1, size, size)), k=1).astype(int)# return torch.from_numpy(1-a)return 1-torch.triu(torch.ones(1, size, size, dtype=torch.int), 1)# 生成掩碼矩陣(padding_mask)
def generate_padding_mask(tensor_x):# tensor_x-->注意力權重分數--》張量tensor_x[tensor_x == 0] = 0tensor_x[tensor_x != 0] = 1return tensor_x.to(dtype=torch.int)# 繪圖:生成下三角矩陣
def show__triu():plt.figure(figsize=(5, 5))plt.imshow(generate_triu(20)[0])plt.show()
attention:基礎注意力計算方式,muti_head_atten將調用次模組
def attention(query, key, value, mask=None, dropout=None):# query/key/value-->[batch_size, seq_len, embed_dim]# mask-->shape-->[batch_size, seq_len, seq_len]# dropout--》實例化的對象# 第一步:獲得詞嵌入表達的維度d_k = query.size(-1)# 第二步:計算query和key之間的相似性分數(注意力權重分數(未經過softmax歸一化的結果))# query-->[2, 4, 512];key-->[2, 4, 512]-->轉置--》[2, 512,4]. 相乘后--》scores-->[2, 4, 4]scores = torch.matmul(query, torch.transpose(key, -1, -2)) / math.sqrt(d_k)# 第三步:判斷是否需要maskif mask is not None:scores = scores.masked_fill(mask==0, -1e9)# print(f'未歸一化的scores--》{scores}')# 第四步:進行softmax歸一化atten_weights = F.softmax(scores, dim=-1)# print(f'atten_weights--》{atten_weights}')# 第五步:如果有dropout 就進行隨機失活防止過擬合if dropout is not None:atten_weights = dropout(atten_weights)return torch.matmul(atten_weights, value), atten_weights # todo 返回注意力輸出,以及注意力權重
多頭注意力類與clones

多頭注意力機制原理(核心)

1. ??輸入與線性變換?

輸入序列(如詞向量)通過三個獨立的線性變換層生成查詢(Query, Q)、鍵(Key, K)和值(Value, V)矩陣:

  • ??自注意力機制??:輸入為同一矩陣?X,通過不同權重矩陣?WQh?,WKh?,WVh??生成Q、K、V。
  • ??交叉注意力機制??:輸入為兩個不同矩陣(如?Xq??和?Xkv?),分別生成Q和K、V

?

2. ??分頭處理與并行計算??

  • ??分頭??:將Q、K、V按頭的數量?h?拆分為多個子矩陣,每個子矩陣對應一個注意力頭。例如,將?Q?拆分為?[Q1?,Q2?,...,Qh?],每個?Qi??的維度為?dk??。
  • ??并行計算??:每個頭獨立計算縮放點積注意力(Scaled Dot-Product Attention):

3. ??多頭輸出的拼接與融合??

  • ??拼接??:將所有頭的輸出?head1?,head2?,...,headh??沿特征維度拼接,形成組合輸出。
  • ??線性變換??:通過權重矩陣?WO??將拼接后的結果映射回原始維度:

?

????????原論文中是先把qkv從[2,6,512]變成[2,6,8,64]后各經過8個權重矩陣總共24個權重矩陣得到變換后的qkv再進行注意力計算再concat拼接起來

? ? ? ? 這里的代碼實現是qkv[[2,6,512]]各經過1個矩陣總共3個矩陣得到[2,6,512]再變成[2,6,8,64]進行注意力計算再concat拼接起來

編碼器實例化一個多頭注意力類且無masked


# clones 的作用:將一個模塊復制N次,并返回一個ModuleList,ModuleList是一個Module的子類,可以迭代,并且可以保存多個Module
def clones(module, N):return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])# todo:2. 定義多頭注意力類,注意 編碼器層的q=k=v=原句子 解碼器層的mask_muti_head輸入的q=k=v=預測的句子 解碼層的第二個muti_head的q=k=編碼器輸出,v=mask_muti_head輸出
class MutiHeadAttention(nn.Module):def __init__(self, head, embed_dim, dropout_p=0.1):super().__init__()# 第一步:確定embed_dim是否能被head整除assert embed_dim % head == 0# 第二步:確定每個head應該處理多少維度特征self.d_k = embed_dim // head# 第三步:定義head的屬性self.head = head# 第四步:定義4個全連接層self.linears = clones(nn.Linear(embed_dim, embed_dim), 4)# 第五步:定義atten權重屬性self.atten = None# 第六步:實例化dropout對象self.dropout = nn.Dropout(p=dropout_p)def forward(self, query, key, value, mask=None):# 需要對mask的形狀進行升維度# mask-->輸入的形狀--》[head, seq_len, seq_len]-->[8, 4, 4],升維之后--》[1, 8, 4, 4]if mask is not None:mask = mask.unsqueeze(dim=0)# 獲取當前輸入的batch_sizebatch_size = query.size(0)# 開始處理query,key,value,都要經過線性變化并且切分為8個頭# model(x)-->就是將數據經過linear層處理x-->[2, 4, 512]-->經過Linear-->[2, 4, 512]-->分割--》[2, 4, 8, 64]-->transpose-->[2, 8, 4, 64]# query,key,value--》shape-->[2, 8, 4, 64]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))]# 接下來將上述處理后的query,key,value--》shape-->[2, 8, 4, 64]送入attention方法進行注意力的計算:# query--》[2, 8, 4, 64]和key--》[2, 8, 4, 64]轉置結果[2, 8, 64, 4]進行相乘--》shape--》[2,8, 4, 4](所以傳的mask矩陣是4維的)# [2, 8, 4, 4]要和value-->[2, 8, 4, 64]-->相乘--》shape--》x-->[2, 8, 4, 64]x, self.atten = attention(query, key, value, mask=mask, dropout=self.dropout)# 需要將多頭注意力的結果進行合并#  x.transpose(1, 2)-->【2,4, 8, 64】# y 合并后的結果-->[2, 4, 512]y = x.transpose(1, 2).contiguous().view(batch_size, -1, self.head*self.d_k)# 經過線性變化得到指定輸出維度的結果return self.linears[-1](y)
前饋全連接層

兩層線性層 作用:進行特征提取,進行非線性映射,簡單來說就是經過兩個線性層一個relu激活函數加入非線性,再dropout隨機失活防止過擬合

class FeedForward(nn.Module):def __init__(self, d_model, d_ff, dropout_p=0.1):super().__init__()# d_model:第一個全連接層輸入的特征維度;第二個全連接層輸出的特征維度self.d_model = d_model# d_ff: 第一個全連接層輸出的特征維度;第二個全連接層輸入的特征維度self.d_ff = d_ff# 定義第一個全連接層self.linear1 = nn.Linear(d_model, d_ff)# 定義第二個全連接層self.linear2 = nn.Linear(d_ff, d_model)# 定義dropout層self.dropout = nn.Dropout(p=dropout_p)def forward(self, x):return self.linear2(self.dropout(F.relu(self.linear1(x))))
規范化層

讓數據符合標準正態分布 作用機制:self.a * (x - x_mean) / (x_std + self.eps) + self.b, eps:防止分母為0

Add中是把原始經過embedding+position后得到的x與經過(多頭注意力層或者前饋全連接層)再進行規范化之后的結果進行相加得到殘差鏈接

殘差鏈接的作用:通過跨層連接(如恒等映射),梯度可直接通過“捷徑”回傳,避免因多層非線性變換導致的信號衰減或放大


class LayerNorm(nn.Module):def __init__(self, features, eps=1e-6):super().__init__()# 定義屬性self.features = features # 代表詞嵌入維度# epsself.eps = eps# 定義一個模型的參數(系數)self.a = nn.Parameter(torch.ones(features))self.b = nn.Parameter(torch.zeros(features))def forward(self, x):# x--->[2, 4, 512]# 1.求出均值:x_mean-->[2, 4, 1]x_mean = torch.mean(x, dim=-1, keepdim=True)# 2.求出標準差x_std = torch.std(x, dim=-1, keepdim=True)return self.a * (x - x_mean) / (x_std + self.eps) + self.b
子層鏈接結構

定義子層連接結構 把norm&add這一層與feedforward層或者muti_head_atten層進行連接,取決與輸入的sublayer是什么層

class SublayerConnection(nn.Module):def __init__(self, size, dropout_p=0.1):super().__init__()# 定義size屬性:詞嵌入的維度大小self.size = size# 實例化規范化層self.layer_norm = LayerNorm(features=size)# 實例化dropout層self.dropout = nn.Dropout(p=dropout_p)def forward(self, x, sublayer):# x--》來自于輸入部分:positionEncoding+WordEmbedding;[batch_size, seq_len, embed_dim]-->[2, 4, 512]# sublayer-->代表函數的對象:可以是處理多頭自注意力機制函數的對象,也可以是前饋全連接層對象# post_normx1 = x + self.dropout(self.layer_norm(sublayer(x)))# pre_norm# x1 = x + self.dropout(sublayer(self.layer_norm(x)))return x1
編碼器層

定義編碼器層 #超級拼裝:先試用子層鏈接拼成(norm&add+feedforward)層與(muti_head_atten+norm&add)層 把這兩個子層拼起來就是編碼器結構

輸入的是輸入部分:positionEncoding+WordEmbedding;[batch_size, seq_len, embed_dim]-->[2, 4, 512],輸出的是編碼器的結果-->送給解碼器當k和v使用

class EncoderLayer(nn.Module):def __init__(self, size, self_atten, feed_forward, dropout_p):super().__init__()# size:代表詞嵌入的維度self.size = size# self_atten:代表多頭自注意力機制的對象self.self_atten = self_atten# feed_forward:代表前饋全連接層的對象self.feed_forward = feed_forward# 定義兩層子層連接結構self.sub_layers = clones(SublayerConnection(size, dropout_p), 2)def forward(self, x, mask):# x-->來自輸入部分--》[batch_size, seq_len, embed_dim]:[2, 4, 512]# mask-->[head, seq_len, seq_len]-=-->[8, 4, 4]# 經過第一個子層連接結構:先經過多頭自注意力層--》然后經過norm-->最后殘差連接x1 = self.sub_layers[0](x, lambda x: self.self_atten(x, x, x, mask))# 經過第二個子層連接結構:先經過前饋全連接層--》然后經過norm-->最后殘差連接x2 = self.sub_layers[1](x1, self.feed_forward)return x2
編碼器

定義編碼器 超級拼裝2.0 n個編碼器層構成一個編碼器,按照這里的代碼,多個編碼器層是串聯執行,上一個編碼器的輸出作為下一個編碼器的輸入,最終輸出編碼器的結果給解碼器當v使用

class Encoder(nn.Module):def __init__(self, layer, N):super().__init__()# layer:代表編碼器層self.layer = layer# N:代表有幾個編碼器層# 定義N個編碼器層self.layers = clones(layer, N)# 實例化規范化層self.norm = LayerNorm(features=layer.size)def forward(self, x, mask):# x-->來自輸入部分--》[batch_size, seq_len, embed_dim]:[2, 4, 512]# mask-->[head, seq_len, seq_len]-=-->[8, 4, 4]# for循環迭代N個編碼器層得到最終的結果for layer in self.layers:x = layer(x, mask)return self.norm(x)

解碼器部分

解碼器層

依舊超級拼裝:先試用子層鏈接拼成(norm&add+feedforward)層,(muti_head_atten+norm&add)層,(mask_muti_head_atten+norm&add)層 ,然后把這三個子層拼起來就是解碼器結構

class DecoderLayer(nn.Module):def __init__(self, size, self_atten, src_atten, feed_forward, dropout_p):super().__init__()# size:代表詞嵌入維度的大小self.size = size# self_atten:自注意力機制的對象:Q=K=Vself.self_atten = self_atten# src_atten:一般注意力機制的對象:Q!=K=Vself.src_atten = src_atten# feed_forward:前饋全連接層對象self.feed_forward = feed_forward# 定義三個子層連接結構self.sub_layers = clones(SublayerConnection(size, dropout_p), 3)def forward(self, y, encoder_output, source_mask, target_mask):# y:代表解碼器的輸入--》[batch_size, seq_len, embed_dim]# encoder_output:代表編碼器的輸出結果--》[batch_size, seq_len, emebed_dim]# target_mask防止未來信息被提前看到/target_mask-->[head, y_seq_len, y_seq_len]# source_mask消除padding的影響# source_mask--shape-->[head, y_seq_len, x_seq_len]# 經過第一個子層連接結構 todo 看圖寫作:第一個子層連接結構是帶mask掩碼滴,輸入是q=k=v==預測值y的positionEncoding+WordEmbedding輸出,y1 = self.sub_layers[0](y, lambda x: self.self_atten(x, x, x, target_mask))# 經過第二個子層連接結構 todo 第二個子層鏈接是不帶mask掩碼,輸入的k=v==(源文本嵌入+位置編碼)再經過編碼器的輸出,v是第一個子層結構的輸出# query--》[2,6,512]-->[2, 8, 6, 64],key/value-->[2, 4, 512]-->[2, 8, 4, 64]# [2, 8, 6, 64]--和[2, 8, 4, 64]轉置[2,8, 64, 4]-->[2, 8, 6, 4]y2 = self.sub_layers[1](y1, lambda x: self.src_atten(x, encoder_output, encoder_output, source_mask))# 經過第三個子層連接結構 todo 這一層就是feed+norm&add 輸入什么維度輸出就是什么維度y3 = self.sub_layers[2](y2, self.feed_forward)return y3
解碼器

拼拼拼:n個解碼器層構成一個解碼器,這里的n==6 按照這里的代碼,多個解碼器層是串聯執行,上一個解碼器的輸出作為下一個解碼器的輸入,最終輸出解碼器的結果給輸出層

class Decoder(nn.Module):def __init__(self, layer, N):super().__init__()# layer:代表解碼器層self.layer = layer# N:代表有幾個解碼器層# 定義N個解碼層self.layers = clones(layer, N)# 實例化規范化層self.norm = LayerNorm(features=layer.size)def forward(self, y, encoder_output, source_mask, target_mask):# y:代表解碼器的輸入--》[batch_size, seq_len, embed_dim]# encoder_output:代表編碼器的輸出結果--》[batch_size, seq_len, emebed_dim]# target_mask防止未來信息被提前看到/target_mask-->[head, y_seq_len, y_seq_len]# source_mask消除padding的影響# source_mask--shape-->[head, y_seq_len, x_seq_len]# for循環迭代N個編碼器層得到最終的結果for layer in self.layers:y = layer(y, encoder_output, source_mask, target_mask)return self.norm(y)

輸出部分

生成器generator

輸出部分:將解碼器輸出經過一個線性層,再經過softmax,得到當前預測的結果

輸出[batch_size,seq_len,vocab_size] vocab_size是詞表詞個數,概率最大的為預測結果

class Generator(nn.Module):def __init__(self, d_model, vocab_size):# 參數d_model 線性層輸入特征尺寸大小# 參數vocab_size 線層輸出尺寸大小super(Generator, self).__init__()# 定義線性層self.project = nn.Linear(d_model, vocab_size)def forward(self, x):# 數據經過線性層 最后一個維度歸一化 log方式x = F.log_softmax(self.project(x), dim=-1)return x

使用部分

模擬使用,僅預測一個單詞
源文本輸入:也就是要翻譯的文本,兩個句子4個單詞
x = torch.tensor([[1, 40, 28, 100], [45, 89, 39, 10]])
上一步預測值輸入:如果為頭單詞,則為sos_token的詞向量表達
y0 = torch.tensor([[2, 4, 10, 29, 67, 89],[34, 56, 78, 20, 19, 6]])
詞表大小:要翻譯的語言總共有多少個單詞
vocab_size = 1000
詞向量維度
embed_dim = 512

總體流程概述:

編碼器部分:源文本輸入x經過embedding后與positionnal_encoding相加結果輸入encoder()

在每一個編碼器層經過兩個子層:

1.多頭自注意力子層+(殘差鏈接+規范化)

在編碼器的多頭注意力層中q=k=v

  1. 前饋全連接層+(殘差鏈接+規范化)

前饋全連接層的作用: 通過增加兩層網絡來增強模型的能力.

輸出x1

經過n個編碼器層后輸出xn給解碼器

解碼器部分:前一步的實際值或預測值 y0 = torch.tensor([[2, 4, 10, 29, 67, 89],[34, 56, 78, 20, 19, 6]])經過embedding后與positionnal_encoding相加輸入結果decoder()

在每一個解碼器層經過三個子層:

1.帶掩碼的多頭自注意力子層+(殘差鏈接+規范化)

在此層q=k=v mask的作用是防止未來信息被提前看見

2.多頭注意力子層+(殘差鏈接+規范化)

在此層k=v = 編碼器的輸出xn , q=上一個子層的輸入

  1. 前饋全連接子層+(殘差鏈接+規范化)

前饋全連接層的作用: 通過增加兩層網絡來增強模型的能力.

經過n個解碼器層后輸出yn給輸出部分

輸出部分:經過一個線性層和一個softmax層

線性層:通過對上一步的線性變化得到指定維度的輸出, 也就是轉換維度的作用.

softmax層:使最后一維的向量中的數字縮放到0-1的概率值域內, 并滿足他們的和為1.

輸出預測值result[batch_size,seq_len,vocab_size],batch_size句seq_len個單詞,其中概率最大的值為預測結果

def usb_position(): #todo 生成位置編碼vocab_size = 1000 # 定義詞匯大小embed_dim = 512 # 詞嵌入維度my_embed = Embeddings(vocab_size, embed_dim)x = torch.tensor([[1, 40, 28, 100], [45, 89, 39, 10]])embed_result = my_embed(x)my_position = PositionEncoding(d_model=512, dropout_p=0.1)position_result = my_position(embed_result)print(f'position_result-->{position_result.shape}')# print(f'position_result-->{position_result}')return position_result
def use_encoder():  # todo 輸入編碼器輸入(待翻譯的句子)以及位置編碼,得到編碼器輸出# 獲取編碼器輸入部分:[2, 4, 512]position_result = usb_position()# 實例化多頭注意力機制對象mutiHead_atten = MutiHeadAttention(head=8, embed_dim=512)# 實例化前饋全連接層對象ff = FeedForward(d_model=512, d_ff=1024)mask = torch.zeros(8, 4, 4)#  實例化編碼器層對象encoder_layer = EncoderLayer(size=512, self_atten=mutiHead_atten, feed_forward=ff, dropout_p=0.1)#  實例化編碼器對象encoder = Encoder(layer=encoder_layer, N=6)# 將數據送入編碼器 todo position_result先encoder_output = encoder(position_result,  mask)print(f'encoder_output編碼器得到的結果--》{encoder_output}')print(f'encoder_output編碼器得到的結果--》{encoder_output.shape}')# todo 編碼器輸出return encoder_output
def use_decoder():  #todo 輸入編碼器輸出,得到解碼器輸出# 定義解碼器端的輸入 todo 編碼器的輸入是對應原始輸入序列(如待翻譯的源語言句子),解碼器輸入的是解碼器的輸入是右移(shifted right)的目標序列(如已生成的部分目標語言句子)。# todo 解碼器的輸出是解碼器逐步生成的目標序列(如翻譯結果),每次預測一個詞。y0 = torch.tensor([[2, 4, 10, 29, 67, 89],[34, 56, 78, 20, 19, 6]])vocab_size = 1000embed_dim = 512# 實例化Embedding層embed = Embeddings(vocab_size, embed_dim)# embed_y-->[2, 6, 512]embed_y = embed(y0)# # 實例化PositionEncoding層position_encode = PositionEncoding(d_model=512, dropout_p=0.1)# todo position_y 是預測的目標序列,位置編碼對預測結果進行編碼,從而提高預測效果。若為首字母則對應sos_tokenposition_y = position_encode(embed_y)# 實例化多頭注意力機制的對象muti_head_atten = MutiHeadAttention(head=8, embed_dim=512)self_atten = copy.deepcopy(muti_head_atten)src_atten = copy.deepcopy(muti_head_atten)# 實例化前饋全連接的對象ff = FeedForward(d_model=512, d_ff=1024)#  實例化解碼器層的對象decoder_layer = DecoderLayer(size=512, self_atten=self_atten, src_atten=src_atten, feed_forward=ff, dropout_p=0.1)# 準備數據# todo encoder_output是編碼器輸出結果,對應源語言句子encoder_output = use_encoder()source_mask = torch.zeros(8, 6, 4)target_mask = torch.zeros(8, 6, 6)#  實例化解碼器的對象decoder = Decoder(layer=decoder_layer, N=6)result = decoder(position_y, encoder_output, source_mask, target_mask)# print(f'解碼器得到的結果--》{result}')# print(f'解碼器得到的結果--》{result.shape}')return resultdef use_generator():x=use_decoder()my_generator  = Generatorresult = my_generator(512, 1000)(x)print(f'生成器得到結果--》{result}')print(f'生成器得到結果--》{result.shape}')return result
if __name__ == '__main__':# use_decoder()use_generator()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90839.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90839.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90839.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

記錄一本書: Python機器學習:基于PyTorch和Scikit-Learn

記錄一本書: Python機器學習:基于PyTorch和Scikit-Learn 作者:(美)塞巴斯蒂安拉施卡(Sebastian Raschka)(美)劉玉溪(海登)(Yuxi(Hayden)Liu) (美)…

Datomic數據庫簡介(TBC)

Datomic 數據庫詳細介紹 Datomic 是一個由 Rich Hickey(Clojure 語言創始人)設計的 不可變、時間感知、分布式數據庫,專為現代應用程序設計,強調 數據不變性(immutability)、查詢靈活性和可審計性。它結合…

xformers 完整安裝教程【pip conda】(解決 conda 版本 pytorch 自適應安裝 xformers)

我個人喜歡用 mamba(conda)創建環境,然后用 mamba 安裝 pytorch CUDA(如果需要使用 CUDA 編譯),還有一些比如 gcc/g 等與 python 無關的一些工具。 但是最近我在擴充環境的時候,發現需要額外安…

VM虛擬機全版本網盤+免費本地網絡穿透端口映射實時同步動態家庭IP教程

VM虛擬機全版本秘鑰,文章末尾。 首先網絡穿透的意義是讓公網可以直接訪問家庭電腦,這樣本地電腦的硬件性能得以完全發揮,特別是在云服務器貴性能又沒家庭電腦好,專線寬帶又貴,第三方網絡穿透貴的場景下。一般第三方網…

C++ - 仿 RabbitMQ 實現消息隊列--項目介紹與環境搭建

目錄 項目介紹 開發環境 技術選型 環境搭建 安裝 wget(一般情況下默認會自帶) 更換國內軟件源 安裝 lrzsz 傳輸工具 安裝編譯器 安裝項目構建工具 make 安裝調試器 安裝 git 安裝 cmake 安裝 Protobuf 安裝 Muduo 安裝 SQLite3 安裝 Gtest 項目介紹 首先說一下…

《目標檢測模塊實踐手冊:從原理到落地的嘗試與分享》第一期

大家好,歡迎來到《目標檢測模塊實踐手冊》系列的第一篇。從今天開始,我想以一種 “實踐記錄者” 的身份,和大家聊聊在目標檢測任務中那些形形色色的模塊。這些內容沒有權威結論,更多的是我在實際操作中的一些嘗試、發現和踩過的坑…

C++11笑傳之引用

C11前言列表初始化{}進行初始化initializer_list右值引用和移動語義左值與右值左值引用與右值引用引用延長生命周期右值引用和移動語義的使用場景左值引用移動構造和移動賦值右值引用在容器插入的提效引用折疊萬能折疊完美轉發前言 C11是C繼98后的更新,其更新了許多…

瀚高數據庫提交數據后,是否需要COMMIT(APP)

文章目錄環境癥狀問題原因解決方案報錯編碼環境 系統平臺: 版本:5.6.5,4.5 癥狀 瀚高數據庫提交數據后,是否需要commit,瀚高數據庫是否有配置項。 問題原因 瀚高數據庫默認自動COMMIT(提交數據)&#…

深大計算機游戲開發實驗三

主要步驟主角飛船的創建和移動邊界設置以及護盾設置創建敵機自動生成敵機圖層設置彈丸設置武器創建不同發射模式管理競態條件擊敗敵機掉落升級道具不同敵機的生成分值顯示實現退出游戲界面之后進入游戲的最高記錄重置游戲界面失敗后重新加載最記錄不會重置任何時候在游戲界面按…

詳解緩存淘汰策略:LRU

文章目錄緩存淘汰策略LRU核心結構核心操作流程局限性源碼走讀AddGet緩存淘汰策略 緩存淘汰策略的存在是為了解決 緩存容量有限性 和 高緩存命中率 之間的矛盾。其核心目標是在有限的緩存空間內,盡可能提高緩存命中率 緩存容量有限性:緩存(例…

什么是 Bootloader?怎么把它移植到 STM32 上?

一、Bootloader 是啥?它都干了些啥?想象一下你的 MCU(比如 STM32)是一個小機器人,上電之后第一件事,它不會立馬開始“干正事”(運行你的主程序),而是先去運行一個“開場引…

無人機避障——感知篇(Ego_Planner_v2中的滾動窗口實現動態實時感知建圖grid_map ROS節點理解與參數調整影響)

處理器:Orin nx 雙目視覺傳感器:ZED2 實時感知建圖方法:Vins Fusion Raycast (VIO與射線投影法感知定位加建圖方法) 項目地址:https://github.com/ZJU-FAST-Lab/EGO-Planner-v2 【注意】:建…

26-計組-尋址方式

指令尋址與PC自增一、指令尋址方式定義:尋找下一條將要執行的指令地址的過程。 核心部件:程序計數器(PC),用于指示待執行指令的地址。 執行流程:CPU根據PC值從主存取指令。取指后,PC自動自增&am…

生成式對抗網絡(GAN)模型原理概述

生成對抗網絡(Generative Adversarial Network, GAN)是一種通過對抗訓練生成數據的深度學習模型,由生成器(Generator)和判別器(Discriminator)兩部分組成,其核心思想源于博弈論中的零…

Vue和Element的使用

文章目錄1.vue 腳手架創建步驟2.vue項目開發流程3.vue路由4.Element1.vue 腳手架創建步驟 創建一個文件夾 vue雙擊進入文件夾,在路徑上輸入cmd輸入vue ui, 目的:調出圖形化用戶界面點擊創建 9. 10.在vscode中打開 主要目錄介紹 src目錄介紹 vue項目啟動 圖形化界面中沒有npm…

如何設置直播間的觀看門檻,讓直播間安全有效地運行?

文章目錄前言一、直播間觀看門檻有哪幾種形式?二、設置直播間的觀看門檻,對直播的好處是什么三、如何一站式實現上述功能?總結前言 打造一個安全、高效、互動良好的直播間并非易事。面對海量涌入的觀眾,如何有效識別并阻擋潛在的…

【SkyWalking】配置告警規則并通過 Webhook 推送釘釘通知

🧭 本文為 【SkyWalking 系列】第 3 篇 👉 系列導航:點擊跳轉 【SkyWalking】配置告警規則并通過 Webhook 推送釘釘通知 簡介 介紹 SkyWalking 告警機制、告警規則格式以及如何通過 webhook 方式將告警信息發送到釘釘。 引入 服務響應超時…

關于 驗證碼系統 詳解

驗證碼系統的目的是:阻止自動化腳本訪問網頁資源,驗證訪問者是否為真實人類用戶。它通過各種測試(圖像、行為、計算等)判斷請求是否來自機器人。一、驗證碼系統的整體架構驗證碼系統通常由 客戶端 服務端 風控模型 數據采集 四…

微服務集成snail-job分布式定時任務系統實踐

前言 從事開發工作的同學,應該對定時任務的概念并不陌生,就是我們的系統在運行過程中能夠自動執行的一些任務、工作流程,無需人工干預。常見的使用場景包括:數據庫的定時備份、文件系統的定時上傳云端服務、每天早上的業務報表數…

依賴注入的邏輯基于Java語言

對于一個廚師,要做一道菜。傳統的做法是:你需要什么食材,就自己去菜市場買什么。這意味著你必須知道去哪個菜市場、怎么挑選食材、怎么討價還價等等。你不僅要會做菜,還要會買菜,職責變得復雜了。 而依賴注入就像是有一…