日撸java三百行day69-70

news2024/11/15 10:03:21

文章目录

  • 说明
  • day69-70 矩阵分界
    • 1.基于矩阵分解的推荐系统(Funk-SVD算法)
    • 2.随机梯度下降(SGD)
      • 2.1 导数
      • 2.2 偏导数
      • 2.3 方向导数
      • 2.4 梯度
      • 2.5 随机梯度下降,与损失函数之间的关系
    • 3.代码理解
      • 3.1 train() 方法
      • 3.2 mae方法(平均绝对误差)
      • 3.3 rsme方法(均方根误差)

说明

闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-CSDN博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata

day69-70 矩阵分界

(如有问题,欢迎指正~)

1.基于矩阵分解的推荐系统(Funk-SVD算法)

基于矩阵分解的推荐系统的算法有许多,如SVD,Funk-SVD,NMF等,而结合今天的文章主要学习的是Funk-SVD算法(一种基于随机梯度下降的简化的SVD算法,通过学习用户特征和项目特征来预测评分)

基于用户-项目评分矩阵,捕捉用户和项目之间的隐含关系,通过将矩阵分解用户特征矩阵和项目特征矩阵的乘积来进行预测,如:矩阵 m ∗ n m*n mn 可以分解为: m ∗ k 与 k ∗ n m*k 与k*n mkkn
例如下,假设我们特征隐含因子k就选2:

用户电影1电影2电影3电影4
user154-2
user2-24-
user33--1
user4-523

我们的用户项目评分矩阵为4*4的矩阵
[ 5 4 − 2 − 2 4 − 3 − − 1 − 5 2 3 ] \left[ \begin{array}{cc} 5 & 4& -& 2 \\ - & 2 & 4& - \\ 3 & - & -& 1 \\ - & 5 & 2& 3\\ \end{array} \right] 5342542213
我们就可以分解为U矩阵 ( 4 ∗ 2 ) (4*2) 42和项目矩阵 ( 2 ∗ 4 ) (2*4) 24
[ u 1 − f e a t u r e 1 u 1 − f e a t u r e 2 u 2 − f e a t u r e 1 u 2 − f e a t u r e 2 u 3 − f e a t u r e 1 u 3 − f e a t u r e 2 u 4 − f e a t u r e 1 u 4 − f e a t u r e 2 ] ∗ [ i 1 − f e a t u r e 1 i 2 − f e a t u r e 1 i 3 − f e a t u r e 1 i 4 − f e a t u r e 1 i 1 − f e a t u r e 2 i 2 − f e a t u r e 2 i 3 − f e a t u r e 2 i 4 − f e a t u r e 2 ] \left[ \begin{array}{cc} u1-feature1 & u1-feature2 \\ u2-feature1 & u2-feature2 \\ u3-feature1 & u3-feature2 \\ u4-feature1 & u4-feature2 \\ \end{array} \right] * \left[ \begin{array}{cccc} i1-feature1 & i2-feature1 & i3-feature1 & i4-feature1 \\ i1-feature2 & i2-feature2 & i3-feature2 & i4-feature2\\ \end{array} \right] u1feature1u2feature1u3feature1u4feature1u1feature2u2feature2u3feature2u4feature2 [i1feature1i1feature2i2feature1i2feature2i3feature1i3feature2i4feature1i4feature2]
所以我们对原始矩阵进行分解后,假设user1对move1进行评分,那我们可以这样计算(矩阵乘法):
( u 1 − f e a t u r e 1 ) ∗ ( i 1 − f e a t u r e 1 ) + ( u 1 − f e a t u r e 2 ) ∗ ( i 1 − f e a t u r e 2 ) (u1-feature1)*(i1-feature1) + (u1-feature2)* (i1-feature2) (u1feature1)(i1feature1)+(u1feature2)(i1feature2)

所以呀,我们将矩阵进行分解,从中提取出用户和项目的隐藏特征,并利用这些特征进行推荐。分解为两个矩阵:用户特征矩阵表示用户在隐藏特征空间中的偏好,而项目特征矩阵表示项目在隐藏特征空间中的属性。原始矩阵: m ∗ n m*n mn, 用户矩阵: m ∗ k m*k mk; 项目特征矩阵: n ∗ k n*k nk(做了转置)
例如:
下面有4个用户对4部电影评分,其中满分为5分,-表示未进行评分,

用户电影1电影2电影3电影4
user154-2
user2-24-
user33--1
user4-523

我们通过分解,分界为两个矩阵:用户特征矩阵和项目特征矩阵。

用户特征矩阵

用户特征1特征2
user10.80.6
user20.40.9
user30.60.3
user40.70.5

项目特征矩阵

项目特征1特征2
电影10.90.5
电影20.30.8
电影30.60.2
电影40.70.6

user1在特征1上得分较高,而user2在特征2 上得分较高。电影1在特征1上得分较高,而电影2在特征2上得分较高。现在,假设我们要向user1进行电影推荐。我们可以通过user1的特征向量与每部电影的特征向量之间进行计算来比较用户更可能喜欢那部电影,进而进行推荐。其实我们计算下来看发现我们猜用户更喜欢电影1(当然,你看我们算出评分才1.02分 好像有点低 所以我们还要进行不断训练来获得一个合理的分数。)
电影1: 0.80.9 + 0.6 * 0.5 = 1.02
电影2: 0.8
0.3 + 0.6 * 0.8 = 0.72
电影3: 0.80.6 + 0.6 * 0.2 = 0.6
电影4: 0.8
0.7 + 0.6 * 0.6 = 0.92

而在这个例子中,隐藏的特征值的个数如何选择?感觉是比较不好界定的,需要不断的进行调优,如果维度低了可能会丢失一些重要信息,而纬度高一些可能会增加计算复杂度和噪音等,所以需要根据具体问题和数据集的特点进行选择。
而在这个过程中,我们就会思考一个问题,这个用户矩阵和项目矩阵的特征值是怎么来的?
答:如果采用本文的算法,我们的用户特征矩阵和项目特征矩阵在最开始是赋的随机值,然后再根据随机梯度下降算法不断的去迭代更新用户和项目特征矩阵的特征值,让起预测结果更接近真实值。

2.随机梯度下降(SGD)

通过一些基础知识的回顾去理解什么是随机梯度下降,导数 -> 偏导数 -> 方向导数 -> 梯度->** 随机梯度下降**

2.1 导数

函数在这一点附近的变化率,切线的斜率,函数 y = f ( x ) y=f(x) y=f(x)在点 x 0 x_{0} x0处的导数: lim ⁡ Δ x → 0 Δ x Δ y = lim ⁡ Δ x → 0 f ( x 0 + Δ x ) − f ( x 0 ) Δ x \lim_{\Delta x \to 0}\frac{\Delta x}{\Delta y}=\lim_{\Delta x \to 0}\frac{f(x_{0} +\Delta x) - f(x_{0})}{\Delta x} Δx0limΔyΔx=Δx0limΔxf(x0+Δx)f(x0)
在这里插入图片描述

2.2 偏导数

一个多变量的函数的偏导数,就是它关于其中一个变量的导数而保持其他变量恒定。基于坐标轴方向的变化率
假设有二元函数 z = f ( x , y ) z=f(x,y) z=f(x,y) ,点 ( x 0 , y 0 ) (x_{0},y_{0}) (x0,y0)是其定义域D 内一点。把 y 固定在 y 0 y_{0} y0而让 x 在 x 0 x_{0} x0 有增量 Δ x \Delta x Δx ,相应地函数 z = f ( x , y ) z=f(x,y) z=f(x,y)有增量(称为对 x 的偏增量) Δ z = f ( x 0 + Δ x , y 0 ) − f ( x 0 , y 0 ) \Delta z=f(x_{0}+\Delta x,y_{0})-f(x_{0},y_{0}) Δz=f(x0+Δx,y0)f(x0,y0) 函数在y方向不变,函数值沿着x轴方向的变化率
f x ( x 0 , y 0 ) = lim ⁡ Δ x → 0 f ( x 0 + Δ x , y 0 ) − f ( x 0 , y 0 ) Δ x f_{x}(x_{0}, y_{0})=\lim_{\Delta x \to 0}\frac{f(x_{0} +\Delta x, y_{0}) - f(x_{0}, y_{0})}{\Delta x} fx(x0,y0)=Δx0limΔxf(x0+Δx,y0)f(x0,y0)
在这里插入图片描述

2.3 方向导数

在函数定义域的内点对某一方向求导得到的导数,一般为二元函数和三元函数的方向导数。方向导数可分为沿直线方向和沿曲线方向的方向导数。相比于偏导数,他能沿任意方向(函数沿着某个特定方向的变化速率) cos ⁡ α , cos ⁡ β \cos \alpha, \cos \beta cosα,cosβL方向余弦
∂ f ∂ l ∣ ( x 0 , y 0 ) = f x ( x 0 , y 0 ) cos ⁡ α + f y ( x 0 , y 0 ) cos ⁡ β \frac{\partial f}{\partial l}|(x_{0}, y_{0})=f_{x}(x_{0}, y_{0})\cos \alpha + f_{y}(x_{0}, y_{0})\cos \beta lf(x0,y0)=fx(x0,y0)cosα+fy(x0,y0)cosβ
在这里插入图片描述

2.4 梯度

是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)
g r a d f ( x , y ) = { ∂ f ∂ x , ∂ f ∂ y } = f x ( x 0 , y 0 ) i ⃗ + f y ( x 0 , y 0 ) j ⃗ gradf(x,y)=\begin{Bmatrix} \frac{\partial f}{\partial x} , \frac{\partial f}{\partial y} \end{Bmatrix}=f_{x}(x_{0},y_{0})\vec{i}+f_{y}(x_{0},y_{0})\vec{j} gradf(x,y)={xf,yf}=fx(x0,y0)i +fy(x0,y0)j

在这里插入图片描述
∂ f ∂ l ∣ ( x 0 , y 0 ) = f x ( x 0 , y 0 ) cos ⁡ α + f y ( x 0 , y 0 ) cos ⁡ β = g r a d f ( x 0 , y 0 ) e i ⃗ = ∣ g r a d f ( x 0 , y 0 ) ∣ cos ⁡ θ \frac{\partial f}{\partial l}|(x_{0}, y_{0})=f_{x}(x_{0}, y_{0})\cos \alpha + f_{y}(x_{0}, y_{0})\cos \beta =gradf(x_{0},y_{0})\vec{e_{i}}=|gradf(x_{0}, y_{0}) |\cos\theta lf(x0,y0)=fx(x0,y0)cosα+fy(x0,y0)cosβ=gradf(x0,y0)ei =gradf(x0,y0)cosθ

2.5 随机梯度下降,与损失函数之间的关系

在机器学习中 随机梯度是指在计算梯度时,仅使用一个样本或一小批样本的数据来估计梯度。
损失函数用来衡量模型的预测输出与实际观测值之间的误差,在训练过程中我们希望最小化损失函数来使预测值接近实际值,随机梯度下降算法是优化损失函数的一种算法。文章参考

总结:

  • 导数:函数在某点附近的变化率,是一个数值。
  • 偏导数:函数某点沿一个某一个维度的变化率,是一个数值。
  • 方向导数:函数某点沿一个某一个方向的变化率,是一个数值.
  • 梯度:函数某点变化率最大的方向,是一个向量
  • 梯度下降
    沿着梯度下降的方向求解极小值,(梯度上升:沿着梯度上升的方向可以求得极大值)梯度下降的基本思想是通过迭代的方式逐步更新模型的参数,使损失函数的值逐渐减小,最终达到局部最优或全局最优的参数值。其中随机梯度下降每次迭代只使用一个样本或一小批样本来计算梯度,并根据该梯度来更新参数(与批量梯度下降有所区别)

3.代码理解

我觉得整体的一个代码还是算比较好理解的。
从main函数出发:

 /**
     * @param args
     */
    public static void main(String args[]) {
        testTrainingTesting("C:/Users/fls/Desktop/Desktopmovielens-943u1682m (2).txt", 943, 1682, 10000, 1, 5, 2000);
    }// Of main

其中

 /**
     * Compute the MAE.
     * @return MAE of the current factorization.
     */
    public static void testTrainingTesting(String paraFilename, int paraNumUsers, int paraNumItems,
                                           int paraNumRatings, double paraRatingLowerBound, double paraRatingUpperBound,
                                           int paraRounds) {
        try {
            // Step 1. read the training and testing data
            MatrixFactorization tempMF = new MatrixFactorization(paraFilename, paraNumUsers,
                    paraNumItems, paraNumRatings, paraRatingLowerBound, paraRatingUpperBound);

            tempMF.setParameters(5, 0.0001, 0.005);

            // Step 3. update and predict
            System.out.println("Begin Training ! ! !");
            tempMF.train(paraRounds);

            double tempMAE = tempMF.mae();
            double tempRSME = tempMF.rsme();
            System.out.println("Finally, MAE = " + tempMAE + ", RSME = " + tempRSME);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

其中构造函数,setter,getter函数主要就是赋初值。

3.1 train() 方法

/**
     * Train.
     * @param paraRounds The number of rounds.
     */
    public void train(int paraRounds) {
        initializeSubspaces();

        for (int i = 0; i < paraRounds; i++) {
            updateNoRegular();
            if (i % 50 == 0) {
                // Show the process
                System.out.println("Round " + i);
                System.out.println("MAE: " + mae());
            }
        }
    }

在这个方法中主要有以下几个调用方法:

  • initializeSubspaces()方法

随机初始化用户矩阵和项目矩阵,而用户矩阵userSubspace和项目矩阵itemSubspace的空间大小:其中numUsers是参与评分的用户数量,numItems是参与评分的项目数量,rank就是低秩数量(隐含特征值个数,低秩的取值应小于原始矩阵的行数和列数)

userSubspace = new double[numUsers][rank];
itemSubspace = new double[numItems][rank];
  • 迭代更新用户矩阵和物品矩阵(updateNoRegular方法)
    通过随机梯度下降算法更新用户矩阵和项目矩阵使其逼近原始评分矩阵。更新的过程中,使用残差(预测评分与真实评分之间的差异)来调整梯度方向,从而逐步优化模型的拟合能力。(这里未加入正则项,)
  /**
     * Update sub-spaces using the training data.
     */
    public void updateNoRegular() {
        for (int i = 0; i < numRatings; i++) {
            int tempUserId = dataset[i].user;
            int tempItemId = dataset[i].item;
            double tempRate = dataset[i].rating;

            //残差:表示了模型对于给定数据的拟合程度,或者说模型预测与实际观测之间的偏差
            double tempResidual = tempRate - predict(tempUserId, tempItemId); // Residual

            // Update user subspace
            double tempValue = 0;
            for (int j = 0; j < rank; j++) {
                tempValue = 2 * tempResidual * itemSubspace[tempItemId][j]; // 调整梯度的方向
                userSubspace[tempUserId][j] += alpha * tempValue;
            }

            // Update item subspace
            for (int j = 0; j < rank; j++) {
                tempValue = 2 * tempResidual * userSubspace[tempUserId][j];

                itemSubspace[tempItemId][j] += alpha * tempValue;
            }
        }
    }

其中tempResidual的计算中,predict方法就是预测用户paraUser对paraItem的评分,公式就是用户矩阵和项目矩阵对应的数据相乘(内积)。

public double predict(int paraUser, int paraItem) {
        double resultValue = 0;
        for (int i = 0; i < rank; i++) {
            // The row vector of an user and the column vector of an item
            resultValue += userSubspace[paraUser][i] * itemSubspace[paraItem][i];
        }
        return resultValue;
    }

updateNoRegular方法中后面两个for循环是利用残差和学习率alpha来更新梯度方向。

3.2 mae方法(平均绝对误差)

MAE的值越小,表示预测值与真实值之间的平均差异越小,模型的预测精度越高

 public double mae() {
        double resultMae = 0;
        int tempTestCount = 0;

        for (int i = 0; i < numRatings; i++) {
            int tempUserIndex = dataset[i].user;
            int tempItemIndex = dataset[i].item;
            double tempRate = dataset[i].rating;

            double tempPrediction = predict(tempUserIndex, tempItemIndex);

            if (tempPrediction < ratingLowerBound) {
                tempPrediction = ratingLowerBound;
            }
            if (tempPrediction > ratingUpperBound) {
                tempPrediction = ratingUpperBound;
            }

            double tempError = tempRate - tempPrediction;

            resultMae += Math.abs(tempError);
            // System.out.println("resultMae: " + resultMae);
            tempTestCount++;
        }

        return (resultMae / tempTestCount);
    }

3.3 rsme方法(均方根误差)

RMSE的值越小,表示预测值与真实值之间的平均差异越小,模型的预测精度越高

 public double rsme() {
        double resultRsme = 0;
        int tempTestCount = 0;

        for (int i = 0; i < numRatings; i++) {
            int tempUserIndex = dataset[i].user;
            int tempItemIndex = dataset[i].item;
            double tempRate = dataset[i].rating;

            double tempPrediction = predict(tempUserIndex, tempItemIndex);// +
            // DataInfo.mean_rating;

            if (tempPrediction < ratingLowerBound) {
                tempPrediction = ratingLowerBound;
            } else if (tempPrediction > ratingUpperBound) {
                tempPrediction = ratingUpperBound;
            }

            double tempError = tempRate - tempPrediction;
            resultRsme += tempError * tempError;
            tempTestCount++;
        }

        return Math.sqrt(resultRsme / tempTestCount);
    }

运行结果:

Begin Training ! ! !
Round 0
MAE: 2.2907399404250066
Round 50
MAE: 0.8993292387753772
Round 100
MAE: 0.7809671561497589
Round 150
MAE: 0.7387296873184198
Round 200
MAE: 0.7170317489750806
Round 250
MAE: 0.7034448480512184
Round 300
MAE: 0.6935587511441117
Round 350
MAE: 0.6857189844613861
Round 400
MAE: 0.6789467220540055
Round 450
MAE: 0.6727002553880987
Round 500
MAE: 0.6668059407389094
Round 550
MAE: 0.6610344533820965
Round 600
MAE: 0.6552091750784605
Round 650
MAE: 0.6492148499949644
Round 700
MAE: 0.643008296616773
Round 750
MAE: 0.6365963019057151
Round 800
MAE: 0.6300215714478256
Round 850
MAE: 0.6232589520093165
Round 900
MAE: 0.6163239674271115
Round 950
MAE: 0.6093028662913618
Round 1000
MAE: 0.6022758971939184
Round 1050
MAE: 0.5953515717080884
Round 1100
MAE: 0.5885803775559597
Round 1150
MAE: 0.5819425503582748
Round 1200
MAE: 0.5755093686810299
Round 1250
MAE: 0.5692686097337987
Round 1300
MAE: 0.5632714589097246
Round 1350
MAE: 0.5574779302146219
Round 1400
MAE: 0.551919113415983
Round 1450
MAE: 0.5465747679448184
Round 1500
MAE: 0.5414617254658267
Round 1550
MAE: 0.5365844001700262
Round 1600
MAE: 0.5319456445117685
Round 1650
MAE: 0.5275238820343752
Round 1700
MAE: 0.5233039966420835
Round 1750
MAE: 0.5192706212957772
Round 1800
MAE: 0.515434234338843
Round 1850
MAE: 0.5118031247338808
Round 1900
MAE: 0.5083451638474644
Round 1950
MAE: 0.5050394579922357
Finally, MAE = 0.501970541233074, RSME = 0.661045778079508
Process finished with exit code 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/683260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

神经网络原理(2)

斯坦福大学的印度学生、机器学习爱好者 PararthShah 在2012年12月22日的使用买芒果的例子解释了神经网络&#xff0c;简单来说就是&#xff1a;如果你需要选芒果&#xff0c;但不知道什么样的芒果最好吃&#xff0c;一个简单粗暴的方法是尝遍所有的芒果&#xff0c;然后总结出个…

窗口函数之-前后函数(lag/lead)

窗口函数之-前后函数 应用&#xff1a;求同比增长、环比增长 lead(expression,n):返回当前行的后n行 > shift(-n) 数据超前n阶&#xff0c;与之对齐的就是后n行的数据lag(expression,n):返回当前行的前n行> shift(n)数据滞后n阶&#xff0c;与之对齐的就是前n行的数据 …

人工智能轨道交通行业周刊-第49期(2023.6.12-6.25)

本期关键词&#xff1a;设备智能维修、故障诊断、无人机巡查、车站联锁、LangChain、腾讯大模型 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMe…

高效进行接口测试,简单易懂!

目录 前言 正文 1.Api文档导入 2.后端接口测试 3.mock数据 4.测试集接口自动化 总结 前言 日常测试过程中&#xff0c;常常需要多种工具来接力完成自己的接口测试任务。 比如说&#xff0c; 使用swagger查看接口文档&#xff0c; 使用mock编造接口数据对前端页面做测试…

面对高速PCB设计,你是否也有这些疑问?

在现代电子产品设计中&#xff0c;高速PCB设计是很重要的组成部分&#xff0c;然而由于高速信号的特殊性和复杂性&#xff0c;很多电子工程师在进行高速PCB设计时难免面临各种挑战及问题&#xff0c;那么面对这些挑战及问题&#xff0c;该如何解决&#xff1f; 1、添加测试点是…

管线业务模块实现

文章目录 1 .配电线路轨迹图2 &#xff09;单线图存储功能3. 设备接线图1 &#xff09;剖面绘制 电力管线业务模块是系统的电力业务功能&#xff0c;主要维护电气设备的电力连接关系以及电 缆在GIS 地图和工井内部的位置和走向。管线业务模块由配电线路的轨迹图、单线图、接 线…

介绍智能照明系统在绿色建筑中的应用与产品选型

【摘要】&#xff1a;智能照明系统应用在智能建筑中不仅能营造出舒适的生活、工作环境以及现代化的管理方式而且要具有一定的节能效果。给出了智能照明和传统照明系统的比较并分析了智能照明系统的节能。 【关键字】&#xff1a;智能建筑&#xff1b;智能照明&#xff1b;节能…

蓝库云:企业绩效管理对公司成长的重要性,被很多企业主所忽略

什么是绩效管理 绩效管理是一种管理方法&#xff0c;通过衡量和评估员工的工作绩效&#xff0c;来提高企业的效率和效益。它涉及一个系统性的过程&#xff0c;包括设定、评估和反馈员工目标&#xff0c;制定和实施成长计划和发展计划&#xff0c;以及与员工进行持续的沟通和反…

MacOS 中 ARM64 汇编 ldr =address 伪指令导致运行时崩溃的原因及解决

0. 概览 我们知道在 MacOS 的 as 汇编器中有一条 ldr 伪指令&#xff0c;使用它我们可以非常方便的将立即数加载到寄存器中。 不过&#xff0c;当 ldr 的源操作数是一个标签&#xff08;Label&#xff09;时&#xff0c;就会导致在运行时发生崩溃&#xff1a; 如上图所示&…

179_自动生成 千万级 Power BI 示例数据

179_自动生成 千万级 Power BI 示例数据 在早一些是时候&#xff0c;我曾写过一个示例数据《赠送300家门店260亿销售额的零售企业Power BI实战示例数据》&#xff0c;本次我们对该示例数据做了一些调整。 一、更新内容 针对有一些朋友不会使用 vba 模块&#xff0c;我们增加了…

RHEL CentOS Debian Ubuntu 如何刷新 DNS 缓存

RHEL CentOS Debian Ubuntu 如何刷新 DNS 缓存 全文&#xff1a;如何刷新 DNS 缓存 (macOS, Linux, Windows) Unix Linux Windows 如何刷新 DNS 缓存 (macOS, FreeBSD, RHEL, CentOS, Debian, Ubuntu, Windows) 请访问原文链接&#xff1a;https://sysin.org/blog/how-to-fl…

【YOLO】目标识别模型的导出和opencv部署

文章目录 0 前期教程1 什么是模型部署2 怎么部署 0 前期教程 【YOLO】朴实无华的yolov5环境配置 【YOLO】yolov5训练自己的数据集 1 什么是模型部署 前期教程当中&#xff0c;介绍了yolov5环境的搭建以及如何利用yolov5进行模型训练和测试&#xff0c;虽然能够实现图片或视频…

语法篇·JSP基础

一、初识JSP 1.1简介 JSP(Java Server Pages),其根本是一个简化的Servlet设计&#xff0c;它实现了在Java中使用HTML标签。JSP是一种动态网页技术标准&#xff0c;也是JavaEE的标准。JSP和Servlet一样&#xff0c;是在服务器端执行的。JSP是在Servlet技术发展之后为了让开发者…

苹果公司开发者账号申请流程

目录 一、注册 Apple ID 账号二、Apple Developer 登录三、申请公司邓白氏编码四、下载 Apple Developer app五、审核六、缴费七、发票 一、注册 Apple ID 账号 注册网址&#xff1a;https://appleid.apple.com/account 二、Apple Developer 登录 登录网址&#xff1a;http…

汽车EBSE测试流程分析(二):关于优势和挑战的案例分析

EBSE专题连载共分为“五个”篇章。此文为该连载系列的“第二”篇章&#xff0c;在之前的“篇章&#xff08;一&#xff09;”中已经阐述了汽车软件工程的特点&#xff0c;以及使用混合方法设计的分阶段EBSE测试过程&#xff0c;并提出问题。接下来&#xff0c;我们将具体分析EB…

抖音矩阵系统源码开发指南

抖音矩阵系统是一个大规模的分布式系统&#xff0c;它可以处理数百万级别的并发请求。要开发和部署抖音矩阵系统源代码 您需要遵循以下步骤&#xff1a; 下载和安装必要的软件依赖项&#xff1a;抖音矩阵系统源代码需要使用Java和Scala编程语言&#xff0c;因此您需要下载和安…

2023年程序员工资中位数增长10%?开发者最常用的语言竟然是……

在调研了全球超过 90000 名开发者之后&#xff0c;程序员社区 Stack Overflow 重磅发布了《2023 Developer Survey》调查报告。在本次报告中&#xff0c;Stack Overflow 从工具、编码、工作、社区等维度展开&#xff0c;同时深入研究了 AI/ML 技术&#xff0c;并解析开发者如何…

python spider 爬虫 之 urllib系列

python 中 集成了 urllib urllib import urllib.request # urlopen 方法 url"url" response urllib.request.urlopen(url)print(type(response )) print(response.read()) # 解码 字节--->字符串 decode 字符串--》字节 encode print(response.read()…

618电商物流内卷,拼速度不是唯一底牌,还有……

每年的618大促&#xff0c;对于消费者来说都是一场购物盛宴&#xff0c;也是各个快递企业的“大练兵”。各大电商平台也纷纷铆足劲&#xff0c;希望能抓住此次机会增加营收。 面对电商平台和消费者需求&#xff0c;今年的快递电商企业在保证速度&#xff0c;提升服务质量的前提…

用CMake下的find_package()函数链接库

文章目录 find_package()原理案例1&#xff1a;为项目添加库 find_package()原理 关于find_package()函数的相关内容可参考&#xff1a; https://www.cnblogs.com/lidabo/p/16635249.html Cmake 会在以下的路径中寻找Config.cmake或Find.cmake文件。找到后即可执行该文件并生…