Linear Regression、Logistic Regression、激励函数activation function(relu,sigmoid, tanh, softplus)
1.5.2.Linear Regression
1.5.2.1.Linear Regression
1.5.2.1.1.案例1
1.5.2.1.2.案例2
1.5.2.1.3.案例3源碼(帶有保存模型)
1.5.2.2.Logistic Regression
1.5.2.2.1.案例1
1.5.2.2.2.更深更寬的網(wǎng)絡(luò)
1.5.2.2.3.邏輯回歸案例
1.5.2.3.Classification
1.5.2.4.激勵函數(shù)activation function(relu,sigmoid, tanh, softplus)
1.5.2.Linear Regression
以下轉(zhuǎn)自:
https://blog.csdn.net/caichao08/article/details/78993893 https://blog.csdn.net/weixin_42587745/article/details/90346126 https://ptorch.com/news/6.html https://www.jb51.net/article/140557.htm1.5.2.1.Linear Regression
對于線性回歸,即給出一系列的點,找一條直線,使得這條直線與這些點的距離之和最小。
上圖就簡單地描繪出了線性回歸的基本原理,接下來我們來重點講講如何用pytorch寫一個簡單的線性回歸。
接下來,使用torch.from_numpy()和numpy函數(shù)即可進(jìn)行相互轉(zhuǎn)換:
x = torch.from_numpy(x) y = torch.from_numpy(y)1.5.2.1.1.案例1
使用PyTorch定義線性回歸模型一般分以下幾步:
1.設(shè)計網(wǎng)絡(luò)架構(gòu)
2.構(gòu)建損失函數(shù)(loss)和優(yōu)化器(optimizer)
3.訓(xùn)練(包括前饋(forward)、反向傳播(backward)、更新模型參數(shù)(update))
迭代十次打印結(jié)果:
0 次循環(huán): 128.36353 1 次循環(huán): 57.22348 2 次循環(huán): 25.55281 3 次循環(huán): 11.452799 4 次循環(huán): 5.1747613 5 次循環(huán): 2.3788614 6 次循環(huán): 1.1331253 7 次循環(huán): 0.57749355 8 次循環(huán): 0.32909214 9 次循環(huán): 0.2174757loss還在繼續(xù)下降,此時輸入4得到的結(jié)果還不是預(yù)測的很準(zhǔn) 當(dāng)?shù)螖?shù)設(shè)置為50時:10 次循環(huán): 0.16676745 11 次循環(huán): 0.14318845 12 次循環(huán): 0.13170049 13 次循環(huán): 0.12560984 14 次循環(huán): 0.12193605 15 次循環(huán): 0.11935152 16 次循環(huán): 0.117265806 17 次循環(huán): 0.11541578 18 次循環(huán): 0.11368369 19 次循環(huán): 0.11201717 20 次循環(huán): 0.11039279 21 次循環(huán): 0.108799875 22 次循環(huán): 0.10723348 23 次循環(huán): 0.105691046 24 次循環(huán): 0.10417137 25 次循環(huán): 0.10267406 26 次循環(huán): 0.10119824 27 次循環(huán): 0.09974393 28 次循環(huán): 0.09831043 29 次循環(huán): 0.0968976 30 次循環(huán): 0.09550497 31 次循環(huán): 0.09413239 32 次循環(huán): 0.09277948 33 次循環(huán): 0.09144618 34 次循環(huán): 0.0901321 35 次循環(huán): 0.08883653 36 次循環(huán): 0.08755979 37 次循環(huán): 0.08630159 38 次循環(huán): 0.085061245 39 次循環(huán): 0.08383879 40 次循環(huán): 0.082633875 41 次循環(huán): 0.08144614 42 次循環(huán): 0.08027585 43 次循環(huán): 0.07912208 44 次循環(huán): 0.07798502 45 次循環(huán): 0.07686419 46 次循環(huán): 0.07575947 47 次循環(huán): 0.07467067 48 次循環(huán): 0.073597685 49 次循環(huán): 0.07253992 predict (after training) 4 [[7.690391]]此時,函數(shù)已經(jīng)擬合比較好了
torch.nn.Linear(1,1),只需要知道輸入和輸出維度,里面的參數(shù)矩陣是隨機(jī)初始化的(具體是不是隨機(jī)的還是按照一定約束條件初始化的我不確定),所有每次計算loss會下降到不同的位置(模型的參數(shù)更新從而也不同),導(dǎo)致結(jié)果不一樣。
1.5.2.1.2.案例2
以下轉(zhuǎn)自:https://blog.csdn.net/caichao08/article/details/78993893
首先第一步是產(chǎn)生訓(xùn)練的數(shù)據(jù),這里我們采用scikit工具箱來完成。
# -*- coding: UTF-8 -*-import numpy as np import matplotlib.pyplot as plt from sklearn.datasets.samples_generator import make_regression import torch import torch.nn as nn from torch.autograd import Variable# n_samples表示樣本數(shù)量, n_features表示輸入?yún)?shù)個數(shù), noise代表噪聲, coef選擇是否輸出系數(shù) # 當(dāng)n_features = 1 時,可以進(jìn)行可視化 X, y, coef =make_regression(n_samples=1000, n_features=1,noise=10, coef=True) plt.scatter(X, y, color='green') plt.plot(X, X*coef, color='red',linewidth=3) plt.xticks(()) plt.yticks(()) plt.show()print(coef) print(np.shape(X)) print(np.shape(y))輸出結(jié)果:
84.20925934904598 (1000, 1) (1000,)下一步是建立一個模型
# 首先將數(shù)據(jù)轉(zhuǎn)換成tensor變量 # 上面的make_regression產(chǎn)生的是double型數(shù)據(jù), 直接導(dǎo)入到tensor里面會跑不通, 這里把它們轉(zhuǎn)成float32型的變量 X = X.astype('float32') y = y.astype('float32')print(np.size(X)) print(np.shape(X)) print(np.shape(y))# 下面的這一步非常的關(guān)鍵, pytorch里面只支持(n, 1)這種類型的matric,而不支持這種(n,)類似的scaler或vector類型的變量 y = np.reshape(y, (np.size(X), 1)) # 下面是將numpy轉(zhuǎn)換成Tensor,使用torch.from_numpy()和numpy函數(shù)即可進(jìn)行相互轉(zhuǎn)換 train_x = torch.from_numpy(X) train_y = torch.from_numpy(y)# 再定義一個模型,一般用類的形式來產(chǎn)生 # 這里的nn.Module是被繼承了,nn.Module里面包含了很多需要的模塊 class linear_regression(nn.Module):"""linear regression module"""def __init__(self):super(linear_regression, self).__init__()# 定義Linear 函數(shù)只有一個輸入一個輸出,這里的nn.Linear表示的是 y=w*x+b,里面的兩個參數(shù)都是1,表示的是x是1維,y也是1維。self.linear = nn.Linear(1, 1)def forward(self, x):out = self.linear(x)return outmodel = linear_regression() print(model) print(train_x.size()) print(train_y.size()) print(type(train_x))輸出結(jié)果:
1000 (1000, 1) (1000,) linear_regression((linear): Linear(in_features=1, out_features=1, bias=True) ) torch.Size([1000, 1]) torch.Size([1000, 1]) <class 'torch.Tensor'>接著對模型的未知參數(shù)進(jìn)行求解
# 緊接著需要定義loss和optimize了 # 利用最小二乘來定義損失 # 學(xué)習(xí)率,當(dāng)學(xué)習(xí)率很小的時候,得循環(huán)很多次才能得到比較好的結(jié)果,如果是le-3,下面的num_epoch得1900次差不多才能得到比較好的效果 learning_rate = 1e-2 # 這里使用的是最小二乘loss,之后我們做分類問題更多的使用的是cross entropy loss,交叉熵。優(yōu)化函數(shù)使用的是隨機(jī)梯度下降,注意需要將model的參數(shù)model.parameters()傳進(jìn)去讓這個函數(shù)知道他要優(yōu)化的參數(shù)是哪些。 criterion = nn.MSELoss() optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)# SGD的第一參數(shù)傳入的是模型要優(yōu)化的參數(shù), 第二個表示的是學(xué)習(xí)率 # 開始訓(xùn)練 num_epoch = 200for epoch in range(num_epoch):# 將數(shù)據(jù)轉(zhuǎn)換成tensor變量,這樣可以自動求導(dǎo)inputs = Variable(train_x)targets = Variable(train_y)# # 前向 + 后向 + 優(yōu)化optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, targets)loss.backward()optimizer.step()if (epoch+1) % 20 == 0:print("loss:" + {loss.item()})#print(f'Epoch[{epoch+1}/{num_epochs}], loss: {loss.item():.6f}')只要learning_rate選的好,這里基本上一步就能得出正確結(jié)果了
再看看預(yù)測的結(jié)果
# 下面來用數(shù)據(jù)做預(yù)測 # 特別注意的是需要用model.eval(),讓model變成測試模式,這主要是對dropout和batch, normalization的操作在訓(xùn)練和測試的時候是不一樣的。 model.eval() # model只支持tensor類型的變量, 所以對model的輸入要進(jìn)行轉(zhuǎn)換, 而畫圖則要轉(zhuǎn)化成numpy類型 predicts = model(Variable(train_x)).data.numpy() plt.figure() plt.plot(X, y, 'go', label=u'original data') plt.plot(X, coef*X, 'b', label=u'ground truth') plt.plot(X, predicts, 'r', label=u'predicted data') plt.legend() plt.show()從下面的結(jié)果圖上來看還是很準(zhǔn)的
1.5.2.1.3.案例3源碼(帶有保存模型)
# -*- coding: UTF-8 -*-import matplotlib.pyplot as plt import numpy as np import torch from torch import nn from torch.autograd import Variablex_train = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168],[9.779], [6.182], [7.59], [2.167], [7.042],[10.791], [5.313], [7.997], [3.1]], dtype=np.float32)y_train = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573],[3.366], [2.596], [2.53], [1.221], [2.827],[3.465], [1.65], [2.904], [1.3]], dtype=np.float32)x_train = torch.from_numpy(x_train)y_train = torch.from_numpy(y_train)# Linear Regression Model class linearRegression(nn.Module):def __init__(self):super(linearRegression, self).__init__()self.linear = nn.Linear(1, 1) # input and output is 1 dimensiondef forward(self, x):out = self.linear(x)return outmodel = linearRegression() # 定義loss和優(yōu)化函數(shù) criterion = nn.MSELoss() optimizer = torch.optim.SGD(model.parameters(), lr=1e-4)# 開始訓(xùn)練 num_epochs = 2000 for epoch in range(num_epochs):inputs = x_traintarget = y_train# forwardout = model(inputs)loss = criterion(out, target)# backwardoptimizer.zero_grad()loss.backward()optimizer.step()if (epoch+1) % 20 == 0:print(f'Epoch[{epoch+1}/{num_epochs}], loss: {loss.item():.6f}')model.eval() with torch.no_grad():predict = model(x_train) predict = predict.data.numpy()fig = plt.figure(figsize=(10, 5)) plt.plot(x_train.numpy(), y_train.numpy(), 'ro', label='Original data') plt.plot(x_train.numpy(), predict, label='Fitting Line') # 顯示圖例 plt.legend() plt.show()# 保存模型 torch.save(model.state_dict(), './linear.pth')運(yùn)行結(jié)果:
Epoch[20/2000], loss: 16.022251 Epoch[40/2000], loss: 11.373667 Epoch[60/2000], loss: 8.088304 Epoch[80/2000], loss: 5.766390 Epoch[100/2000], loss: 4.125387 Epoch[120/2000], loss: 2.965617 Epoch[140/2000], loss: 2.145954 Epoch[160/2000], loss: 1.566661 Epoch[180/2000], loss: 1.157250 Epoch[200/2000], loss: 0.867900 Epoch[220/2000], loss: 0.663402 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Epoch[1960/2000], loss: 0.170428 Epoch[1980/2000], loss: 0.170426 Epoch[2000/2000], loss: 0.1704251.5.2.2.Logistic Regression
以下參考:https://www.jb51.net/article/140557.htm
http://blog.csdn.net/m0_37306360
線性回歸是解決回歸問題的,邏輯回歸和線性回歸很像,但是它是解決分類問題的(一般二分類問題:0 or 1)。也可以多分類問題(用softmax可以實現(xiàn))。
使用pytorch實現(xiàn)邏輯回歸的基本過程和線性回歸差不多,但是有以下幾個區(qū)別:
以下為sigmoid函數(shù):
在邏輯回歸中,我們預(yù)測如果當(dāng)輸出大于0.5時,y=1;否則y=0。
損失函數(shù)一般采用交叉熵loss:
1.5.2.2.1.案例1
import torch from torch.autograd import Variablex_data = Variable(torch.Tensor([[0.6], [1.0], [3.5], [4.0]])) y_data = Variable(torch.Tensor([[0.], [0.], [1.], [1.]]))class Model(torch.nn.Module):def __init__(self):super(Model, self).__init__()self.linear = torch.nn.Linear(1, 1) # One in one outself.sigmoid = torch.nn.Sigmoid()def forward(self, x):y_pred = self.sigmoid(self.linear(x))return y_pred# Our model model = Model()# Construct loss function and optimizer criterion = torch.nn.BCELoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.01)# Training loop for epoch in range(500):# Forward passy_pred = model(x_data)# Compute lossloss = criterion(y_pred, y_data)if epoch % 20 == 0:print(loss.data.numpy())# Zero gradientsoptimizer.zero_grad()# Backward passloss.backward()# update weightsoptimizer.step()# After training hour_var = Variable(torch.Tensor([[0.5]])) print("predict (after training)", 0.5, model.forward(hour_var).data[0][0]) hour_var = Variable(torch.Tensor([[7.0]])) print("predict (after training)", 7.0, model.forward(hour_var).data[0][0])輸出結(jié)果為:
2.1419365 1.5513724 1.0856804 0.7997792 0.6584054 0.59043765 0.55404615 0.53147745 0.5154158 0.50267094 0.49175227 0.4819196 0.47278577 0.46413925 0.4558599 0.44787702 0.44014725 0.432643 0.4253458 0.41824245 0.4113233 0.4045803 0.3980071 0.3915978 0.38534725 predict (after training) 0.5 tensor(0.4064) predict (after training) 7.0 tensor(0.9840)訓(xùn)練完模型之后,輸入新的數(shù)據(jù)0.5,此時輸出小于0.5,則為0類別,輸入7輸出大于0.5,則為1類別。使用softmax做多分類時,哪個維度的數(shù)值大,則為哪個數(shù)值所對應(yīng)位置的類別。
1.5.2.2.2.更深更寬的網(wǎng)絡(luò)
前面的例子都是淺層輸入為一維的網(wǎng)絡(luò),如果需要更深更寬的網(wǎng)絡(luò),使用pytorch也可以很好的實現(xiàn),以邏輯回歸為例:
當(dāng)輸入x的維度很大時,需要更寬的網(wǎng)絡(luò):
更深的網(wǎng)絡(luò):
采用下面數(shù)據(jù)集(下載地址:https://github.com/hunkim/PyTorchZeroToAll/tree/master/data)
輸入維度為八:
結(jié)果:
(Before training) tensor([[0.3952]]) 0 0.78095376 50 0.7321978 100 0.7009846 150 0.68111795 200 0.668492 250 0.66046023 300 0.6553401 350 0.65206724 400 0.6499692 xxxxxxxxxxxxxxxxxxx 1550 0.6460486 1600 0.6460425 1650 0.64603657 1700 0.6460306 1750 0.64602476 1800 0.6460189 1850 0.6460131 1900 0.6460073 1950 0.6460014 predict (after training) [[0.6534828]]1.5.2.2.3.邏輯回歸案例:
# -*- coding: UTF-8 -*-import timeimport torch from torch import nn from torch.utils.data import DataLoader from torchvision import datasets, transforms# 定義超參數(shù) batch_size = 64 learning_rate = 1e-3 num_epochs = 100# 下載訓(xùn)練集 MNIST 手寫數(shù)字訓(xùn)練集 train_dataset = datasets.FashionMNIST(root='../datasets', train=True, transform=transforms.ToTensor(), download=True)test_dataset = datasets.FashionMNIST(root='../datasets', train=False, transform=transforms.ToTensor())train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)# 定義 Logistic Regression 模型 class Logistic_Regression(nn.Module):def __init__(self, in_dim, n_class):super(Logistic_Regression, self).__init__()self.logistic = nn.Linear(in_dim, n_class)def forward(self, x):out = self.logistic(x)return outmodel = Logistic_Regression(28 * 28, 10) # 圖片大小是28x28 use_gpu = torch.cuda.is_available() # 判斷是否有GPU加速 if use_gpu:model = model.cuda() # 定義loss和optimizer criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)# 開始訓(xùn)練 for epoch in range(num_epochs):print('*' * 10)print(f'epoch {epoch + 1}')since = time.time()running_loss = 0.0running_acc = 0.0model.train()for i, data in enumerate(train_loader, 1):img, label = dataimg = img.view(img.size(0), -1) # 將圖片展開成 28x28if use_gpu:img = img.cuda()label = label.cuda()# 向前傳播out = model(img)loss = criterion(out, label)running_loss += loss.item()_, pred = torch.max(out, 1)running_acc += (pred == label).float().mean()# 向后傳播optimizer.zero_grad()loss.backward()optimizer.step()if i % 300 == 0:print(f'[{epoch + 1}/{num_epochs}] Loss: {running_loss / i:.6f}, Acc: {running_acc / i:.6f}')print(f'Finish {epoch + 1} epoch, Loss: {running_loss / i:.6f}, Acc: {running_acc / i:.6f}')model.eval()eval_loss = 0.eval_acc = 0.for data in test_loader:img, label = dataimg = img.view(img.size(0), -1)if use_gpu:img = img.cuda()label = label.cuda()with torch.no_grad():out = model(img)loss = criterion(out, label)eval_loss += loss.item()_, pred = torch.max(out, 1)eval_acc += (pred == label).float().mean()print(f'Test Loss: {eval_loss / len(test_loader):.6f}, Acc: {eval_acc / len(test_loader):.6f}')print(f'Time:{(time.time() - since):.1f} s')# 保存模型 torch.save(model.state_dict(), './logstic.pth')1.5.2.3.Classification
以下參考:https://www.jb51.net/article/139098.htm
1.5.2.4.激勵函數(shù)activation function
以下參考:https://www.jb51.net/article/139098.htm
Torch的激勵函數(shù)都在torch.nn.functional中,relu,sigmoid, tanh, softplus都是常用的激勵函數(shù)。
相關(guān)代碼:
# -*- coding: UTF-8 -*-import torch import torch.nn.functional as F from torch.autograd import Variable import matplotlib.pyplot as pltx = torch.linspace(-5, 5, 200) x_variable = Variable(x) # 將x放入Variable x_np = x_variable.data.numpy()# 經(jīng)過4種不同的激勵函數(shù)得到的numpy形式的數(shù)據(jù)結(jié)果 y_relu = F.relu(x_variable).data.numpy() y_sigmoid = torch.sigmoid(x_variable).data.numpy() y_tanh = torch.tanh(x_variable).data.numpy() y_softplus = F.softplus(x_variable).data.numpy()plt.figure(1, figsize=(8, 6))plt.subplot(221) plt.plot(x_np, y_relu, c='red', label='relu') plt.ylim((-1, 5)) plt.legend(loc='best')plt.subplot(222) plt.plot(x_np, y_sigmoid, c='red', label='sigmoid') plt.ylim((-0.2, 1.2)) plt.legend(loc='best')plt.subplot(223) plt.plot(x_np, y_tanh, c='red', label='tanh') plt.ylim((-1.2, 1.2)) plt.legend(loc='best')plt.subplot(224) plt.plot(x_np, y_softplus, c='red', label='softplus') plt.ylim((-0.2, 6)) plt.legend(loc='best')plt.show()輸出結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的Linear Regression、Logistic Regression、激励函数activation function(relu,sigmoid, tanh, softplus)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 79式70毫米微型反坦克火箭
- 下一篇: 一嗨租车坦克300边境限定版怎么样