加載tf模型 正確率很低_深度學習模型訓練全流程!

↑↑↑關注后"星標"Datawhale

每日干貨 &?每月組隊學習,不錯過

Datawhale干貨?

作者:黃星源、奉現,Datawhale優秀學習者

本文從構建數據驗證集、模型訓練、模型加載和模型調參四個部分對深度學習中模型訓練的全流程進行講解。一個成熟合格的深度學習訓練流程至少具備以下功能:在訓練集上進行訓練;在驗證集上進行驗證;模型可以保存最優的權重,并讀取權重;記錄下訓練集和驗證集的精度,便于調參。

本文CNN模型構建參考:

https://mp.weixin.qq.com/s/JhFun5I_8Kjkbz6S4613Xw

數據及背景??

https://tianchi.aliyun.com/competition/entrance/531795/introduction(阿里天池 - 零基礎入門CV賽事)

構建驗證集

在機器學習模型(特別是深度學習模型)的訓練過程中,模型是非常容易過擬合的。深度學習模型在不斷的訓練過程中訓練誤差會逐漸降低,但測試誤差的走勢則不一定。

在模型的訓練過程中,模型只能利用訓練數據來進行訓練,并不能接觸到測試集上的樣本,故需要構建驗證數據集對模型進行驗證。

過擬合與欠擬合

786d84bf3d1991ba6c8be760b21a922e.png

擬合(Fitting):就是說這個曲線能不能很好的描述某些樣本,并且有比較好的泛化能力。

過擬合(Overfitting):模型把數據學習的太徹底,以至于把噪聲數據的特征也學習到了,這樣就會導致在后期測試的時候不能夠很好地識別數據,即不能正確的分類,模型泛化能力太差。

欠擬合(UnderFitting):模型沒有很好地捕捉到數據特征,不能夠很好地擬合數據,或者是模型過于簡單無法擬合或區分樣本。

807f4bb9e632cfe061746b2694e06445.png

1fb1fea5ad51ad2964e5201c5dfa527f.png

防止過擬合方法
  1. 正則化方法。正則化方法包括L0正則、L1正則和L2正則,而正則一般是在目標函數之后加上對于的范數。但是在機器學習中一般使用L2正則。
  2. 數據增強(Data augmentation),增大數據的訓練量,還有一個原因就是我們用于訓練的數據量太小導致的,訓練數據占總數據的比例過小。
  3. 重新清洗數據,導致過擬合的一個原因也有可能是數據不純導致的,如果出現了過擬合就需要我們重新清洗數據。
  4. 提前終止法(Early stopping),對模型進行訓練的過程即是對模型的參數進行學習更新的過程,這個參數學習的過程往往會用到一些迭代方法,如梯度下降(Gradient descent)學習算法。提前終止法便是一種迭代次數截斷的方法來防止過擬合的方法,即在模型對訓練數據集迭代收斂之前停止迭代來防止過擬合。
  5. 丟棄法(Dropout)。這個方法在神經網絡里面很常用。丟棄法是ImageNet中提出的一種方法,通俗一點講就是丟棄法在訓練的時候讓神經元以一定的概率不工作。具體看下圖:

6029776c9ef43ed0ce039921eef35789.png

左側為全連接網絡,右側的網絡以 0.5 的概率丟棄神經元。輸出層并沒有應用 Dropout
方法1:L1正則化

在原始的代價函數后面加上一個L1正則化項,即全部權重的絕對值的和,再乘以(這里不像L2正則化項那樣,須要再乘以1/2)。

先計算導數:

上式中表示的符號,那么權重w的更新規則為:比原始的更新規則多出了這一項。

當為正時,, 則更新后的變小;當為負時,>0, 則更新后的變大——因此它的效果就是讓往0靠,使網絡中的權重盡可能為0,也就相當于減小了網絡復雜度,防止過擬合。

另外,上面沒有提到一個問題,當為0時怎么辦?當等于0時,是不可導的。所以我們僅僅能依照原始的未經正則化的方法去更新,這就相當于去掉 這一項,所以我們能夠規定,這樣就把的情況也統一進來了。(編程時,令

方法2:L2正則化(權重衰減)

L2正則化就是在代價函數后面再加上一個正則化項:前一項代表原始的代價函數,后面那一項就是L2正則化項。它是這樣來的:全部參數的平方和,除以訓練集的樣本大小n。λ就是正則項系數,權衡正則項與項的比重。另外另一個系數1/2,1/2經常會看到,主要是為了后面求導的結果方便,后面那一項求導會產生一個2,與1/2相乘剛好湊整。L2正則化項是怎么避免過擬合的呢?我們推導一下看看,先求導:能夠發現L2正則化項對 b 的更新沒有影響,可是對于w的更新有影響:在不使用L2正則化時。求導結果中前系數為 1,經變化后前面系數為 ,由于、、都是正的。所以小于1,它的效果是減小,這也就是權重衰減(weight decay)的由來。

當然考慮到后面的導數項,終于的值可能增大也可能減小。

另外,必須提一下,對于基于mini-batch的隨機梯度下降,w和b更新的公式跟上面給出的有點不同:對照上面參數的更新公式。能夠發現后面那一項變了,變成全部導數加和,乘以再除以,是一個mini-batch中樣本的個數。

在此我們僅僅是解釋了L2正則化項有讓“變小”的效果,可是還沒解釋為什么“變小”能夠防過擬合?

一個所謂“顯而易見”的解釋就是:更小的權值,從某種意義上說,表示網絡的復雜度更低,對數據的擬合剛剛好(這個法則也叫做奧卡姆剃刀),而在實際應用中,也驗證了這一點,L2正則化的效果往往好于未經正則化的效果。當然,對于非常多人(包含我)來說,這個解釋似乎不那么顯而易見,所以這里加入一個略微數學一點的解釋(引自知乎):過擬合的時候,擬合函數的系數往往非常大,為什么?過擬合,就是擬合函數須要顧忌每個點。終于形成的擬合函數波動非常大。在某些非常小的區間里,函數值的變化非常劇烈。

這就意味著函數在某些小區間里的導數值(絕對值)非常大,由于自變量值可大可小,所以僅僅有系數足夠大,才干保證導數值非常大。而L2正則化是通過約束參數的范數使其不要太大,所以能夠在一定程度上降低過擬合情況。

方法3:數據增強(Data augmentation)

在深度學習方法中,海量的訓練數據,意味著能夠用更深的網絡,訓練出更好的模型。所以,能夠在原始數據上做些改動,得到很多其它的數據,以圖片數據集舉例,能夠做各種變換,如:

  • 將原始圖片旋轉一個小角度
  • 加入隨機噪聲
  • 一些有彈性的畸變(elastic distortions),論文《Best practices for convolutional neural networks applied to visual document analysis》對MNIST做了各種變種擴增。
  • 截取(crop)原始圖片的一部分,比方DeepID中,從一副人臉圖中,截取出了100個小patch作為訓練數據,極大地添加了數據集。

法4:提前終止法(Early stopping)

對模型進行訓練的過程即是對模型的參數進行學習更新的過程,這個參數學習的過程往往會用到一些迭代方法,如梯度下降(Gradient descent)學習算法。提前終止法便是一種迭代次數截斷的方法來防止過擬合的方法,即在模型對訓練數據集迭代收斂之前停止迭代來防止過擬合。

提前終止法的具體做法是,在每一個Epoch結束時(一個Epoch集為對所有的訓練數據的一輪遍歷)計算驗證集的正確率,當正確率不再提高時,就停止訓練。這種做法很符合直觀感受,因為正確率都不再提高了,在繼續訓練也是無益的,只會提高訓練的時間。

那么該做法的一個重點便是怎樣才認為驗證集正確率不再提高了呢?并不是說驗證集正確率一降下來便認為不再提高了,因為可能經過這個Epoch后,正確率降低了,但是隨后的Epoch又讓正確率又上去了,所以不能根據一兩次的連續降低就判斷不再提高。一般的做法是,在訓練的過程中,記錄到目前為止最好的驗證集正確率,當連續10次Epoch(或者更多次)沒達到最佳正確率時,則可以認為正確率不再提高了。此時便可以停止迭代了(Early Stopping)。這種策略也稱為“No-improvement-in-n”,n即Epoch的次數,可以根據實際情況取。

方法5:丟棄法(Dropout)

L1、L2正則化是通過改動代價函數來實現的,而丟棄法則是通過改動神經網絡本身來實現的,它是在訓練網絡時用的一種技巧(trike),它的流程例如以下:

835784155749c02d72bd28743f610b4b.png

假設我們要訓練上圖這個網絡,在訓練開始時,我們隨機地“刪除”一部分的隱層單元,視它們為不存在。

477432cb70a8fc813f0bca1a72f5626b.png

保持輸入輸出層不變,如上圖所示,依照BP算法更新上圖神經網絡中的權值(虛線連接的單元不更新,由于它們被“暫時刪除”了)。

以上就是一次迭代的過程,在第二次迭代中,也用相同的方法,僅僅只是這次刪除的那一部分隱層單元,跟上一次刪除掉的肯定是不一樣的。我們每一次迭代都是“隨機”地去刪掉一部分,直至訓練結束。

以上就是 丟棄法t,它為什么有助于防止過擬合呢?能夠簡單地這樣解釋,運用了 丟棄法的訓練過程,相當于訓練了非常多個僅僅有部分隱層單元的神經網絡,每個這種半數網絡,都能夠給出一個分類結果,這些結果有的是正確的,有的是錯誤的。隨著訓練的進行,大部分半數網絡都能夠給出正確的分類結果。那么少數的錯誤分類結果就不會對終于結果造成大的影響。

刪除神經單元,不工作,通常keep_prob取0.5,在編程時可以利用TensorFlow中 DropoutWrappera函數。在訓練過程引入丟棄策略,其Dropout層保留節點比例(keep_prob),每批數據輸入時神經網絡中的每個單元會以1-keep_prob的概率不工作,防止過擬合。

lstmCell = tf.contrib.rnn.DropoutWrapper(cell=lstmCell, output_keep_prob=0.5)

防止欠擬合方法

  1. 添加其他特征項,有時候我們模型出現欠擬合的時候是因為特征項不夠導致的,可以添加其他特征項來很好地解決。例如,“組合”、“泛化”、“相關性”三類特征是特征添加的重要手段,無論在什么場景,都可以照葫蘆畫瓢,總會得到意想不到的效果。除上面的特征之外,“上下文特征”、“平臺特征”等等,都可以作為特征添加的首選項。
  2. 添加多項式特征,這個在機器學習算法里面用的很普遍,例如將線性模型通過添加二次項或者三次項使模型泛化能力更強。例如上面的圖片的例子。
  3. 減少正則化參數,正則化的目的是用來防止過擬合的,但是現在模型出現了欠擬合,則需要減少正則化參數。

數據集劃分

  • 訓練集(Train Set):模型用于訓練和調整模型參數。
  • 驗證集(Validation Set):用來驗證模型精度和調整模型超參數。
  • 測試集(Test Set):驗證模型的泛化能力。

因為訓練集和驗證集是分開的,所以模型在驗證集上面的精度在一定程度上可以反映模型的泛化能力。在劃分驗證集的時候,需要注意驗證集的分布應該與測試集盡量保持一致,不然模型在驗證集上的精度就失去了指導意義。

既然驗證集這么重要,那么如何劃分本地驗證集呢。在一些比賽中,賽題方會給定驗證集;如果賽題方沒有給定驗證集,那么參賽選手就需要從訓練集中拆分一部分得到驗證集。驗證集的劃分有如下幾種方式:

b9a54ef3ddb5019b7d2f2edaaca18fe3.png

  • 留出法(Hold-Out) 直接將訓練集劃分成兩部分,新的訓練集和驗證集。這種劃分方式的優點是最為直接簡單;缺點是只得到了一份驗證集,有可能導致模型在驗證集上過擬合。留出法應用場景是數據量比較大的情況。

  • 交叉驗證法(Cross Validation,CV) 將訓練集劃分成K份,將其中的K-1份作為訓練集,剩余的1份作為驗證集,循環K訓練。這種劃分方式是所有的訓練集都是驗證集,最終模型驗證精度是K份平均得到。這種方式的優點是驗證集精度比較可靠,訓練K次可以得到K個有多樣性差異的模型;CV驗證的缺點是需要訓練K次,不適合數據量很大的情況。

  • 自助采樣法(BootStrap) 通過有放回的采樣方式得到新的訓練集和驗證集,每次的訓練集和驗證集都是有區別的。這種劃分方式一般適用于數據量較小的情況。

這些劃分方法是從數據劃分方式的角度來講的,在現有的數據比賽中一般采用留出法和交叉驗證法。如果數據量比較大,留出法還是比較合適的。當然任何的驗證集劃分得到的驗證集都是要保證訓練集-驗證集-測試集的分布一致,所以如果不管劃分何種的劃分方式都是需要注意的。(這里的分布一般指的是與標簽相關的統計分布,如果標簽是帶有時序信息,則驗證集和測試集的時間間隔應該保持一致。)

模型訓練和驗證

訓練神經網絡的流程

1. 好好檢查數據

訓練神經網絡的第一步是完全不接觸任何神經網絡代碼,而是從徹底檢查數據開始。此步驟至關重要。花時間去檢查數據是一件比較重要的工作。因為數據中往往可能存在異常值,而且了解它們的分布可以有利于我們找到一個更好的模型。

2. 評估框架并得到一個并不完美的baseline

此階段的提示和技巧:

  • 固定隨機種子:始終使用固定的隨機種子來確保兩次運行代碼時您將獲得相同的結果。

  • 簡化:在此階段,請務必關閉任何數據擴充功能。數據擴充是我們稍后可能會采用的一種正則化策略,但是目前這只是引入一種錯誤的嘗試。

  • 驗證損失:驗證您的損失是否從正確的損失值開始。

  • 設定一個好的初始化

  • 人類基線:監控除損失之外的指標,這些指標是人類可以解釋和檢查的(例如準確性)。盡可能評估自己(人類)的準確性并與之進行比較。

  • 可視化預測動態。我喜歡在培訓過程中可視化固定測試批次上的模型預測。這些預測如何運動的“動力”將使您對培訓的進行方式有非常好的直覺。如果網絡以某種方式過度擺動,可能會感覺網絡“努力”以適應您的數據,這表明不穩定。抖動量也很容易注意到非常低或非常高的學習率。

3. 過度擬合

找到一個好的模型的方法有兩個階段:首先獲得一個足夠大的模型以使其可以過度擬合(即專注于訓練損失),然后適當地對其進行正則化(放棄一些訓練損失以提高驗證損失)。

此階段的一些提示和技巧:

  • 選擇模型:為了減少訓練損失,您需要為數據選擇合適的體系結構。

  • Adam是安全的。在設定基準的早期階段,我喜歡以3e-4的學習率使用Adam 。以我的經驗,亞當更寬容超參數,包括不良的學習速度。對于ConvNets,調整良好的SGD幾乎總是比Adam稍勝一籌,但是最佳學習率區域要狹窄得多且針對特定問題。

  • 一次只使一個復雜化。如果您有多個信號要插入您的分類器,我建議您將它們一個接一個地插入,并每次確保獲得預期的性能提升。

  • 不要相信學習率衰減的默認值。如果您要重新使用其他領域的代碼,請務必小心學習率。

4. 正則化

此階段的一些提示和技巧:

  • 獲取更多數據

  • 數據擴充

  • 創意增強:如果半假數據沒有做到這一點,偽造數據也可能會有所作為。人們正在尋找擴展數據集的創新方法。例如,領域隨機化,模擬的使用,巧妙的混合,例如將(潛在模擬的)數據插入場景,甚至GAN。

  • 使用預訓練網絡

  • 堅持監督學習

  • 減小輸入維數

  • 減小模型尺寸

  • 減小批量大小

  • Dropout

  • 提早停止訓練。根據您測得的驗證損失提前停止訓練,以在模型快要過擬合的時候捕獲模型。

  • 嘗試更大的模型。大型模型大多數最終會過擬合,但是它們的“早期停止”性能通常會比小型模型好得多。

5. 微調

此階段的一些提示和技巧:

  • 隨機網格搜索

  • 超參數優化

6. 進一步提高精確率

  • 模型集成

本節目標是使用Pytorch來完成CNN(卷積神經網絡)的訓練和驗證過程,CNN網絡結構。需要完成的邏輯結構如下:

  • 構造訓練集和驗證集;

  • 每輪進行訓練和驗證,并根據最優驗證集精度保存模型。

# 將自定義的Dataset封裝成一個Batch Size大小的Tensor,用于后面的訓練。# 訓練集封裝?批量處理數據train_loader = torch.utils.data.DataLoader(train_dataset,????# 數據加載batch_size=10,?????# 批處理大小設置shuffle=True,?????# 是否進項洗牌操作num_workers=10,???# 是否進行多進程加載數據設置)# 驗證集封裝val_loader = torch.utils.data.DataLoader(val_dataset,batch_size=10,shuffle=False,num_workers=10,)model = SVHN_Model1()criterion = nn.CrossEntropyLoss (size_average=False) # 計算交叉熵(交叉熵損失函數optimizer = torch.optim.Adam(model.parameters())  # Adam優化算法best_loss = 1000.0for epoch in range(20):train(train_loader, model, criterion, optimizer, epoch)val_loss = validate(val_loader, model, criterion)# 保存驗證集精度if val_loss < best_loss:best_loss = val_losstorch.save(model.state_dict(), './model.pt')  print('Epoch: ', epoch)
  • train()、validate()與predict()代碼如下:

# 訓練函數def train(train_loader, model, criterion, optimizer, epoch):????# 切換模型為訓練模式    model.train()    for i, (input, target) in enumerate(train_loader):        c0, c1, c2, c3, c4, c5 = model(data[0])        loss = criterion(c0, data[1][:, 0]) + \                criterion(c1, data[1][:, 1]) + \                criterion(c2, data[1][:, 2]) + \                criterion(c3, data[1][:, 3]) + \                criterion(c4, data[1][:, 4]) + \                criterion(c5, data[1][:, 5])        loss /= 6        optimizer.zero_grad()        loss.backward()        optimizer.step()# 驗證函數def validate(val_loader, model, criterion):    # 切換模型為預測模型    model.eval()    val_loss = []    # 不記錄模型梯度信息    with torch.no_grad():        for i, (input, target) in enumerate(val_loader):            c0, c1, c2, c3, c4, c5 = model(data[0])            loss = criterion(c0, data[1][:, 0]) + \                criterion(c1, data[1][:, 1]) + \                    criterion(c2, data[1][:, 2]) + \                    criterion(c3, data[1][:, 3]) + \                    criterion(c4, data[1][:, 4]) + \                    criterion(c5, data[1][:, 5])            loss /= 6            val_loss.append(loss.item())    return np.mean(val_loss)# 預測函數def predict(test_loader, model, tta=10):    model.eval()    test_pred_tta = None    # TTA 次數    for _ in range(tta):        test_pred = []        with torch.no_grad():            for i, (input, target) in enumerate(test_loader):????????????????#?if?use_cuda:????????????????#?input?=?input.cuda()                c0, c1, c2, c3, c4, c5 = model(input)                output = np.concatenate([                    c0.data.numpy(),                    c1.data.numpy(),                    c2.data.numpy(),                    c3.data.numpy(),                    c4.data.numpy()], axis=1)                test_pred.append(output)        test_pred = np.vstack(test_pred)        if test_pred_tta is None:            test_pred_tta = test_pred        else:            test_pred_tta += test_pred    return test_pred_tta

模型保存與加載

在Pytorch中模型的保存和加載非常簡單,比較常見的做法是保存和加載模型參數:

# 保存模型為文件model.pttorch.save(model_object.state_dict(), 'model.pt')# 讀取文件model.pt載入模型model.load_state_dict(torch.load(' model.pt'))

模型調參

深度學習原理少但實踐性非常強,基本上很多的模型的驗證只能通過訓練來完成。同時深度學習有眾多的網絡結構和超參數,因此需要反復嘗試。訓練深度學習模型需要GPU的硬件支持,也需要較多的訓練時間,如何有效的訓練深度學習模型逐漸成為了一門學問。

深度學習有眾多的訓練技巧,本節挑選了常見的一些技巧來講解,并針對本次賽題進行具體分析。與傳統的機器學習模型不同,深度學習模型的精度與模型的復雜度、數據量、正則化、數據擴增等因素直接相關。所以當深度學習模型處于不同的階段(欠擬合、過擬合和完美擬合)的情況下,大家可以知道可以什么角度來繼續優化模型。在參加本次比賽的過程中建議大家以如下邏輯完成:

  1. 初步構建簡單的CNN模型,不用特別復雜,跑通訓練、驗證和預測的流程。
  2. 簡單CNN模型的損失會比較大,嘗試增加模型復雜度,并觀察驗證集精度。
  3. 在增加模型復雜度的同時增加數據擴增方法,直至驗證集精度不變。

c5f1dc5c343f81a33a1b693c2b11ec9a.png

寫到最后

1. 神經網絡訓練并不是一個十全十美的抽象

據稱,訓練神經網絡很容易上手。許多庫和框架都以顯示30行奇跡片段來解決您的數據問題為榮,給人以假的印象,即這些東西是即插即用的。

>>> your_data = # plug your awesome dataset here>>> model = SuperCrossValidator(SuperDuper.fit, your_data, ResNet50, SGDOptimizer)# conquer world here
比如說,以上代碼給人一種假象,即只通過一行代碼就可以完成對神經網絡的訓練。但事實上神經網絡的訓練是一件很復雜的事情。如果您堅持使用該技術而不了解其工作原理,則很可能會失敗。

2. 神經網絡的訓練不知道怎么的就失敗了

當你錯誤配置代碼時,通常會遇到某種異常:插入了一個整數,該整數應為字符串;該函數僅需要3個參數;導入失敗;該密鑰不存在;兩個列表中的元素數量不相等。此外,通常可以為某些功能創建單元測試。這只是訓練神經網絡的開始。可能在語法上,所有內容都是正確的,但還是會訓練失敗,而且也很難看出來到底哪里錯了。例如,也許在數據增強過程中左右翻轉圖像時忘記了翻轉標簽。網絡仍然可以工作良好,因為網絡可以在內部學習檢測翻轉的圖像,然后左右翻轉預測;也許由于一個錯誤,自回歸模型意外地將它試圖預測的東西作為輸入;或者,嘗試修剪漸變,但修剪了損失,導致在訓練過程中忽略了異常示例;或者,從預先訓練的檢查點初始化了權重,但未使用原始均值;或者,只是搞砸了正則化強度,學習率,其衰減率,模型大小等設置。在大多數情況下,它會訓練,但默默地工作會更糟。

訓練神經網絡的快速而暴力的方法行不通,這往往會令人感到難受。事實上,使得神經網絡正常工作本身就是一件比較困難的事情,可以通過縝密的思考,提高警惕,利用可視化幫助我們訓練神經網絡。

延伸閱讀:
  • 書籍:《深度實踐OCR:基于深度學習的文字識別》

  • 作者:劉樹春 阿里巴巴本地生活研究院算法專家,前復旦七牛云聯合實驗室OCR算法負責人

fa0cde71d86d5edf9194e17abd6e6b3c.gif

專知,專業可信的人工智能知識分發,讓認知協作更快更好!歡迎注冊登錄專知www.zhuanzhi.ai,獲取5000+AI主題干貨知識資料!612e445f470db5ee6b9117419ac15b97.png歡迎微信掃一掃加入專知人工智能知識星球群,獲取最新AI專業干貨知識教程資料和與專家交流咨詢ace7d86cce4f2e265486ce5050191ed6.png點擊“閱讀原文”,了解使用專知,查看獲取5000+AI主題知識資源

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

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

相關文章

Python學習17 Turtle庫繪圖

學習網址&#xff1a;https://docs.python.org/zh-cn/3/library/turtle.html Turtle庫 Turtle庫是Python語言中一個很流行的繪制圖像的函數庫&#xff0c;一個小烏龜&#xff0c;在一個橫軸為x、縱軸為y的坐標系原點&#xff08;畫布中心&#xff09;&#xff0c;(0,0)位置開…

android ros 節點編寫_嵌入式的我們為什么要學ROS

前言本來是要寫一篇STM32移植ROS的一個小lib庫&#xff0c;ROS一般都是需要跑在Linux上的&#xff0c;STM32使用就是當成一個ROS通訊的小節點&#xff0c;但是寫文章時間不夠&#xff0c;所以就簡單做一篇ROS的介紹文章&#xff0c;分享給嵌入式的小伙伴們。ROS現在在機器人領域…

STL源碼剖析 __type_traits

traits編程 彌補了C本身的不足STL只對迭代器進行規范制定出了iterator_traits&#xff0c;SGI在此基礎上進一步擴展&#xff0c;產生了__type_traits雙下劃線的含義是這個是SGI內部使用的東西&#xff0c;不屬于STL標準iterator_traits 負責萃取迭代器的特性__type_traits負責萃…

java 學生成績

題目 對學生成績大于60分的&#xff0c;輸出“合格”。低于60分的&#xff0c;輸出“不合格” 代碼 使用/除法簡化代碼 package l1_switch_case;import java.util.Scanner;public class SwitchDemo2 {public static void main(String[] args) {Scanner scanner new Scanne…

STL源碼剖析 序列式容器|Vector

容器的概觀和分類 array 數組 、list 鏈表、tree樹 、stack堆棧、queue隊列、hash table散列表、set集合、map映射表根據數據在容器中的排列順序&#xff0c;將上述數據結構分為序列式和關聯式兩種類型SGI STL使用內縮方式來表達基層和衍生層之間的關系衍生不是派生&#xff0…

ansible 修改文件變量_Ansible Playbook中的變量與引用

Ansible是一個系列文章&#xff0c;我會盡量以通俗易懂、詼諧幽默的總結方式給大家呈現這些枯燥的知識點&#xff0c;讓學習變的有趣一些。Ansible自動化運維前言前面有說到使用playbook來搞一些復雜的功能&#xff0c;我們使用YAML來寫playbook&#xff0c;就像我們用其它語言…

java 判斷日期為第幾天

題目1 編寫程序&#xff1a;從鍵盤上輸入2019年的“month”和“day”&#xff0c;要求通過程序 輸出輸入的日期為2019年的第幾天。 代碼1 從12月往下加日期數 package l1_switch_case; import java.util.Scanner; public class SwitchDemo4 {public static void main(Strin…

STL源碼剖析 list概述

目錄 list的節點(node) list迭代器 list 的構造和內存管理 list 的元素操作 list相較于vector連續的線性空間就顯得很復雜&#xff0c;他的存儲空間是不連續的&#xff0c;好處是每次插入和刪除一個元素的時候&#xff0c;只需要配置或者釋放一個元素的空間 插入和刪除十分的…

vsftp不允許切換到其它目錄_IntelliJ IDEA如何對project的目錄進行篩選顯示?

如果你的項目很龐大&#xff0c;同一個功能用到的各種文件散落在多個文件夾&#xff0c;開發時切換不便&#xff0c;可以利用scope功能&#xff0c;只顯示該功能用到的文件&#xff0c;讓project列表十分清爽&#xff0c;提高開發效率。本文使用的IDEA版本為2020.1。1、打開sco…

java 年份對應的中國生肖

題目 編寫一個程序&#xff0c;為一個給定的年份找出其對應的中國生肖。 中國的生肖基于12年一個周期&#xff0c; 每年用一個動物代表&#xff1a; rat、ox、tiger、rabbit、dragon、snake、horse、sheep、monkey、 rooster、dog、pig。 提示&#xff1a;2019年&#xff1a;豬…

密碼學專題 對稱加密算法

一般來說&#xff0c;使用OpenSSL對稱加密算法有兩種方式&#xff0c;一種是使用API函數的方式&#xff0c;一種是使用OpenSSL提供的對稱加密算法指令方式。本書將介紹對稱加密算法的指令方式OpenSSL的對稱加密算法指令主要用來對數據進行加密和解密處理&#xff0c;輸入輸出的…

網絡防火墻單向和雙向_單向晶閘管與雙向晶閘管之間的不同之處

晶閘管是回一個可以控導點開關&#xff0c;能以弱電去控制強電的各種電路。晶閘管常用于整流&#xff0c;調壓&#xff0c;交直流變化&#xff0c;開關&#xff0c;調光等控制電路中。具有提交小&#xff0c;重量輕&#xff0c;耐壓高&#xff0c;容量大&#xff0c;效率高&…

java 遍歷100以內的偶數,偶數的和,偶數的個數

題目 遍歷100以內的偶數&#xff0c;偶數的和&#xff0c;偶數的個數 代碼 package l2_for; /*遍歷100以內的偶數&#xff0c;偶數的和&#xff0c;偶數的個數*/ public class ForDemo1 {public static void main(String[] args) {//方法1&#xff1a;int sum1 0,count10;f…

python版本切換_怎么切換python版本

展開全部 &#xff08;1&#xff09;分別安2113裝 python-2.7.12.amd64.msi python-3.5.2-amd64.exe &#xff08;python官網下載的&#xff09; 順序無所謂&#xff08;為5261了看著4102方便&#xff0c;我把安裝路徑修改統一了1653&#xff09; &#xff08;2&#xff09;配置…

java 打印

題目 編寫程序從1循環到150&#xff0c;并在每行打印一個值&#xff0c;另外在每個3的倍數行 上打印出“foo”,在每個5的倍數行上打印“biz”,在每個7的倍數行上打印 輸出“baz”。 代碼 package l2_for;/** 編寫程序從1循環到150&#xff0c;并在每行打印一個值&#xff0c…

react.lazy 路由懶加載_Vue面試題: 如何實現路由懶加載?

非懶加載import List from /components/list.vue const router new VueRouter({routes: [{ path: /list, component: List }] })方案一(常用)const List () > import(/components/list.vue) const router new VueRouter({routes: [{ path: /list, component: List }] })方…

STL源碼剖析 deque雙端隊列 概述

vector是單向開口的連續線性空間&#xff0c;deque是一種雙向開口的連續線性空間。deque可以在頭尾兩端分別進行元素的插入和刪除操作vector和deque的差異 1&#xff0c;deque允許常數時間內對于頭端元素進行插入和刪除操作2&#xff0c;deque沒有所謂容量(capacity)的概念&…

java 最大公約數和最小公倍數

題目 題目&#xff1a;輸入兩個正整數m和n&#xff0c;求其最大公約數和最小公倍數。 比如&#xff1a;12和20的最大公約數是4&#xff0c;最小公倍數是60。 說明&#xff1a;break關鍵字的使用 代碼一 package l2_for; //題目&#xff1a;輸入兩個正整數m和n&#xff0c;求…

python的自帶數據集_Python的Sklearn庫中的數據集

一、Sklearn介紹 scikit-learn是Python語言開發的機器學習庫&#xff0c;一般簡稱為sklearn&#xff0c;目前算是通用機器學習算法庫中實現得比較完善的庫了。其完善之處不僅在于實現的算法多&#xff0c;還包括大量詳盡的文檔和示例。其文檔寫得通俗易懂&#xff0c;完全可以當…

STL源碼剖析 stack 棧 概述->(使用deque雙端隊列 / list鏈表)作為stack的底層容器

Stack是一種先進后出的數據結構&#xff0c;他只有一個出口stack允許 新增元素、移除元素、取得最頂端的元素&#xff0c;但是無法獲得stack的內部數據&#xff0c;因此satck沒有遍歷行為Stack定義的完整列表 (雙端隊列作為Stack的底層容器) 將deque作為Stack的底部結構&#…