【Python学习笔记】调参工具Optuna + 泰坦尼克号案例

news2024/9/23 7:25:14

【Python学习笔记】调参工具Optuna&泰坦尼克号案例

背景前摇:(省流可不看)
最近找了份AI标注师的实习,但是全程都在做文本相关的活,本质上还是拧螺丝,就想着学点调参、部署什么的技能增加一些竞争力,以后简历也好包装。
当然找教程首选B站大学了,果然让我搜到了一个好评众多的免费调参工具Optuna
另外顺便提一句,我做的实习是内容安全方向的文本标注(人话:保证训练集的内容是政治正确的),但我之前看别的视频学习Yolo5做口罩和人脸识别的时候了解到有一款免费的图像标注工具很好用,我自己亲手测试过,安装和使用都很便捷,而且没有任何广告和累赘,主打一个简洁高效。
工具名称:LabelImg
导师之前分享的一篇公众号文章介绍的很全面:
https://mp.weixin.qq.com/s/AE_rJwd9cKQkUGFGD6EfAg
公众号传送门
在这里插入图片描述
————————————————————————————————————————————

正文:关于Optuna及学习过程
**视频教程链接:**https://www.bilibili.com/list/watchlater?oid=832000670&bvid=BV1c34y1G7E8&spm_id_from=333.1007.top_right_bar_window_view_later.content.click
B站大神的视频
在这里插入图片描述
安装方式:
在这里插入图片描述
Anaconda应该也可通过conda安装,我这图省事就直接按视频里面那样pip安装了。
————————————————————————————————————————————

大神使用的Kaggle案例链接:
https://www.kaggle.com/code/yunsuxiaozi/learn-to-use-the-optuna/notebook
传送门
在这里插入图片描述
虽然复制粘贴很爽,但为了保持手感+感受细节,建议有时间的还是慢慢手写一遍,哪怕是照着敲,都比直接复制粘贴要好。初学一门技能的时候,慢就是快。
同样,如果电脑上有Anaconda的话,建议建一个专门的虚拟环境来测试Optuna,防止出现冲突现象。
————————————————————————————————————————————

CSDN大神的conda虚拟环境搭建以及jupyter虚拟环境配置教程:
https://blog.csdn.net/fanstering/article/details/123459665
如果没有Anaconda可以跳过此步骤

建立虚拟环境这一步我之前已经很熟了,环境和Optuna包明明install装好了,Jupyter一运行还在报没有Optuna这个库,按照这位大神的教程装了个nb_conda以后问题就解决了。
在这里插入图片描述
在这里插入图片描述
————————————————————————————————————————————

然后进入熟悉的写代码环节,首先导入需要的几个Python库,缺什么装什么。pip install 或者conda install 都可,有Anaconda的建议后者。

如果他报了一个鬼迷日眼的错误的话: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.read
zhebu在这里插入图片描述

不要怕,只是需要把Jupyter升级一下。
在这里插入图片描述
在这里插入图片描述
我做完了前三步以后,重新刷新运行这步程序就没事了。
在这里插入图片描述
————————————————————————————————
在这里插入图片描述
数据集下载链接:https://www.kaggle.com/competitions/titanic/data?select=train.csv
传送门
在这里插入图片描述
在这里插入图片描述

total_df['Embarked_is_nan']=(total_df['Embarked']!=total_df['Embarked'])

这行代码建了一个新列 ‘Embarked_is_nan’,用于标记 ‘Embarked’ 列中的空值(NaN)。如果 ‘Embarked’ 列中的元素不是它自己(即元素是 NaN),则新列的对应位置将被设为 True。
这种写法我还是第一次见。

keys=['Pclass','Sex','SibSp','Parch']
for key in keys:
    values=np.unique(train_df[key].values)
    
    if len(values)<10 and key!="Survived":
        print(f"key:{key},values:{values}") 
        
        key_target=train_df['Survived'].groupby([train_df[key]]).mean()
        keys=key_target.keys().values
        target=key_target.values
        key_target=pd.DataFrame({key:keys,key+"_target":target})
        total_df=pd.merge(total_df,key_target,on=key,how="left")
total_df.head()

这一段代码有点复杂,首先筛选了四个重要特征[‘Pclass’,‘Sex’,‘SibSp’,‘Parch’],存储在keys列表里,这些列被认为可能与乘客的生存情况有关。
然后逐个遍历该列表,看看每个特征在训练集里的数量有多少不重复的值values。
如果某个关键列的唯一值数量len(values)少于10个,代码会进一步分析这个列与生存情况的关系。
(我有点疑惑的是为什么要强调 key!=“Survived”,这个keys列表里本来也没有“Survived”这个取值啊??)
打印出来发现四个属性都满足条件:
在这里插入图片描述

key_target=train_df['Survived'].groupby([train_df[key]]).mean()

这一步在训练集train_df当中,代码计算了keys这个列表中,每个唯一值对应的’Survived’列的平均生存率。
在这里插入图片描述
由图可见,key_target这个dataframe的值每次循环都随着关键属性的值变化,比如在处理到key = Pclass的时候,key_target的键就是1,2,3,值就是对应的平均生存率;处理到key = sex的时候,key_target的键是‘Female’和‘Male’,值同样是对应的平均生存率。
后续的步骤有一些复杂,画个word表格配合理解一下:
keys里面一共四个属性,每次就拿其中一个来说事,最后把四个属性的数据都存在total_df里面汇总并返回。
这是拿PClass说事的情况,PClass有三个值:1/2/3,针对每个值计算了平均存活率,并保存在key_target中。
然后取出了key_target的键存在keys列表(是的没错这个列表也叫keys……,但此时里面的值应该是PClass的1/2/3这三个取值)里面,值存在target列表里面(即0.629630,0.472826,0.242363这三个数字),然后人为给键和值这两列取名字,键这一列还叫PClass,值这一列比较有个性,要叫‘PClass_target’。
在这里插入图片描述
以此类推,后面三个属性的key_target都是这套路,但是total_df这张表一直在扩大。
在这里插入图片描述
(male这里是word超界,图截掉了,后面单独补了一块)
直到最后total_df变为一张大表:
在这里插入图片描述
说实话,对于一个主要目的是教人怎么使用调参工具的Optuna案例来说,原作者这一步写的逻辑真的很给我增加了理解负担……
我让Kimi把这段代码改写成了一个更加清晰简单的版本,这样不容易混淆这么多满屏的key和target:
在这里插入图片描述
这部分不是调参步骤的重点,如果实在搞不明白可以跳过。————————————————————————————————————————————
使用平均值填充缺失值,这学到的数据处理常见步骤,标记一下。
在这里插入图片描述
补充:之前上数据分析与Tableau可视化这门课的时候,老师分享的一个帖子专门介绍了很多数据缺失的类型和处理方法:https://towardsdatascience.com/all-about-missing-data-handling-b94b8b5d2184
添加链接描述
帖子是全英文,需要注册登录一下观看。
————————————————————————————————————————————
有了属性更多更全面的数据集total_df以后,按照之前的长度再划分回训练集和测试集。
在这里插入图片描述
————————————————————————————————————————————
在这里插入图片描述
这里提到训练集和测试集的比例为8:2,即4:1,是一个很常见的划分比例。
原作者这里应该是把test和valid看作一个东西,所以命名没有特别刻意区分。
在这里插入图片描述
但实际上这两个概念并不是完全一样(但我看到有时候确实区分得不严格),这里我统一采用了全是test_X和test_y的写法。
在这里插入图片描述
在这里插入图片描述
————————————————————————————————————————————
导入LGBM回归器,虽然泰坦尼克号数据集用于分类问题(预测一位乘客能否生还)较多,但原作者在这里把他视作回归问题处理。我考虑到作为入门来说,选择数据集简单熟悉、有视频解说的教程容易上手一些,所以没有纠结回归还是分类问题的细节。后续熟练了流程的话可以网上找更多复杂和规范的数据来练习。
补充学习链接:《LGBMRegressor 参数设置 lgbmclassifier参数》
https://blog.51cto.com/u_12219/10333606
添加链接描述
(话说这帖子里不是有LGBM分类器么,为什么作者在视频里要专门提到当回归问题处理呢?)
————————————————————————————————————————————
RMSE作为损失函数,即评估指标,是**计算均方根误差(Root Mean Square Error)**的Python函数,越小越好
在这里插入图片描述
————————————————————————————————————————————
根据原作者视频的讲解设置任务objective的参数:
具体参数名称、含义、建议值可以参考上面那个《LGBMRegressor 参数设置 lgbmclassifier参数》补充学习贴。

def objective(trial):
    param = {
        'metric':'rmse',
        'random_state':trial.suggest_int('random_state', 2023, 2023),  #随机种子固定,所以设置为2023-2023
        'n_estimators':trial.suggest_int('n_estimators', 50, 300),  #迭代器数量 50-300 的整数
        'reg_alpha':trial.suggest_loguniform('reg_alpha', 1e-3, 10.0),
        'reg_lambda':trial.suggest_loguniform('reg_lambda', 1e-3, 10.0),  #对数正态分布的建议值
        'colsample_bytree':trial.suggest_float('colsample_bytree', 0.5, 1), #浮点数
        'subsample':trial.suggest_float('subsample', 0.5, 1),
        'learning_rate':trial.suggest_float('learning_rate', 1e-4, 0.1, log = True),
        'num_leaves':trial.suggest_int('num_leaves', 8, 64),  #整数
        'min_child_samples':trial.suggest_int('min_child_smaples', 1, 100),        
    }
    model = LGBMRegressor(**param)  #调用模型
    model.fit(train_X, train_y, eval_set = [(test_X, test_y)], early_stopping_rounds = 100, verbose = False)  #拟合
    preds = model.predict(test_X)  #计算测试集的损失
    rmse = RMSE(test_y, preds)
    return rmse

————————————————————————————————————————————
关键代码:调用Optuna,创建一个学习任务,指定让损失最小,设置任务名称:

#创建的研究命名,找最小值
study = optuna.create_study(direction = 'minimize', study_name = 'Optimize boosting hpyerparameters')  #创建了一个Optuna研究对象,用于优化超参数。
#关键代码:调用Optuna,创建一个学习任务,指定让损失最小,设置任务名称。
#目标函数,尝试的次数
study.optimize(objective, n_trials = 100) #将设定好参数的object任务传进来,尝试一百次
#输出最佳的参数
print('Best Trial: ',study.best_trial.params) #找到最佳参数  tudy.best_trial 表示在所有尝试中损失最小的那次试验,params 是一个字典,包含了那次试验中使用的超参数。
lgbm_params = study.best_trial.params #这行代码将最佳参数赋值给 lgbm_params 变量。这样可以将这些参数用于LightGBM模型或其他需要这些超参数的模型。

在这里插入图片描述
————————————————————————————————————————————
思路没问题,但我们遇到一个奇怪的报错:fit() got an unexpected keyword argument ‘early_stopping_rounds’:
在这里插入图片描述
Kimi的方法试了还是报错,所以,多半又不是该我们背锅。在这里插入图片描述
在这里插入图片描述
StackFlow的大神们提供了两个解决方案:
https://stackoverflow.com/questions/76895269/lgbmclassifier-fit-got-an-unexpected-keyword-argument-early-stopping-rounds

传送门
在这里插入图片描述
在这里插入图片描述
注意最好用pip install的方式,conda install好像装不上。
在这里插入图片描述
但我发现并没有什么用……还是报一样的错误,不认识early_stopping_rounds,甚至删掉以后还不认识后面一个参数verbose……
按照前面那个补充的参数帖子改也不行,看来这信息更新有亿点点滞后啊……
在这里插入图片描述
在这里插入图片描述

————————————————————————————————————————————
顺便搜的过程中还发现一个易错点:这个early_stopping_rounds好像最大也只能顶到100。
https://blog.csdn.net/YangTinTin/article/details/120708391
传送门
在这里插入图片描述
————————————————————————————————————————————
我在网上手动搜了一圈加上询问Kimi,暂时还没有找到很有效的替代方案。鉴于我们主要是希望尝试一下Optuna的使用过程,所以先把这俩惹麻烦的参数删去。

model.fit(train_X, train_y, eval_set=[(test_X, test_y)])  #拟合

完整objective代码:

def objective(trial):
    param = {
        'metric':'rmse',
        'random_state':trial.suggest_int('random_state', 2023, 2023),  #随机种子固定,所以设置为2023-2023
        'n_estimators':trial.suggest_int('n_estimators', 50, 300),  #迭代器数量 50-300 的整数
        'reg_alpha':trial.suggest_loguniform('reg_alpha', 1e-3, 10.0),
        'reg_lambda':trial.suggest_loguniform('reg_lambda', 1e-3, 10.0),  #对数正态分布的建议值
        'colsample_bytree':trial.suggest_float('colsample_bytree', 0.5, 1), #浮点数
        'subsample':trial.suggest_float('subsample', 0.5, 1),
        'learning_rate':trial.suggest_float('learning_rate', 1e-4, 0.1, log = True),
        'num_leaves':trial.suggest_int('num_leaves', 8, 64),  #整数
        'min_child_samples':trial.suggest_int('min_child_smaples', 1, 100),        
    }
    model = LGBMRegressor(**param)  #调用模型
    model.fit(train_X, train_y, eval_set=[(test_X, test_y)])  #拟合
    preds = model.predict(test_X)  #计算测试集的损失
    rmse = RMSE(test_y, preds)
    return rmse

然后就可以得到Best_Trial了:
在这里插入图片描述
————————————————————————————————————————————
类似的,原UP还用了xgboost和catboost类似方法来找最佳参数。
不难看出,三个不同的方法主要区别是选用的参数param,以及model指定的函数方法。
XGBoost:
在这里插入图片描述
在这里插入图片描述
XGBoost结果
在这里插入图片描述
————————————————————————————————————————————
CatBoost:
在这里插入图片描述
在这里插入图片描述
CatBoost结果:
在这里插入图片描述
————————————————————————————————————————————
最后使用K折交叉验证得到最佳结果:
交叉验证也是个机器学习常用词。
在这里插入图片描述

def accuracy(y_true, y_pred):
    return np.sum(y_true == y_pred)/len(y_true)

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
kf 是一个 KFold 对象,它是 scikit-learn 库中用于实现 K 折交叉验证的工具。KFold 将数据集分成 n_splits 个子集,每个子集轮流作为验证集,其余的作为训练集。
for train_index, valid_index in kf.split(x): 这行代码会迭代 KFold 对象,每次迭代返回两个数组:train_index 和 valid_index。train_index 包含了用于训练的数据点的索引,而 valid_index 包含了用于验证的数据点的索引。根据索引到全集X,y里面就能取到每一次的训练集和验证集数据,这个过程好比全班打乱,每次随机抽学号喊几个同学一组。
————————————————————————————————————————————
现在又遇到一个常见bug,虽然我不太知道这是怎么产生的,不知道是不是又该Python背锅。(因为之前X,y数据集的shape和作者是一模一样的,后面按道理也没有另外对他们做什么操作……)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
遇到问题不要怕,改!这把要相信Kimi!(顺便一提,我实习的这家做人工智能的公司员工他们自己也用的Kimi,所以Kimi还是比较可信的,而且还免费!!)
在这里插入图片描述
别忘了同时把early_stopping_rounds和verbose这俩参数毙了,免得又惹出报错。
在这里插入图片描述
这一块代码比较长,重复差不多的地方有点多,注意不要写漏写错了。

from sklearn.model_selection import KFold  #在机器学习库中导入k折交叉验证的函数
from xgboost import XGBRegressor
from lightgbm import  LGBMRegressor
from catboost import CatBoostRegressor  

def accuracy(y_true,y_pred):
    return np.sum(y_true==y_pred)/len(y_true)
print("start fit.")
folds = 10  #将数据分成10份
y=train_df['Survived']
X=train_df.drop(['Survived'],axis=1)

train_accuracy=[]
valid_accuracy=[]
# 存储已学习模型的列表
models = []

#将数据集随机打乱,并分成folds份
kf = KFold(n_splits=folds, shuffle=True, random_state=2023) 

#从x_train中按照9:1的比例分成训练集和验证集,并取出下标
for train_index, valid_index in kf.split(X):
    
    #根据下标取出训练集和验证集的数据
    x_train_cv = X.iloc[train_index]
    y_train_cv = y.iloc[train_index]
    x_valid_cv =X.iloc[valid_index]
    y_valid_cv = y.iloc[valid_index]
    
    model = LGBMRegressor(**lgbm_params)
    
    #模型用x_train_cv去训练,用x_train_cv和x_valid_cv一起去评估
    model.fit(
        x_train_cv, 
        y_train_cv, 
        eval_set = [(x_train_cv, y_train_cv), (x_valid_cv, y_valid_cv)], 
        #early_stopping_rounds=100,
        #verbose = 100, #迭代100次输出一个结果
    )
    
    #对训练集进行预测
    y_pred_train = model.predict(x_train_cv)        
    #对验证集进行预测
    y_pred_valid = model.predict(x_valid_cv) 
    
    y_pred_train=(y_pred_train>=0.5)
    y_pred_valid=(y_pred_valid>=0.5)
    
    train_acc=accuracy(y_pred_train,y_train_cv)
    valid_acc=accuracy(y_pred_valid,y_valid_cv)
    
    train_accuracy.append(train_acc)
    valid_accuracy.append(valid_acc)
    
    #将model保存进列表中
    models.append(model)
    
    model = XGBRegressor(**xgb_params)
    
    #模型用x_train_cv去训练,用x_train_cv和x_valid_cv一起去评估
    model.fit(
        x_train_cv, 
        y_train_cv, 
        eval_set = [(x_train_cv, y_train_cv), (x_valid_cv, y_valid_cv)], 
        #early_stopping_rounds=100,
        #verbose = 100, #迭代100次输出一个结果
    )
    
    #对训练集进行预测
    y_pred_train = model.predict(x_train_cv)        
    #对验证集进行预测
    y_pred_valid = model.predict(x_valid_cv) 
    
    y_pred_train=(y_pred_train>=0.5)
    y_pred_valid=(y_pred_valid>=0.5)
    
    train_acc=accuracy(y_pred_train,y_train_cv)
    valid_acc=accuracy(y_pred_valid,y_valid_cv)
    
    train_accuracy.append(train_acc)
    valid_accuracy.append(valid_acc)
    
    #将model保存进列表中
    models.append(model) 
    
    model = CatBoostRegressor(**cat_params)
    
    #模型用x_train_cv去训练,用x_train_cv和x_valid_cv一起去评估
    model.fit(
        x_train_cv, 
        y_train_cv, 
        eval_set = [(x_train_cv, y_train_cv), (x_valid_cv, y_valid_cv)], 
        #early_stopping_rounds=100,
        #verbose = 100, #迭代100次输出一个结果
    )
    
    #对训练集进行预测
    y_pred_train = model.predict(x_train_cv)        
    #对验证集进行预测
    y_pred_valid = model.predict(x_valid_cv) 
    
    y_pred_train=(y_pred_train>=0.5)
    y_pred_valid=(y_pred_valid>=0.5)
    
    train_acc=accuracy(y_pred_train,y_train_cv)
    valid_acc=accuracy(y_pred_valid,y_valid_cv)
    
    train_accuracy.append(train_acc)
    valid_accuracy.append(valid_acc)
    
    #将model保存进列表中
    models.append(model) 
    
    print(f"train_accuracy:{train_accuracy}, valid_accuracy:{valid_accuracy}")

train_accuracy=np.array(train_accuracy)
valid_accuracy=np.array(valid_accuracy)

print(f"mean_train_accuracy: {np.mean(train_accuracy)}")
print(f"mean_valid_accuracy: {np.mean(valid_accuracy)}")

我跟原作者的中间输出有些不一样,不知道差距是什么造成的:
在这里插入图片描述
在这里插入图片描述
不过好在目前看来,结果还不算太差:
在这里插入图片描述
在这里插入图片描述
————————————————————————————————————————————
在测试集上测试每个模型的效果:

test_X = test_df.drop(['Survived'], axis = 1).values

preds_test = []

#用每个保存的模型都对x_test预测一次,然后取平均值
for model in models:
    pred = model.predict(test_X)
    preds_test.append(pred)
#将预测结果转换为np.array
preds_test_np = np.array(preds_test)

#按行对每个模型的预测结果取平均值
test_pred= preds_test_np.mean(axis = 0 )
test_pred=(test_pred >= 0.5).astype(np.int64) 
#平均预测值与 0.5 进行比较,根据比较结果(大于等于 0.5 为 True,否则为 False)将每个值转换为二进制形式(即 1 或 0),然后使用 astype(np.int64) 将布尔值转换为 64 位整数类型。
test_pred

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
看输出的test_pred.shape,不要看这个array长得四四方方的,看他shape还是个一维数组,拥有 418 个元素。
在 Python 中,一维数组的形状通常表示为 (N,),其中 N 是数组中的元素总数。
————————————————————————————————————————————
像test_pred=(test_pred >= 0.5).astype(np.int64) 这句用到的一样,创建新列并且通过比较大小来赋Bool值是True还是False的例子,在这个项目里还有很多:
在这里插入图片描述
在这里插入图片描述
————————————————————————————————————————————
最后保存并写入CSV文件:

submission=pd.read_csv("D:/StudyFiles/Optuna_Titanic/data/gender_submission.csv")  #读取CSV文件,并将其存储在变量submission中
submission['Survived']=test_pred  #更新了submission DataFrame中的'Survived'列,使其包含模型预测的生存概率或分类结果。
submission.to_csv("submission.csv",index=None) #将更新后的submission DataFrame保存为一个新的CSV文件"submission.csv"。参数index=None表示在保存CSV文件时不包括行索引。
submission.head()

在这里插入图片描述
————————————————————————————————————————————
我会把我的代码包发到CSDN主页,有需要的朋友欢迎自行下载,那我们下一个教程再见吧。
在这里插入图片描述
————————————————————————————————————————————
其他相关的学习内容:
(一)**9.1 模型调参【斯坦福21秋季:实用机器学习中文版】:**李沐老师的视频,介绍了一些关于调参的理论,不了解调参的可以看看学习一下基础知识。
https://www.bilibili.com/video/BV1vQ4y1e7LF/?spm_id_from=333.788.recommend_more_video.1&vd_source=cdfd0a0810bcc0bcdbcf373dafdf6a82
传送门
(二)这个自动调参神器简直是太强了!能完全满足机器学习和深度学习调参日常使用!初学者必备工具!:视频内容不如我跟的这个示范视频,主要就是简单讲了一下Optuna,没有实操案例。
https://www.bilibili.com/video/BV1Zs421K7Qj/?spm_id_from=333.788.recommend_more_video.6&vd_source=cdfd0a0810bcc0bcdbcf373dafdf6a82
传送门
不过我对这位UP介绍的这本书很感兴趣,因为对于我这种缺乏经验又喜欢找规律的小白来说,很希望能有一本指导手册给我介绍一些万能公式和方向。

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

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

相关文章

昇思MindSpore学习笔记6-02计算机视觉--ResNet50迁移学习

摘要&#xff1a; 记录MindSpore AI框架使用ResNet50迁移学习方法对ImageNet狼狗图片分类的过程、步骤。包括环境准备、下载数据集、数据集加载、构建模型、固定特征训练、训练评估和模型预测等。 一、概念 迁移学习的方法 在大数据集上训练得到预训练模型 初始化网络权重参数…

爬虫-浏览器自动化

什么是selenium selenium是浏览器自动化测试框架&#xff0c;原本用于网页测试。但到了爬虫领域&#xff0c;它又成为了爬虫的好帮手。有了 selenium&#xff0c;我们便不再需要判断网页数据加载的方式&#xff0c;只要让 selenium 自动控制浏览器&#xff0c;就像有双无形的手…

海南云亿商务咨询有限公司抖店开店正规吗?

在当今的数字经济时代&#xff0c;抖音电商已经成为一股不可忽视的力量。无论是品牌商还是个人创业者&#xff0c;都纷纷涌入这个充满活力和潜力的市场。而在这个风起云涌的浪潮中&#xff0c;海南云亿商务咨询有限公司以其专业的服务和敏锐的市场洞察力&#xff0c;成为抖音电…

GitHub 创始人资助的开源浏览器「GitHub 热点速览」

你是否注意到&#xff0c;现在主流的浏览器如 Chrome、Edge、Brave 和 Opera 都采用了谷歌的 Chromium 引擎&#xff1f;同时&#xff0c;谷歌每年不惜花费数十亿美元&#xff0c;确保其搜索引擎在 Safari 中的默认地位&#xff0c;甚至连 Firefox 也难逃商业利益的影响&#x…

一款好用的特殊字符处理工具

跟mybatis代码的时候&#xff0c;偶然发现的一款特殊字符处理工具java.lang.StringTokenizer。平常&#xff0c;我们看到的mybatis mapper.xml里面各种换行各种缩进&#xff0c;但日志文件里面的sql都是整整齐齐的。没有换行符&#xff0c;缩进等。就是利用该工具做的格式化处理…

在Ubuntu下安装samba实现和Windows系统文件共享

一、安装 apt install -y samba samba-clientSamba is not being run as an AD Domain Controller: Masking samba-ad-dc.service Please ignore the following error about deb-systemd-helper not finding those services. (samba-ad-dc.service masked) Created symlink /et…

每天一个数据分析题(四百二十七)- 方差分析

下面是一个方差分析表&#xff1a; 表中A&#xff0c;B&#xff0c;C&#xff0c;D&#xff0c;E五个单元格内的数据分别是&#xff08; &#xff09;。 A. 40&#xff0c;5&#xff0c;35&#xff0c;60&#xff0c;1.71 B. 40&#xff0c;5&#xff0c;35&#xff0c;60&a…

仙侠天花板,圆你土豪梦,上古传说手游详细图文架设教程

前言 这次给大家带来的是一款我的心头好&#xff0c;绝对是我所有架设游戏里排名前三的&#xff0c;一款经典的仙侠手游&#xff0c;安卓苹果双端&#xff0c;画质精美程度真的没有哪几个游戏可以比得上&#xff0c;故事情节加上背景音乐绝对值得沉浸其中慢慢玩&#xff0c;最…

JSONObject和Map<String, Object>的转换

一、前言 Java开发中出参返回和入参传入更灵活的方法是使用Map<String, Object>入参或出参&#xff0c;或者使用JSONObject。 1、好处&#xff0c;参数可变&#xff0c;对接口扩展性很友好。 public ResponseData<WXModelDTO> getUserInfo(RequestBody Map<…

【unity笔记】常见问题收集

一 . Unity Build GI data 卡住问题 问题解决: 参考官方文档&#xff0c;GI(Global Illumination) data 指的是全局照明信息。 在Unity的Edit->Preference中&#xff0c;可以编辑GI缓存路径和分配GI缓存大小。 调出Window->Rendering->Lighting窗口&#xff0c;取消…

OceanMind海睿思成功签约苏州天准,助力数据管理流程闭环!

近日&#xff0c;中新赛克海睿思与苏州天准科技股份有限公司&#xff08;以下简称“苏州天准”&#xff09;达成深度战略合作&#xff0c;为苏州天准提供数据工程平台。 双方将依托OceanMind海睿思提供的业内领先的数据工程建设理念&#xff0c;为苏州天准搭建以数字化平台底座…

大模型中 KV Cache 原理及显存占用分析

本文记录大模型推理阶段 KV Cache 的原理及显存占用情况。 Self-Attention 与 KV Cache 如图&#xff0c;当新生成的 token x 进到模型计算 Attention 时&#xff0c;先分别乘上参数矩阵 W q W_q Wq​、 W k W_k Wk​、 W v W_v Wv​ 得到向量 q&#xff0c;以及矩阵 K、V。…

汽车零配件行业看板管理系统应用

生产制造已经走向了精益生产&#xff0c;计算时效产出、物料周转时间等问题&#xff0c;成为每一个制造企业要面临的问题&#xff0c;工厂更需要加快自动化&#xff0c;信息化&#xff0c;数字化的布局和应用。 之前的文章多次讲解了企业MES管理系统&#xff0c;本篇文章就为大…

华为机试题-从(0,0)开始,计算绘图面积-Java

代码在最后面 1 题目描述 绘图机器的绘图笔初始位置在原点(0,0)&#xff0c;机器启动后按照以下规则来进行绘制直线。 尝试沿着横线坐标正向绘制直线直到给定的终点E。期间可以通过指令在纵坐标轴方向进行偏移&#xff0c;offset Y为正数表示正向偏移&#xff0c;为负数表示负…

linux源码安装mysql8.0的小白教程

1.下载8.x版本的mysql MySQL :: Download MySQL Community Server (Archived Versions) 2.安装linux 我安装的是Rocky Linux8.6 3.设置ip地址,方便远程连接 使用nmcli或者nmtui设置或修改ip地址 4.使用远程连接工具MobaXterm操作: (1)将mysql8版本的压缩包上传到mybaxterm…

【电商选品干货】差异化卖点要这样打造,80%商家却做不到

今天就给大家说说&#xff0c;如何去挖掘产品的差异化卖点&#xff1f;我们要找差异化卖点&#xff0c;就是因为我们的产品转化率不足&#xff0c;通常有下面几点原因&#xff1a; 1、产品差异化卖点不足&#xff0c;商家占比30% 2、流量和产品卖点不匹配&#xff0c;商家占比…

U-2 Net原理+代码实战教程

目录 一、显著性目标检测1.1 核心目标1.2 技术方法 二、U2-Net2.1 双层嵌套U结构2.2 残差U块&#xff08;RSU&#xff09;2.3 网络训练和监督 三、代码实战3.1 克隆仓库3.2 下载预训练模型3.3 安装依赖3.4 运行模型显著性目标检测&#xff1a;训练模型&#xff1a; 一、显著性目…

美团到家平台业务探索

背景 到家业务发展已经近10年&#xff0c;目前最为火热的应该有美团到家、抖音到家等&#xff0c;这种极具挑战性的业务&#xff0c;值得学习和思考。 既然是服务平台化&#xff0c;那一定是兼容了多种业务以及多种模式。 挑战 订单、骑手规模大&#xff0c;供需匹配过程的…

UDS协议——Authentication(29服务)

诊断协议那些事儿 诊断协议那些事儿专栏系列文章,本文介绍诊断和通讯管理功能单元下的29服务Authentication (29 16) service。此服务是在ISO 14229-2020版本中首次增加的为应对网联汽车日益增加的安全风险的新服务。为Client和Server之间的身份认证提供一种方法,以便对意图…

常用3D建模软件有哪些?如何实现3D模型在线预览?

3D建模是指使用计算机软件或其他工具创建三维物体模型的过程。3D建模大概可分为NURBS和多边形网格两类。NURBS对要求精细、弹性与复杂的模型有较好的应用&#xff0c;适合量化生产用途&#xff1b;多边形网格建模则靠拉面方式&#xff0c;适合做效果图与复杂场景动画。建模方法…