從零開始實現神經網絡(三)_RNN循環神經網絡

參考文章:rnn循環神經網絡介紹

循環神經網絡 (RNN) 是一種專門處理序列的神經網絡。它們通常用于自然語言處理?(NLP) 任務,因為它們在處理文本方面很有效。在這篇文章中,我們將探討什么是 RNN,了解它們是如何工作的,并在?Python 中從頭開始(僅使用?numpy)構建一個真正的 RNN。

這篇文章假設你對神經網絡有基本的了解

我的另一篇文章(從零開始實現神經網絡(一)_NN神經網絡)涵蓋了你需要知道的一切,所以我建議先閱讀它。

讓我們開始吧!

一. 使用rnn的原因

普通神經網絡(以及CNN)的一個問題是,它們只在預定大小的情況下工作:它們接受固定大小的輸入并產生固定大小的輸出。RNN 很有用,因為它們讓我們可以將可變長度的序列作為輸入和輸出。以下是 RNN 的幾個示例:

輸入為紅色,RNN 本身為綠色,輸出為藍色

這種處理序列的能力使得RNN非常有用。例如:

  • 機器翻譯(例如谷歌翻譯)是用“多對多”RNN完成的。原始文本序列被輸入到 RNN 中,然后生成翻譯后的文本作為輸出。
  • 情感分析(例如,這是正面評論還是負面評論?)通常使用“多對一”RNN來完成。要分析的文本被輸入到RNN中,然后生成單個輸出分類(例如,這是一個正面評論)。

在本文的后面,我們將從頭開始構建一個“多對一”的 RNN 來執行基本的情感分析。

二. 如何實現rnn

讓我們考慮一個帶有輸入的“多對多”RNN ,輸入是x0,x1,x2.......xn,想要產生輸出y0?,y1?,y2......yn?.這些xi?和yi?是向量,可以具有任意維度。

RNN 通過迭代更新隱藏狀態(h)來工作,這也是一個可以具有任意維度的向量。在任何給定步數(t)時

  1. 下一個隱藏狀態 (?ht? )使用先前的隱藏狀態( ht-1)和下一個輸入xt?進行計算。舉例:如果要求h2的值,那么就是h1和x2的值進行計算得出。
  2. 下一個輸出yt?是由ht計算得來?.

這就是 RNN?循環的原因它對每個步驟使用相同的權重。更具體地說,一個典型的 vanilla RNN 只使用 3 組權重來執行其計算:

  • W_{xh}?,權重用于所有x_{t}?h_{t}之間的運算。
  • W_{hh},權重用于所有h_{t-1}???h_{t}之間的運算。
  • W_{hy}?,權重用于所有h_{t}??y_{t}之間的運算。

我們還將對 RNN 使用兩種偏差:

  • b_{h},在計算h_{t}時被加上。
  • b_{y}?,在計算y_{t}時被加上.

我們將權重表示為矩陣,將偏差表示為向量。這 3 個權重和 2 個偏差構成了整個 RNN!

以下是將所有內容組合在一起的方程式:

h_{t} = tanh(W_{xh}*x_{t} + W_{hh}*h_{t-1} + b_{h})

y_{t} = W_{hy}*h_{t} + b_{y}

不要略過這些方程式。停下來盯著它看一分鐘。另外,請記住,權重是矩陣,其他變量是向量

使用矩陣乘法應用所有權重,并將偏差添加到所得產品中。然后我們使用?tanh?作為第一個方程的激活函數(但也可以使用其他激活,如?sigmoid)。

三. rnn要解決的問題

讓我們親自動手!我們將從頭開始實現一個 RNN 來執行一個簡單的情感分析任務:確定給定的文本字符串是正向情感的還是負向情感。

以下是我為這篇文章整理的小型數據集中的一些示例:

文本字符串正向?
i am good?
i am bad?
this is very good?
this is not bad?
i am bad not good?
i am not at all happy?
this was good earlier?
i am not at all bad or sad right now?

四. 使用方案

由于這是一個分類問題,我們將使用“多對一”RNN。這類似于我們之前討論的“多對多”RNN,但它只使用最終的隱藏狀態來產生一個輸出y:

每個x_{i}將是一個向量,表示文本中的單詞。輸出 y 將是一個包含兩個數字的向量,一個表示正數,另一個表示負數。我們將應用?Softmax?將這些值轉換為概率,并最終在正/負之間做出決定。

讓我們開始構建我們的 RNN!

五. 預處理

我前面提到的數據集由兩個 Python 字典組成,True = 正,False = 負

#this file is data.pytrain_data = {'good': True,'bad': False,# ... more data
}test_data = {'this is happy': True,'i am good': True,# ... more data
}

我們必須進行一些預處理,以將數據轉換為可用的格式。首先,我們將構建數據中存在的所有單詞的詞匯表

#this file is main.py
from data import train_data, test_data# Create the vocabulary.
vocab = list(set([w for text in train_data.keys() for w in text.split(' ')]))
vocab_size = len(vocab)
print('%d unique words found' % vocab_size) # 18 unique words found

vocab現在包含至少一個訓練文本中出現的所有單詞的列表。接下來,我們將分配一個整數索引來表示詞匯中的每個單詞。

#this file is main.py
# Assign indices to each word.
word_to_idx = { w: i for i, w in enumerate(vocab) }
idx_to_word = { i: w for i, w in enumerate(vocab) }
print(word_to_idx['good']) # 16 (this may change)
print(idx_to_word[0]) # sad (this may change)

現在,我們可以用其相應的整數索引來表示任何給定的單詞!這是必要的,因為 RNN 無法理解單詞——我們必須給它們數字。

最后,回想一下每個輸入?x_{i} ?我們的RNN是一個向量。我們將使用?one-hot?(獨熱)向量,它包含除了一個是 1 之外其他都為零的向量。每個 one-hot 向量中的“one”將位于單詞的相應整數索引處。

由于我們的詞匯表中有 18 個獨特的單詞,因此每個單詞x_{i}?將是一個 18 維的獨熱向量。

#this file is main.pyimport numpy as npdef createInputs(text):'''Returns an array of one-hot vectors representing the wordsin the input text string.- text is a string- Each one-hot vector has shape (vocab_size, 1)'''inputs = []for w in text.split(' '):v = np.zeros((vocab_size, 1))v[word_to_idx[w]] = 1inputs.append(v)return inputs

我們稍后將使用向量輸入來傳遞到我們的 RNN。createInputs()

六. 前向傳播

是時候開始實現我們的 RNN 了!我們將首先初始化我們的 RNN 需要的 3 個權重和 2 個偏差:

#this file is rnn.pyimport numpy as np
from numpy.random import randnclass RNN:# A Vanilla Recurrent Neural Network.def __init__(self, input_size, output_size, hidden_size=64):# Weightsself.Whh = randn(hidden_size, hidden_size) / 1000self.Wxh = randn(hidden_size, input_size) / 1000self.Why = randn(output_size, hidden_size) / 1000# Biasesself.bh = np.zeros((hidden_size, 1))self.by = np.zeros((output_size, 1))

注意:我們將除以 1000 以減少權重的初始方差。這不是初始化權重的最佳方法,但它很簡單,適用于這篇文章。

我們使用?np.random.randn()?從標準正態分布初始化我們的權重。

接下來,讓我們實現 RNN 的前向傳播。還記得我們之前看到的這兩個方程式嗎?

h_{t} = tanh(W_{xh}*x_{t} + W_{hh}*h_{t-1} + b_{h})

y_{t} = W_{hy}*h_{t} + b_{y}

以下是代碼實現這個方程式:

#this file is rnn.py
class RNN:# ...def forward(self, inputs):'''Perform a forward pass of the RNN using the given inputs.Returns the final output and hidden state.- inputs is an array of one-hot vectors with shape (input_size, 1).'''h = np.zeros((self.Whh.shape[0], 1))# Perform each step of the RNNfor i, x in enumerate(inputs):h = np.tanh(self.Wxh @ x + self.Whh @ h + self.bh)# Compute the outputy = self.Why @ h + self.byreturn y, h

很簡單,對吧?請注意,我們初始化了?h?到第一步的零向量,因為沒有上一步?h?我們可以在當前節點上使用。

#this file is main.py
# ...def softmax(xs):# Applies the Softmax Function to the input array.return np.exp(xs) / sum(np.exp(xs))# Initialize our RNN!
rnn = RNN(vocab_size, 2)inputs = createInputs('i am very good')
out, h = rnn.forward(inputs)
probs = softmax(out)
print(probs) # [[0.50000095], [0.49999905]]

如果您需要復習 Softmax,請閱讀我當前系列的cnn文章,里面有詳細介紹。

我們的 RNN 有效,但還不是很有用。讓我們改變一下......

七. 反向傳播

為了訓練我們的RNN,我們首先需要一個損失函數。我們將使用交叉熵損失,它通常與 Softmax 配對。以下是我們的計算方式:

L = -ln(p_{c})

pc是我們的 RNN 對正確類別(正或負)的預測概率。例如,如果我們的 RNN 預測一個正文本為 90%,則損失為:

L = -ln(0.90) = 0.105

想要更長的解釋嗎?閱讀我的CNN中的交叉熵損失部分。

現在我們有一個損失,我們將使用梯度下降來訓練我們的 RNN,以盡量減少損失。這意味著是時候推導出一些梯度了!

???以下部分假定您具備多變量微積分的基本知識。如果你愿意,你可以跳過它,但我建議你略讀一下,即使你不太了解。在得出結果時,我們將逐步編寫代碼,即使是表面的理解也會有所幫助。

7.1 定義

首先,定義一些變量:

  • 讓 y 表示 RNN 的原始輸出。
  • 讓 p 表示最終概率:p=softmax(y)
  • 讓?c?引用某個文本樣本的真實標簽,也稱為“正確”類。
  • 讓?L?是交叉熵損失:L = -ln(p_{c})
  • W_{xh}?,W_{hh},W_{hy}成為我們 RNN 中的 3 個權重矩陣。
  • b_{h}?和b_{y}成為我們 RNN 中的 2 個偏置向量。

7.2 設置

接下來,我們需要修改我們的正向傳播,以緩存一些數據以在反向傳播使用。與此同時,我們還將為反向傳播搭建骨架。

rnn.py
class RNN:# ...def forward(self, inputs):'''Perform a forward pass of the RNN using the given inputs.Returns the final output and hidden state.- inputs is an array of one-hot vectors with shape (input_size, 1).'''h = np.zeros((self.Whh.shape[0], 1))self.last_inputs = inputsself.last_hs = { 0: h }# Perform each step of the RNNfor i, x in enumerate(inputs):h = np.tanh(self.Wxh @ x + self.Whh @ h + self.bh)self.last_hs[i + 1] = h# Compute the outputy = self.Why @ h + self.byreturn y, hdef backprop(self, d_y, learn_rate=2e-2):'''Perform a backward pass of the RNN.- d_y (dL/dy) has shape (output_size, 1).- learn_rate is a float.'''pass

是不是好奇我們為什么要做這個緩存?在前面cnn的章節中有相關解釋

?

7.3 梯度(求偏導)

現在是數學時間!我們將從計算\frac{\partial L}{\partial y}開始.

我們知道:

p_{c} = softmax(y_{c})

L = -ln(p_{c} ) = -ln(softmax(y_{c}))

我將留下\frac{\partial L}{\partial y}?使用鏈式法則:

這里假設當前要計算的索引值的i,那么當i是正確的類c時,有:

\frac{\partial L}{\partial y_{i}}\left\{\begin{matrix} p_{i} & if (i\neq c) \\ p_{i}-1 & if(i=c) \end{matrix}\right.?

例如,如果我們有p=[0.?2,0.?2,0.6],正確的類是c=0,那么我們會得到\frac{\partial L}{\partial y}=[?0.8,0.2,0.6]。這也很容易轉化為代碼:

# Loop over each training example
for x, y in train_data.items():inputs = createInputs(x)target = int(y)# Forwardout, _ = rnn.forward(inputs)probs = softmax(out)# Build dL/dyd_L_d_y = probsd_L_d_y[target] -= 1# Backwardrnn.backprop(d_L_d_y)

?好。接下來,讓我們來看看偏導W_{HY}b_{y},僅用于將最終的隱藏狀態轉換為 RNN 的輸出。我們有


h_{n}?是最終的隱藏狀態。因此

同樣地

我們現在可以開始實現反向傳播了!backprop()

class RNN:# ...def backprop(self, d_y, learn_rate=2e-2):'''Perform a backward pass of the RNN.- d_y (dL/dy) has shape (output_size, 1).- learn_rate is a float.'''n = len(self.last_inputs)# Calculate dL/dWhy and dL/dby.d_Why = d_y @ self.last_hs[n].T    d_by = d_y

?

提醒:我們之前創建過。self.last_hs? ?forward()

最后,我們需要偏導W_{hh}W_{xh}b_h,在 RNN 期間的每一步都會使用。我們有:

因為改變?W_{xh}影響每一個?h_t,這些都會影響y,并最終影響L。為了充分計算W_{xh},我們需要通過所有時間步進反向傳播,這稱為時間反向傳播?(BPTT):

W_{xh}用于所有xt???ht?前向鏈接,因此我們必須向反傳播回每個鏈接。

一旦我們到達給定的步驟t,我們需要計算\frac{\partial h_{t}}{\partial W_{xh}}:

h_t = tanh(W_{xh}*x_t +W_{hh}*h_{t-1}+b_h )

我們所知道的tanh求導:

\frac{dtanh(x)}{dx}=1-tanh^{2}(x)

我們像之前那樣使用鏈式法則:

\frac{\partial h_t}{\partial W_{xh}} = (1-h^{2}_t)x_t

同理:

\frac{\partial h_t}{\partial W_{hh}} = (1-h^{2}_t)h_{t-1}

\frac{\partial h_t}{\partial b_{h}} = (1-h^{2}_t)

最后一步,我們需要\frac{\partial y}{\partial h_t},我們可以遞歸計算

我們將從最后一個隱藏狀態開始實現 BPTT 并反向傳播,因此我們已經有了\frac{\partial y}{\partial h_{T+1}}?到我們要計算\frac{\partial y}{\partial h_t}的時候?!最后一個隱藏狀態是例外,h_n

\frac{\partial y}{\partial h_n} = W_{HY}

我們現在擁有最終實現 BPTT 并完成了所需的一切:backprop()

class RNN:# ...def backprop(self, d_y, learn_rate=2e-2):'''Perform a backward pass of the RNN.- d_y (dL/dy) has shape (output_size, 1).- learn_rate is a float.'''n = len(self.last_inputs)# Calculate dL/dWhy and dL/dby.d_Why = d_y @ self.last_hs[n].Td_by = d_y# Initialize dL/dWhh, dL/dWxh, and dL/dbh to zero.d_Whh = np.zeros(self.Whh.shape)d_Wxh = np.zeros(self.Wxh.shape)d_bh = np.zeros(self.bh.shape)# Calculate dL/dh for the last h.d_h = self.Why.T @ d_y# Backpropagate through time.for t in reversed(range(n)):# An intermediate value: dL/dh * (1 - h^2)temp = ((1 - self.last_hs[t + 1] ** 2) * d_h)# dL/db = dL/dh * (1 - h^2)d_bh += temp# dL/dWhh = dL/dh * (1 - h^2) * h_{t-1}d_Whh += temp @ self.last_hs[t].T# dL/dWxh = dL/dh * (1 - h^2) * xd_Wxh += temp @ self.last_inputs[t].T# Next dL/dh = dL/dh * (1 - h^2) * Whhd_h = self.Whh @ temp# Clip to prevent exploding gradients.for d in [d_Wxh, d_Whh, d_Why, d_bh, d_by]:np.clip(d, -1, 1, out=d)# Update weights and biases using gradient descent.self.Whh -= learn_rate * d_Whhself.Wxh -= learn_rate * d_Wxhself.Why -= learn_rate * d_Whyself.bh -= learn_rate * d_bhself.by -= learn_rate * d_by

?需要注意的幾點:

  • 我們已經合并了\frac{\partial L}{\partial y} * \frac{\partial y}{\partial h}\frac{\partial L}{\partial h}
  • 我們會不斷更新一個包含最新變量的變量d_h,\frac{\partial L}{\partial h_{t+1}}?,我們需要計算\frac{\partial L}{\partial h_t}?.
  • 完成 BPTT 后,我們?np.clip()?限制低于 -1 或高于 1 的梯度值。這有助于緩解梯度爆炸問題,即梯度由于具有大量相乘項而變得非常大。對于普通 RNN 來說,梯度的爆炸或消失是相當成問題的——更復雜的 RNN(如?LSTM)通常更有能力處理它們。
  • 計算完所有梯度后,我們使用梯度下降更新權重和偏差。

我們做到了!我們的 RNN 已經完成了。

八. 進行預測

終于到了我們期待的時刻——讓我們測試一下我們的 RNN!

首先,我們將編寫一個輔助函數來使用 RNN 處理數據:

import randomdef processData(data, backprop=True):'''Returns the RNN's loss and accuracy for the given data.- data is a dictionary mapping text to True or False.- backprop determines if the backward phase should be run.'''items = list(data.items())random.shuffle(items)loss = 0num_correct = 0for x, y in items:inputs = createInputs(x)target = int(y)# Forwardout, _ = rnn.forward(inputs)probs = softmax(out)# Calculate loss / accuracyloss -= np.log(probs[target])num_correct += int(np.argmax(probs) == target)if backprop:# Build dL/dyd_L_d_y = probsd_L_d_y[target] -= 1# Backwardrnn.backprop(d_L_d_y)return loss / len(data), num_correct / len(data)

?現在,我們可以編寫訓練循環:

# Training loop
for epoch in range(1000):train_loss, train_acc = processData(train_data)if epoch % 100 == 99:print('--- Epoch %d' % (epoch + 1))print('Train:\tLoss %.3f | Accuracy: %.3f' % (train_loss, train_acc))test_loss, test_acc = processData(test_data, backprop=False)print('Test:\tLoss %.3f | Accuracy: %.3f' % (test_loss, test_acc))

?運行應該輸出如下內容:main.py

--- Epoch 100
Train:  Loss 0.688 | Accuracy: 0.517
Test:   Loss 0.700 | Accuracy: 0.500
--- Epoch 200
Train:  Loss 0.680 | Accuracy: 0.552
Test:   Loss 0.717 | Accuracy: 0.450
--- Epoch 300
Train:  Loss 0.593 | Accuracy: 0.655
Test:   Loss 0.657 | Accuracy: 0.650
--- Epoch 400
Train:  Loss 0.401 | Accuracy: 0.810
Test:   Loss 0.689 | Accuracy: 0.650
--- Epoch 500
Train:  Loss 0.312 | Accuracy: 0.862
Test:   Loss 0.693 | Accuracy: 0.550
--- Epoch 600
Train:  Loss 0.148 | Accuracy: 0.914
Test:   Loss 0.404 | Accuracy: 0.800
--- Epoch 700
Train:  Loss 0.008 | Accuracy: 1.000
Test:   Loss 0.016 | Accuracy: 1.000
--- Epoch 800
Train:  Loss 0.004 | Accuracy: 1.000
Test:   Loss 0.007 | Accuracy: 1.000
--- Epoch 900
Train:  Loss 0.002 | Accuracy: 1.000
Test:   Loss 0.004 | Accuracy: 1.000
--- Epoch 1000
Train:  Loss 0.002 | Accuracy: 1.000
Test:   Loss 0.003 | Accuracy: 1.000

?

九. 結束

就是這樣!在這篇文章中,我們完成了循環神經網絡的演練,包括它們是什么、它們是如何工作的、為什么它們有用、如何訓練它們以及如何實現它們。

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

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

相關文章

圖文教程:從0開始安裝stable-diffusion

現在AI繪畫還是挺火,Midjourney雖然不錯,但是對于我來說還是挺貴的。今天我就來安一下開源的AI繪畫stable-diffusion,它的缺點就是對電腦的要求比較高,尤其是顯卡。 話不多說開搞。 訪問sd的github,https://github.com/AUTOMATIC…

〖大前端 - 基礎入門三大核心之JS篇(51)〗- 面向對象之認識上下文與上下文規則

說明:該文屬于 大前端全棧架構白寶書專欄,目前階段免費,如需要項目實戰或者是體系化資源,文末名片加V!作者:哈哥撩編程,十余年工作經驗, 從事過全棧研發、產品經理等工作,目前在公司…

qt-C++筆記之addAction和addMenu的區別以及QAction的使用場景

qt-C筆記之addAction和addMenu的區別以及QAction的使用場景 code review! 文章目錄 qt-C筆記之addAction和addMenu的區別以及QAction的使用場景1.QMenu和QMenuBar的關系與區別2.addMenu和addAction的使用場景區別3.將QAction的信號連接到槽函數4.QAction的使用場景5.將例1修改…

基于單片機智能澆花控制系統設計

**單片機設計介紹,基于單片機智能澆花控制系統設計 文章目錄 一 概要二、功能設計設計思路 三、 軟件設計原理圖 五、 程序六、 文章目錄 一 概要 基于單片機的智能澆花控制系統可以通過水泵、傳感器和單片機等硬件組件實現自動澆水,減輕人工澆花的工作…

【LeeCode】151.翻轉字符串里的單詞

給你一個字符串 s ,請你反轉字符串中 單詞 的順序。 單詞 是由非空格字符組成的字符串。s 中使用至少一個空格將字符串中的 單詞 分隔開。 返回 單詞 順序顛倒且 單詞 之間用單個空格連接的結果字符串。 注意:輸入字符串 s中可能會存在前導空格、尾隨…

Mysql mybatis 語法示例

service package com.ruoyi.goods.service;import java.util.List; import com.ruoyi.goods.domain.GoodsProducts;/*** 商品Service接口* * author ruoyi* date 2023-08-27*/ public interface IGoodsProductsService {/*** 查詢商品* * param ProductID 商品主鍵* return 商…

基于OpenCV+CNN+IOT+微信小程序智能果實采摘指導系統——深度學習算法應用(含python、JS工程源碼)+數據集+模型(三)

目錄 前言總體設計系統整體結構圖系統流程圖 運行環境Python環境TensorFlow 環境Jupyter Notebook環境Pycharm 環境微信開發者工具OneNET云平臺 模塊實現1. 數據預處理1)爬取功能2)下載功能 2. 創建模型并編譯1)定義模型結構2)優化…

Docker與K8s的區別

Docker 和 K8s(Kubernetes)是兩個不同的技術,它們在容器化應用程序的管理和部署方面有著不同的角色和功能。 Docker 是一種容器化平臺,它允許您將應用程序及其所有依賴項打包到一個獨立的、可移植的容器中。Docker 提供了一種輕量…

《PySpark大數據分析實戰》-03.了解Hive

📋 博主簡介 💖 作者簡介:大家好,我是wux_labs。😜 熱衷于各種主流技術,熱愛數據科學、機器學習、云計算、人工智能。 通過了TiDB數據庫專員(PCTA)、TiDB數據庫專家(PCTP…

恢復Django 項目

隨筆記錄 目錄 1. 重建Mysql DB 2. 啟動Django 項目 2.1 確保你的系統上已安裝pip工具。你可以使用以下命令來檢查pip是否已安裝 2.2 安裝Packages 2.2.1 安裝Django 2.2.2 安裝pymysql 2.2.3 安裝 kafka 2.2.4 安裝 requests 2.2.5 安裝simplepro 2.2.6 安裝libjp…

持續集成交付CICD:GitLabCI上傳Nexus制品

目錄 一、實驗 1.GitLabCI上傳Nexus制品 2.優化GitLabCI(引用系統變量) 3.添加if條件判斷項目類型 4.優化GitLabCI(模板類) 二、問題 1.GitLabCI獲取jar文件失敗 2. GitLabCI獲取流水線項目命名空間失敗 3.GItLab Packag…

.NET 8 編寫 LiteDB vs SQLite 數據庫 CRUD 接口性能測試(準備篇)

WebAppDbTest 項目準備 項目準備1、.net cli 創建項目2、nuget 包引用和項目結構2.1、項目添加相關 nuget 包2.2、WebAppDbTest 項目結構 3、項目代碼說明3.1、CSharp/C# 類文件說明3.2、json 配置文件說明 4、項目運行預覽 數據庫 .db 文件準備1、創建 SQLite 數據庫1.1、在 W…

c#讀取CSV文件跟Excel導入成DataTble

1.讀取CSV文件 /// <summary>/// 讀取CSV文件/// </summary>/// <param name"fileName">文件路徑</param>public static DataTable ReadCSV(string fileName){DataTable dt new DataTable();FileStream fs new FileStream(fileName, FileM…

Python---綜合案例

一、系統需求分析 1、需求分析 使用面向對象編程思想完成學員管理系統的開發&#xff0c;具體如下&#xff1a; ① 系統要求&#xff1a;學員數據存儲在文件中 ② 系統功能&#xff1a;添加學員、刪除學員、修改學員信息、查詢學員信息、顯示所有學員信息、保存學員信息及退…

56.windows docker 安裝ES、Go操作ES

文章目錄 一、環境準備1、 docker安裝ES2、啟動容器3、圖像化客戶端工具ElasticSearch-Head 二、Go ES連接與認證1、 連接ES2、配置ES認證 三、索引的增刪改查四、文檔的增刪改創建單個文檔根據文檔id刪除文檔批量刪除文檔批量創建文檔 五、文檔查詢列表查詢精確匹配模糊匹配嵌…

ubuntu18.04配置cuda+cudnn+tensorrt+anconda+pytorch-gpu+pycharm

一、顯卡驅動安裝 執行nvidia-smi查看安裝情況 二、cuda安裝 cuda官網下載cuda_11.6.2_510.47.03_linux.run&#xff0c;安裝執行 sudo sh cuda_11.6.2_510.47.03_linux.run提升安裝項&#xff0c;驅動不用安裝&#xff0c;即第一項&#xff08;Driver&#xff09;&#xff…

如何使用Java在Excel中添加動態數組公式?

本文由葡萄城技術團隊發布。轉載請注明出處&#xff1a;葡萄城官網&#xff0c;葡萄城為開發者提供專業的開發工具、解決方案和服務&#xff0c;賦能開發者。 前言 動態數組公式是 Excel 引入的一項重要功能&#xff0c;它將 Excel 分為兩種風格&#xff1a;Excel 365 和傳統 …

虹科技術 | IO-Link Wireless如何賦能工廠車間邁向無線自動化?

大規模定制、卓越運營和商業智能正在從根本上改變制造業&#xff0c;為了在競爭中立于不敗之地&#xff0c;制造商需要更加靈活、通用、可擴展和具有成本效益的機器和生產線。隨著制造商向工業 4.0 邁進&#xff0c;更好的適應性、更高的吞吐量和更短的停機時間是他們的共同要求…

打包CSS

接上一個打包HTML繼續進行CSS的打包 1.在之前的文件夾里的src文件夾創建一個css文件 2.在瀏覽器打開webpack——>中文文檔——>指南——>管理資源——>加載CSS 3.復制第一句代碼到終端 4.復制下圖代碼到webpack.config.js腳本的plugins&#xff1a;[.....]內容下…