深度學習基本模塊:RNN 循環神經網絡

循環神經網絡(RNN)是一種專門用于處理序列數據的神經網絡架構。與處理空間數據的卷積神經網絡(Conv2D)不同,RNN通過引入循環連接使網絡具有"記憶"能力,能夠利用之前的信息來影響當前的輸出,非常適合處理音頻波形、頻譜。

一、RNN介紹

1.1 結構

  • 輸入層:序列數據,通常為形狀為(batch_size, seq_len, input_size)的張量
示例:音頻頻譜處理:將音頻轉換為頻譜圖后,seq_len對應時間幀數,input_size對應每個時間幀的頻率維度(如梅爾頻帶數),梅爾頻譜圖特征形狀為 (batch_size, 128, 100) 表示:
-128個時間幀(seq_len=128-每個時間幀有100個梅爾頻帶特征(input_size=100)原始波形處理:直接處理音頻波形時,seq_len對應采樣點數,input_size對應特征維度(如單聲道為1,立體聲為2),16kHz音頻的2秒片段形狀為 (batch_size, 32000, 1) 表示:
-32000個采樣點(seq_len=32000-單聲道音頻(input_size=1
  • RNN層

    • 循環單元:包含一個或多個RNN單元,每個單元包含以下可學習參數:
      • 輸入到隱藏的權重WxhW_{xh}Wxh?,形狀:(hidden_size, input_size)
      • 隱藏到隱藏的權重WhhW_{hh}Whh?,形狀:(hidden_size, hidden_size)
      • 偏置bhb_hbh?,形狀:(hidden_size,)
    • 隱藏狀態hth_tht?,形狀:(batch_size, hidden_size):存儲網絡的狀態信息,在時間步之間傳遞
  • 激活函數

    • 隱藏層激活:通常使用TanhReLUtanh將輸出壓縮到[-1,1]范圍,有助于緩解梯度爆炸;ReLU計算高效,但可能導致梯度消失。
    • 輸出層激活:根據任務選擇(Softmax用于分類,線性激活用于回歸)

1.2 參數

  • input_size:每個時間步輸入的特征數量。對于音頻頻譜,通常是頻率維度(如梅爾頻帶數)
  • hidden_size:隱藏狀態的維度,決定RNN的記憶容量和表征能力
  • num_layers:堆疊的RNN層數,增加層數可提高模型復雜度但也會增加計算量
  • nonlinearity:激活函數選擇,Tanh適合大多數情況,RELU在某些場景可能表現更好
  • bias:是否在計算中添加可學習的偏置項
  • batch_first:輸入張量的維度順序。True: (batch, seq, feature)False: (seq, batch, feature)
  • dropout:在多層RNN中應用dropout防止過擬合,0表示不使用dropout
  • bidirectional:是否使用雙向RNN,True時會同時考慮前向和后向序列信息

1.3 輸入輸出維度

  • 輸入數據維度(batch_size, seq_len, input_size)(當 batch_first=True 時)
  • 輸出序列維度(batch_size, seq_len, hidden_size * num_directions)(當 batch_first=True 時)
  • 最終隱藏狀態(num_layers * num_directions, batch_size, hidden_size)

1.4 計算過程

ht=tanh?(Wxh×xt+Whh×ht?1+bh)h_t = \tanh(W_{xh} \times x_t + W_{hh} \times h_{t-1} + b_h)ht?=tanh(Wxh?×xt?+Whh?×ht?1?+bh?)

其中:

  • hth_tht?:當前時間步的隱藏狀態(也是該時間步的輸出)
  • ht?1h_{t-1}ht?1?:上一時間步的隱藏狀態
  • xtx_txt?:當前時間步的輸入
  • WxhW_{xh}Wxh?:輸入到隱藏的權重矩陣
  • WhhW_{hh}Whh?:隱藏到隱藏的權重矩陣
  • bhb_hbh?:偏置項
  • tanh?\tanhtanh:激活函數

對于多層RNN(num_layers > 1):
ht(l)=tanh?(Wxh(l)ht(l?1)+Whh(l)ht?1(l)+bh(l))h_t^{(l)} = \tanh(W_{xh}^{(l)} h_t^{(l-1)} + W_{hh}^{(l)} h_{t-1}^{(l)} + b_h^{(l)})ht(l)?=tanh(Wxh(l)?ht(l?1)?+Whh(l)?ht?1(l)?+bh(l)?)

其中
ht(0)=xth_t^{(0)} = x_tht(0)?=xt?

1.5 計算過程可視化

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.patches import Circle, Arrow# 創建畫布
fig, ax = plt.subplots(figsize=(12, 6))
ax.set_xlim(0, 10)
ax.set_ylim(0, 5)
ax.axis('off')
plt.title('RNN Computation Process', fontsize=16, pad=20)# 顏色定義
input_color = '#FFD700'  # 金色
hidden_color = '#1E90FF'  # 道奇藍
active_color = '#FF4500'  # 橙紅色
arrow_color = '#8B0000'  # 深紅色# 初始化節點
time_steps = 3
input_nodes = []
hidden_nodes = []
input_texts = []
hidden_texts = []# 初始隱藏狀態
h_init = Circle((0.5, 2.5), 0.3, facecolor='lightgray', edgecolor='black')
ax.add_patch(h_init)
ax.text(0.5, 2.5, 'h_{-1}', ha='center', va='center', fontsize=10)# 創建節點
for t in range(time_steps):# 輸入節點input_circle = Circle((2.5 + t * 2.5, 4), 0.3, facecolor=input_color, edgecolor='black', alpha=0.7)ax.add_patch(input_circle)input_nodes.append(input_circle)input_text = ax.text(2.5 + t * 2.5, 4, f'x_{t}', ha='center', va='center', fontsize=10)input_texts.append(input_text)# 隱藏狀態節點hidden_circle = Circle((2.5 + t * 2.5, 2.5), 0.3, facecolor=hidden_color, edgecolor='black', alpha=0.7)ax.add_patch(hidden_circle)hidden_nodes.append(hidden_circle)hidden_text = ax.text(2.5 + t * 2.5, 2.5, f'h_{t}', ha='center', va='center', fontsize=10)hidden_texts.append(hidden_text)# 時間步標簽ax.text(2.5 + t * 2.5, 4.8, f'Time Step {t}', ha='center', fontsize=10)# 繪制連接線
arrows = []
arrow_labels = []# 輸入到隱藏的連接
for t in range(time_steps):arrow = Arrow(2.5 + t * 2.5, 3.7, 0, -0.9, width=0.1, color='gray', alpha=0.3)ax.add_patch(arrow)arrows.append(arrow)label = ax.text(2.7 + t * 2.5, 3.2, '$W_{xh}$', fontsize=10, alpha=0.3)arrow_labels.append(label)# 隱藏到隱藏的連接
for t in range(time_steps):if t == 0:# 初始隱藏狀態到第一個隱藏狀態arrow = Arrow(0.8, 2.5, 1.5, 0, width=0.1, color='gray', alpha=0.3)ax.add_patch(arrow)arrows.append(arrow)label = ax.text(1.5, 2.7, '$W_{hh}$', fontsize=10, alpha=0.3)arrow_labels.append(label)else:# 隱藏狀態之間的連接arrow = Arrow(2.5 + (t - 1) * 2.5, 2.5, 2.5, 0, width=0.1, color='gray', alpha=0.3)ax.add_patch(arrow)arrows.append(arrow)label = ax.text(2.5 + (t - 1) * 2.5 + 1.25, 2.7, '$W_{hh}$', fontsize=10, alpha=0.3)arrow_labels.append(label)# 添加公式
formula_text = ax.text(5, 1, '', fontsize=14, ha='center')# 動畫更新函數
def update(frame):# 重置所有顏色for node in input_nodes + hidden_nodes:node.set_alpha(0.7)if node.get_facecolor() != active_color:node.set_facecolor(input_color if node in input_nodes else hidden_color)for arrow in arrows:arrow.set_alpha(0.3)arrow.set_color('gray')for label in arrow_labels:label.set_alpha(0.3)# 根據幀數更新if frame == 0:# 初始狀態formula_text.set_text('Initialization: $h_{-1} = 0$')h_init.set_facecolor(active_color)h_init.set_alpha(1.0)elif frame <= time_steps:t = frame - 1# 激活當前輸入input_nodes[t].set_facecolor(active_color)input_nodes[t].set_alpha(1.0)# 激活輸入到隱藏的連接arrows[t].set_alpha(1.0)arrows[t].set_color(arrow_color)arrow_labels[t].set_alpha(1.0)# 激活隱藏狀態hidden_nodes[t].set_facecolor(active_color)hidden_nodes[t].set_alpha(1.0)# 激活隱藏到隱藏的連接if t == 0:arrows[time_steps].set_alpha(1.0)arrows[time_steps].set_color(arrow_color)arrow_labels[time_steps].set_alpha(1.0)else:arrows[time_steps + t].set_alpha(1.0)arrows[time_steps + t].set_color(arrow_color)arrow_labels[time_steps + t].set_alpha(1.0)# 顯示公式formula_text.set_text(f'Compute $h_{t}$: $h_{t} = \\tanh(W_{{xh}} x_{t} + W_{{hh}} h_{t - 1} + b_h)$')return input_nodes + hidden_nodes + arrows + arrow_labels + [formula_text, h_init]# 創建動畫
animation = FuncAnimation(fig, update, frames=range(time_steps + 1),interval=1500, blit=True)plt.tight_layout()
animation.save('rnn_core_animation.gif', writer='pillow', fps=1, dpi=100)
plt.show()

在這里插入圖片描述

二、代碼示例

通過兩層RNN處理一段音頻頻譜,打印每層的輸出形狀、參數形狀,并可視化特征圖。

import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import librosa
import numpy as np# 定義 RNN 模型
class RNNModel(nn.Module):def __init__(self, input_size):super(RNNModel, self).__init__()self.rnn1 = nn.RNN(input_size, 128, batch_first=True)self.rnn2 = nn.RNN(128, 64, batch_first=True)def forward(self, x):h_out1, _ = self.rnn1(x)h_out2, _ = self.rnn2(h_out1)return h_out1, h_out2  # 返回兩層的輸出# 讀取音頻文件并處理
file_path = 'test.wav'
waveform, sample_rate = librosa.load(file_path, sr=16000, mono=True)# 選取 3 秒的數據
start_sample = int(1.5 * sample_rate)
end_sample = int(4.5 * sample_rate)
audio_segment = waveform[start_sample:end_sample]# 轉換為頻譜
n_fft = 512
hop_length = 256
spectrogram = librosa.stft(audio_segment, n_fft=n_fft, hop_length=hop_length)
spectrogram_db = librosa.amplitude_to_db(np.abs(spectrogram))
spectrogram_tensor = torch.tensor(spectrogram_db, dtype=torch.float32).unsqueeze(0)
spectrogram_tensor = spectrogram_tensor.permute(0, 2, 1)  # 調整為 (batch_size, seq_len, input_size)
print(f"Spectrogram tensor shape: {spectrogram_tensor.shape}")# 創建 RNN 模型實例
input_size = spectrogram_tensor.shape[2]
model = RNNModel(input_size)# 前向傳播
rnn_output1, rnn_output2 = model(spectrogram_tensor)
print(f"RNN Layer 1 output shape: {rnn_output1.shape}")
print(f"RNN Layer 2 output shape: {rnn_output2.shape}")# 打印每層的參數形狀
print(f"RNN Layer 1 weights shape: {model.rnn1.weight_ih_l0.shape}")
print(f"RNN Layer 1 hidden weights shape: {model.rnn1.weight_hh_l0.shape}")
print(f"RNN Layer 1 bias shape: {model.rnn1.bias_ih_l0.shape}")print(f"RNN Layer 2 weights shape: {model.rnn2.weight_ih_l0.shape}")
print(f"RNN Layer 2 hidden weights shape: {model.rnn2.weight_hh_l0.shape}")
print(f"RNN Layer 2 bias shape: {model.rnn2.bias_ih_l0.shape}")# 可視化原始頻譜
plt.figure(figsize=(10, 4))
plt.imshow(spectrogram_db, aspect='auto', origin='lower', cmap='inferno')
plt.title("Original Spectrogram")
plt.xlabel("Time Frames")
plt.ylabel("Frequency Bins")
plt.colorbar(format='%+2.0f dB')
plt.tight_layout()# 可視化 RNN 輸出的特征圖
plt.figure(figsize=(10, 4))# 繪制第一層 RNN 輸出的特征圖
plt.subplot(2, 1, 1)
plt.imshow(rnn_output1[0].detach().numpy().T, aspect='auto', origin='lower', cmap='inferno')  # 轉置
plt.title("RNN Layer 1 Output Feature Map")
plt.xlabel("Time Steps")
plt.ylabel("Hidden State Dimensions")
plt.colorbar(label='Hidden State Value')# 繪制第二層 RNN 輸出的特征圖
plt.subplot(2, 1, 2)
plt.imshow(rnn_output2[0].detach().numpy().T, aspect='auto', origin='lower', cmap='inferno')  # 轉置
plt.title("RNN Layer 2 Output Feature Map")
plt.xlabel("Time Steps")
plt.ylabel("Hidden State Dimensions")
plt.colorbar(label='Hidden State Value')plt.tight_layout()
plt.show()
Spectrogram tensor shape: torch.Size([1, 188, 257])
RNN Layer 1 output shape: torch.Size([1, 188, 128])
RNN Layer 2 output shape: torch.Size([1, 188, 64])
RNN Layer 1 weights shape: torch.Size([128, 257])
RNN Layer 1 hidden weights shape: torch.Size([128, 128])
RNN Layer 1 bias shape: torch.Size([128])
RNN Layer 2 weights shape: torch.Size([64, 128])
RNN Layer 2 hidden weights shape: torch.Size([64, 64])
RNN Layer 2 bias shape: torch.Size([64])

在這里插入圖片描述
在這里插入圖片描述

三、RNN的梯度消失與長期依賴問題

循環神經網絡(RNN)在處理序列數據時面臨兩個核心問題:梯度消失問題和長期依賴問題。這些問題的根源在于RNN的結構和訓練機制。

3.1 梯度消失問題

RNN通過時間反向傳播(BPTT)算法進行訓練,梯度需要沿著時間步反向傳播。當序列較長時,梯度在反向傳播過程中會指數級地減小或增大。

考慮RNN的計算公式:
ht=tanh?(Wxhxt+Whhht?1+bh)h_t = \tanh(W_{xh}x_t + W_{hh}h_{t-1} + b_h)ht?=tanh(Wxh?xt?+Whh?ht?1?+bh?)

在反向傳播時,需要計算損失函數LLL對參數WhhW_{hh}Whh?的梯度:
?L?Whh=∑t=1T?L?hT?hT?ht?ht?Whh\frac{\partial L}{\partial W_{hh}} = \sum_{t=1}^T \frac{\partial L}{\partial h_T} \frac{\partial h_T}{\partial h_t} \frac{\partial h_t}{\partial W_{hh}}?Whh??L?=t=1T??hT??L??ht??hT???Whh??ht??

關鍵項是?hT?ht\frac{\partial h_T}{\partial h_t}?ht??hT??,它可以通過鏈式法則展開:
?hT?ht=∏k=tT?1?hk+1?hk=∏k=tT?1Whh??diag(tanh?′(zk))\frac{\partial h_T}{\partial h_t} = \prod_{k=t}^{T-1} \frac{\partial h_{k+1}}{\partial h_k} = \prod_{k=t}^{T-1} W_{hh}^\top \cdot \text{diag}(\tanh'(z_k))?ht??hT??=k=tT?1??hk??hk+1??=k=tT?1?Whh???diag(tanh(zk?))

其中
zk=Wxhxk+Whhhk?1+bhz_k = W_{xh}x_k + W_{hh}h_{k-1} + b_hzk?=Wxh?xk?+Whh?hk?1?+bh?

由于tanh?\tanhtanh的導數tanh?′(z)=1?tanh?2(z)\tanh'(z) = 1 - \tanh^2(z)tanh(z)=1?tanh2(z)的值域為(0,1](0, 1](0,1],且WhhW_{hh}Whh?通常初始化為小隨機數,這個連乘積會指數級衰減:
∣∏k=tT?1?hk+1?hk∣≤∣Whh∣T?t?(max?tanh?′)T?t\left| \prod_{k=t}^{T-1} \frac{\partial h_{k+1}}{\partial h_k} \right| \leq \left| W_{hh} \right|^{T-t} \cdot (\max \tanh')^{T-t}?k=tT?1??hk??hk+1???Whh?T?t?(maxtanh)T?t
T?tT-tT?t很大時,這個值趨近于0,導致早期時間步的梯度消失。

影響

  • 早期時間步的參數無法有效更新:網絡難以學習長序列中早期時間步的重要信息
  • 訓練過程緩慢且不穩定:梯度太小導致參數更新幅度極小
  • 模型無法捕捉長期模式:只能記住短期信息,難以學習長序列中的依賴關系

3.2 長期依賴問題

即使沒有梯度消失問題,RNN也難以有效利用序列中相距較遠的信息。這是因為隱藏狀態的表示能力有限,信息在多次變換中逐漸"稀釋"。

考慮信息從時間步t傳遞到時間步T的過程:
hT=f(hT?1,xT)=f(f(hT?2,xT?1),xT)=?=f(?f(ht,xt+1)??,xT)h_T = f(h_{T-1}, x_T) = f(f(h_{T-2}, x_{T-1}), x_T) = \cdots = f(\cdots f(h_t, x_{t+1}) \cdots, x_T)hT?=f(hT?1?,xT?)=f(f(hT?2?,xT?1?),xT?)=?=f(?f(ht?,xt+1?)?,xT?)

每次變換fff都會對信息進行非線性轉換和壓縮,經過多次變換后,早期信息hth_tht?hTh_ThT?的影響變得微弱且難以區分。

示例在語言建模中,考慮句子:"The clouds in the sky are [...] color." 要預測最后一個詞"blue",需要記住開頭的"clouds"信息。標準RNN很難保持這種長距離依賴。

3.3 梯度爆炸問題

與梯度消失相反,當權重矩陣WhhW_{hh}Whh?的特征值大于 1 時,梯度在反向傳播過程中會指數級增長。這種現象被稱為梯度爆炸。

在 RNN 的反向傳播過程中,梯度的計算可以表示為:
∣∏k=tT?1?hk+1?hk∣≤∣Whh∣T?t\left| \prod_{k=t}^{T-1} \frac{\partial h_{k+1}}{\partial h_k} \right| \leq \left| W_{hh} \right|^{T-t}?k=tT?1??hk??hk+1???Whh?T?t

如果∥Whh∥>1\| W_{hh} \| > 1Whh?>1,則梯度的范數會指數增長,導致以下問題:

  • 參數更新過大:由于梯度過大,參數更新可能會超出合理范圍,導致模型無法收斂。
  • 訓練不穩定:模型的訓練過程可能變得不穩定,導致損失函數波動較大。
  • 可能產生 NaN 值:在極端情況下,過大的參數更新可能導致數值溢出,從而產生 NaN 值。

為了解決梯度爆炸問題,可以采取以下措施:

  • 梯度裁剪:通過限制梯度的大小,確保參數更新不會過大。常用的方法是將梯度的 L2 范數限制在一個預設的閾值之內。例如,如果梯度的范數超過閾值,則按比例縮放梯度。
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm)
    
  • 權重正則化:通過約束權重矩陣的范數,防止權重過大。常見的正則化方法包括 L2 正則化(權重衰減)和 L1 正則化。

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

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

相關文章

React18學習筆記(二) React的狀態管理工具--Redux,案例--移動端外賣平臺

文章目錄一.Redux的基礎用法1.示例:普通網頁中的Redux計步器2.Redux管理數據的流程3.配套工具和環境準備3.1.配套工具3.2.環境準備4.示例:React項目中的Redux計步器思路步驟step1:創建子模塊step2:導入子模塊step3:注入store實例step4:React組件內使用store中的數據step5:在組件…

34.Socket編程(UDP)(上)

點分十進制字符串IP 轉 32位網絡序列IP 分析&#xff1a;1&#xff09;IP轉成4字節 2&#xff09;4字節轉成網絡序列 思路&#xff1a; "192.168.1.1" 進行字符串劃分&#xff0c;以 "." 為分割符&#xff0c;分割出"192"&#xff0c;&qu…

Redis的持久化工具包—RDB AOF

文章目錄 前言 一、RDB 持久化&#xff08;快照持久化&#xff09; 1. 定義 2. RDB 觸發機制 &#xff08;1&#xff09;手動觸發 &#xff08;2&#xff09;自動觸發 3. RDB 持久化流程 4. RDB 核心配置 5. RDB 優缺點 二、AOF 持久化&#xff08;日志持久化&#xff09; 1. 定…

【Web安全】XXL-JOB框架SRC高頻漏洞分析總結

文章目錄前言一、核心漏洞分類與技術細節二、漏洞關聯利用與攻擊路徑三、版本演進與修復策略四、安全運維建議五、典型漏洞復現環境搭建六、總結前言 XXL-JOB是國內主流的開源分布式任務調度框架&#xff0c;由徐雪里開發維護&#xff0c;以輕量易用、高可用、適配分布式場景等…

Capacitor 打包后接口訪問不到的排查經歷

我最近在用 Quasar Capacitor 6 做一個 Android App&#xff0c;前端用的是 Vue3 Quasar&#xff0c;打包交給 Capacitor 去跑在手機的 WebView 里&#xff0c;后端是 FastAPI 提供接口。開發模式下一切順利&#xff0c;瀏覽器里訪問接口沒有任何問題&#xff0c;我甚至覺得打…

【正點原子】Linux應用編程入門~概念及環境介紹

應用編程概念 應用編程&#xff08;也可稱為系統編程&#xff09;與驅動編程、裸機編程有何不同&#xff1f;系統調用&#xff1b;何為庫函數&#xff1b;應用程序的 main()函數&#xff1b;應用程序開發環境的介紹&#xff1b;系統調用 定義系統調用&#xff08;system call&a…

一、HTML 完全指南:從零開始構建網頁

文章目錄前言一、 HTML 結構認識 HTML 標簽HTML 文件基本結構標簽層次結構快速生成代碼框架二、 HTML 常見標簽詳解2.1 注釋標簽2.2 標題標簽 (h1 - h6)2.3 段落標簽 (p)2.4 換行標簽 (br)2.5 格式化標簽2.6 圖片標簽 (img)2.7 超鏈接標簽 (a)2.8 表格標簽基本使用合并單元格2.…

基于POI-TL實現動態Word模板的數據填充:【散點圖】特殊處理方案

基于POI-TL實現動態Word模板的數據填充:散點圖特殊處理方案 在使用POI-TL進行Word模板動態數據填充時,圖表生成是一個常見需求。最近在項目中使用POI-TL處理散點圖時遇到了一個特殊問題,經過研究后找到了解決方案,特此記錄分享。 問題背景 POI-TL作為一款優秀的Java Wor…

使用node-Express框架寫一個學校宿舍管理系統練習項目-前后端分離

今天繼續分享一個新的練習項目&#xff0c;是使用node做為后端語言&#xff0c;來寫的一個前后端分離項目&#xff1a;學校宿舍管理系統。我們如果想掌握一門編程語言&#xff0c;就是需要大量的練習。所以當我們學習到了一些知識&#xff0c;自己想一下 可以拿學到的知識&…

Kafka 運維實戰基本操作含命令與最佳實踐

1. 基礎概覽與工具入口 Kafka 發行包的所有 CLI 工具均在 bin/ 目錄下。任何工具不帶參數運行都會顯示所有可用選項。本文命令默認&#xff1a;--bootstrap-server localhost:9092&#xff1b;生產請替換為你的控制面或內網 VIP。 2. 主題管理&#xff08;創建 / 修改 / 刪除 /…

貪心算法應用:航班起降問題詳解

Java中的貪心算法應用&#xff1a;航班起降問題詳解 貪心算法是一種在每一步選擇中都采取當前狀態下最優的選擇&#xff0c;從而希望導致全局最優解的算法策略。在航班起降問題中&#xff0c;貪心算法可以有效地解決機場跑道調度問題&#xff0c;即如何安排航班的起降順序以最大…

uniapp scroll-view 設置scrollTop無效

當我們使用 scroll-view的scroll-top的時候 默認想讓它回到頂部&#xff0c;當我們設置值為0的時候會不生效&#xff0c;在實際運用過程中&#xff0c;發現設置了scroll-top無效&#xff0c;滾動條位置并沒有發生變化&#xff0c;是因為微信小程序的官方框架處于性能考慮&#…

網絡與通信

1.TCP協議與UDP協議TCP&#xff08;Transmission Control Protocol&#xff0c;傳輸控制協議&#xff09;和 UDP&#xff08;User Datagram Protocol&#xff0c;用戶數據報協議&#xff09;是 TCP/IP 協議族中兩種核心的傳輸層協議&#xff0c;它們在數據傳輸方式、可靠性、適…

Node.js中package.json詳解

1. name&#xff08;名稱&#xff09; 如果你計劃發布你的包&#xff0c;package.json 中最重要的字段是 name 和 version&#xff0c;因為它們是必需的。name 和 version 共同組成一個假定完全唯一的標識符。包的更改應伴隨版本號的更新。如果你不打算發布包&#xff0c;那么…

代碼隨想錄第14天| 翻轉、對稱與深度

226.翻轉二叉樹 &#xff08;優先掌握遞歸&#xff09; 題目鏈接/文章講解/視頻講解&#xff1a;翻轉二叉樹 交換的是指針&#xff0c;而不是數值&#xff0c;如果用數值做交換&#xff0c;需要交換的節點下面無法很好的操作。 使用遞歸來實現&#xff0c;但要提前清除是什么順…

DNS-Windows上使用DNS

DNS-Windows上使用DNS一、查看與修改DNS配置1.1、查看當前DNS服務器設置1.2、臨時修改 DNS 服務器&#xff08;命令行&#xff09;二、DNS緩存相關操作2.1、查看DNS緩存內容2.2、 刷新 DNS 緩存&#xff08;清除過期記錄&#xff09;三、測試域名解析&#xff08;nslookup 工具…

3dsMax 2026 .NET Core 8 轉型下的Maxscript腳本開發:動態編譯模塊的重構策略與兼容性升級路徑

3ds Max 長期以來一直提供出色的 .NET 集成,使 Maxscript 能夠無縫利用任何 .NET 庫的強大功能。部分開發者在工具中廣泛使用了 .NET 功能。 之前,3ds Max 依賴于 .NET Framework 4.8 并且最近更新到了 4.8.1,用于 2025 版本的發布。然而,隨著 3ds Max 2026 的推出,Autod…

golang 做webrtc開發核心

在Golang中進行WebRTC開發&#xff0c;核心在于理解WebRTC協議的工作原理以及如何利用Go生態中的庫來實現關鍵功能。以下是Golang WebRTC開發的核心要點&#xff1a; WebRTC基礎概念 了解ICE&#xff08;Interactive Connectivity Establishment&#xff09;協議用于NAT穿越掌握…

RabbitMQ 異步化抗洪實戰

說明&#xff1a;本文僅展示架構思路與安全片段&#xff0c;所有敏感字段已用占位符&#xff1b;不含可直接復刻的生產細節。數據與接口均為演示/虛擬。0. 背景與目標長耗時/不確定接口&#xff08;如對接第三方機器人平臺&#xff09;的同步阻塞&#xff0c;容易造成請求堆積與…

接口返回 2 萬條數據,easy-trans導致多了20s耗時排查過程

內網訪問排版核料詳情功能&#xff0c;用戶反饋要等十幾秒排查 sql&#xff1a;sql 比較簡單排查內存計算&#xff1a;arthus trace 類名 方法名 總耗時2s排查頁面渲染是否緩慢&#xff1a;F12 查看接口 等待服務器響應 20s 下載時間 30s, 故不考慮渲染問題排查請求響應日志打…