<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] > [參考](https://tonybai.com/2024/06/10/go-and-nn-part2-linear-regression) ## 概述 說明一下人工智能、機器學習、神經網絡以及深度學習的關系 ![](https://img.kancloud.cn/e5/ae/e5aebad94a6d56af0efacc225897ec1d_561x411.png) 詳細圖 ![](https://img.kancloud.cn/e4/e2/e4e285d0d8c8c60b5a4841edc226c50b_800x853.png) ## 概念 ### 特征、標簽與模型 ![](https://img.kancloud.cn/51/7e/517eb973897ccda8049b7644b4d6ffa6_1361x611.png) - 左上角的表格就是“喂給”機器學習訓練的**訓練數據集(training dataset )** - 表中每條數據有三個影響房價的“因子”:居住面積、離市中心距離和建成時間(也就是房齡),這些因子共同決定了房子的價格。在機器學習中,我們稱這些“因子”為**特征(feature)**。而房價則被稱為**標簽(label)**。 ![](https://img.kancloud.cn/fa/53/fa539c266efb6fa2c3fcd4fac97a4ea8_761x401.png) 機器學習的目的就是找到通過特征預測標簽的函數(即**模型**),然后將得到的函數應用于生產中進行標簽預測。特征是機器學習模型的輸入,標簽是機器學習模型的輸出。無論是在訓練階段,還是在預測階段。特征的個數稱為特征的維度,維度越高,數據集越復雜 ### 數據收集與預處理 數據收集渠道有多種,有爬取互聯網的數據,有開源數據集(Image Net、Kaggle、Google Public Data Explorer),有購買的,還有客戶積攢的海量歷史數據等 數據的預處理是十分重要的工作,預處理的好壞直接決定了訓練出來的機器學習模型的有效性 * 可視化:用Excel表和各種數據分析工具(如Matplotlib等)從各種角度(如列表、直方圖、散點圖等)探索一下數據。對數據有了基本的了解后,才方便進一步分析判斷,即為后續的模型選擇奠定基礎。 * [數據向量化](https://tonybai.com/2024/05/09/text-vectorization-using-ollama-and-go-based-on-text-embedding-models/):把原始數據格式化,使其變得機器可以讀取。例如,將原始圖片轉換為機器可以讀取的數字矩陣,將文字轉換為one-hot編碼,將文本類別(如男、女)轉換成0、1這樣的數值。 * 處理壞數據和空數據:一條數據可不是全部都能用,要利用數據處理工具來把“搗亂”的“壞數據”(冗余數據、離群數據、錯誤數據)處理掉,把缺失值補充上。 * 特征縮放:可以顯著提升模型的性能和訓練效率。許多機器學習算法,例如梯度下降法,依賴于特征之間的距離計算。如果特征的尺度差異很大,會導致算法在不同特征方向上以不同的速度進行更新,從而降低收斂速度。特征縮放可以將所有特征縮放到相同的尺度,使算法能夠更快地收斂到最優解。特征尺度差異過大可能導致數值計算不穩定,例如出現梯度爆炸或梯度消失現象,影響模型訓練效果。特征縮放還可以使模型的權重更加可解釋。當特征尺度差異很大時,模型的權重可能無法反映特征的實際重要性。特征縮放可以使權重更加反映特征的真實貢獻。 特征縮放適用于大多數機器學習算法,包括線性回歸、邏輯回歸、支持向量機、神經網絡等。常見的特征縮放方法包括如下幾種: * 標準化 (Standardization):對數據特征分布的轉換,目標是使其符合正態分布(均值為0,標準差為1)。在實踐中,會去除特征的均值來轉換數據, 使其居中,然后除以特征的標準差來對其進行縮放。 * 歸一化/規范化 (Normalization):將特征數據縮放到特定范圍,通常是0到1之間。歸一化不會改變數據的分布形態。 ### 選擇機器學習模型 在前期的傳統機器學習階段,不同的數據和問題需要采用不同的機器學習方法和模型。 影響機器學習模型選擇的一些關鍵的因素包括: * 數據類型和特征:比如圖像數據和文本數據一般需要不同的模型。數據的維度、稀疏程度等也會影響選擇的模型。 * 任務類型:分類、回歸、聚類等任務適合不同的模型。有監督學習和無監督學習也需要不同的方法。 * 數據規模:對于大規模數據,可擴展性強的模型如深度學習效果更好。小樣本數據可能更適合傳統的機器學習算法。 * 領域知識:某些領域問題需要結合專業領域知識,不能單純依賴通用的機器學習模型。 #### 有監督學習和無監督學習 **有監督學習** 有監督學習是一種通過使用已標注的數據(即如前面圖中的訓練數據集那樣,樣本數據包含特征與對應的標簽)來訓練模型的方法。在這種方法中,每個訓練樣本都是一個輸入-輸出對,模型通過學習這些對的關系來預測新的輸入數據的輸出。有監督學習擅長的任務類型包括下面這幾個: * 分類任務:將輸入數據分類到預定義的類別中,例如垃圾郵件檢測、圖像分類。 * 回歸任務:預測連續的數值輸出,例如房價預測(前面圖中的示例)、股票價格預測。 * 標注任務:為輸入數據中的每個元素分配一個標簽。例如:命名實體識別(NER):在文本中識別出人名、地名、組織名等。 * 排序任務:根據某種標準對項目進行排序。例如:信息檢索、推薦系統。 * 序列預測任務:根據時間序列數據進行預測。例如,銷售額預測、天氣預報等。 **無監督學習** 而無監督學習則是一種通過使用未標注的數據來訓練模型的方法。在這種方法中,模型試圖從數據中發現結構或模式,而無需使用明確的輸入-輸出對。無監督學習擅長的任務類型包括下面幾個: * 聚類任務:將相似的樣本歸為一類,比如給定一組照片,模型能把它們分成風景照片、狗、嬰兒、貓和山峰。同樣,給定一組用戶的網頁瀏覽記錄,模型能將具有相似行為的用戶聚類。 * 降維任務:減少數據的維度,同時保持其重要特征,例如主成分分析(PCA)問題,模型能否找到少量的參數來準確地捕捉數據的線性相關屬性?比如,一個球的運動軌跡可以用球的速度、直徑和質量來描述。 * 異常檢測:識別數據中的異常或異常模式,例如欺詐檢測、設備故障檢測。 把特征數據放到圖形中,為一個直線函數 ![](https://img.kancloud.cn/d4/90/d490c212efef55c90b93f47fab33ce40_1487x737.png) 這個函數叫做假設函數 ![](https://img.kancloud.cn/b5/a2/b5a2d7497b0c25a380e94d209ad267ea_571x61.png) (也叫預測函數),其中的w1、w2和w3稱為權重,權重決定了每個特征對我們預測值的影響。b稱為偏置(bias)、 偏移量(offset)或截距(intercept)。偏置是指當所有特征都取值為0時,預測值應該為多少 現在權重w1、w2、w3和偏置b的值都是未知的,它們也被稱為模型內的參數,直接影響模型的預測結果。 首先就是**權重和偏置參數的初始值**,對于這個示例我們可采用**隨機初始化**的方式,即將參數隨機地設置在一個合理的范圍內。這種方法簡單快捷,但對于復雜的模型,可能會導致收斂速度慢或陷入局部最優 我們要確定一個y’計算結果與訓練數據集中標簽值的差距計算方法。機器學習領域稱這個計算方法為**損失函數(Loss function)**。損失也就是 誤差,也稱為成本(cost)或代價,用于體現當前預測值和真實值之間的差距 用于回歸的損失函數就有:均方誤差(Mean Square Error,MSE)函數、平均絕對誤差(Mean Absolute Error,MAE)函數和平均偏差誤差(mean bias error)函數。用于分類的損失函數有交叉熵損失(cross-entropy loss)函數和多分類SVM損失(hinge loss)函數等 在此示例中,可使用均方差函數L ![](https://img.kancloud.cn/47/43/474357c498110bb12283a70df9378bab_331x101.png) ``` x1 = 55, x2 = 11, x3 = 5, y = 210 y' = 0.1 * 55 + 0.1 * 11 + 0.1 * 5 + 0.1 = 7.2 L = 1/2 * (7.2 - 210)^2 = 20563.920000000002 ``` 可以看出損失函數值過大,優化算法通常基于一種基本方法–**梯度下降(gradient descent)**進行調整,簡而言之,在每個步驟中,梯度下降法都會檢查每個參數,看看如果僅對該參數進行少量變動,訓練集損失會朝哪個方向移動。然后,它在可以減少損失的方向上優化參數。 偏導數公式的推導過程: ![](https://img.kancloud.cn/e5/21/e521796dc55a7a4b18a87fab2eafb0c8_1581x1191.png) 針對每個樣本,我們計算其損失值(y’-y)與該樣本特征(x1)的乘積。取這些乘積的平均值就得到了L對w1的偏導值 ![](https://img.kancloud.cn/14/97/1497b619c5a70a48b93fd95e2d19314f_491x541.png) 偏導數為我們指定了參數調整方向,下面是w1、w2、w3和b的更新公式: ![](https://img.kancloud.cn/46/43/464380e17b457ec10ac3e0ca1d12a321_401x491.png) 更新公式中有一個新的變量α,該變量代表的是學習率(learning rate)。是一個**超參數**,它控制著模型參數更新的步伐大小,太大參數更新步伐過大,可能導致模型無法收斂甚至發散,參數更新步伐過小,訓練時間會過長且可能陷入局部最小值 #### 超參調試與性能優化 學習率(learning rate)、訓練輪數(Epochs)等,是模型外部的可以通過人工調節的參數,這樣的參數稱為**超參數(Hyperparameters)**。大多數機器學習從業者真正花費相當多的時間來調試的正是這類超參數 在實際應用中,選擇合適的學習率和訓練輪數等超參數通常需要結合以下方法: * 經驗法則:基于先前經驗和領域知識設定初始值。 * 交叉驗證:通過交叉驗證選擇一組最優的超參數。 * 網格搜索:在多個可能的超參數組合上進行搜索,找到效果最好的參數組合。 * 學習率調度:動態調整學習率,比如在訓練過程中逐漸減小學習率。 ### 線性回歸:機器學習的Hello, World 數據 ``` $cat train.csv 面積,距離,房價 50,10,200 60,12,220 70,15,250 80,20,300 90,25,330 100,30,360 110,35,390 120,40,420 130,45,450 140,50,480 $cat test.csv 面積,距離,房價 55,11,210 65,13,230 75,17,260 85,22,310 95,27,340 105,32,370 115,37,400 125,42,430 135,47,460 145,52,490 ``` 通過編碼來實現對csv文件的讀取 ``` / go-and-nn/linear-regression/main.go func readCSV(filePath string) ([][]float64, error) { file, err := os.Open(filePath) if err != nil { return nil, err } defer file.Close() reader := csv.NewReader(file) records, err := reader.ReadAll() if err != nil { return nil, err } data := make([][]float64, len(records)-1) for i := 1; i < len(records); i++ { data[i-1] = make([]float64, len(records[i])) for j := range records[i] { data[i-1][j], err = strconv.ParseFloat(records[i][j], 64) if err != nil { return nil, err } } } return data, nil } ``` 拿到數據后,標準化后的數據會使模型訓練更加穩定和快速,從而可能提高模型的預測性能 ``` // go-and-nn/linear-regression/main.go func standardize(data [][]float64) ([][]float64, []float64, []float64) { mean := make([]float64, len(data[0])-1) std := make([]float64, len(data[0])-1) for i := 0; i < len(data[0])-1; i++ { for j := 0; j < len(data); j++ { mean[i] += data[j][i] } mean[i] /= float64(len(data)) } for i := 0; i < len(data[0])-1; i++ { for j := 0; j < len(data); j++ { std[i] += math.Pow(data[j][i]-mean[i], 2) } std[i] = math.Sqrt(std[i] / float64(len(data))) } standardizedData := make([][]float64, len(data)) for i := 0; i < len(data); i++ { standardizedData[i] = make([]float64, len(data[i])) for j := 0; j < len(data[i])-1; j++ { standardizedData[i][j] = (data[i][j] - mean[j]) / std[j] } standardizedData[i][len(data[i])-1] = data[i][len(data[i])-1] } return standardizedData, mean, std } ``` tandardize中的mean和std分別用于存儲每個特征的均值和標準差(標準差是反應一組數據離散程度最常用的一種量化形式,累加每個樣本的特征值與均值的平方差,然后除以樣本數量,再開平方,便可得到該特征的標準差)。有了均值和標準差后,我們用原始特征值減去均值,然后除以標準差,得到標準化后的特征值。標簽無需標準化 **訓練** 訓練代碼 ``` // go-and-nn/linear-regression/main.go func trainModel(data [][]float64, learningRate float64, epochs int) ([]float64, float64) { features := len(data[0]) - 1 weights := make([]float64, features) bias := 0.0 for epoch := 0; epoch < epochs; epoch++ { gradW := make([]float64, features) gradB := 0.0 mse := 0.0 for i := 0; i < len(data); i++ { prediction := bias for j := 0; j < features; j++ { prediction += weights[j] * data[i][j] } error := prediction - data[i][features] mse += error * error for j := 0; j < features; j++ { gradW[j] += error * data[i][j] } gradB += error } mse /= float64(len(data)) // 更新權重 for j := 0; j < features; j++ { gradW[j] /= float64(len(data)) weights[j] -= learningRate * gradW[j] } gradB /= float64(len(data)) // 更新偏置 bias -= learningRate * gradB // Output the current weights, bias and loss fmt.Printf("Epoch %d: Weights: %v, Bias: %f, MSE: %f\n", epoch+1, weights, bias, mse) } return weights, bias } ``` 驅動訓練函數的代碼 ``` // go-and-nn/linear-regression/main.go func main() { // Read training data trainData, err := readCSV("train.csv") if err != nil { log.Fatalf("failed to read training data: %v", err) } // Read testing data testData, err := readCSV("test.csv") if err != nil { log.Fatalf("failed to read testing data: %v", err) } // Standardize training data standardizedTrainData, mean, std := standardize(trainData) // Train model learningRate := 0.0001 epochs := 1000 weights, bias := trainModel(standardizedTrainData, learningRate, epochs) fmt.Printf("Trained Weights: %v\n", weights) fmt.Printf("Trained Bias: %f\n", bias) // Evaluate model on test data predictAndEvaluate2(testData, weights, bias, mean, std) } ``` 這里我們設置超參學習率為0.0001,設置epochs為1000,即進行1000輪完整的訓練 我們基于訓練后的模型以及測試數據集進行模型效果評估 ``` // go-and-nn/linear-regression/main.go func predictAndEvaluate(data [][]float64, weights []float64, bias float64, mean []float64, std []float64) { features := len(data[0]) - 1 mse := 0.0 for i := 0; i < len(data); i++ { // Standardize the input features using the training mean and std standardizedFeatures := make([]float64, features) for j := 0; j < features; j++ { standardizedFeatures[j] = (data[i][j] - mean[j]) / std[j] } // Calculate the prediction prediction := bias for j := 0; j < features; j++ { prediction += weights[j] * standardizedFeatures[j] } // Calculate the error and accumulate the MSE error := prediction - data[i][features] mse += error * error // Print the prediction and the actual value fmt.Printf("Sample %d: Predicted Value: %f, Actual Value: %f\n", i+1, prediction, data[i][features]) } // Calculate the final MSE mse /= float64(len(data)) fmt.Printf("Mean Squared Error: %f\n", mse) } ``` 輸出 ``` $go build $./demo Epoch 1: Weights: [0.009191300234460844 0.009159461537409297], Bias: 0.034000, MSE: 124080.000000 Epoch 2: Weights: [0.018380768863390594 0.01831709148135162], Bias: 0.067997, MSE: 124053.513977 Epoch 3: Weights: [0.02756840625241513 0.027472890197452842], Bias: 0.101990, MSE: 124027.033923 Epoch 4: Weights: [0.03675421276708735 0.036626858051265865], Bias: 0.135980, MSE: 124000.559834 Epoch 5: Weights: [0.04593818877288719 0.0457789954082706], Bias: 0.169966, MSE: 123974.091710 ... ... Epoch 997: Weights: [8.311660331200889 8.279923139396109], Bias: 32.264505, MSE: 100432.407457 Epoch 998: Weights: [8.319195610465172 8.287426591989], Bias: 32.295278, MSE: 100411.202067 Epoch 999: Weights: [8.326729388699432 8.294928543563927], Bias: 32.326049, MSE: 100390.001368 Epoch 1000: Weights: [8.334261666203304 8.302428994420524], Bias: 32.356816, MSE: 100368.805359 Trained Weights: [8.334261666203304 8.302428994420524] Trained Bias: 32.356816 Sample 1: Predicted Value: 10.081607, Actual Value: 210.000000 Sample 2: Predicted Value: 14.223776, Actual Value: 230.000000 Sample 3: Predicted Value: 19.606495, Actual Value: 260.000000 Sample 4: Predicted Value: 25.609490, Actual Value: 310.000000 Sample 5: Predicted Value: 31.612486, Actual Value: 340.000000 Sample 6: Predicted Value: 37.615481, Actual Value: 370.000000 Sample 7: Predicted Value: 43.618476, Actual Value: 400.000000 Sample 8: Predicted Value: 49.621471, Actual Value: 430.000000 Sample 9: Predicted Value: 55.624466, Actual Value: 460.000000 Sample 10: Predicted Value: 61.627461, Actual Value: 490.000000 Mean Squared Error: 104949.429046 ``` Predicted Valu 與Actual Value 相差太差 **超參調試和優化** ``` $go build $./demo Epoch 1: Weights: [0.009191300234460844 0.009159461537409297], Bias: 0.034000, MSE: 124080.000000 Epoch 2: Weights: [0.018380768863390594 0.01831709148135162], Bias: 0.067997, MSE: 124053.513977 Epoch 3: Weights: [0.02756840625241513 0.027472890197452842], Bias: 0.101990, MSE: 124027.033923 Epoch 4: Weights: [0.03675421276708735 0.036626858051265865], Bias: 0.135980, MSE: 124000.559834 Epoch 5: Weights: [0.04593818877288719 0.0457789954082706], Bias: 0.169966, MSE: 123974.091710 Epoch 6: Weights: [0.055120334635221604 0.05492930263387402], Bias: 0.203949, MSE: 123947.629550 ... ... Epoch 996: Weights: [47.520035679041236 44.407936879025506], Bias: 339.984720, MSE: 44.287037 Epoch 997: Weights: [47.521568654779436 44.406403906767075], Bias: 339.984872, MSE: 44.286092 Epoch 998: Weights: [47.523101572396406 44.404870992560404], Bias: 339.985024, MSE: 44.285147 Epoch 999: Weights: [47.524634431895045 44.40333813640399], Bias: 339.985174, MSE: 44.284203 Epoch 1000: Weights: [47.52616723327823 44.401805338296306], Bias: 339.985322, MSE: 44.283259 Trained Weights: [47.52616723327823 44.401805338296306] Trained Bias: 339.985322 Sample 1: Predicted Value: 216.742422, Actual Value: 210.000000 Sample 2: Predicted Value: 239.923439, Actual Value: 230.000000 Sample 3: Predicted Value: 269.738984, Actual Value: 260.000000 Sample 4: Predicted Value: 302.871794, Actual Value: 310.000000 Sample 5: Predicted Value: 336.004604, Actual Value: 340.000000 Sample 6: Predicted Value: 369.137414, Actual Value: 370.000000 Sample 7: Predicted Value: 402.270225, Actual Value: 400.000000 Sample 8: Predicted Value: 435.403035, Actual Value: 430.000000 Sample 9: Predicted Value: 468.535845, Actual Value: 460.000000 Sample 10: Predicted Value: 501.668655, Actual Value: 490.000000 Mean Squared Error: 54.966611 ``` 這回我們看懂,訓練后的模型在測試集上的預測結果與實際標簽值非常接近,可以看到對超參learningRate的調整見效了!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看