Deep Learning With Pytorch - 最基本的感知機、貫序模型/分類、擬合

文章目錄

如何利用pytorch創建一個簡單的網絡模型?

Step1. 感知機,多層感知機(MLP)的基本結構

感知機(Perceptron)是神經網絡中的基本單元,神經網絡的雛形,也被稱作神經元(原理就是仿照生物上的神經元)、單層神經網絡。

通過設置不同的權重,并加上一個激活函數(判決門限),就構成了一個單層感知機的基本網絡結構,可以實現與或非三種基本邏輯:
在這里插入圖片描述
在這里插入圖片描述
但是單層感知機的功能還是具有局限性,因為它畢竟只是一種二元線性分類模型(其輸入為實例的特征向量,輸出為實例的類別,取1和0【sigmoid激活判決】或+1和-1【sign激活判決】 ),像同或、異或這種稍微復雜一點的邏輯,就無法用單層感知機擬合出結果:
在這里插入圖片描述
所以通過擴展感知機的層數,引入更多層的神經元(多層感知機MLP的由來),從而帶來更多可以訓練的參數,得到一種非線性模型,以達到擬合出預期的效果:
在這里插入圖片描述
加入一層隱層網絡之后,同或數據集就變得可以擬合了:

a 1 [ 1 ] = s i g m o i d ( ω 1 , 1 [ 1 ] ? x 1 + ω 2 , 1 [ 1 ] ? x 2 + b 1 [ 1 ] ) a_1^{[1]}=sigmoid(\omega_{1,1}^{[1]}·x_1+\omega_{2,1}^{[1]}·x_2+b_1^{[1]}) a1[1]?=sigmoid(ω1,1[1]??x1?+ω2,1[1]??x2?+b1[1]?)

a 2 [ 1 ] = s i g m o i d ( ω 2 , 1 [ 1 ] ? x 1 + ω 2 , 2 [ 1 ] ? x 2 + b 2 [ 1 ] ) a_2^{[1]}=sigmoid(\omega_{2,1}^{[1]}·x_1+\omega_{2,2}^{[1]}·x_2+b_2^{[1]}) a2[1]?=sigmoid(ω2,1[1]??x1?+ω2,2[1]??x2?+b2[1]?)

a 1 [ 2 ] = s i g m o i d ( ω 1 , 1 [ 2 ] ? a 1 [ 1 ] + ω 2 , 1 [ 2 ] ? a 2 [ 1 ] + b [ 2 ] ) a_1^{[2]}=sigmoid(\omega_{1,1}^{[2]}·a_1^{[1]}+\omega_{2,1}^{[2]}·a_2^{[1]}+b^{[2]}) a1[2]?=sigmoid(ω1,1[2]??a1[1]?+ω2,1[2]??a2[1]?+b[2])【邏輯值】

上標 [ i ] ^{[i]} [i]代表第幾層;
在這里插入圖片描述

Step2. 超平面 ω T ? x + b = 0 \omega^{T}·x+b=0 ωT?x+b=0 or ω T ? x = b \omega^{T}·x=b ωT?x=b

初學者第一次見到 ω T ? x + b = 0 \omega^{T}·x+b=0 ωT?x+b=0這個表達式時,會覺得它非常像線性函數, ω T ? x + b = 0 \omega^{T}·x+b=0 ωT?x+b=0為什么是一條斜線呢?實際上這只是為了在二維平面更好表示其線性分類效果;
在這里插入圖片描述
在三維空間中,分類效果是這樣:
在這里插入圖片描述
投影在 XOZ/YOZ 軸平面就是二維平面中所看到的效果。

在高等數學中我們學習過三維平面的一般表達式: A x + B y + C z + D = 0 Ax+By+Cz+D=0 Ax+By+Cz+D=0

( A , B , C ) (A, B, C) (A,B,C)為平面的法向量,亦可寫為點法式: A ( x ? x 0 ) + B ( y ? y 0 ) + C ( z ? z 0 ) = 0 A(x-x_0)+B(y-y_0)+C(z-z_0)=0 A(x?x0?)+B(y?y0?)+C(z?z0?)=0

( x 0 , y 0 , z 0 ) (x_0, y_0, z_0) (x0?,y0?,z0?)是平面上的一個點,將點法式拆開: A x + B y + C z = A x 0 + B y 0 + C z 0 Ax+By+Cz=Ax_0+By_0+Cz_0 Ax+By+Cz=Ax0?+By0?+Cz0?

這里的 A x 0 + B y 0 + C z 0 Ax_0+By_0+Cz_0 Ax0?+By0?+Cz0?就是一般式中的 D D D.

當擴展至N維超平面時,式子就變成了: A ( x 1 ? x 0 ) + B ( x 2 ? x 0 ) + C ( x 3 ? x 0 ) + . . . + N ( x n ? x 0 ) = 0 A(x_1-x_0)+B(x_2-x_0)+C(x_3-x_0)+...+N(x_n-x_0)=0 A(x1??x0?)+B(x2??x0?)+C(x3??x0?)+...+N(xn??x0?)=0

A x 1 + B x 2 + C x 3 + . . . N x n = A x 0 + B x 0 + C x 0 + . . . N x 0 Ax_1+Bx_2+Cx_3+...Nx_n=Ax_0+Bx_0+Cx_0+...Nx_0 Ax1?+Bx2?+Cx3?+...Nxn?=Ax0?+Bx0?+Cx0?+...Nx0?

改寫成向量相乘的形式:

令行向量 ω T = [ ω 1 , ω 2 , . . . , ω n ] = [ A , B , . . . , N ] \omega^T = [\omega_1, \omega_2,...,\omega_n]=[A, B,..., N] ωT=[ω1?,ω2?,...,ωn?]=[A,B,...,N]

列向量 x = [ x 1 , x 2 , . . . , x n ] ′ x = [x_1, x_2, ... ,x_n]' x=[x1?,x2?,...,xn?] b = A x 0 + B x 0 + C x 0 + . . . N x 0 b = Ax_0+Bx_0+Cx_0+...Nx_0 b=Ax0?+Bx0?+Cx0?+...Nx0?

則N維超平面的定義式: ω T ? x = b \omega^{T}·x=b ωT?x=b 就產生了, b b b為超平面的常數項截距, ω T \omega^{T} ωT是超平面的法向量。

感知機函數

Step1中我們見過了感知機加激活函數得到與門的效果:
在這里插入圖片描述
感知機函數可以表示為: S i g m o i d ( ω T x + b ) Sigmoid(\omega^{T}x+b) Sigmoid(ωTx+b)

S i g m o i d ( ω T ? x + b ) = { 1 , ω T x + b ≥ 0 0 , ω T x + b < 0 Sigmoid(\omega^{T}·x+b) = \begin{cases} 1, \qquad \omega^{T}x+b≥0\\ 0,\qquad \omega^{T}x+b<0\end{cases} Sigmoid(ωT?x+b)={1,ωTx+b00,ωTx+b<0?

S i g n ( ω T ? x + b ) = { + 1 , ω T x + b ≥ 0 ? 1 , ω T x + b < 0 Sign(\omega^{T}·x+b) = \begin{cases} +1, \qquad \omega^{T}x+b≥0\\ -1,\qquad \omega^{T}x+b<0\end{cases} Sign(ωT?x+b)={+1,ωTx+b0?1,ωTx+b<0?

我們現在采用 S i g n Sign Sign 符號函數作為激活函數,利用超平面 ω T x + b = 0 \omega^{T}x+b=0 ωTx+b=0 進行決策分類任務,并定義輸出標簽 y = + 1 y=+1 y=+1 時為“是”, y = ? 1 y=-1 y=?1 時為“否”;

則分類出現錯誤時必定會有 y ? ( ω T x + b ) < 0 y·(\omega^{T}x+b)<0 y?(ωTx+b)<0.

因此,我們定義損失函數: L ( ω , b ) = ? ∑ i = 1 n y i ? ( ω i T x + b ) \mathcal{L}(\omega,b)=-\sum_{i=1}^{n}y_i·(\omega^{T}_ix+b) L(ω,b)=?i=1n?yi??(ωiT?x+b)

實際上損失函數的定義也并非這么直截了當就得出,因為還要保證損失函數連續可導,才能對其求偏導進行 a r g m i n ( ω , b ) argmin(\omega, b) argmin(ω,b);極小化損失函數的過程不是一次使得所有誤分類點的梯度下降,而是一次隨機選取一個誤分類點使其梯度下降,而損失函數中 y i ? ( ω i T x + b ) y_i·(\omega^{T}_ix+b) yi??(ωiT?x+b)的由來,其實就是選取了誤分類點到超平面距離公式中的分子項,分母項是個L2范數只起到了縮放作用,不影響損失函數的優化,所以可以忽略不計。
具體推導過程可以參考:感知機w·x+b=0怎么理解?數學推導是什么樣的?

我們的目標就是想讓損失函數盡可能地小,并選取使得損失函數最小的 w w w b b b.

利用經典的隨機梯度下降(SGD)算法對損失函數進行優化訓練:

{ ? L ? ω = L ( ω , b ) = ? ∑ i = 1 n y i ? x ? L ? b = L ( ω , b ) = ? ∑ i = 1 n y i \begin{cases}\frac{\partial{L}}{\partial{\omega}}=\mathcal{L}(\omega,b)=-\sum_{i=1}^{n}y_i·x\\\frac{\partial{L}}{\partial{b}}=\mathcal{L}(\omega,b)=-\sum_{i=1}^{n}y_i\end{cases} {?ω?L?=L(ω,b)=?i=1n?yi??x?b?L?=L(ω,b)=?i=1n?yi??

{ ω = ω + α ? L ? ω b = b + α ? L ? b \begin{cases}\omega = \omega + \alpha\frac{\partial{L}}{\partial{\omega}}\\ b = b + \alpha\frac{\partial{L}}{\partial{b}}\end{cases} {ω=ω+α?ω?L?b=b+α?b?L??

利用感知機進行線性分類的訓練過程如上,這也是支持向量機(SVM)算法的雛形。

Step3. 利用感知機進行決策分類的訓練過程 -【Matlab代碼】

clc,clear,close all;
%% 定義變量
n = 50;        % 正負樣本的個數,總樣本數為2n
r = 0.5;       % 學習率
m = 2;         % 樣本的維數
i_max = 100;  % 最大迭代次數%% 生成樣本(以二維為例)
pix = linspace(-pi,pi,n);
randx = 2*pix.*rand(1,n) - pi;
x1 = [cos(randx) + 2*rand(1,n); 3+sin(randx) + 2*rand(1,n)];
x2 = [3+cos(randx) + 2*rand(1,n); sin(randx) + 2*rand(1,n)];
x = [x1'; x2'];  % 一共2n個點
y = [ones(n,1); -ones(n,1)];  %添加標簽
figure(1)
hold on; 
plot(x1(1,:),x1(2,:),'rx'); 
plot(x2(1,:),x2(2,:),'go'); %% 訓練感知機
x = [ones(2*n,1) x];    % 增加一個常數偏置項 [1, x1;x2]
w = zeros(1,m+1);       % 初始化權值 [w0, w1, w2]
flag = true;            % 退出循環的標志,為true時退出循環
for i=1:i_max for j=1:2*n if sign(x(j,:)*w') ~= y(j)  % 超平面加激活函數:sign(w'x+w0)disp(num2str(sign(x(j,:)*w')))disp(y(j))flag = false; w = w + r*y(j)*x(j,:);  % 利用SGD算法更新參數% beginpause(0.3);cla('reset');axis([-1,6,-1,6]);hold onplot(x1(1,:),x1(2,:),'rx'); plot(x2(1,:),x2(2,:),'go');x_test = linspace(0,5,20); y_test = -w(2)/w(3).*x_test-w(1)/w(3); plot(x_test,y_test,'m-.');% endM=getframe(gcf);nn=frame2im(M);[nn,cm]=rgb2ind(nn,256);if i==1imwrite(nn,cm,'out.gif','gif','LoopCount',inf,'DelayTime',0.1);elseimwrite(nn,cm,'out.gif','gif','WriteMode','append','DelayTime',0.5)endend end if flagdisp(num2str(sign(x(j,:)*w')))disp(y(j))break; end 
end
disp(num2str(sign(x(j,:)*w')))
disp(y(j))%% 畫分割線
cla('reset');
hold on
axis([-1,6,-1,6]);
plot(x1(1,:),x1(2,:),'rx'); 
plot(x2(1,:),x2(2,:),'go');
x_test = linspace(0,5,20); 
y_test = -w(2)/w(3).*x_test-w(1)/w(3);  
plot(x_test,y_test,'linewidth',2);
legend('標簽為正的樣本','標簽為負的樣本','分類超平面');
M=getframe(gcf);
nn=frame2im(M);
[nn,cm]=rgb2ind(nn,256);
imwrite(nn,cm,'out.gif','gif','WriteMode','append','DelayTime',0.5)

程序中的超平面就是一條二維直線: ω 1 + ω 2 x 1 + ω 3 x 2 = 0 \omega_1+\omega_2x_1+\omega_3x_2=0 ω1?+ω2?x1?+ω3?x2?=0

訓練出的超平面縱坐標 y t e s t = x 2 = ? ω 1 / ω 3 ? ω 2 x 1 / ω 3 y_{test}=x_2=-\omega_1/\omega_3-\omega_2x_1/\omega_3 ytest?=x2?=?ω1?/ω3??ω2?x1?/ω3?.

在這里插入圖片描述

打印觀察 S i g n ( ω T ? x + b ) Sign(\omega^{T}·x+b) Sign(ωT?x+b)和標簽 y y y的值:

disp(num2str(sign(x(j,:)*w')))disp(y(j))
011-1-111-1-111-1-111-1-111-1-111-1-111-1-111-1-1-1

可以看到當 S i g n ( ω T ? x + b ) = = y Sign(\omega^{T}·x+b)==y Sign(ωT?x+b)==y的時候終止迭代循環,得到正確分類結果。

從線性回歸到貫序模型

除了感知機,ML入門時我們還會使用線性回歸和邏輯回歸這類經典統計分析方法。線性回歸就是想要通過數據,訓練出一個符合數據變化規律的超平面(二維中的超平面就是一條直線,三維中的超平面是一個平面)進行未來數據的預測。
正是因為實際問題中的數據可能是復雜多變的,所以僅靠線性的超平面不一定能得到最好的擬合效果,所以可以通過添加其他的網絡結構,添加非線性的隱藏層來實現具有更復雜擬合能力的網絡結構。
在這里插入圖片描述

而所謂的貫序模型就是將自定義的不同層網絡(可以是線性層,激活函數層,卷積層、池化層、循環層、注意力層等等)串成一個模型。

# 添加激活層后的貫序模型
seq_model = nn.Sequential(OrderedDict([('input_linear', nn.Linear(1, 12)),('hidden_activation', nn.Tanh()),('output_linear', nn.Linear(12, 1))
]))

該模型的網絡結構包括:
輸入層:第一層是一個線性層 (nn.Linear(1, 12)),它將接受一個維度為1的輸入。
隱藏層:包含一個激活函數層 (nn.Tanh())。該隱藏層不改變維度,僅應用激活函數。
輸出層:包含一個線性層 (nn.Linear(12, 1)),將隱藏層的輸出維度(12)投影到一個維度為1的輸出。
因此,該模型總共有三層:輸入層、隱藏層和輸出層。輸入層的維度為1,輸出層的維度為1。

nn.Linear(_, _)

nn.Linear 是 PyTorch 中的一個類,也可以理解為一個函數,用于定義一個線性變換(也稱為全連接層或仿射變換),將輸入特征映射到輸出特征。它是神經網絡模塊 nn 提供的一個常用函數之一。

nn.Linear(in_features, out_features)中的第一個參數為in_features: 輸入特征的數量(維度)。這個參數決定了輸入的大小,通常也就是數據集中的特征數,即輸入張量的最后一維大小;

nn.Linear(in_features, out_features)中的第二個參數為out_features: 輸出特征的數量(維度)。這個參數決定了輸出的大小,即輸出張量的最后一維大小。

bias: 是否在變換中使用偏置項(偏置向量)。默認為 True,表示會使用偏置項;設置為 False 則不使用偏置項。
前向傳播計算: 在神經網絡的前向傳播過程中,nn.Linear 定義的線性變換會對輸入特征進行矩陣乘積運算,然后加上偏置項。具體計算公式如下:

output = input × weight ? + bias \text{output} = \text{input} \times \text{weight}^{\top} + \text{bias} output=input×weight?+bias

其中,in_features是需要嚴格按照數據集中需要訓練的特征數確定的,如波士頓房價數據集中:

0-505就是數據集的batch_size,batch_size表示一次選多少行數據進行訓練,而crim, age, tax…這類的特征一共14個特征數量,就是nn.Linear中的in_features了,當然大小也是根據你需要哪幾個特征參與訓練確定的。

在這里插入圖片描述
nn,Linear線性層計算的輸入和輸出格式:

在這里插入圖片描述

相比in_features, out_features 就靈活多變一些。如果 out_features 設置得太大,模型可能會過于復雜,導致過擬合問題。相反,如果設置得太小,模型可能無法捕捉足夠的特征,導致欠擬合問題。選擇適當的輸出特征數量是在訓練集和驗證集上達到良好性能的關鍵之一。

nn.Linear 在神經網絡中非常常見,它可以用于構建模型的一層或多層,實現從輸入到輸出的特征變換。通過多層的堆疊和非線性激活函數的引入,可以構建出更復雜的神經網絡模型,適用于各種任務。

模型訓練

在pytorch中我們通過定義一個training_loop來指定模型訓練時的迭代次數,所選優化方法,調用創建的網絡模型,以及選取的損失函數、訓練集/驗證集:

def training_loop(n_epochs, optimizer, model, loss_fn, t_u_train, t_u_val,t_c_train, t_c_val):for epoch in range(1, n_epochs + 1):t_p_train = model(t_u_train)loss_train = loss_fn(t_p_train, t_c_train)t_p_val = model(t_u_val)loss_val = loss_fn(t_p_val, t_c_val)optimizer.zero_grad()   # 清除舊梯度loss_train.backward()   # 后向傳播計算新梯度optimizer.step()        # 根據梯度進行SGD優化if epoch == 1 or epoch % 500 == 0:print(f"Epoch {epoch}, Training loss {loss_train.item():.4f},"f" Validation loss {loss_val.item():.4f}")def loss_fn(t_p, t_c):squared_diffs = (t_p - t_c) ** 2return squared_diffs.mean()linear_model = nn.Linear(1, 1)
optimizer = optim.SGD(linear_model.parameters(), lr=1e-2)# 嘗試線性模型訓練
training_loop(n_epochs=3000,optimizer=optimizer,model=linear_model,# loss_fn=loss_fn,loss_fn=nn.MSELoss(),t_u_train=t_un_train,t_u_val=t_un_val,t_c_train=t_c_train,t_c_val=t_c_val)

貫序模型例程 -【Pytorch完整代碼】

import torch
import torch.optim as optim
import torch.nn as nn
from collections import OrderedDict
from matplotlib import pyplot as plttorch.set_printoptions(edgeitems=2, linewidth=75)# 數據集準備
t_c = [0.5, 14.0, 15.0, 28.0, 11.0, 8.0, 3.0, -4.0, 6.0, 13.0, 21.0]
t_u = [35.7, 55.9, 58.2, 81.9, 56.3, 48.9, 33.9, 21.8, 48.4, 60.4, 68.4]
t_c = torch.tensor(t_c).unsqueeze(1)
t_u = torch.tensor(t_u).unsqueeze(1)n_samples = t_u.shape[0]  # 獲取數據集的樣本數量(數據集中元素的數量)
n_val = int(0.2 * n_samples)  # 計算驗證集的樣本數量。這里使用了0.2作為驗證集的比例,將數據集中的20%作為驗證集# 生成一個長度為n_samples的隨機排列的索引數組。這里使用torch.rand-perm函數生成一個隨機排列的整數數組,用于打亂原始數據集的索引順序
shuffled_indices = torch.randperm(n_samples)
train_indices = shuffled_indices[:-n_val]
val_indices = shuffled_indices[-n_val:]
t_u_train = t_u[train_indices]
t_c_train = t_c[train_indices]
t_u_val = t_u[val_indices]
t_c_val = t_c[val_indices]
t_un_train = 0.1 * t_u_train
t_un_val = 0.1 * t_u_vallinear_model = nn.Linear(1, 1)
linear_model(t_un_val)def training_loop(n_epochs, optimizer, model, loss_fn, t_u_train, t_u_val,t_c_train, t_c_val):for epoch in range(1, n_epochs + 1):t_p_train = model(t_u_train)loss_train = loss_fn(t_p_train, t_c_train)t_p_val = model(t_u_val)loss_val = loss_fn(t_p_val, t_c_val)optimizer.zero_grad()   # 清除舊梯度loss_train.backward()   # 后向傳播計算新梯度optimizer.step()        # 根據梯度進行SGD優化if epoch == 1 or epoch % 500 == 0:print(f"Epoch {epoch}, Training loss {loss_train.item():.4f},"f" Validation loss {loss_val.item():.4f}")def loss_fn(t_p, t_c):squared_diffs = (t_p - t_c) ** 2return squared_diffs.mean()linear_model = nn.Linear(1, 1)
optimizer = optim.SGD(linear_model.parameters(), lr=1e-2)# 嘗試線性模型訓練
training_loop(n_epochs=3000,optimizer=optimizer,model=linear_model,# loss_fn=loss_fn,loss_fn=nn.MSELoss(),t_u_train=t_un_train,t_u_val=t_un_val,t_c_train=t_c_train,t_c_val=t_c_val)print()
print(linear_model.weight)
print(linear_model.bias)# 添加激活層后的貫序模型
seq_model = nn.Sequential(OrderedDict([('input_linear', nn.Linear(1, 12)),('hidden_activation', nn.Tanh()),('output_linear', nn.Linear(12, 1))
]))print(seq_model)
print([param.shape for param in seq_model.parameters()])for name, param in seq_model.named_parameters():print(name, param.shape)optimizer = optim.SGD(seq_model.parameters(), lr=1e-3)training_loop(n_epochs=5000,optimizer=optimizer,model=seq_model,        # 使用貫序模型重新訓練loss_fn=nn.MSELoss(),t_u_train=t_un_train,t_u_val=t_un_val,t_c_train=t_c_train,t_c_val=t_c_val)# 打印模型參數訓練結果:
# print('output', seq_model(t_un_val))
# print('answer', t_c_val)
# print('hidden', seq_model.hidden_linear.weight.grad)t_range = torch.arange(20., 90.).unsqueeze(1)fig = plt.figure(dpi=100)
plt.xlabel("Fahrenheit")
plt.ylabel("Celsius")
plt.plot(t_u.numpy(), t_c.numpy(), 'o')
plt.plot(t_range.numpy(), seq_model(0.1 * t_range).detach().numpy(), 'c-')
plt.plot(t_u.numpy(), seq_model(0.1 * t_u).detach().numpy(), 'kx')
plt.show()

打印結果:

Epoch 1, Training loss 287.7947, Validation loss 243.3686
Epoch 500, Training loss 6.3782, Validation loss 5.3946
Epoch 1000, Training loss 2.9283, Validation loss 6.1271
Epoch 1500, Training loss 2.4918, Validation loss 6.4090
Epoch 2000, Training loss 2.4366, Validation loss 6.5120
Epoch 2500, Training loss 2.4296, Validation loss 6.5489
Epoch 3000, Training loss 2.4288, Validation loss 6.5621Parameter containing:
tensor([[5.4817]], requires_grad=True)
Parameter containing:
tensor([-17.4273], requires_grad=True)
Sequential((hidden_linear): Linear(in_features=1, out_features=12, bias=True)(hidden_activation): Tanh()(output_linear): Linear(in_features=12, out_features=1, bias=True)
)
[torch.Size([12, 1]), torch.Size([12]), torch.Size([1, 12]), torch.Size([1])]
hidden_linear.weight torch.Size([12, 1])
hidden_linear.bias torch.Size([12])
output_linear.weight torch.Size([1, 12])
output_linear.bias torch.Size([1])
Epoch 1, Training loss 200.8066, Validation loss 149.6482
Epoch 500, Training loss 8.0419, Validation loss 6.9692
Epoch 1000, Training loss 2.8967, Validation loss 9.0610
Epoch 1500, Training loss 1.7860, Validation loss 8.2857
Epoch 2000, Training loss 1.4266, Validation loss 7.6947
Epoch 2500, Training loss 1.3101, Validation loss 7.3714
Epoch 3000, Training loss 1.2710, Validation loss 7.2340
Epoch 3500, Training loss 1.2550, Validation loss 7.2035
Epoch 4000, Training loss 1.2451, Validation loss 7.2175
Epoch 4500, Training loss 1.2367, Validation loss 7.2404
Epoch 5000, Training loss 1.2289, Validation loss 7.2637

這個例子中雖然采用的輸入層和輸出層都是線性層nn.Linear,但是最終擬合出的卻是曲線,而非二維的超平面(一條直線),這就是因為隱藏層我們選用了tanh函數,是非線性的,也因此提升了網絡的擬合效果:
在這里插入圖片描述
如果我們將nn.Tanh()改為nn.Relu()激活函數,擬合出來的就是一條直線了:
在這里插入圖片描述

參考文獻:
[1] Pytorch官方 - Deep Learning With Pytorch
[2] 《零基礎學機器學習》
[3] 感知機 - 謝晉- 算法與數學之美
[4] 感知機w·x+b=0怎么理解?數學推導是什么樣的?
[5] 啥都斷更的小c-從0開始深度學習:什么是線性層?pytorch中nn.linear怎么用?
[6] 機器學習| 算法筆記-線性回歸(Linear Regression)

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

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

相關文章

SpringBoot整合Minio

SpringBoot整合Minio 在企業開發中&#xff0c;我們經常會使用到文件存儲的業務&#xff0c;Minio就是一個不錯的文件存儲工具&#xff0c;下面我們來看看如何在SpringBoot中整合Minio POM pom文件指定SpringBoot項目所依賴的軟件工具包 <?xml version"1.0" …

Ubuntu上安裝RabbitMQ

在Ubuntu上安裝RabbitMQ并設置管理員用戶為"admin"&#xff0c;密碼為"123456"&#xff0c;并開啟開機自啟 更新系統軟件包列表。在終端中執行以下命令&#xff1a; sudo apt update安裝RabbitMQ服務器軟件包。運行以下命令&#xff1a; sudo apt insta…

DaVinci Resolve Studio 18 for Mac 達芬奇調色

DaVinci Resolve Studio 18是一款專業的視頻編輯和調色軟件&#xff0c;適用于電影、電視節目、廣告等各種視覺媒體的制作。它具有完整的后期制作功能&#xff0c;包括剪輯、調色、特效、音頻處理等。 以下是DaVinci Resolve Studio 18的主要特點&#xff1a; - 提供了全面的視…

Linux 設置 ssh 內網穿透

背景&#xff1a;有三臺機器A、B、C&#xff0c;機器 A 位于某局域網內&#xff0c;能夠連接到互聯網。機器 B 有公網 IP&#xff0c;能被 A 訪問到。機器 C 位于另外一個局域網內&#xff0c;能夠連接到互聯網&#xff0c;能夠訪問 B。 目標&#xff1a;以 B 為中介&#xff…

Jmeter-壓測時接口按照順序執行-臨界部分控制器

文章目錄 臨界部分控制器存在問題 臨界部分控制器 在進行壓力測試時&#xff0c;需要按照順序進行壓測&#xff0c;比如按照接口1、接口2、接口3、接口4 進行執行 查詢結果是很混亂的&#xff0c;如果請求次數少&#xff0c;可能會按照順序執行&#xff0c;但是隨著次數增加&a…

Python-OpenCV中的圖像處理-模板匹配

Python-OpenCV中的圖像處理-模板匹配 模板匹配單對象的模板匹配多對象的模板匹配 模板匹配 使用模板匹配可以在一幅圖像中查找目標函數&#xff1a; cv2.matchTemplate()&#xff0c; cv2.minMaxLoc()模板匹配是用來在一副大圖中搜尋查找模版圖像位置的方法。 OpenCV 為我們提…

無線充電底座

<項目>無線充電器 前言 個人DIY的無線充電底座&#xff08;帶磁吸&#xff09;&#xff0c;基于IP6829方案。 Drawn By:67373 硬件部分 3D模型 資料開源鏈接 https://github.com/linggan17/WirelessCharge

面試熱題(每日溫度)

請根據每日 氣溫 列表 temperatures &#xff0c;重新生成一個列表&#xff0c;要求其對應位置的輸出為&#xff1a;要想觀測到更高的氣溫&#xff0c;至少需要等待的天數。如果氣溫在這之后都不會升高&#xff0c;請在該位置用 0 來代替。 輸入: temperatures [73,74,75,71,69…

SpringBoot + Mybatis多數據源

一、配置文件 spring: # datasource: # username: root # password: 123456 # url: jdbc:mysql://127.0.0.1:3306/jun01?characterEncodingutf-8&serverTimezoneUTC # driver-class-name: com.mysql.cj.jdbc.Driverdatasource:# 數據源1onedata:jdbc-url: j…

SCF金融公鏈新加坡啟動會 鏈結創新驅動未來

新加坡迎來一場引人矚目的金融科技盛會&#xff0c;SCF金融公鏈啟動會于2023年8月13日盛大舉行。這一受矚目的活動將為金融科技領域注入新的活力&#xff0c;并為廣大投資者、合作伙伴以及關注區塊鏈發展的人士提供一個難得的交流平臺。 在SCF金融公鏈啟動會上&#xff0c; Wil…

CentOS7的journalctl日志查看方法

多臺服務器間免密登錄|免密拷貝 Cenos7 搭建Minio集群部署服務器(一) Cenos7 搭建Minio集群Nginx統一訪問入口|反向動態代理(二) Spring Boot 與Minio整合實現文件上傳與下載(三) CentOS7的journalctl日志查看方法 MySQL8.xx一主兩從復制安裝與配置 1、概述 日志管理工…

【ElasticSearch入門】

目錄 1.ElasticSearch的簡介 2.用數據庫實現搜素的功能 3.ES的核心概念 3.1 NRT(Near Realtime)近實時 3.2 cluster集群&#xff0c;ES是一個分布式的系統 3.3 Node節點&#xff0c;就是集群中的一臺服務器 3.4 index 索引&#xff08;索引庫&#xff09; 3.5 type類型 3.6 doc…

【佳佳怪文獻分享】MVFusion: 利用語義對齊的多視角 3D 物體檢測雷達和相機融合

標題&#xff1a;MVFusion: Multi-View 3D Object Detection with Semantic-aligned Radar and Camera Fusion 作者&#xff1a;Zizhang Wu , Guilian Chen , Yuanzhu Gan , Lei Wang , Jian Pu 來源&#xff1a;2023 IEEE International Conference on Robotics and Automat…

kubernetes企業級高可用部署

目錄 1、Kubernetes高可用項目介紹 2、項目架構設計 2.1、項目主機信息 2.2、項目架構圖 1、Kubernetes高可用項目介紹 2、項目架構設計 2.1、項目主機信息 2.2、項目架構圖 2.3、項目實施思路 3、項目實施過程 3.1、系統初始化 3.2、配置部署keepalived服務 3.3、…

強制Edge或Chrome使用獨立顯卡【WIN10】

現代瀏覽器通常將圖形密集型任務卸載到 GPU&#xff0c;以改善你的網頁瀏覽體驗&#xff0c;從而釋放 CPU 資源用于其他任務。 如果你的系統有多個 GPU&#xff0c;Windows 10 可以自動決定最適合 Microsoft Edge 自動使用的 GPU&#xff0c;但這并不一定意味著最強大的 GPU。 …

Linux/centos上如何配置管理NFS服務器?

Linux/centos上如何配置管理NFS服務器&#xff1f; 1 NFS基礎了解1.1 NFS概述1.2 NFS工作流程 2 安裝和啟動NFS服務2.1 安裝NFS服務器2.2 啟動NFS服務 3 配置NFS服務器和客戶端3.1 配置NFS服務器3.2 配置NFS客戶端 4 實際示例4.1 基本要求4.2 案例實現 1 NFS基礎了解 NFS&…

LAXCUS如何通過技術創新管理數千臺服務器

隨著互聯網技術的不斷發展&#xff0c;服務器已經成為企業和個人獲取信息、進行計算和存儲的重要工具。然而&#xff0c;隨著服務器數量的不斷增加&#xff0c;傳統的服務器管理和運維方式已經無法滿足現代企業的需求。LAXCUS做為專注服務器集群的【數存算管】一體化平臺&#…

Jtti:Windows server如何備份與還原注冊表

在 Windows Server 中&#xff0c;備份和還原注冊表是一項重要的任務&#xff0c;可以幫助你在系統配置更改之前創建一個恢復點&#xff0c;以防止出現問題。以下是在 Windows Server 上備份和還原注冊表的步驟&#xff1a; 備份注冊表&#xff1a; 1.打開“運行”對話框&…

企業數據庫遭到360后綴勒索病毒攻擊,360勒索病毒解密

在當今數字化時代&#xff0c;企業的數據安全變得尤為重要。隨著數字化辦公的推進&#xff0c;企業的生產運行效率得到了很大提升&#xff0c;然而針對網絡安全威脅&#xff0c;企業也開始慢慢引起重視。近期&#xff0c;我們收到很多企業的求助&#xff0c;企業的服務器遭到了…

代理模式(Java實現)

代理模式是常見的設計模式之一&#xff0c;顧名思義&#xff0c;代理模式就是代理對象具備真實對象的功能&#xff0c;并代替真實對象完成相應操作&#xff0c;并能夠在操作執行的前后&#xff0c;對操作進行增強處理。&#xff08;為真實對象提供代理&#xff0c;然后供其他對…