日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pytorch argmax_一起无聊地用PyTorch刷爆sklearn的内置数据集吧(`?ω?′)

發(fā)布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pytorch argmax_一起无聊地用PyTorch刷爆sklearn的内置数据集吧(`?ω?′) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們都知道sklearn有一個datasets的子庫,里面有許多可以直接調(diào)取的小型數(shù)據(jù)集。我們可以通過PyTorch來在這些數(shù)據(jù)集上做訓(xùn)練和預(yù)測。

只是無聊。測試速度。如果你是一個剛剛上手pytorch的新手玩家,你也可以通過這個來刷刷題,練練手。

看看從數(shù)據(jù)集的調(diào)用,網(wǎng)絡(luò)的建立到訓(xùn)練評估你要花多長時間。
本文并沒有什么技術(shù)含量,只是單純?yōu)榱耸煜ぁD阃耆梢远酥槐Х冗吅冗吚肞yTorch消解“無聊”的weekend

波士頓房價預(yù)測

使用線性層在波士頓房價數(shù)據(jù)集上建立模型

先導(dǎo)入相關(guān)庫,因為數(shù)據(jù)量小,我們可以一次性學(xué)習(xí)一整個數(shù)據(jù)集,所以此處我們就不構(gòu)建數(shù)據(jù)加載器了。

from sklearn.datasets import load_bostonimport torch.nn as nnimport torchimport matplotlib.pyplot as pltimport pandas as pd?X, y = load_boston(return_X_y=True)# X.shape : (506, 13)# y.shape : (506,)# type : <class 'numpy.ndarray'>

然后構(gòu)建線性層類LR:

class LR(nn.Module):def __init__(self, input_dim, output_dim):super(LR, self).__init__()self.fc = nn.Sequential(nn.Linear(input_dim, 64),nn.Linear(64, 128),nn.Linear(128, 32),)?self.regression = nn.Linear(32, 1)?def forward(self, x):out = self.fc(x)out = self.regression(out)return out

接下來,記得把輸入數(shù)據(jù)轉(zhuǎn)換成tensor,并獲取訓(xùn)練需要的對象:

# 數(shù)據(jù)類型轉(zhuǎn)換X_t = torch.tensor(X, dtype=torch.float32)y_t = torch.tensor(y, dtype=torch.float32)?# 網(wǎng)絡(luò)實例化net = LR(input_dim=13, output_dim=1)# 獲取損失函數(shù)loss_func = nn.MSELoss()# 獲取優(yōu)化器對象optimizer = torch.optim.Adam(net.parameters(), lr=0.0001)?loss_all = []

最后訓(xùn)練網(wǎng)絡(luò),并做數(shù)據(jù)可視化:

# 開始訓(xùn)練for epoch in range(25):# 前向傳播output = net(X_t)# 計算損失loss = loss_func(output.flatten(), y_t.flatten())# 梯度清空optimizer.zero_grad()# 反向傳播loss.backward()# 更新網(wǎng)絡(luò)optimizer.step()?loss_all.append(loss.item())?data = pd.DataFrame({"loss" : loss_all}, columns=["loss"])data["loss"].plot(x="iteration", y="loss")plt.show()

out:


手寫數(shù)字集識別

手寫數(shù)字集,這個你可以認為是小型的MNIST,MNIST是28*28的,而sklearn中提供的是8*8,而且給了1797條,用來玩夠了。

我會無聊地使用線性層,卷積層,循環(huán)層分別搭建網(wǎng)絡(luò)來預(yù)測這個小型手寫數(shù)字集。

先導(dǎo)入需要使用的手寫數(shù)字集,并觀察形狀:

from sklearn.datasets import load_digitsfrom sklearn.metrics import accuracy_scoreimport matplotlib.pyplot as pltimport numpy as npimport pandas as pdimport torch.nn as nnimport torchimport torch.utils.data as Datafrom random import shuffle?X, y = load_digits(return_X_y=True)# X.shape:(1797, 64)# y.shape:(1797,)# type : <class 'numpy.ndarray'>?# 構(gòu)建數(shù)據(jù)加載器?img = X[0].reshape([8, 8])plt.imshow(img, cmap=plt.cm.gray)plt.show()

out:

定義數(shù)據(jù)加載器:

# 原數(shù)據(jù)可能會把相近的類別放在一起,所以分割數(shù)據(jù)前最好要打亂choose_index = np.arange(X.shape[0])shuffle(choose_index)?# 轉(zhuǎn)換為tensorX_t = torch.tensor(X, dtype=torch.float32)y_t = torch.tensor(y, dtype=torch.int64)?# 將數(shù)據(jù)和標簽整合在一起train_data = Data.TensorDataset(X_t[choose_index[:1300]],y_t[choose_index[:1300]])test_data = Data.TensorDataset(X_t[choose_index[1300:]],y_t[choose_index[1300:]])?# 構(gòu)建數(shù)據(jù)加載器train_loader = Data.DataLoader(dataset=train_data,batch_size=64,shuffle=True,num_workers=0)?test_loader = Data.DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0)

我們測試一下loader,并可視化一個batch中的第一張圖片及其對應(yīng)的標簽,看看loader是否正常工作:

for batch in train_loader:img = batch[0][1]label = batch[1][1]?img = img.data.numpy().reshape([8,8])plt.imshow(img, cmap=plt.cm.gray)plt.title(f"label={label}")breakplt.show()

out:

下面嘗試使用線性算子、卷積算子,循環(huán)神經(jīng)網(wǎng)絡(luò)來建立模型

線性層的效果

先使用線性層預(yù)測,首先定義網(wǎng)絡(luò):

# 定義網(wǎng)絡(luò)class LinearLayerClassifier(nn.Module):def __init__(self, input_dim, output_dim):super(LinearLayerClassifier, self).__init__()self.linear_layer = nn.Sequential(nn.Linear(input_dim, 128),nn.Tanh(),nn.Linear(128, 256),nn.Tanh(),nn.Linear(256, 128),nn.Tanh(),nn.Linear(128, 64),nn.Tanh(),)?self.output = nn.Sequential(nn.Linear(64, output_dim),nn.Tanh(),)?def forward(self, x):out = self.linear_layer(x)out = self.output(out)# 最后對結(jié)果softmax一下softmax_result = nn.functional.softmax(out, dim=1)return softmax_result

然后獲取訓(xùn)練需要的對象:

# 網(wǎng)絡(luò)實例化net = LinearLayerClassifier(input_dim=64, output_dim=10)# 獲取優(yōu)化器optimizer = torch.optim.RMSprop(net.parameters(), lr=0.001)# 獲取損失函數(shù)loss_func = nn.CrossEntropyLoss(reduction="mean")# 記錄損失train_loss, train_acc = [], []test_loss, test_acc = [], []

訓(xùn)練并做數(shù)據(jù)可視化:

# 開始訓(xùn)練for epoch in range(8):# 遍歷生成器net.train()epoch_loss, epoch_acc = [], [] # 記錄當(dāng)前epoch的loss和accuracyfor batch in train_loader:data, label = batch# 前向傳播output = net(data)# 預(yù)測標簽predict_label = torch.argmax(output, dim=1)# 計算損失loss = loss_func(output, label)# 梯度清空optimizer.zero_grad()# 反向傳播loss.backward()# 更新參數(shù)optimizer.step()?# 記錄訓(xùn)練結(jié)果epoch_loss.append(loss.item())epoch_acc.append(accuracy_score(predict_label, label))?train_loss.append(np.mean(epoch_loss))train_acc.append(np.mean(epoch_acc))?# 遍歷測試集net.eval()epoch_loss, epoch_acc = [], []for batch in test_loader:data, label = batchoutput = net(data)predict_label = torch.argmax(output, dim=1)loss = loss_func(output, label)epoch_loss.append(loss.item())epoch_acc.append(accuracy_score(predict_label, label))?test_loss.append(np.mean(epoch_loss))test_acc.append(np.mean(epoch_acc))?# 可視化數(shù)據(jù)label_name = ["train_loss", "test_loss", "train_acc", "test_acc"]for index, name in enumerate([train_loss, test_loss, train_acc, test_acc]):plt.plot(name, "o-", label=label_name[index])?plt.legend()plt.grid(True)plt.show()

out:

模型最終收斂了,但是顯然很不穩(wěn)定

CNN算子的效果

由于卷積和后續(xù)的循環(huán)神經(jīng)網(wǎng)絡(luò)都需要基于各自類型的數(shù)據(jù)維度,CNN的基本輸入數(shù)據(jù)維度為[B, C, H, W],RNN的基本輸入維度為[B, time_step, embedding_dim]。所以我們需要重構(gòu)數(shù)據(jù)加載器。其實重構(gòu)很簡單,我們只要修改X的維度即可:

X, y = load_digits(return_X_y=True)# X.shape:(1797, 64)# y.shape:(1797,)# type : <class 'numpy.ndarray'>?X = [x.reshape([1, 8, 8]).tolist() for x in X]?# 原數(shù)據(jù)可能會把相近的類別放在一起,所以分割數(shù)據(jù)前最好要打亂choose_index = np.arange(1797)shuffle(choose_index)?# 轉(zhuǎn)換成tensorX_t = torch.tensor(X, dtype=torch.float32)y_t = torch.tensor(y, dtype=torch.int64)?# 將數(shù)據(jù)和標簽整合在一起train_data = Data.TensorDataset(X_t[choose_index[:1300]], y_t[choose_index[:1300]])test_data = Data.TensorDataset(X_t[choose_index[1300:]], y_t[choose_index[1300:]])?# 構(gòu)建數(shù)據(jù)加載器train_loader = Data.DataLoader(dataset=train_data,batch_size=64,shuffle=True,num_workers=0)?test_loader = Data.DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0)其實上面只改了一行代碼(第六行)

接下來搭建網(wǎng)絡(luò)類:

# 定義網(wǎng)絡(luò)class CNNClassifier(nn.Module):def __init__(self, input_channels, output_dim):super(CNNClassifier, self).__init__()self.conv = nn.Sequential(nn.Conv2d(in_channels=input_channels,out_channels=16,kernel_size=3,stride=1,padding=1), # [B, 16, 8, 8]nn.Tanh(),nn.Conv2d(16, 32, 3, 2, 1), # [B, 32, 4, 4]nn.Tanh(),nn.Conv2d(32, 16, 3, 2, 1), # [B, 16, 2, 2]nn.Tanh(),nn.Conv2d(16, 8, 3, 1, 1) # [B, 8, 2, 2])?self.output = nn.Linear(32, 10)?def forward(self, x):out = self.conv(x)# out : [B, 8, 2, 2]out = self.output(out.flatten(start_dim=1))out = nn.functional.softmax(out, dim=1)return out

接下來的訓(xùn)練和各種對象的獲取和上面線性算子的過程一致,除了網(wǎng)絡(luò)實例化:

# 網(wǎng)絡(luò)實例化net = CNNClassifier(input_channels=1, output_dim=10)

out:

效果看起來沒有線性算子好,因為處理的圖片還是很小的且通道數(shù)只有一,等到處理的圖片較大,且有多個顏色通道時,卷積算子的優(yōu)勢就會體現(xiàn)得比較明顯了。

RNN算子的效果

此處的RNN的cell就使用GRU算子。首先還是修改數(shù)據(jù)輸入維度,和CNN相比,RNN的數(shù)據(jù)維度少了通道這一維,所以我們在數(shù)據(jù)加載器這一步,我們只要改一步:

X = [x.reshape([8, 8]).tolist() for x in X]

定義RNN網(wǎng)絡(luò),我們使用GRU算子:

# 定義網(wǎng)絡(luò)class RNNClassifier(nn.Module):def __init__(self, input_size, hidden_size, n_layers=1):super(RNNClassifier, self).__init__()self.gru = nn.GRU(input_size=input_size,hidden_size=hidden_size,num_layers=n_layers,batch_first=True)self.output = nn.Linear(hidden_size, 10)?def forward(self, embedding):# embedding : [B, 8, 8]outputs, hidden = self.gru(embedding)# outputs : [B, 8, 32]# hidden : [1, B, 32]out = outputs[:,-1,:]out = self.output(out).softmax(dim=1)return out

然后最后的還是和上面一樣,除了網(wǎng)絡(luò)實例化:

# 網(wǎng)絡(luò)實例化net = RNNClassifier(input_size=8, hidden_size=64)

out:


鳶尾花數(shù)據(jù)集分類

該數(shù)據(jù)集為三分類數(shù)據(jù)集。每條數(shù)據(jù)有4個特征。

先導(dǎo)入需要的庫,并導(dǎo)入數(shù)據(jù)集:

import torchfrom torch import nnfrom sklearn.datasets import load_irisfrom sklearn.metrics import accuracy_score, classification_reportimport numpy as npimport matplotlib.pyplot as plt?X, y = load_iris(return_X_y=True)# X.shape = (150,4)# y.shape = (150,)sample_num = X.shape[0]

由于原本的數(shù)據(jù)集中標簽相同的數(shù)據(jù)是放在一起的,所以我們在使用前需要先打亂數(shù)據(jù):

# 分割獲取訓(xùn)練集和測試集index = np.arange(sample_num)np.random.shuffle(index)split_ratio = 0.8 # 訓(xùn)練集的比例offline = int(split_ratio * sample_num) # 劃分的索引界線# 訓(xùn)練集train_X = torch.tensor(X[index[:offline]], dtype=torch.float32)train_y = torch.tensor(y[index[:offline]], dtype=torch.int64)# 測試集test_X = torch.tensor(X[index[offline:]], dtype=torch.float32)test_y = torch.tensor(y[index[offline:]], dtype=torch.int64)

然后定義我們的網(wǎng)絡(luò),此時還是使用簡單的MLP:

# 定義網(wǎng)絡(luò)class MyNet(nn.Module):def __init__(self):super(MyNet, self).__init__()self.fc = nn.Sequential(nn.Linear(4, 32),nn.ReLU(),nn.Linear(32, 64),nn.ReLU(),nn.Linear(64, 3),nn.Tanh())?def forward(self, x):out = self.fc(x)return out.softmax(dim=1)

接下來我們實例化網(wǎng)絡(luò)并獲取訓(xùn)練需要的損失函數(shù)與優(yōu)化器對象,繼而開始訓(xùn)練。由于數(shù)據(jù)量很小,所以我們直接一次性使用整個訓(xùn)練集做前饋:

# 網(wǎng)絡(luò)實例化net = MyNet()# 獲取損失函數(shù)和優(yōu)化器loss_func = nn.CrossEntropyLoss()optimizer = torch.optim.RMSprop(net.parameters(), lr=1e-3)?losses = []acc = []?# 開始訓(xùn)練net.train()for epoch in range(20):# 前向傳播output = net(train_X)# 計算預(yù)測標簽值pre_label = torch.argmax(output, dim=1)# 計算損失loss = loss_func(output, train_y)# 梯度清空optimizer.zero_grad()# 反向傳播loss.backward()# 更新參數(shù)optimizer.step()# 記錄訓(xùn)練過程losses.append(loss.item())acc.append(accuracy_score(pre_label, train_y))?# 可視化訓(xùn)練過程plt.style.use("seaborn")plt.plot(losses, label="loss")plt.plot(acc, label="acc")plt.legend()plt.show()

out:

out:

precision recall f1-score support?0 1.00 1.00 1.00 121 1.00 1.00 1.00 112 1.00 1.00 1.00 7?micro avg 1.00 1.00 1.00 30macro avg 1.00 1.00 1.00 30weighted avg 1.00 1.00 1.00 30由于數(shù)據(jù)量太小了,所以訓(xùn)練結(jié)果會因為隨機化分割數(shù)據(jù)集的結(jié)果而有較大的區(qū)別

癌癥數(shù)據(jù)集分類

該數(shù)據(jù)集任務(wù)為二分類,輸出是否為癌癥患者。該數(shù)據(jù)的每條有30個特征。

引入庫和數(shù)據(jù)集:

from sklearn.datasets import load_breast_cancerfrom sklearn.metrics import accuracy_score, classification_reportimport torchfrom torch import nnimport matplotlib.pyplot as pltimport numpy as np?X, y = load_breast_cancer(return_X_y=True)# X.shape = (569, 30)# y.shape = (569, )

將數(shù)據(jù)轉(zhuǎn)化為tensor,并打亂,切分:

index = np.arange(X.shape[0])np.random.shuffle(index)?X_t = torch.tensor(X, dtype=torch.float32)y_t = torch.tensor(y, dtype=torch.int64)?train_X, train_y = X_t[index[:500]], y_t[index[:500]]test_X, test_y = X_t[index[500:]], y_t[index[500:]]

分類器網(wǎng)絡(luò)定義成一個簡單的MLP:

class cancerClassifier(nn.Module):def __init__(self, input_dim, output_dim):super(cancerClassifier, self).__init__()self.fc = nn.Sequential(nn.Linear(input_dim, 64),nn.ReLU(),nn.Linear(64, 128),nn.ReLU(),nn.Linear(128, 64),nn.ReLU(),nn.Linear(64, 32),nn.ReLU(),nn.Linear(32, 16),nn.ReLU(),nn.Linear(16, 8),nn.ReLU(),nn.Linear(8, 2),nn.Tanh())?def forward(self, x):out = self.fc(x)return out.softmax(dim=1)

實例化網(wǎng)絡(luò)、獲取優(yōu)化器、訓(xùn)練、可視化、測試網(wǎng)絡(luò):

# 網(wǎng)絡(luò)實例化net = cancerClassifier(input_dim=30,output_dim=2)?# 獲取優(yōu)化器optimizer = torch.optim.RMSprop(net.parameters(), lr=1e-4)?train_loss, train_acc = [], []?for epoch in range(20):output = net(train_X)pre_label = torch.argmax(output, dim=1)loss = nn.functional.cross_entropy(output, train_y, reduction="mean")optimizer.zero_grad()loss.backward()optimizer.step()?train_loss.append(loss.item())train_acc.append(accuracy_score(pre_label, train_y))?plt.style.use("seaborn")plt.plot(train_loss, label="loss")plt.plot(train_acc, label="acc")plt.legend()plt.show()?# 在測試集上檢測結(jié)果net.eval()output = net(test_X)pre_label = torch.argmax(output, dim=1)print(classification_report(pre_label, test_y))

out:

這個模型好像很不穩(wěn)定,隨著初始數(shù)據(jù)隨機劃分的結(jié)果不同,網(wǎng)絡(luò)acc有時會收斂到65%,有時會收斂到90%,若有更好的網(wǎng)絡(luò)方案,歡迎在評論區(qū)提出。

to be continued...

總結(jié)

以上是生活随笔為你收集整理的pytorch argmax_一起无聊地用PyTorch刷爆sklearn的内置数据集吧(`?ω?′)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。