RNN人名分類器案例

RNN人名分類器案例

1 任務目的:

目的: 給定一個人名,來判定這個人名屬于哪個國家
典型的文本分類任務: 18分類---多分類任務

2 數據格式

  • 注意:兩列數據,第一列是人名,第二列是國家類別,中間用制表符號"\t"隔開

Ang Chinese
AuYong? Chinese
Yuasa?? Japanese
Yuhara? Japanese
Yunokawa??? Japanese

3 任務實現流程

1. 獲取數據:案例中是直接給定的
2. 數據預處理: 臟數據清洗、數據格式轉換、數據源Dataset的構造、數據迭代器Dataloader的構造
3. 模型搭建: RNN、LSTM、GRU一系列模型
4. 模型訓練和評估(測試)
5. 模型上線---API接口(后續會講)

4 數據預處理

4.1讀取txt文檔數據

目的:

將文檔里面的數據讀取到內存中,實際上我們做了一個操作: 將人名存放到一個列表中,國家類別存放到一個列表中

代碼實現

def read_data(filename):# 1. 初始化兩個空列表my_list_x, my_list_y = [], []# 2. 讀取文件內容with open(filename,'r', encoding='utf-8') as fr:for line in fr.readlines():if len(line) <= 5:continue# strip()方法默認將字符串首尾兩端的空白去掉x, y = line.strip().split('\t')my_list_x.append(x)my_list_y.append(y)
?return my_list_x, my_list_y

4.2 構建自己的數據源DataSet

目的:

使用Pytorch框架,一般遵從一個規矩:使用DataSet方法構造數據源,來讓模型進行使用
構造數據源的過程中:必須繼承torch.utils.data.Dataset類,必須構造兩個魔法方法:__len__(), __getitem__()
__len__(): 一般返回的是樣本的總個數,我們可以直接len(dataset對象)直接就可以獲得結果
__getitem__(): 可以根據某個索引取出樣本值,我們可以直接用dataset對象[index]來直接獲得結果

代碼實現:

class NameClassDataset(Dataset):def __init__(self, mylist_x, mylist_y):self.mylist_x = mylist_xself.mylist_y = mylist_yself.sample_len = len(mylist_x)
?# 定義魔法方法lendef __len__(self):return self.sample_len
?# 定義魔法方法getitemdef __getitem__(self, index):# 1.index異常值處理index = min(max(index, 0), self.sample_len - 1)# 2. 根據index取出人名和國家名x = self.mylist_x[index]# print(f'x--->{x}')y = self.mylist_y[index]# print(f'y--->{y}')# 3.需要對人名進行one-hot編碼表示:這里的思路是:針對每個人名組成的單詞進行one-hot,然后再拼接tensor_x = torch.zeros(len(x), n_letter)# print(f'tensor_x-->{tensor_x}')for li, letter in enumerate(x):tensor_x[li][all_letters.find(letter)] = 1# 4.獲取標簽#  print(f'dataset內部的tensor_x--》{tensor_x.shape}')tensor_y = torch.tensor(categorys.index(y), dtype=torch.long)# print(f'dataset內部的tensor_y-->{tensor_y}')return tensor_x, tensor_y

4.3 構建數據迭代器Dataloader

目的:

為了將Dataset我們上一步構建的數據源,進行再次封裝,變成一個迭代器,可以進行for循環,而且,可以自動為我們dataset里面的數據進行增維(bath_size),也可以隨機打亂我們的取值順序

代碼實現:

filename = './data/name_classfication.txt'
my_list_x, my_list_y = read_data(filename)
mydataset = NameClassDataset(mylist_x=my_list_x, mylist_y=my_list_y)
my_dataloader = DataLoader(dataset=mydataset, batch_size=1, shuffle=True)

5 模型搭建

5.1 搭建RNN模型

  • 注意事項

RNN模型在實例化的時候,默認batch_first=False,因此,需要小心輸入數據的形狀
因為: dataloader返回的結果x---》shape--〉[batch_size, seq_len, input_size], 所以課堂上代碼和講義稍微有點不同,講義是默認的batch_first=False,而我們的代碼是batch_first=True,這樣做的目的,可以直接承接x的輸入。

  • 代碼實現

class MyRNN(nn.Module):def __init__(self, input_size, hidden_size, ouput_size, num_layers=1):super().__init__()# input_size 代表詞嵌入維度;self.input_size = input_size# hidden_size代表RNN隱藏層維度self.hidden_size = hidden_size# output_size代表:國家種類個數self.ouput_size = ouput_sizeself.num_layers = num_layers# 定義RNN網絡層# 和講義不一樣,我設定了batch_first=True,意味著rnn接受的input第一個參數是batch_sizeself.rnn = nn.RNN(self.input_size, self.hidden_size,num_layers=self.num_layers, batch_first=True)# 定義輸出網絡層self.linear = nn.Linear(self.hidden_size, self.ouput_size)
?# 定義softmax層self.softmax = nn.LogSoftmax(dim=-1)
?def forward(self, input, hidden):# input的shape---》[batch_size, seq_len, input_size] [1, 9, 57]# hidden的shape---》[num_layers, batch_size, hidden_size] [1,1,128]
?# 將input和hidden送入RNN模型得到結果rnn_output【1,9,128】,rnn_hn[1,1,128]rnn_output, rnn_hn = self.rnn(input, hidden)# print(f'rnn_output--》{rnn_output.shape}')# temp:[1, 128]tmep = rnn_output[0][-1].unsqueeze(0)# print(f'tmep--》{tmep.shape}')# 將臨時tmep:代表當前樣本最后一詞的隱藏層輸出結果[1, 18]output = self.linear(tmep)# print(f'output--》{output.shape}')# 經過softmaxreturn self.softmax(output), rnn_hn
?def inithidden(self):return torch.zeros(self.num_layers, 1, self.hidden_size)

RNN模型測試

def test_RNN():# 1.得到數據my_dataloader = get_dataloader()# 2.實例化模型input_size = n_letter # 57hidden_size = 128 # 自定設定RNN模型輸出結果維度output_size = len(categorys) # 18my_rnn = MyRNN(input_size, hidden_size, output_size)h0 = my_rnn.inithidden()# 3.將數據送入模型for i, (x, y) in enumerate(my_dataloader):print(f'x--->{x.shape}')output, hn = my_rnn(input=x, hidden=h0)print(f'output模型輸出結果-->{output.shape}')print(f'hn-->{hn.shape}')break

5.2 搭建LSTM模型

  • 注意事項

LSTM模型在實例化的時候,默認batch_first=False,因此,需要小心輸入數據的形狀 因為: dataloader返回的結果x---》shape--〉[batch_size, seq_len, input_size], 所以課堂上代碼和講義稍微有點不同,講義是默認的batch_first=False,而我們的代碼是batch_first=True,這樣做的目的,可以直接承接x的輸入。

  • 代碼實現

class MyLSTM(nn.Module):def __init__(self, input_size, hidden_size, ouput_size, num_layers=1):super().__init__()# input_size 代表詞嵌入維度;self.input_size = input_size# hidden_size代表RNN隱藏層維度self.hidden_size = hidden_size# output_size代表:國家種類個數self.ouput_size = ouput_sizeself.num_layers = num_layers# 定義LSTM網絡層# 和講義不一樣,我設定了batch_first=True,意味著rnn接受的input第一個參數是batch_sizeself.lstm = nn.LSTM(self.input_size, self.hidden_size,num_layers=self.num_layers, batch_first=True)# 定義輸出網絡層self.linear = nn.Linear(self.hidden_size, self.ouput_size)
?# 定義softmax層self.softmax = nn.LogSoftmax(dim=-1)
?def forward(self, input, hidden, c0):# input的shape---》[batch_size, seq_len, input_size] [1, 9, 57]# hidden的shape---》[num_layers, batch_size, hidden_size] [1,1,128]
?# 將input和hidden送入RNN模型得到結果rnn_output【1,9,128】,rnn_hn[1,1,128]lstm_output, (lstm_hn, lstm_cn) = self.lstm(input, (hidden, c0))# print(f'rnn_output--》{rnn_output.shape}')# temp:[1, 128]tmep = lstm_output[0][-1].unsqueeze(0)# print(f'tmep--》{tmep.shape}')# 將臨時tmep:代表當前樣本最后一詞的隱藏層輸出結果[1, 18]output = self.linear(tmep)# print(f'output--》{output.shape}')# 經過softmaxreturn self.softmax(output), lstm_hn, lstm_cn
?def inithidden(self):h0 = torch.zeros(self.num_layers, 1, self.hidden_size)c0 = torch.zeros(self.num_layers, 1, self.hidden_size)return h0, c0

LSTM測試

def test_LSTM():# 1.得到數據my_dataloader = get_dataloader()# 2.實例化模型input_size = n_letter # 57hidden_size = 128 # 自定設定LSTM模型輸出結果維度output_size = len(categorys) # 18my_lstm = MyLSTM(input_size, hidden_size, output_size)h0, c0 = my_lstm.inithidden()# 3.將數據送入模型for i, (x, y) in enumerate(my_dataloader):print(f'x--->{x.shape}')output, hn, cn = my_lstm(input=x, hidden=h0, c0=c0)print(f'output模型輸出結果-->{output.shape}')print(f'hn-->{hn.shape}')print(f'cn-->{cn.shape}')break

5.3 搭建GRU模型

  • 注意事項

GRU模型在實例化的時候,默認batch_first=False,因此,需要小心輸入數據的形狀 因為: dataloader返回的結果x---》shape--〉[batch_size, seq_len, input_size], 所以課堂上代碼和講義稍微有點不同,講義是默認的batch_first=False,而我們的代碼是batch_first=True,這樣做的目的,可以直接承接x的輸入。

  • 代碼實現

class MyGRU(nn.Module):def __init__(self, input_size, hidden_size, ouput_size, num_layers=1):super().__init__()# input_size 代表詞嵌入維度;self.input_size = input_size# hidden_size代表RNN隱藏層維度self.hidden_size = hidden_size# output_size代表:國家種類個數self.ouput_size = ouput_sizeself.num_layers = num_layers# 定義GRU網絡層# 和講義不一樣,我設定了batch_first=True,意味著rnn接受的input第一個參數是batch_sizeself.gru = nn.GRU(self.input_size, self.hidden_size,num_layers=self.num_layers, batch_first=True)# 定義輸出網絡層self.linear = nn.Linear(self.hidden_size, self.ouput_size)
?# 定義softmax層self.softmax = nn.LogSoftmax(dim=-1)
?def forward(self, input, hidden):# input的shape---》[batch_size, seq_len, input_size] [1, 9, 57]# hidden的shape---》[num_layers, batch_size, hidden_size] [1,1,128]
?# 將input和hidden送入RNN模型得到結果rnn_output【1,9,128】,rnn_hn[1,1,128]gru_output, gru_hn = self.gru(input, hidden)# print(f'rnn_output--》{rnn_output.shape}')# temp:[1, 128]tmep = gru_output[0][-1].unsqueeze(0)# print(f'tmep--》{tmep.shape}')# 將臨時tmep:代表當前樣本最后一詞的隱藏層輸出結果[1, 18]output = self.linear(tmep)# print(f'output--》{output.shape}')# 經過softmaxreturn self.softmax(output), gru_hn
?def inithidden(self):return torch.zeros(self.num_layers, 1, self.hidden_size)

GRU測試

def test_GRU():# 1.得到數據my_dataloader = get_dataloader()# 2.實例化模型input_size = n_letter # 57hidden_size = 128 # 自定設定RNN模型輸出結果維度output_size = len(categorys) # 18my_gru = MyGRU(input_size, hidden_size, output_size)# 2.1 初始化參數h0 = my_gru.inithidden()# 3.將數據送入模型for i, (x, y) in enumerate(my_dataloader):print(f'x--->{x.shape}')output, hn = my_gru(input=x, hidden=h0)print(f'output模型輸出結果-->{output.shape}')print(f'hn-->{hn.shape}')break

6 模型訓練

基本過程

1.獲取數據
2.構建數據源Dataset
3.構建數據迭代器Dataloader
4.加載自定義的模型
5.實例化損失函數對象
6.實例化優化器對象
7.定義打印日志參數
8.開始訓練
8.1 實現外層大循環epoch
(可以在這構建數據迭代器Dataloader)
8.2 內部遍歷數據迭代器dataloader
8.3 將數據送入模型得到輸出結果
8.4 計算損失
8.5 梯度清零: optimizer.zero_grad()
8.6 反向傳播: loss.backward()
8.7 參數更新(梯度更新): optimizer.step()
8.8 打印訓練日志
9. 保存模型: torch.save(model.state_dict(), "model_path")

6.1 RNN模型訓練代碼實現

my_lr = 1e-3
epochs = 1
# 訓練rnn模型
def train_rnn():# 讀取數據my_list_x, my_list_y = read_data(filepath='./data/name_classfication.txt')# 實例化dataset數據源對象my_dataset = NameClassDataset(my_list_x, my_list_y)# 實例化模型# n_letters=57, hidden_size=128,類別總數output_size=18my_rnn = My_RNN(input_size=57, hidden_size=128, output_size=18)# 實例化損失函數對象my_nll_loss = nn.NLLLoss()# 實例化優化器對象my_optim = optim.Adam(my_rnn.parameters(), lr=my_lr)# 定義打印日志的參數start_time = time.time()total_iter_num = 0 # 當前已經訓練的樣本總數total_loss = 0 ?# 已經訓練的損失值total_loss_list = [] # 每隔n個樣本,保存平均損失值total_acc_num = 0 # 預測正確的樣本個數total_acc_list = [] # 每隔n個樣本,保存平均準確率# 開始訓練for epoch_idx in range(epochs):# 實例化dataloadermy_dataloader = DataLoader(dataset=my_dataset, batch_size=1, shuffle=True)# 開始內部迭代數據,送入模型for i, (x, y) in enumerate(tqdm(my_dataloader)):# print(f'x--》{x.shape}')# print(f'y--》{y}')output, hn = my_rnn(input=x[0], hidden=my_rnn.inithidden())# print(f'output--》{output}') # [1, 18]# 計算損失my_loss = my_nll_loss(output, y)# print(f'my_loss--》{my_loss}')# print(f'my_loss--》{type(my_loss)}')
?# 梯度清零my_optim.zero_grad()# 反向傳播my_loss.backward()# 梯度更新my_optim.step()
?# 統計一下已經訓練樣本的總個數total_iter_num = total_iter_num + 1
?# 統計一下已經訓練樣本的總損失total_loss = total_loss + my_loss.item()
?# 統計已經訓練的樣本中預測正確的個數i_predict_num = 1 if torch.argmax(output).item() == y.item() else 0total_acc_num = total_acc_num + i_predict_num# 每隔100次訓練保存一下平均損失和準確率if total_iter_num % 100 == 0:avg_loss = total_loss / total_iter_numtotal_loss_list.append(avg_loss)
?avg_acc = total_acc_num / total_iter_numtotal_acc_list.append(avg_acc)# 每隔2000次訓練打印一下日志if total_iter_num % 2000 == 0:temp_loss = total_loss / total_iter_numtemp_acc = total_acc_num / total_iter_numtemp_time = time.time() - start_timeprint('輪次:%d, 損失:%.6f, 時間:%d,準確率:%.3f' %(epoch_idx+1, temp_loss, temp_time, temp_acc))torch.save(my_rnn.state_dict(), './save_model/ai20_rnn_%d.bin'%(epoch_idx+1))# 計算總時間total_time = int(time.time() - start_time)print('訓練總耗時:', total_time)# 將結果保存到文件中dict1 = {"avg_loss":total_loss_list,"all_time": total_time,"avg_acc": total_acc_list}with open('./save_results/ai_rnn.json', 'w') as fw:fw.write(json.dumps(dict1))
?return total_loss_list, total_time, total_acc_list

6.2 LSTM模型訓練代碼實現

基本原理同上

6.3 GRU模型訓練代碼

基本原理同上

7 模型預測

基本過程

1.獲取數據
2.數據預處理:將數據轉化one-hot編碼
3.實例化模型
4.加載模型訓練好的參數: model.load_state_dict(torch.load("model_path"))
5.with torch.no_grad():
6.將數據送入模型進行預測(注意:張量的形狀變換)

RNN模型預測代碼:

def line2tensor(x):# x-->"bai"tensor_x = torch.zeros(len(x), n_letters)# one-hot表示for li, letter in enumerate(x):tensor_x[li][letters.find(letter)] = 1
?return tensor_x
# 構造rnn預測函數
def rnn_predict(x):# 將數據x進行張量的轉換tensor_x = ?line2tensor(x)# 加載訓練好的模型my_rnn = My_RNN(input_size=57, hidden_size=128, output_size=18)my_rnn.load_state_dict(torch.load('./save_model/ai20_rnn_3.bin'))# 實現模型的預測with torch.no_grad():# 將數據送入模型output, hn = my_rnn(tensor_x, my_rnn.inithidden())print(f'output--》{output}')# 獲取output最大的前3個值# output.topk(3, 1, True)values, indexes = torch.topk(output, k=3, dim=-1, largest=True)print(f'values-->{values}')print(f'indexes-->{indexes}')for i in range(3):value = values[0][i]index = indexes[0][i]category = categorys[index]print(f'當前預測的值是:{value}, 國家類別是:{category}')

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

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

相關文章

鴻蒙HarmonyOS 關于圖片、視頻的選擇詳解

背景 在聊天軟件中&#xff0c;發送相冊中視頻和照片、用相機拍攝視頻和圖片發送是很常用的功能。在Android和iOS端&#xff0c;大部分應用都通過API方式定義UI來實現相冊選擇照片、視頻&#xff0c;相機拍攝照片、視頻&#xff0c;它們一般都支持以下功能&#xff1a; 相冊選…

iOS 網絡請求斷連重試失敗?抓包分析丟包原因的完整流程

在移動 App 的開發中&#xff0c;中斷網絡環境&#xff08;如切換到飛行模式再回網&#xff09;后&#xff0c;App 在重連過程中有時會出現請求未重新發送或丟包的情況。這類問題難重現、難定位&#xff0c;尤其在 iOS 平臺上更容易被忽視。我們最近就遇到一個用戶反饋“切換網…

使用 DHTMLX Gantt 添加迷你地圖:提升大型項目可視化與導航體驗

在應對數千個任務構成的大型項目時&#xff0c;DHTMLX Gantt 以其卓越的性能表現和流暢渲染能力廣受歡迎。然而&#xff0c;在實際使用中&#xff0c;終端用戶往往需要快速定位到時間線中的特定位置&#xff0c;這在面對龐雜任務結構時尤為困難。為此&#xff0c;DHTMLX 提供了…

ROM修改進階教程------用于自啟腳本來打開系統的一些常用開關等指令 備份收藏 【一】

在定制化rom中。有很多項目需要反編譯系統的相關應用來實現。但有些功能項完全可以使用指令來更改。那么結合自啟腳本就可以很方便的來實現很多功能。網絡雖然有很多類似的指令,但一些相關定制化項目的指令很少見而且不全面。此博文將全面收錄此類指令。方便rom修改用戶借鑒參…

騰訊云TSE注冊中心實戰:Nacos高可用集群搭建與流量治理避坑指南

1. 為什么選擇騰訊云TSE托管Nacos&#xff1f; 在微服務架構中&#xff0c;注冊中心承擔著服務發現與配置管理的核心職能。Nacos作為阿里開源的動態服務發現組件&#xff0c;已成為國內微服務生態的事實標準。騰訊云微服務引擎TSE&#xff08;Tencent Cloud Service Engine&am…

領域驅動設計(DDD)【26】之CQRS模式初探

文章目錄 一 CQRS初探&#xff1a;理解基本概念1.1 什么是CQRS&#xff1f;1.2 CQRS與CRUD的對比1.3 為什么需要CQRS&#xff1f; 二 CQRS深入&#xff1a;架構細節2.1 基本架構組成2.2 數據流示意圖 三 CQRS實戰&#xff1a;電商訂單案例3.1 傳統CRUD方式的訂單處理3.2 CQRS方…

項目測試-接口測試

軟件測試的分類 軟件測試主要分硬件和軟件 硬件測試: cpu,內存條,顯卡...測試可以看得見摸得著的東西 軟件測試: web,app,小程序... 測試可以看得見摸不著的東西 web端 web端是在電腦上常常使用的, 也可以稱之為網站.(web端是B/S架構) web端的客戶端是任何一個訪問這個網…

相機的光圈

光圈&#xff08;Aperture&#xff09;是鏡頭中一個控制光線進入相機的開口&#xff0c;它在攝影中起著至關重要的作用。光圈的大小決定了進入相機傳感器的光線數量&#xff0c;并影響曝光、景深、以及拍攝效果。光圈參數通常用f/值&#xff08;光圈值&#xff09;來表示&#…

HarmonyOS NEXT倉頡開發語言實戰案例:小而美的旅行App

大家周末好&#xff0c;本文分享一個小而美的旅行app首頁&#xff0c;效果圖如下&#xff1a; 很顯然這個頁面還是使用List容器&#xff0c;頁面兩側有統一的邊距&#xff0c;我們可以在List容器統一設置&#xff1a; List(space:20){ } .padding(left:14,right:14,top:62) .w…

Python銀行管理系統01升級(適合初學者)

目錄 框架如下: 1. Account類 - 賬戶數據模型 2. Bank類 - 銀行業務邏輯 3. BankApp類 - 圖形用戶界面 關鍵概念解析(適合初學者) 1. 面向對象編程(OOP)概念 2. Tkinter GUI編程基礎 3. 數據持久化 4. 輸入驗證 學習建議 系統功能概覽 完整代碼: 在Python銀行…

華為防火墻雙向NAT實驗

如圖所示&#xff0c; 企業內網有一臺Server2&#xff0c;通過在FW1上配置nat server&#xff0c;將Server2的www端口映射到了公網&#xff1b; 實驗環境中&#xff0c;內網和外網都使用外網的server1提供的DNS服務&#xff0c;在DNS服務器上添加A記錄&#xff0c;www.baidu.c…

前端路由的基石:深度剖析 Hash 與 History 模式的本質差異與實戰抉擇

在單頁面應用&#xff08;SPA&#xff09;統治現代Web開發的今天&#xff0c;前端路由已成為構建流暢用戶體驗的核心技術。而hash和history作為兩種主流實現方案&#xff0c;其設計理念和技術細節的差異直接影響著應用架構的選擇。本文將深入解析二者的技術本質&#xff0c;通過…

微機系統 - 緒論

緒論: 一:微處理器,微型計算機和微型計算機系統: 分類: 按照系統結構和基本工作原理.計算機分為5大部分:運算器,控制器,存儲器,輸入設備,輸出設備 按照體積,性能和價格分5類:巨型機,大型機,中型機,小型機,微型計算機(單板機,單片機) 微型計算機的特點:集成度高,體積小,重量輕…

基于Java+Springboot的寵物健康咨詢系統

源碼編號&#xff1a;S564 源碼名稱&#xff1a;基于Springboot的寵物健康咨詢系統 用戶類型&#xff1a;多角色&#xff0c;用戶、顧問、管理員 數據庫表數量&#xff1a;12 張表 主要技術&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven 運行環境&#xff1a;Win…

SpringBoot+MySQL寵物貓店管理系統

概述 基于SpringBootMySQL開發的寵物貓店管理系統完整源碼。該系統功能完善&#xff0c;包含前后臺完整功能模塊&#xff0c;代碼規范易于二次開發&#xff0c;是學習SpringBoot項目實戰的優秀范例。 主要內容 前臺功能展示 系統前臺設計簡潔實用&#xff0c;主要包含以下核…

UE5 - 制作《塞爾達傳說》中林克的技能 - 16 - 遙控炸彈(一)

讓我們繼續《塞爾達傳說》中林克技能的制作&#xff01;&#xff01;&#xff01; 本章節的核心目標&#xff1a;素材導入與遙控炸彈的外觀 先讓我們看一下完成后的效果&#xff1a; 基本流程&#xff1a;素材準備->C類開發->藍圖配置->場景部署 1.素材準備&#xff1…

HTTP中常見的Content-Type

Content-Type&#xff0c;也稱為互聯網媒體類型或MIME類型&#xff0c;是HTTP協議中的一個頭部字段&#xff0c;用于指定處理請求和響應中的媒體類型信息。它告訴服務器如何處理請求的數據&#xff0c;同時也指導客戶端&#xff08;通常是瀏覽器&#xff09;如何解析響應的數據…

Android11 wifi開啟源碼分析

目錄 一、APP層源碼分析 1.1、尋找頁面activity 1.2、尋找頁面開關按鈕布局 二&#xff0c;framework層代碼分析 2.1 開啟wifi入口 2.2 WiFiNative 三&#xff0c;HAL層代碼分析 這段時間擼了WIFI開啟流程源碼&#xff0c;本著前人栽樹后人乘涼的原則&#xff0c;有志于…

R語言使用nonrandom包進行傾向評分匹配

傾向評分匹配&#xff08;Propensity Score Matching&#xff0c;簡稱PSM&#xff09;是一種統計學方法&#xff0c;用于處理觀察研究&#xff08;Observational Study&#xff09;的數據&#xff0c;在SCI文章中應用非常廣泛。在觀察研究中&#xff0c;由于種種原因&#xff0…

LeetCode Hot 100 找到字符串中所有字母異位詞

給定兩個字符串 s 和 p&#xff0c;找到 s 中所有 p 的 異位詞 的子串&#xff0c;返回這些子串的起始索引。不考慮答案輸出的順序。 示例 1: 輸入: s "cbaebabacd", p "abc" 輸出: [0,6] 解釋: 起始索引等于 0 的子串是 "cba", 它是 "a…