LSTM進行字符級文本生成(pytorch實現)

文章目錄
  • 基于pytorch的LSTM進行字符集文本生成
  • 前言
  • 一、數據集
  • 二、代碼實現
    • 1.到入庫和LSTM進行模型構建
    • 2.數據預處理函數
    • 3.訓練函數
    • 4.預測函數
    • 5.文本生成函數
    • 6.主函數
  • 完整代碼
  • 總結

前言

本文介紹了機器學習中深度學習的內容使用pytorch構建LSTM模型進行字符級文本生成任務

一、數據集

https://download.csdn.net/download/qq_52785473/78428834

二、代碼實現

1.導入庫及LSTM模型構建

代碼如下:

# coding: utf-8
import torch
import torch.nn as nn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import OneHotEncoder
import torch.nn.functional as Fclass lstm_model(nn.Module):def __init__(self, vocab, hidden_size, num_layers, dropout=0.5):super(lstm_model, self).__init__()self.vocab = vocab  # 字符數據集# 索引,字符self.int_char = {i: char for i, char in enumerate(vocab)}self.char_int = {char: i for i, char in self.int_char.items()}# 對字符進行one-hot encodingself.encoder = OneHotEncoder(sparse=True).fit(vocab.reshape(-1, 1))self.hidden_size = hidden_sizeself.num_layers = num_layers# lstm層self.lstm = nn.LSTM(len(vocab), hidden_size, num_layers, batch_first=True, dropout=dropout)# 全連接層self.linear = nn.Linear(hidden_size, len(vocab))def forward(self, sequence, hs=None):out, hs = self.lstm(sequence, hs)  # lstm的輸出格式(batch_size, sequence_length, hidden_size)out = out.reshape(-1, self.hidden_size)  # 這里需要將out轉換為linear的輸入格式,即(batch_size * sequence_length, hidden_size)output = self.linear(out)  # linear的輸出格式,(batch_size * sequence_length, vocab_size)return output, hsdef onehot_encode(self, data):  # 對數據進行編碼return self.encoder.transform(data)def onehot_decode(self, data):  # 對數據進行解碼return self.encoder.inverse_transform(data)def label_encode(self, data):  # 對標簽進行編碼return np.array([self.char_int[ch] for ch in data])def label_decode(self, data):  # 對標簽進行解碼return np.array([self.int_char[ch] for ch in data])

2.數據預處理函數

def get_batches(data, batch_size, seq_len):''':param data: 源數據,輸入格式(num_samples, num_features):param batch_size: batch的大小:param seq_len: 序列的長度(精度):return: (batch_size, seq_len, num_features)'''num_features = data.shape[1]num_chars = batch_size * seq_len  # 一個batch_size的長度num_batches = int(np.floor(data.shape[0] / num_chars))  # 計算出有多少個batchesneed_chars = num_batches * num_chars  # 計算出需要的總字符量targets = np.vstack((data[1:].A, data[0].A))  # 可能版本問題,取成numpy比較好reshapeinputs = data[:need_chars].A.astype("int")  # 從原始數據data中截取所需的字符數量need_wordstargets = targets[:need_chars]targets = targets.reshape(batch_size, -1, num_features)inputs = inputs.reshape(batch_size, -1, num_features)for i in range(0, inputs.shape[1], seq_len):x = inputs[:, i: i+seq_len]y = targets[:, i: i+seq_len]yield x, y  # 節省內存

3.訓練函數

def train(model, data, batch_size, seq_len, epochs, lr=0.01, valid=None):device = 'cuda' if torch.cuda.is_available() else 'cpu'model = model.to(device)optimizer = torch.optim.Adam(model.parameters(), lr=lr)criterion = nn.CrossEntropyLoss()if valid is not None:data = model.onehot_encode(data.reshape(-1, 1))valid = model.onehot_encode(valid.reshape(-1, 1))else:data = model.onehot_encode(data.reshape(-1, 1))train_loss = []val_loss = []for epoch in range(epochs):model.train()hs = None  # hs等于hidden_size隱藏層節點train_ls = 0.0val_ls = 0.0for x, y in get_batches(data, batch_size, seq_len):optimizer.zero_grad()x = torch.tensor(x).float().to(device)out, hs = model(x, hs)hs = ([h.data for h in hs])y = y.reshape(-1, len(model.vocab))y = model.onehot_decode(y)y = model.label_encode(y.squeeze())y = torch.from_numpy(y).long().to(device)loss = criterion(out, y.squeeze())loss.backward()optimizer.step()train_ls += loss.item()if valid is not None:model.eval()hs = Nonewith torch.no_grad():for x, y in get_batches(valid, batch_size, seq_len):x = torch.tensor(x).float().to(device)  # x為一組測試數據,包含batch_size * seq_len個字out, hs = model(x, hs)# out.shape輸出為tensor[batch_size * seq_len, vocab_size]hs = ([h.data for h in hs])  # 更新參數y = y.reshape(-1, len(model.vocab))  # y.shape為(128,100,43),因此需要轉成兩維,每行就代表一個字了,43為字典大小y = model.onehot_decode(y)  # y標簽即為測試數據各個字的下一個字,進行one_hot解碼,即變為字符# 但是此時y 是[[..],[..]]形式y = model.label_encode(y.squeeze())  # 因此需要去掉一維才能成功解碼# 此時y為[12...]成為一維的數組,每個代表自己字典里對應字符的字典序y = torch.from_numpy(y).long().to(device)# 這里y和y.squeeze()出來的東西一樣,可能這里沒啥用,不太懂loss = criterion(out, y.squeeze())  # 計算損失值val_ls += loss.item()val_loss.append(np.mean(val_ls))train_loss.append(np.mean(train_ls))print("train_loss:", train_ls)plt.plot(train_loss, label="train_loss")plt.plot(val_loss, label="val loss")plt.title("loop vs epoch")plt.legend()plt.show()model_name = "lstm_model.net"with open(model_name, 'wb') as f:  # 訓練完了保存模型torch.save(model.state_dict(), f)

4.預測函數

def predict(model, char, top_k=None, hidden_size=None):device = 'cuda' if torch.cuda.is_available() else 'cpu'model.to(device)model.eval()  # 固定參數with torch.no_grad():char = np.array([char])  # 輸入一個字符,預測下一個字是什么,先轉成numpychar = char.reshape(-1, 1)  # 變成二維才符合編碼規范char_encoding = model.onehot_encode(char).A  # 對char進行編碼,取成numpy比較方便reshapechar_encoding = char_encoding.reshape(1, 1, -1)  # char_encoding.shape為(1, 1, 43)變成三維才符合模型輸入格式char_tensor = torch.tensor(char_encoding, dtype=torch.float32)  # 轉成tensorchar_tensor = char_tensor.to(device)out, hidden_size = model(char_tensor, hidden_size)  # 放入模型進行預測,out為結果probs = F.softmax(out, dim=1).squeeze()  # 計算預測值,即所有字符的概率if top_k is None:  # 選擇概率最大的top_k個indices = np.arange(vocab_size)else:probs, indices = probs.topk(top_k)indices = indices.cpu().numpy()probs = probs.cpu().numpy()char_index = np.random.choice(indices, p=probs/probs.sum())  # 隨機選擇一個字符索引作為預測值char = model.int_char[char_index]  # 通過索引找出預測字符return char, hidden_size

5.文本生成函數

def sample(model, length, top_k=None, sentence="c"):hidden_size = Nonenew_sentence = [char for char in sentence]for i in range(length):next_char, hidden_size = predict(model, new_sentence[-1], top_k=top_k, hidden_size=hidden_size)new_sentence.append(next_char)return "".join(new_sentence)

6.主函數

def main():hidden_size = 512num_layers = 2batch_size = 128seq_len = 100epochs = 2lr = 0.01f = pd.read_csv("../datasets/dev.tsv", sep="\t", header=None)f = f[0]text = list(f)text = ".".join(text)vocab = np.array(sorted(set(text)))  # 建立字典vocab_size = len(vocab)val_len = int(np.floor(0.2 * len(text)))  # 劃分訓練測試集trainset = np.array(list(text[:-val_len]))validset = np.array(list(text[-val_len:]))model = lstm_model(vocab, hidden_size, num_layers)  # 模型實例化train(model, trainset, batch_size, seq_len, epochs, lr=lr, valid=validset)  # 訓練模型model.load_state_dict(torch.load("lstm_model.net"))  # 調用保存的模型new_text = sample(model, 100, top_k=5)  # 預測模型,生成100個字符,預測時選擇概率最大的前5個print(new_text)  # 輸出預測文本if __name__ == "__main__":main()

本代碼還是有很大改進空間,例如進行詞語級的文本生成,以及使用word2vec等引入詞向量等,都可以是的模型獲得更好的效果。

完整代碼

# coding: utf-8
import torch
import torch.nn as nn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import OneHotEncoder
import torch.nn.functional as Fclass lstm_model(nn.Module):def __init__(self, vocab, hidden_size, num_layers, dropout=0.5):super(lstm_model, self).__init__()self.vocab = vocab  # 字符數據集# 索引,字符self.int_char = {i: char for i, char in enumerate(vocab)}self.char_int = {char: i for i, char in self.int_char.items()}# 對字符進行one-hot encodingself.encoder = OneHotEncoder(sparse=True).fit(vocab.reshape(-1, 1))self.hidden_size = hidden_sizeself.num_layers = num_layers# lstm層self.lstm = nn.LSTM(len(vocab), hidden_size, num_layers, batch_first=True, dropout=dropout)# 全連接層self.linear = nn.Linear(hidden_size, len(vocab))def forward(self, sequence, hs=None):out, hs = self.lstm(sequence, hs)  # lstm的輸出格式(batch_size, sequence_length, hidden_size)out = out.reshape(-1, self.hidden_size)  # 這里需要將out轉換為linear的輸入格式,即(batch_size * sequence_length, hidden_size)output = self.linear(out)  # linear的輸出格式,(batch_size * sequence_length, vocab_size)return output, hsdef onehot_encode(self, data):return self.encoder.transform(data)def onehot_decode(self, data):return self.encoder.inverse_transform(data)def label_encode(self, data):return np.array([self.char_int[ch] for ch in data])def label_decode(self, data):return np.array([self.int_char[ch] for ch in data])def get_batches(data, batch_size, seq_len):''':param data: 源數據,輸入格式(num_samples, num_features):param batch_size: batch的大小:param seq_len: 序列的長度(精度):return: (batch_size, seq_len, num_features)'''num_features = data.shape[1]num_chars = batch_size * seq_len  # 一個batch_size的長度num_batches = int(np.floor(data.shape[0] / num_chars))  # 計算出有多少個batchesneed_chars = num_batches * num_chars  # 計算出需要的總字符量targets = np.vstack((data[1:].A, data[0].A))  # 可能版本問題,取成numpy比較好reshapeinputs = data[:need_chars].A.astype("int")  # 從原始數據data中截取所需的字符數量need_wordstargets = targets[:need_chars]targets = targets.reshape(batch_size, -1, num_features)inputs = inputs.reshape(batch_size, -1, num_features)for i in range(0, inputs.shape[1], seq_len):x = inputs[:, i: i+seq_len]y = targets[:, i: i+seq_len]yield x, y  # 節省內存def train(model, data, batch_size, seq_len, epochs, lr=0.01, valid=None):device = 'cuda' if torch.cuda.is_available() else 'cpu'model = model.to(device)optimizer = torch.optim.Adam(model.parameters(), lr=lr)criterion = nn.CrossEntropyLoss()if valid is not None:data = model.onehot_encode(data.reshape(-1, 1))valid = model.onehot_encode(valid.reshape(-1, 1))else:data = model.onehot_encode(data.reshape(-1, 1))train_loss = []val_loss = []for epoch in range(epochs):model.train()hs = None  # hs等于hidden_size隱藏層節點train_ls = 0.0val_ls = 0.0for x, y in get_batches(data, batch_size, seq_len):optimizer.zero_grad()x = torch.tensor(x).float().to(device)out, hs = model(x, hs)hs = ([h.data for h in hs])y = y.reshape(-1, len(model.vocab))y = model.onehot_decode(y)y = model.label_encode(y.squeeze())y = torch.from_numpy(y).long().to(device)loss = criterion(out, y.squeeze())loss.backward()optimizer.step()train_ls += loss.item()if valid is not None:model.eval()hs = Nonewith torch.no_grad():for x, y in get_batches(valid, batch_size, seq_len):x = torch.tensor(x).float().to(device)  # x為一組測試數據,包含batch_size * seq_len個字out, hs = model(x, hs)# out.shape輸出為tensor[batch_size * seq_len, vocab_size]hs = ([h.data for h in hs])  # 更新參數y = y.reshape(-1, len(model.vocab))  # y.shape為(128,100,43),因此需要轉成兩維,每行就代表一個字了,43為字典大小y = model.onehot_decode(y)  # y標簽即為測試數據各個字的下一個字,進行one_hot解碼,即變為字符# 但是此時y 是[[..],[..]]形式y = model.label_encode(y.squeeze())  # 因此需要去掉一維才能成功解碼# 此時y為[12...]成為一維的數組,每個代表自己字典里對應字符的字典序y = torch.from_numpy(y).long().to(device)# 這里y和y.squeeze()出來的東西一樣,可能這里沒啥用,不太懂loss = criterion(out, y.squeeze())  # 計算損失值val_ls += loss.item()val_loss.append(np.mean(val_ls))train_loss.append(np.mean(train_ls))print("train_loss:", train_ls)plt.plot(train_loss, label="train_loss")plt.plot(val_loss, label="val loss")plt.title("loop vs epoch")plt.legend()plt.show()model_name = "lstm_model.net"with open(model_name, 'wb') as f:  # 訓練完了保存模型torch.save(model.state_dict(), f)def predict(model, char, top_k=None, hidden_size=None):device = 'cuda' if torch.cuda.is_available() else 'cpu'model.to(device)model.eval()  # 固定參數with torch.no_grad():char = np.array([char])  # 輸入一個字符,預測下一個字是什么,先轉成numpychar = char.reshape(-1, 1)  # 變成二維才符合編碼規范char_encoding = model.onehot_encode(char).A  # 對char進行編碼,取成numpy比較方便reshapechar_encoding = char_encoding.reshape(1, 1, -1)  # char_encoding.shape為(1, 1, 43)變成三維才符合模型輸入格式char_tensor = torch.tensor(char_encoding, dtype=torch.float32)  # 轉成tensorchar_tensor = char_tensor.to(device)out, hidden_size = model(char_tensor, hidden_size)  # 放入模型進行預測,out為結果probs = F.softmax(out, dim=1).squeeze()  # 計算預測值,即所有字符的概率if top_k is None:  # 選擇概率最大的top_k個indices = np.arange(vocab_size)else:probs, indices = probs.topk(top_k)indices = indices.cpu().numpy()probs = probs.cpu().numpy()char_index = np.random.choice(indices, p=probs/probs.sum())  # 隨機選擇一個字符索引作為預測值char = model.int_char[char_index]  # 通過索引找出預測字符return char, hidden_sizedef sample(model, length, top_k=None, sentence="c"):hidden_size = Nonenew_sentence = [char for char in sentence]for i in range(length):next_char, hidden_size = predict(model, new_sentence[-1], top_k=top_k, hidden_size=hidden_size)new_sentence.append(next_char)return "".join(new_sentence)def main():hidden_size = 512num_layers = 2batch_size = 128seq_len = 100epochs = 2lr = 0.01f = pd.read_csv("../datasets/dev.tsv", sep="\t", header=None)f = f[0]text = list(f)text = ".".join(text)vocab = np.array(sorted(set(text)))  # 建立字典vocab_size = len(vocab)val_len = int(np.floor(0.2 * len(text)))  # 劃分訓練測試集trainset = np.array(list(text[:-val_len]))validset = np.array(list(text[-val_len:]))model = lstm_model(vocab, hidden_size, num_layers)  # 模型實例化train(model, trainset, batch_size, seq_len, epochs, lr=lr, valid=validset)  # 訓練模型model.load_state_dict(torch.load("lstm_model.net"))  # 調用保存的模型new_text = sample(model, 100, top_k=5)  # 預測模型,生成100個字符,預測時選擇概率最大的前5個print(new_text)  # 輸出預測文本if __name__ == "__main__":main()

總結

這個案例他數據預處理的時候,一個序列對應一個序列的關系,例如abcd對應的標簽為dabc,而不是一個字符,因此可能后面進行了某些操作使得他變成一個字符對應一個字符標簽的操作了吧,從而使得預測的時候,只能通過一個字符預測其后面的字符,這就有點失去循環神經網絡精髓的味道了,感覺是割裂字符之間的關系,變成一個普通單純的分類了。

循環神經網絡,因為能夠處理序列位置的信息,需要設定一個滑動窗口值,或者說時間步長什么的,作用應該就是保留序列特征,例如abcdef為訓練數據,設置滑動窗口為3的話,那么按照正常的序列思路可以劃分為abc-d、bcd-e、cde-f作為訓練數據的形式,即連續的三個字符對應的標簽為其后面一個字符,那么我們訓練出來的模型也是需要輸入三個字符,然后生成一個字符,再用預測出來的字符加上他前面兩個字符再預測新的字符,例如預測的初始序列為abc加入abc預測出來d,那么下一次預測就是bcd作為輸入,就像一個窗口一步一步滑動過去一樣,窗口的大小就為開始設定的3。

因此對于這個案例,它雖然seq_len=100,即滑動窗口為100,但是它的訓練數據就不太對,而且模型預測時也是一個字符預測下一個字符,并沒有體現滑動窗口的思想,因此這個代碼案例大家可以自己進行改進優化。

下面是對代碼部分地方的改動,使得它能夠按滑動窗口的思維來進行訓練和預測

數據預處理函數

def get_batches(data, batch_size, seq_len):''':param data: 源數據,輸入格式(num_samples, num_features):param batch_size: batch的大小:param seq_len: 序列的長度(精度):return: (batch_size, seq_len, num_features)'''num_features = data.shape[1]num_chars = batch_size * seq_len  # 一個batch_size的長度num_batches = int(np.floor(data.shape[0] / num_chars))  # 計算出有多少個batchesneed_chars = num_batches * num_chars  # 計算出需要的總字符量targets = np.vstack((data[1:].A, data[0].A))  # 可能版本問題,取成numpy比較好reshapeinputs = data[:need_chars].A.astype("int")  # 從原始數據data中截取所需的字符數量need_wordstargets = targets[:need_chars]train_data = np.zeros((inputs.shape[0] - seq_len, seq_len, num_features))train_label = np.zeros((inputs.shape[0] - seq_len, num_features))for i in range(0, inputs.shape[0] - seq_len, 1):# inputs就是字符數 * 詞向量大小(表示一個字符)# 思路就是abcd中ab-c, bc-d,一共4-3+1個train_data[i] = inputs[i:i+seq_len]  # 每seq_len=100的字符train_label[i] = inputs[i+seq_len-1] # 訓練標簽就為他后面那個字符print(train_data.shape)print(train_label.shape)for i in range(0, inputs.shape[0] - seq_len, batch_size):  x = train_data[i:i+batch_size] # 每batch_size=128個一起進行訓練更新參數y = train_label[i:i+batch_size]  # 對應的128個標簽print(x.shape)print(y.shape)print("-----------")yield x, y

模型構建部分

class lstm_model(nn.Module):def __init__(self, vocab, hidden_size, num_layers, dropout=0.5, seq_len=100):super(lstm_model, self).__init__()self.seq_len = seq_lenself.vocab = vocab  # 字符數據集# 索引,字符self.int_char = {i: char for i, char in enumerate(vocab)}self.char_int = {char: i for i, char in self.int_char.items()}# 對字符進行one-hot encodingself.encoder = OneHotEncoder(sparse=True).fit(vocab.reshape(-1, 1))self.hidden_size = hidden_sizeself.num_layers = num_layers# lstm層self.lstm = nn.LSTM(len(vocab), hidden_size, num_layers, batch_first=True, dropout=dropout)# 全連接層self.linear = nn.Linear(hidden_size, len(vocab))def forward(self, sequence, hs=None):# print("==========")# print("forward:", sequence.shape)out, hs = self.lstm(sequence, hs)  # lstm的輸出格式(batch_size, sequence_length, hidden_size)print("----", out.shape)# out = out.reshape(-1, self.hidden_size)  # 這里需要將out轉換為linear的輸入格式,即(batch_size * sequence_length, hidden_size)print("========", out[:, -1].shape)output = self.linear(out[:, -1])  # 只取[bacth_size,hidden_size],即找到batch_size里每個元素的標簽吧print("output-----:", output.shape)return output, hsdef onehot_encode(self, data):return self.encoder.transform(data)def onehot_decode(self, data):return self.encoder.inverse_transform(data)def label_encode(self, data):return np.array([self.char_int[ch] for ch in data])def label_decode(self, data):return np.array([self.int_char[ch] for ch in data])

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

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

相關文章

王者榮耀整蠱搭建直播新玩法/obs貼紙配置教程

最近很火的王者榮耀整蠱直播,相信很多玩王者的玩家也想開一個直播,但是看到這種直播娛樂效果很有意思也想搭建一個,這里夢哥給大家出了一期搭建的教程! 進階版視頻教程: 這期的教程是進階版新玩法升級,具體…

Vue3:使用 Composition API 不需要 Pinia

在 Vue.js 開發的動態環境中,在單個組件中處理復雜的業務邏輯可能會導致笨重的文件和維護噩夢。雖然 Pinia 提供集中式狀態管理,但僅依賴它來處理復雜的業務邏輯可能會導致代碼混亂。本文探討了使用 Composition API 的替代方法,說明開發人員…

數據庫表 索引

目錄 一、索引的分類 1、按存儲形式: 1)B-TREE索引: 2)位圖索引: 3)反向鍵索引: 4)基于函數的索引: 2、按唯一性: 1)唯一索引: 3、按列的個數…

代碼隨想錄算法訓練營第八天

344. 反轉字符串 方法&#xff1a; 方法一&#xff1a; 直接用reverse函數 注意&#xff1a; 代碼&#xff1a; class Solution { public:void reverseString(vector<char>& s) {return reverse(s.begin(), s.end());} };運行結果&#xff1a; 方法&#xff1…

解釋前端路由的概念,以及單頁應用(SPA)和多頁應用(MPA)的區別

前端路由是現代Web應用中的一種設計模式&#xff0c;它允許用戶在單個網頁應用程序&#xff08;SPA&#xff09;內部通過改變URL而無需重新加載整個頁面來切換不同的視圖或內容。在傳統的多頁應用&#xff08;MPA&#xff09;中&#xff0c;每訪問一個新頁面&#xff0c;瀏覽器…

搜索算法(算法競賽、藍橋杯)--雙向DFS+二分查找

1、B站視頻鏈接&#xff1a;B26 雙向DFS 送禮物_嗶哩嗶哩_bilibili #include <bits/stdc.h> using namespace std; int n,m; int g[46];//存儲所有物品的質量 int w[1<<23];//存儲所有能湊出來的重量 int ans,cnt;//w的個數是cnt//搜索第u個數&#xff0c;和為s; …

Geeker Admin添加若以分離版本的后臺作為后臺

添加驗證碼 下載若依賴前后端分離版本&#xff0c;配置好自己數據庫&#xff0c;redis連接地址 登錄添加驗證碼 配置自己的若依后端連接地址 添加驗證碼請求方法 登錄頁面登錄輸入框添加驗證碼&#xff0c;uuid,調用的驗證碼刷新方法 注意&#xff1a;這里要用響應式定義驗證…

5_怎么看原理圖之協議類接口之NAND Flash筆記

NAND Flash原理圖&#xff1a; 由NAND Flash的原理圖可以看出&#xff0c;做為一個存儲芯片&#xff0c;只有I/O引腳&#xff0c;并沒有地址引腳&#xff0c;怎么傳地址&#xff1f;遵循一定的規范&#xff0c;先通過LDATA把地址傳出去&#xff0c;再傳數據。具體的需要查看芯片…

vue前端數據轉換顯示

<el-table-column label"項目模板名稱" align"center" prop"tempName" width"180" :formatter"templFormat" /> :formatter"templFormat" // 模板名單 optionTempls: [], // datas value templFormat(row,…

HTTP Cookie 你了解多少?

Cookie是什么&#xff1f; 先給大家舉個例子&#xff0c;F12 打開瀏覽器的頁面之后&#xff0c;我們能在 Response Headers 的字段里面看到一個header 叫做 Set-Cookie&#xff0c;如下所示 圖中包含的 Set-Cookie 為 Set-Cookie:uuid_tt_dd10_20293537580-1709432565344-232…

Transformer模型分布式并行通信量淺析

1.數據并行DP&#xff08;樸素數據并行&#xff0c;Zero數據并行之后補充&#xff09; O ( h 2 ? l ) O(h^2*l) O(h2?l) 每臺機器做完自己的梯度后需要做一次All reduce操作來累積梯度&#xff0c;故一個batch計算發送的數據量為每層梯度大小 h 2 h^2 h2乘以層數 l l l 優點…

【李沐論文精讀】Resnet精讀

論文地址&#xff1a;Deep Residual Learning for Image Recognition 參考&#xff1a;撐起計算機視覺半邊天的ResNet【論文精讀】、ResNet論文逐段精讀【論文精讀】、【李沐論文精讀系列】 一、導論 深度神經網絡的優點&#xff1a;可以加很多層把網絡變得特別深&#xff0c;…

力扣周賽387

第一題 代碼 package Competition.The387Competitioin;public class Demo1 {public static void main(String[] args) {}public int[] resultArray(int[] nums) {int ans[]new int[nums.length];int arr1[]new int[nums.length];int arr2[]new int[nums.length];if(nums.leng…

Linux系統Docker部署RStudio Server

文章目錄 前言1. 安裝RStudio Server2. 本地訪問3. Linux 安裝cpolar4. 配置RStudio server公網訪問地址5. 公網遠程訪問RStudio6. 固定RStudio公網地址 前言 RStudio Server 使你能夠在 Linux 服務器上運行你所熟悉和喜愛的 RStudio IDE&#xff0c;并通過 Web 瀏覽器進行訪問…

第二十四章 :Docker 部署 SpringBoot

第二十四章 :Docker SpringBoot 配置文件容器外加載部署 Docker version 25.0.3, build 4debf41 ,Docker Compose version v2.24.2容器運行后,若需修改配置文件,只需修改宿主機的application-prod.yml ,重啟容器即可。 Springboot 2.x 版本 部署規劃 服務器IP192.168.92…

4. 編寫app組件

1. 代碼 main.ts // 引入createApp用于創建應用 import {createApp} from "vue"// 引入App根組件 import App from ./App.vue createApp(App).mount(#app) App.vue <!-- vue文件可以寫三種標簽1. template標簽&#xff0c;寫html結構2. script 腳本標簽&…

判斷docker 鏡像啟動成功 shell腳本

要編寫一個Shell腳本來判斷Docker鏡像是否啟動成功&#xff0c;你可以使用docker ps命令來檢查容器是否在運行狀態。以下是一個簡單的Shell腳本示例&#xff0c;用于判斷Docker鏡像是否成功啟動&#xff1a; #!/bin/bash# 指定要檢查的容器名稱或ID CONTAINER_NAME"your_c…

風險評估是什么意思?與等保測評有什么區別?

最近看到不少小伙伴在問&#xff0c;風險評估是什么意思&#xff1f;與等保測評有什么區別&#xff1f;這里我們就來簡單聊聊。 風險評估是什么意思&#xff1f; 風險評估是指對某個特定領域或項目進行全面分析和評估&#xff0c;以確定可能存在的潛在風險和危害&#xff0c;并…

2023全球軟件開發大會-上海站:探索技術前沿,共筑未來軟件生態(附大會核心PPT下載)

隨著信息技術的迅猛發展&#xff0c;全球軟件開發大會&#xff08;QCon&#xff09;已成為軟件行業最具影響力的年度盛會之一。2023年&#xff0c;QCon再次來到上海&#xff0c;匯聚了眾多業界精英、技術領袖和開發者&#xff0c;共同探討軟件開發的最新趨勢和實踐。 一、大會…

服務器感染了.ma1x0勒索病毒,如何確保數據文件完整恢復?

引言&#xff1a; 網絡安全成為至關重要的議題。.ma1x0勒索病毒是當前網絡威脅中的一種惡意軟件&#xff0c;它的出現給用戶帶來了極大的困擾。然而&#xff0c;正如任何挑戰一樣&#xff0c;我們也有方法來面對并克服.ma1x0勒索病毒。本文將全面介紹這種病毒的特點&#xff0…