PyTorch實戰(2)——使用PyTorch構建神經網絡

PyTorch實戰(2)——使用PyTorch構建神經網絡

    • 0. 前言
    • 1. PyTorch 構建神經網絡初體驗
      • 1.1 使用 PyTorch 構建神經網絡
      • 1.2 神經網絡數據加載
      • 1.3 模型測試
      • 1.4 獲取中間層的值
    • 2. 使用 Sequential 類構建神經網絡
    • 3. PyTorch 模型的保存和加載
      • 3.1 模型保存所需組件
      • 3.2 模型狀態
      • 3.3 模型保存
      • 3.4 模型加載
    • 小結
    • 系列鏈接

0. 前言

我們已經學習了深度學習的基本概念,神經網絡通常包括輸入層、隱藏層、輸出層、激活函數、損失函數和學習率等基本組件。在本節中,我們將學習如何在簡單數據集上使用 PyTorch 構建神經網絡,利用張量對象操作和梯度值計算更新網絡權重。

1. PyTorch 構建神經網絡初體驗

1.1 使用 PyTorch 構建神經網絡

為了介紹如何使用 PyTorch 構建神經網絡,我們將嘗試解決兩個數字的相加問題。

(1) 初始化數據集,定義輸入 (x) 和輸出 (y) 值:

import torch
x = [[1,2],[3,4],[5,6],[7,8]]
y = [[3],[7],[11],[15]]

在初始化的輸入和輸出變量中,輸入中的每個列表的值之和就是輸出列表中對應的值。

(2) 將輸入列表轉換為張量對象:

X = torch.tensor(x).float()
Y = torch.tensor(y).float()

在以上代碼中,將張量對象轉換為浮點對象。此外,將輸入 ( X ) 和輸出 ( Y ) 數據點注冊到 device 中:

device = 'cuda' if torch.cuda.is_available() else 'cpu'
X = X.to(device)
Y = Y.to(device)

(3) 定義神經網絡架構。

導入 torch.nn 模塊用于構建神經網絡模型:

from torch import nn

創建神經網絡架構類 MyNeuralNet,繼承自 nn.Modulenn.Module 是所有神經網絡模塊的基類:

class MyNeuralNet(nn.Module):

在類中,使用 __init__ 方法初始化神經網絡的所有組件,調用 super().__init__() 確保類繼承 nn.Module

    def __init__(self):super().__init__()

使用以上代碼,通過指定 super().__init__() 可以利用為 nn.Module 編寫的所有預構建函數,初始化的組件將用于 MyNeuralNet 類中的不同方法。

定義神經網絡中的網絡層:

        self.input_to_hidden_layer = nn.Linear(2,8)self.hidden_layer_activation = nn.ReLU()self.hidden_to_output_layer = nn.Linear(8,1)

在以上代碼中,指定了神經網絡的所有層——一個全連接層 (self.input_to_hidden_layer),使用 ReLU 激活函數 (self.hidden_layer_activation),最后仍是一個全連接層 (self.hidden_to_output_layer)。

將初始化后的神經網絡組件連接在一起,并定義網絡的前向傳播方法 forward

    def forward(self, x):x = self.input_to_hidden_layer(x)x = self.hidden_layer_activation(x)x = self.hidden_to_output_layer(x)return x

必須使用 forward 作為前向傳播的函數名,因為 PyTorch 保留此函數作為執行前向傳播的方法,使用其他名稱都會引發錯誤。

通過打印 nn.Linear 方法的輸出了解函數作用:

print(nn.Linear(2, 7))
# Linear(in_features=2, out_features=7, bias=True)

在以上代碼中,全連接層以 2 個值作為輸入并輸出 7 個值,且包含與之關聯的偏置參數。

(4) 通過執行以下代碼訪問每個神經網絡組件的初始權重。

創建 MyNeuralNet 類對象的實例并將其注冊到 device

mynet = MyNeuralNet().to(device)

可以通過類似代碼訪問每一層的權重和偏置:

print(mynet.input_to_hidden_layer.weight)

代碼輸出結果如下:

Parameter containing:
tensor([[ 0.0984,  0.3058],[ 0.2913, -0.3629],[ 0.0630,  0.6347],[-0.5134, -0.2525],[ 0.2315,  0.3591],[ 0.1506,  0.1106],[ 0.2941, -0.0094],[-0.0770, -0.4165]], device='cuda:0', requires_grad=True)

每次執行時輸出的值并不相同,因為神經網絡每次都使用隨機值進行初始化。如果希望每次在執行相同代碼時保持相同輸出,則需要在創建類對象的實例之前使用 Torch 中的 manual_seed 方法指定隨機種子 torch.manual_seed(0)

(5) 可以通過以下代碼獲得神經網絡的所有參數:

mynet.parameters()

以上代碼會返回一個生成器對象,最后通過生成器循環獲取參數:

for param in mynet.parameters():print(param)

代碼輸出結果如下:

Parameter containing:
tensor([[ 0.2955,  0.3231],[ 0.5153,  0.1734],[-0.6359, -0.1406],[ 0.3820, -0.1085],[ 0.2816, -0.2283],[ 0.4633,  0.6564],[-0.1605, -0.4450],[ 0.0788, -0.0147]], device='cuda:0', requires_grad=True)
Parameter containing:
tensor([[ 0.2955,  0.3231],[ 0.5153,  0.1734],[-0.6359, -0.1406],[ 0.3820, -0.1085],[ 0.2816, -0.2283],[ 0.4633,  0.6564],[-0.1605, -0.4450],[ 0.0788, -0.0147]], device='cuda:0', requires_grad=True)
Parameter containing:
tensor([-0.4761,  0.6370,  0.6744, -0.4103, -0.3714,  0.1491, -0.2304,  0.5571],device='cuda:0', requires_grad=True)
Parameter containing:
tensor([[-0.0440,  0.0028,  0.3024,  0.1915,  0.1426, -0.2859, -0.2398, -0.2134]],device='cuda:0', requires_grad=True)
Parameter containing:
tensor([-0.3238], device='cuda:0', requires_grad=True)

該模型已將這些張量注冊為跟蹤前向和反向傳播所必需的特殊對象,在 __init__ 方法中定義 nn 神經網絡層時,它會自動創建相應的張量并同時進行注冊,也可以使用 nn.parameter(<tensor>) 函數手動注冊這些參數。因此,本節定義的神經網絡類 myNeuralNet 等價于以下代碼:

class MyNeuralNet(nn.Module):def __init__(self):super().__init__()self.input_to_hidden_layer = nn.parameter(torch.rand(2,8))self.hidden_layer_activation = nn.ReLU()self.hidden_to_output_layer = nn.parameter(torch.rand(8,1))def forward(self, x):x = x @ self.input_to_hidden_layerx = self.hidden_layer_activation(x)x = x @ self.hidden_to_output_layerreturn x

(6) 定義損失函數,由于需要預測連續輸出,因此使用均方誤差作為損失函數:

loss_func = nn.MSELoss()

通過將輸入值傳遞給神經網絡對象,然后計算給定輸入的損失函數值:

_Y = mynet(X)
loss_value = loss_func(_Y,Y)
print(loss_value)
# tensor(127.4498, device='cuda:0', grad_fn=<MseLossBackward>)

在以上代碼中,mynet(X) 根據給定輸入通過神經網絡計算輸出值,loss_func 函數計算對應于神經網絡預測 (_Y) 和實際值 (Y) 的 MSELoss 值。需要注意的是,根據 PyTorch 約定,在計算損失時,我們總是首先傳入預測結果,然后傳入實際標記值。

(7) 定義用于降低損失值的優化器,優化器的輸入是與神經網絡相對應的參數(權重和偏置項)以及更新權重時的學習率。本節,我們使用隨機梯度下降 (Stochastic Gradient Descent, SGD)。從 torch.optim 模塊中導入 SGD 方法,然后將神經網絡對象 (mynet) 和學習率 (lr) 作為參數傳遞給 SGD 方法:

from torch.optim import SGD
opt = SGD(mynet.parameters(), lr = 0.001)

(8) 一個 epoch 訓練過程包含以下步驟:

  • 計算給定輸入和輸出對應的損失值
  • 計算參數對應的梯度
  • 根據參數的學習率和梯度更新權重
  • 更新權重后,確保在下一個 epoch 計算梯度之前刷新上一步中計算的梯度
    opt.zero_grad()loss_value = loss_func(mynet(X),Y)loss_value.backward()opt.step()

使用 for 循環重復執行上述步驟。在以下代碼中,執行 50epoch,此外,在 loss_history 列表中存儲每個 epoch 中的損失值:

loss_history = []
for _ in range(50):opt.zero_grad()loss_value = loss_func(mynet(X),Y)loss_value.backward()opt.step()loss_history.append(loss_value.item())

繪制損失隨 epoch 的變化情況:

import matplotlib.pyplot as plt
plt.plot(loss_history)
plt.title('Loss variation over increasing epochs')
plt.xlabel('epochs')
plt.ylabel('loss value')
plt.show()

損失值變化情況

1.2 神經網絡數據加載

批大小 (batch size) 是神經網絡中的重要超參數,批大小是指計算損失值或更新權重時考慮的數據樣本數。假設數據集中有數百萬個數據樣本,一次將所有數據點用于一次權重更新并非最佳選擇,因為內存可能無法容納如此多數據。使用抽樣樣本可以充分代表數據,批大小可以用于獲取具有足夠代表性的多個數據樣本。在本節中,我們指定計算權重梯度時要考慮的批大小以更新權重,然后計算更新后的損失值。

(1) 導入用于加載數據和處理數據集的方法:

from torch.utils.data import Dataset, DataLoader
import torch
import torch.nn as nn

(2) 導入數據,將數據轉換為浮點數,并將它們注冊到相應設備中:

x = [[1,2],[3,4],[5,6],[7,8]]
y = [[3],[7],[11],[15]]X = torch.tensor(x).float()
Y = torch.tensor(y).float()device = 'cuda' if torch.cuda.is_available() else 'cpu'
X = X.to(device)
Y = Y.to(device)

(3) 創建數據集類 MyDataset

class MyDataset(Dataset):

MyDataset 類中,存儲數據信息以便可以將一批 (batch) 數據點捆綁在一起(使用 DataLoader),并通過一次前向和反向傳播更新權重。

定義 __init__ 方法,該方法接受輸入和輸出對并將它們轉換為 Torch 浮點對象:

    def __init__(self,x,y):self.x = x.clone().detach() # torch.tensor(x).float()self.y = y.clone().detach() # torch.tensor(y).float()

指定輸入數據集的長度 (__len__):

    def __len__(self):return len(self.x)

__getitem__ 方法用于獲取指定數據樣本:

    def __getitem__(self, ix):return self.x[ix], self.y[ix]

在以上代碼中,ix 表示要從數據集中獲取的數據索引。

(4) 創建自定義類的實例:

ds = MyDataset(X, Y)

(5) 通過 DataLoader 傳遞數據集實例,從原始輸入輸出張量對象中獲取 batch_size 個數據點:

dl = DataLoader(ds, batch_size=2, shuffle=True)

在以上代碼中,指定從原始輸入數據集 (ds) 中獲取兩個 (batch_size=2) 隨機樣本 (shuffle=True)數據點。

循環遍歷 dl 獲取批數據信息:

for x, y in dl:print(x, y)

輸出結果如下所示:

tensor([[3., 4.],[5., 6.]], device='cuda:0') tensor([[ 7.],[11.]], device='cuda:0')
tensor([[1., 2.],[7., 8.]], device='cuda:0') tensor([[ 3.],[15.]], device='cuda:0')

可以看到以上代碼生成了兩組輸入-輸出對,因為原始數據集中共有 4 個數據點,而指定的批大小為 2

(6) 定義神經網絡類:

class MyNeuralNet(nn.Module):def __init__(self):super().__init__()self.input_to_hidden_layer = nn.Linear(2,8)self.hidden_layer_activation = nn.ReLU()self.hidden_to_output_layer = nn.Linear(8,1)def forward(self, x):x = self.input_to_hidden_layer(x)x = self.hidden_layer_activation(x)x = self.hidden_to_output_layer(x)return x

(7) 定義模型對象 (mynet)、損失函數 (loss_func) 和優化器 (opt):

mynet = MyNeuralNet().to(device)
loss_func = nn.MSELoss()
from torch.optim import SGD
opt = SGD(mynet.parameters(), lr = 0.001)

(8) 最后,循環遍歷批數據點以最小化損失值:

import time
loss_history = []
start = time.time()
for _ in range(50):for data in dl:x, y = dataopt.zero_grad()loss_value = loss_func(mynet(x),y)loss_value.backward()opt.step()loss_history.append(loss_value.item())
end = time.time()
print(end - start)
# 0.08548569679260254

雖然以上代碼與上一小節中使用的代碼非常相似,但與上一小節相比,每個 epoch 更新權重的次數變為原來的 2 倍,因為本節中使用的批大小為 2,而上一小節中的批大小為 4 (即一次使用全部數據點)。

1.3 模型測試

在上一小節中,我們學習了如何在已知數據點上擬合模型。在本節中,我們將學習如何利用上一小節訓練的 mynet 模型中定義的前向傳播方法 forward 來預測模型沒有見過的數據點(測試數據)。

(1) 創建用于測試模型的數據點:

val_x = [[10,11]]

新數據集 (val_x) 與輸入數據集相同,也是由列表數據組成的列表。

(2) 將新數據點轉換為張量浮點對象并注冊到 device 中:

val_x = torch.tensor(val_x).float().to(device)

(3) 通過訓練好的神經網絡 (mynet) 傳遞張量對象,與通過模型執行前向傳播的用法相同:

print(mynet(val_x))
# tensor([[20.0105]], device='cuda:0', grad_fn=<AddmmBackward>)

以上代碼返回模型對輸入數據點的預測輸出值。

1.4 獲取中間層的值

在實際應用中,我們可能需要獲取神經網絡的中間層值,例如風格遷移和遷移學習等,PyTorch 提供了兩種方式獲取神經網絡中間值。

一種方法是直接調用神經網絡層,將它們當做函數使用:

print(mynet.hidden_layer_activation(mynet.input_to_hidden_layer(X)))

需要注意的是,我們必須安裝模型輸入、輸出順序調用相應神經網絡層,例如,在以上代碼中 input_to_hidden_layer 的輸出是 hidden_layer_activation 層的輸入。

另一種方法是在 forward 方法中指定想要查看的網絡層,雖然以下代碼與上一小節中的 MyNeuralNet 類基本相同,但 forward 方法不僅返回輸出,還返回激活后的隱藏層值 (hidden2):

class MyNeuralNet(nn.Module):def __init__(self):super().__init__()self.input_to_hidden_layer = nn.Linear(2,8)self.hidden_layer_activation = nn.ReLU()self.hidden_to_output_layer = nn.Linear(8,1)def forward(self, x):hidden1 = self.input_to_hidden_layer(x)hidden2 = self.hidden_layer_activation(hidden1)x = self.hidden_to_output_layer(hidden2)return x, hidden2

通過使用以下代碼訪問隱藏層值,mynet 的第 0 個索引輸出是網絡前向傳播的最終輸出,而第 1 個索引輸出是隱藏層激活后的值:

print(mynet(X)[1])

2. 使用 Sequential 類構建神經網絡

我們已經學習了如何通過定義一個類來構建神經網絡,在該類中定義了層以及層之間的連接方式。然而,除非需要構建一個復雜的網絡,否則,只需要利用 Sequential 類并指定層和層堆疊的順序即可搭建神經網絡,本節繼續使用簡單數據集訓練神經網絡。

(1) 導入相關庫并定義使用的設備:

import torch
import torch.nn as nn
import numpy as np
from torch.utils.data import Dataset, DataLoader
device = 'cuda' if torch.cuda.is_available() else 'cpu'

(2) 定義數據集與數據集類 (MyDataset):

x = [[1,2],[3,4],[5,6],[7,8]]
y = [[3],[7],[11],[15]]class MyDataset(Dataset):def __init__(self, x, y):self.x = torch.tensor(x).float().to(device)self.y = torch.tensor(y).float().to(device)def __getitem__(self, ix):return self.x[ix], self.y[ix]def __len__(self): return len(self.x)

(3) 定義數據集 (ds) 和數據加載器 (dl) 對象:

ds = MyDataset(x, y)
dl = DataLoader(ds, batch_size=2, shuffle=True)

(4) 使用 nn 模塊中 Sequential 類定義模型架構:

model = nn.Sequential(nn.Linear(2, 8),nn.ReLU(),nn.Linear(8, 1)
).to(device)

在以上代碼中,我們定義了與上小節相同的網絡架構,nn.Linear 接受二維輸入并為每個數據點提供八維輸出,nn.ReLU 在八維輸出之上執行 ReLU 激活,最后,使用 nn.Linear 接受八維輸入并得到一維輸出。

(5) 打印模型的摘要 (summary),查看模型架構信息。

為了查看模型摘要,需要使用 pip 安裝 torchsummary 庫:

pip install torchsummary

安裝完成后,導入庫 torchsummary

from torchsummary import summary

打印模型摘要,函數接受模型名稱及模型輸入大小(需要使用整數元組)作為參數:

print(summary(model, (2,)))

輸出結果如下所示:

----------------------------------------------------------------Layer (type)               Output Shape         Param #
================================================================Linear-1                    [-1, 8]              24ReLU-2                    [-1, 8]               0Linear-3                    [-1, 1]               9
================================================================
Total params: 33
Trainable params: 33
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.00
Estimated Total Size (MB): 0.00
----------------------------------------------------------------

以第一層輸出為例,其形狀為 (-1, 8),其中 -1 表示 batch size8 表示對于每個數據點會得到一個 8 維輸出,得到形狀為 batch size x 8 的輸出。

(6) 接下來,定義損失函數 (loss_func) 和優化器 (opt) 并訓練模型:

loss_func = nn.MSELoss()
from torch.optim import SGD
opt = SGD(model.parameters(), lr = 0.001)
import time
loss_history = []
start = time.time()
for _ in range(50):for ix, iy in dl:opt.zero_grad()loss_value = loss_func(model(ix),iy)loss_value.backward()opt.step()loss_history.append(loss_value.item())
end = time.time()
print(end - start)

(7) 訓練模型后,在驗證數據集上預測值。

定義驗證數據集:

val = [[8,9],[10,11],[1.5,2.5]]

將驗證數據轉換為浮點數,然后將它們轉換為張量對象并將它們注冊到 device 中,通過模型傳遞驗證數據預測輸出:

val = torch.tensor(val).float()
print(model(val.to(device)))
"""
tensor([[16.7774],[20.6186],[ 4.2415]], device='cuda:0', grad_fn=<AddmmBackward>)
"""

3. PyTorch 模型的保存和加載

神經網絡模型處理的一個重要方面是在訓練后保存和加載模型,保存模型后,我們可以利用已經訓練好的模型中進行推斷,只需要加載已經訓練過的模型,而無需再次對其進行訓練。

3.1 模型保存所需組件

首先了解保存神經網絡模型所需的完整組件:

  • 每個張量(參數)的唯一名稱(鍵)
  • 網絡中張量間的連接的方式
  • 每個張量的值(權重/偏置值)

第一個組件是在定義的 __init__ 階段處理的,而第二個組件是在前向計算方法定義期間處理的。默認情況下,張量中的值在 __init__ 階段隨機初始化,但加載預訓練模型時我們需要加載一組在訓練模型時學習到的固定權重值,并將每個值與特定名稱相關聯。

3.2 模型狀態

model.state_dict() 可以用于了解保存和加載 PyTorch 模型的工作原理,model.state_dict() 中的字典 (OrderedDict) 對應于模型的參數名稱(鍵)及其值(權重和偏置值),state 指的是模型的當前快照,返回的輸出中,鍵是模型網絡層的名稱,值對應于這些層的權重:

print(model.state_dict())
"""
OrderedDict([('0.weight', tensor([[-0.4732,  0.1934],[ 0.1475, -0.2335],[-0.2586,  0.0823],[-0.2979, -0.5979],[ 0.2605,  0.2293],[ 0.0566,  0.6848],[-0.1116, -0.3301],[ 0.0324,  0.2609]], device='cuda:0')), ('0.bias', tensor([ 0.6835,  0.2860,  0.1953, -0.2162,  0.5106,  0.3625,  0.1360,  0.2495],device='cuda:0')), ('2.weight', tensor([[ 0.0475,  0.0664, -0.0167, -0.1608, -0.2412, -0.3332, -0.1607, -0.1857]],device='cuda:0')), ('2.bias', tensor([0.2595], device='cuda:0'))])
"""

3.3 模型保存

使用 torch.save(model.state_dict(), 'mymodel.pth') 可以將模型以 Python 序列化格式保存在磁盤上,其中 mymodel.pth 表示文件名。在調用 torch.save 之前最好將模型傳輸到 CPU 中,將張量保存為 CPU 張量有助于將模型加載到任意機器上:

save_path = 'mymodel.pth'
torch.save(model.state_dict(), save_path)

3.4 模型加載

加載模型首先需要初始化模型,然后從 state_dict 中加載權重:

(1) 使用與訓練時相同的代碼創建一個空模型:

model = nn.Sequential(nn.Linear(2, 8),nn.ReLU(),nn.Linear(8, 1)
).to(device)

(2) 從磁盤加載模型并反序列化以創建一個 OrderedDict 值:

state_dict = torch.load('mymodel.pth')

(3) 加載 state_dict 到模型中,并將其注冊到 device 中,執行預測任務:

model.load_state_dict(state_dict)
model.to(device)val = [[8,9],[10,11],[1.5,2.5]]
val = torch.tensor(val).float()
model(val.to(device))

小結

在本節中,我們使用 PyTorch 在簡單數據集上構建了一個神經網絡,訓練神經網絡來映射輸入和輸出,并通過執行反向傳播來更新權重值以最小化損失值,并利用 Sequential 類簡化網絡構建過程;介紹了獲取網絡中間值的常用方法,以及如何使用 saveload 方法保存和加載模型,以避免再次訓練模型。

系列鏈接

PyTorch實戰(1)——深度學習概述

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

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

相關文章

關于git的安裝(windows)

1.git的介紹 Git 是一個分布式版本控制系統&#xff0c;由 Linus Torvalds 在 2005 年為 Linux 內核開發而創建。它能夠高效地處理從小型到超大型項目的版本管理&#xff0c;具有以下特點&#xff1a; 分布式架構&#xff1a;每個開發者本地都有完整的倉庫副本高效性能&#…

Java后端開發?接口封裝器!

開發接口確實是Java后端開發中最核心、最可見的產出工作。“對入參校驗、處理業務邏輯、返回格式處理”——精準地描述了一個API接口的核心處理流程。 但這只是冰山之上最直觀的部分。一個專業、穩健、可擴展的后端系統&#xff0c;其復雜性和價值絕大部分隱藏在冰山之下。結合…

【沉浸式解決問題】NVIDIA 顯示設置不可用。 您當前未使用連接到NVIDIA GPU 的顯示器。

目錄一、問題描述二、環境版本三、原因分析四、解決方案一、問題描述 在看一篇cuda安裝的教程時&#xff0c;第一步是打開NVIDIA 控制面板&#xff0c;但是我打不開&#xff1a; NVIDIA 顯示設置不可用。 您當前未使用連接到NVIDIA GPU 的顯示器。 二、環境版本 設備&#xf…

牛客周賽 Round 106(小苯的方格覆蓋/小苯的數字折疊/ 小苯的波浪加密器/小苯的數字變換/小苯的洞數組構造/ 小苯的數組計數)

A 小苯的方格覆蓋思路&#xff1a;怎么擺第三行都是橫放的2*1&#xff1b;故若n為奇數&#xff0c;總格子數3n為奇數&#xff0c;無法被2整除&#xff0c;直接排除。#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<iostream> #include<bits/stdc…

高并發內存池(16)-三層緩存的回收過程

高并發內存池&#xff08;16&#xff09;-三層緩存的回收過程 內存池的回收過程是內存管理系統的關鍵環節&#xff0c;它通過分層協作和智能合并機制&#xff0c;確保內存高效重復利用。以下是完整的回收流程解析&#xff1a;一、回收觸發場景 ThreadCache回收&#xff1a;線程…

深入解析MyBatis Mapper接口工作原理

在Java持久層框架中&#xff0c;MyBatis以其靈活性和易用性贏得了廣大開發者的青睞。作為MyBatis的核心概念之一&#xff0c;Mapper接口機制極大地簡化了數據庫操作代碼的編寫。本文將深入剖析MyBatis Mapper接口的工作原理&#xff0c;從基礎概念到底層實現&#xff0c;幫助開…

瘋狂星期四文案網第49天運營日記

網站運營第49天&#xff0c;點擊觀站&#xff1a; 瘋狂星期四 crazy-thursday.com 全網最全的瘋狂星期四文案網站 運營報告 今日訪問量 常州蘇州那些ip鍥而不舍的掃了很多php的頁面 今日搜索引擎收錄情況 k頁面比較嚴重了&#xff0c;哎。 我感覺不該做其他類型文案的 網…

從GPT-5發布來分析LLM大模型幻覺收斂(一)

GPT-5 號稱在任何領域都有博士級別能力。在醫療健康領域&#xff0c;能夠對專業的癌癥診斷報告做通俗易懂的解讀。對復雜的放射治療方案決策&#xff0c;也能提供詳細的分析報告&#xff0c;幫助病人權衡利弊。一位癌癥患者的家屬在發布會上表示&#xff0c;“ 真正鼓舞人心的是…

大模型安全概述、LlamaFirewall

資料搜集整理自網絡。 概述 大模型爆火之后&#xff0c;衍生出大模型安全這一個比較新的領域。和之前的文章一樣&#xff0c;本文有不少新穎的名詞、概念、理論。 信通院、清華大學等多個單位聯合發布的《大模型安全實踐&#xff08;2024&#xff09;》&#xff0c;提出LLM安…

【目標檢測】論文閱讀3

Lightweight tomato ripeness detection algorithm based on the improved RT-DETR 論文地址 摘要 番茄具有很高的營養價值&#xff0c;需要對成熟果實進行準確的成熟度鑒定和選擇性采收&#xff0c;以顯著提高番茄收獲管理的效率和經濟效益。以往對番茄智能收獲的研究往往只以…

Python音頻分析與線性回歸:探索聲音中的數學之美

摘要&#xff1a;通過Python實現WAV音頻信號處理與線性回歸建模&#xff0c;揭示雙聲道音頻的數學關聯性&#xff0c;為聲音特征分析提供新視角。1. 音頻數據處理流程 1.1 WAV文件讀取與預處理 使用scipy.io.wavfile讀取音頻文件&#xff0c;獲取采樣率與時域信號數據&#xff…

Linux shell腳本數值計算與條件執行

變量的數值計算實踐 1 算術運算符 如果要執行算術運算&#xff0c;就會離不開各種運算符號&#xff0c;和其他編程語言類似&#xff0c;Shell 也有很多算術運算符。 下面就給大家介紹一下常見的 Shell 算術運算符&#xff1a; 、-&#xff0c;一元正號和負號。、-&#xff0c;加…

C#實戰:基于iTextSharp實現PDF加密小工具

目錄 1、技術框架 2、代碼實戰 2.1 創建窗體 2.2 后臺代碼邏輯 2.3 PDF加密用戶類型 2.4 PDF加密權限列表 3、運行效果 4、總結 大家日常辦公中有時候為了文檔資料的安全需要對文檔進行加密,尤其是針對PDF文檔這個場景還是非常廣泛的。今天給大家分享使用C#來實現PDF…

基于Labview的旋轉機械AI智能診斷系統

1.摘要本文基于 CWRU 公開軸承數據集提出了一套“AI 輕量級模型 LabVIEW 智能診斷系統”。首先&#xff0c;LabVIEW 端構建了可視化、可交互的智能診斷平臺。系統能夠加載本地振動信號數據&#xff0c;調用訓練好的深度學習模型進行故障識別與狀態判斷。界面集成信號時域監測、…

Qt從qmake遷移到cmake的記錄

文章目錄1.UI程序[開啟/關閉]控制臺2.增加宏定義3.在主項目中引入子項目4.使用C語言文件1.UI程序[開啟/關閉]控制臺 qmake&#xff1a; CONFIG console DEFINES QT_MESSAGELOGCONTEXTcmake&#xff1a; set(CMAKE_WIN32_EXECUTABLE OFF) # ON為關閉控制臺 OFF為開啟控制臺2…

LangChain4J-(3)-模型參數配置

LangChain4j 提供了靈活的模型參數配置方式&#xff0c;允許你根據不同的 AI 模型&#xff08;如 OpenAI、GPT-4、Anthropic 等&#xff09;設置各種參數來控制生成結果。后面手擼代碼繼續在之前章節的代碼上拓展一、日志配置&#xff08;Logging&#xff09;在 LangChain4j 中…

LangGraph - API多種訪問方式

本文介紹了Langgraph服務的四種調用方式&#xff1a;1. 通過LangGraph Studio UI界面手動測試&#xff1b;2. 使用Python SDK進行同步/異步調用&#xff1b;3. 通過REST API測試&#xff1b;4. 使用JavaScript SDK接入。Langgraph 服務端代碼 graph.pyfrom langchain_openai im…

HEI-612 HART/EtherNet/IPModbus TCP 網關:打通工業通信壁壘

在工業自動化領域&#xff0c;HART 協議設備的廣泛應用與以太網網絡的高效管理常面臨 “協議孤島” 難題 —— 老舊 HART 傳感器、變送器難以接入 EtherNet/IP 或 Modbus TCP 系統&#xff0c;數據雙向交互卡頓、調試復雜、兼容性差等問題&#xff0c;嚴重制約生產效率提升。上…

OSPF 的工作過程、Router ID 機制、報文結構

視頻版講解>>>>>>>>>>>>>>路由協議深度解析&#xff1a;從靜態路由到 OSPF 實戰 一、回顧靜態路由&#xff1a;拓撲與核心邏輯 我們先回到上周講解的拓撲圖&#xff0c;這張圖是理解靜態路由的核心載體 —— 路由器作為網段分割的…

Qt 6 與 Qt 5 存在的兼容性差異

之前有提到。我的是Qt5&#xff0c;我朋友的是Qt 6&#xff0c;由于版本不兼容問題&#xff0c;在遷移時會有問題。所以這一我們說說這兩個的區別。&#xff08; 正文開始嘍&#xff01; 總結來說&#xff1a;Qt5遷移至 Qt 6 需&#xff1a;1. 破壞性變更&#xff08;必須修改…