【AI奇技淫巧】使用Optuna进行机器学习模型调参

news2025/1/13 10:14:42

使用Optuna进行机器学习模型调参

  • Optuna简介
  • 框架特点
  • 安装方式
  • 举个例子
  • 高级配置
    • 搜索方式
    • 分支(Branches)与循环(Loops)
    • 分布式优化
    • 命令行界面
    • 用户定义属性
    • 将用户定义属性添加到Study
      • 将用户属性添加到Trial中
    • 对无望的Trial进行剪枝(Pruning)
      • 开启Pruner
      • 用于Pruning的集成模块
    • 用户定义的采样器(Sampler)
      • Sampler概述
      • 案例,实现模拟退火Sampler(SimulatedAnnealingSampler)
  • 使用Optuna对LGBM进行调参
    • 定义Objective
    • 调参try
    • 绘图
      • 优化历史
      • 并行化参数选择
      • 重要性参数
  • 使用Optuna对XGBoost进行调参
    • 定义Objective
    • 调参try
    • 绘图
  • 参考资料
  • 参考资料

Optuna简介

Optuna 是一个使用Python编写的开源的超参数优化框架,它可以自动为机器学习模型找到最佳超参数。最基本的(也可能是众所周知的)替代方案是 sklearn 的 GridSearchCV,它将尝试多种超参数组合并根据交叉验证选择最佳组合。

  • GridSearchCV 将在先前定义的空间内尝试组合。例如,对于随机森林分类器,可能想要测试几个不同的树的最大深度。GridSearchCV 会提供每个超参数的所有可能值,并查看所有组合。
  • Optuna会在定义的搜索空间中使用自己尝试的历史来确定接下来要尝试的值。它使用的方法是一种称为“Tree-structured Parzen Estimator”的贝叶斯优化算法。

PS: Optuna是一种为自动和加速研究而设计的框架

这种不同的方法意味着它不是无意义的地尝试每一个值,而是在尝试之前寻找最佳候选者,这样可以节省时间,否则这些时间会花在尝试没有希望的替代品上(并且可能也会产生更好的结果)。

一个极简的Optuna的优化程序只有三个最核心的概念,目标函数(objective),单次实验(trial)和研究(study),其中objective负责定义待优化函数并指定参数/超参数的范围,trial对应着objective的单次执行,study则负责管理优化,决定优化的方式,总实验的次数、实验结果的记录等功能。
Optuna

最后,它与框架无关,这意味着可以将它与TensorFlowKerasPyTorch 或任何其他 ML 框架一起使用。

框架特点

  • 小巧轻量,通用且与平台无关
  • Python形式的超参数空间搜索
  • 高效的优化算法
  • 写法简单,可以并行
  • 快速可视化

安装方式

(1)PyPI
$ pip install optuna
(2)Anaconda
$ conda install -c conda-forge optuna

举个例子

定义 x , y ∈ ( − 10 , 10 ) x,y\in (-10, 10) x,y(10,10),求 f ( x ) = ( x + y ) 2 f(x)=(x+y)^2 f(x)=(x+y)2取得最大值时,x,y的取值?

import optuna

def objective(trial):
    x = trial.suggest_uniform('x', -10, 10)
    y = trial.suggest_uniform('y', -10, 10)
    return (x + y) **2

study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)

print(study.best_params)
print(study.best_value)

执行结果:
计算过程及结果
获得最佳trial:

print(study.best_trial)
FrozenTrial(number=21, values=[397.3121495333754], datetime_start=datetime.datetime(2022, 12, 26, 10, 17, 40, 813392), datetime_complete=datetime.datetime(2022, 12, 26, 10, 17, 40, 818404), params={'x': 9.956757602729924, 'y': 9.975932871297294}, distributions={'x': FloatDistribution(high=10.0, log=False, low=-10.0, step=None), 'y': FloatDistribution(high=10.0, log=False, low=-10.0, step=None)}, user_attrs={}, system_attrs={}, intermediate_values={}, trial_id=21, state=TrialState.COMPLETE, value=None)

获得所有 trials:

print(study.trials)

获得trials的数目:

len(study.trials)

(在优化结束后)通过再次执行 optimize(),我们可以继续优化过程。

study.optimize(objective, n_trials=100)

Optuna Dashboard是Optuna的实时web仪表板。可以在图表中检查优化历史、超参数重要性等。

% pip install optuna-dashboard
% optuna-dashboard sqlite:///db.sqlite3

高级配置

搜索方式

optuna根据需要,支持多种不同的搜索方式(含有low和high值的都是左闭右开):

def objective(trial):
    # Categorical parameter
    optimizer = trial.suggest_categorical('optimizer', ['MomentumSGD', 'Adam'])  # 选择型搜索方式

    # Int parameter
    num_layers = trial.suggest_int('num_layers', 1, 3) # 整数型搜索方式

    # Uniform parameter
    dropout_rate = trial.suggest_uniform('dropout_rate', 0.0, 1.0) # 连续均匀采样搜索方式

    # Loguniform parameter
    learning_rate = trial.suggest_loguniform('learning_rate', 1e-5, 1e-2) # 对数均匀采样方式

    # Discrete-uniform parameter
    drop_path_rate = trial.suggest_discrete_uniform('drop_path_rate', 0.0, 1.0, 0.1) # 离散均匀采样方式

    ...

除此之外,对于trail.suggest_uniform,trail.suggest_loguniform以及trail.suggest_discrete_uniform三种形式,optuna提供了一个统一封装形式(详情见OPTUNA/optuna/trail/_trail.pydef suggest_float(self,name,low,high,*,step,log)->float.

分支(Branches)与循环(Loops)

根据不同的参数,选择使用分支或者循环

def objective(trial):
    classifier_name = trial.suggest_categorical('classifier', ['SVC', 'RandomForest'])
    if classifier_name == 'SVC':
        svc_c = trial.suggest_loguniform('svc_c', 1e-10, 1e10)
        classifier_obj = sklearn.svm.SVC(C=svc_c)
    else:
        rf_max_depth = int(trial.suggest_loguniform('rf_max_depth', 2, 32))
        classifier_obj = sklearn.ensemble.RandomForestClassifier(max_depth=rf_max_depth)

    ...
def create_model(trial):
    n_layers = trial.suggest_int('n_layers', 1, 3)

    layers = []
    for i in range(n_layers):
        n_units = int(trial.suggest_loguniform('n_units_l{}'.format(i), 4, 128))
        layers.append(L.Linear(None, n_units))
        layers.append(F.relu)
    layers.append(L.Linear(None, 10))

    return chainer.Sequential(*layers)

注意:随着参数个数的增长,优化的难度约成指数增长。也就是说,当你增加参数的个数的时候,优化所需要的 trial 个数会呈指数增长。因此我们推荐不要增加不必要的参数。

分布式优化

Optuna的分布式优化只需要让不同的节点/进程共享一个相同的study名。

  1. 首先,使用optuna create-study命令(如果是在Python脚本中的话,就用optuna.create_study())创建一个共享的study。
$ optuna create-study --study-name "distributed-example" --storage "sqlite:///example.db"
[I 2018-10-31 18:21:57,885] A new study created with name: distributed-example
  1. 然后写一个包含如下代码的脚本,foo.py,来进行优化。
import optuna

def objective(trial):
    x = trial.suggest_uniform('x', -10, 10)
    return (x - 2) ** 2

if __name__ == '__main__':
    study = optuna.load_study(study_name='distributed-example', storage='sqlite:///example.db')
    study.optimize(objective, n_trials=100)
  1. 最后,从不同的进程中分别运行这个share study。比如说,在一个终端中运行Process 1,在另一个终端中运行Process 2。这些进程基于这个共享study的trial历史记录来获取参数建议(parameter suggrestion)
    进程1:
$ python foo.py
[I 2018-10-31 18:46:44,308] Finished a trial resulted in value: 1.1097007755908204. Current best value is 0.00020881104123229936 with parameters: {'x': 2.014450295541348}.
[I 2018-10-31 18:46:44,361] Finished a trial resulted in value: 0.5186699439824186. Current best value is 0.00020881104123229936 with parameters: {'x': 2.014450295541348}.
......

进程2(使用和进程 1 相同的命令):

$ python foo.py
[I 2018-10-31 18:47:02,912] Finished a trial resulted in value: 29.821448668796563. Current best value is 0.00020881104123229936 with parameters: {'x': 2.014450295541348}.
[I 2018-10-31 18:47:02,968] Finished a trial resulted in value: 0.7962498978463782. Current best value is 0.00020881104123229936 with parameters: {'x': 2.014450295541348}.
...

注意:

  • 不推荐在大型的分布式优化中使用 SQLite,因为这可能导致性能问题。在这种情况下,请考虑使用其他数据库,比如 PostgreSQL 或 MySQL.
  • 在运行分布式优化时,不要将 SQLite 数据库文件放在 NFS (Network File System) 文件系统中。具体原因见 : https://www.sqlite.org/faq.html#q5

命令行界面

命令功能描述
create-study创建一个新的study
delete-study删除所给的 study
dashboard启动 web 面板 (beta)
storage upgrade升级数据库 schema
studies输出study列表
study optimize针对一个study开始优化过程
study set-user-attr设置study的用户属性

Optuna提供的命令行界面包括上表中的所有命令。
示例(Python脚本文件):

import optuna

def objective(trial):
    x = trial.suggest_uniform('x', -10, 10)
    return (x - 2) ** 2

if __name__ == '__main__':
    study = optuna.create_study()
    study.optimize(objective, n_trials=100)
    print('Best value: {} (params: {})\n'.format(study.best_value, study.best_params))

然后,通过optuna命令,可以少些一些上面的模板代码。假设有一个foo.py文件,它只包含如下代码:

def objective(trial):
    x = trial.suggest_uniform('x', -10, 10)
    return (x - 2) ** 2

即使在这种情况下,我们也可以利用如下命令启动优化过程:

$ cat foo.py
def objective(trial):
    x = trial.suggest_uniform('x', -10, 10)
    return (x - 2) ** 2

$ STUDY_NAME=`optuna create-study --storage sqlite:///example.db`
$ optuna study optimize foo.py objective --n-trials=100 --storage sqlite:///example.db --study-name $STUDY_NAME
[I 2018-05-09 10:40:25,196] Finished a trial resulted in value: 54.353767789264026. Current best value is 54.353767789264026 with parameters: {'x': -5.372500782588228}.
[I 2018-05-09 10:40:25,197] Finished a trial resulted in value: 15.784266965526376. Current best value is 15.784266965526376 with parameters: {'x': 5.972941852774387}.
...
[I 2018-05-09 10:40:26,204] Finished a trial resulted in value: 14.704254135013741. Current best value is 2.280758099793617e-06 with parameters: {'x': 1.9984897821018828}.

注意:foo.py中只包含目标函数的定义。通过向optuna study optimize命令传递该文件名和对应目标函数的方法名,就可以启动优化过程。

用户定义属性

将用户定义属性添加到Study

Study对象提供了一个将键值对设置为用户自定义属性的方法:set_user_attr()。这里的键应该属于str类型,而值可以是任何能用json.dumps来序列化的对象。

import optuna
study = optuna.create_study(storage='sqlite:///example.db')
study.set_user_attr('contributors', ['Akiba','Sano'])
study.set_user_attr('dataset', 'MNIST')

可以利用user_attr属性来获取所有定义过的属性。

study.user_attrs  # {'contributors': ['Akiba', 'Sano'], 'dataset': 'MNIST'}

StudySummary对象中也包含了用户的自定义属性。可以从get_all_study_summaries()中获取它。

study_summaries = optuna.get_all_study_summaries('sqlite:///example.db')
study_summaries[0].user_attrs  # {'contributors': ['Akiba', 'Sano'], 'dataset': 'MNIST'}

注意:在命令行界面里,optuna study set-user-attr 可用于设置用户定义属性。

将用户属性添加到Trial中

和Study类似,Trial对象也提供了一个设置属性的方法set_user_attr()方法。这些属性是在目标函数内部设置的。

def objective(trial):
    iris = sklearn.datasets.load_iris()
    x, y = iris.data, iris.target

    svc_c = trial.suggest_loguniform('svc_c', 1e-10, 1e10)
    clf = sklearn.svm.SVC(C=svc_c)
    accuracy = sklearn.model_selection.cross_val_score(clf, x, y).mean()
    trial.set_user_attr('accuracy', accuracy)
    return 1.0 - accuracy  # return error for minimization

可以用如下方式获取这些注解的属性:

study.trials[0].user_attrs  # {'accuracy': 0.83}

注意,在本例中,属性不是被注解到Study的,它属于一个单独的Trial.

对无望的Trial进行剪枝(Pruning)

该功能可以在训练的早期阶段自动终止无望的Trial (a.k.a., 自动化 early-stopping)。 Optuna 提供了一些接口,可以用于在迭代训练算法中简洁地实现剪枝 (Pruning)。

开启Pruner

为了打开Pruning功能,需要在迭代式训练的每一步完成后调用函数report()should_prune()

  • report()定期监测这个过程中的目标函数值。
  • should_prune()根据提前定义好的条件,判定该trial是否需要终止。
"""filename: prune.py"""

import sklearn.datasets
import sklearn.linear_model
import sklearn.model_selection

import optuna

def objective(trial):
    iris = sklearn.datasets.load_iris()
    classes = list(set(iris.target))
    train_x, valid_x, train_y, valid_y = \
        sklearn.model_selection.train_test_split(iris.data, iris.target, test_size=0.25, random_state=0)

    alpha = trial.suggest_float('alpha',  0.00001, 0.001, log=True)
    clf = sklearn.linear_model.SGDClassifier(alpha=alpha)

    for step in range(100):
        clf.partial_fit(train_x, train_y, classes=classes)

        # Report intermediate objective value.
        intermediate_value = 1.0 - clf.score(valid_x, valid_y)
        trial.report(intermediate_value, step)

        # Handle pruning based on the intermediate value.
        if trial.should_prune():
            raise optuna.TrialPruned()

    return 1.0 - clf.score(valid_x, valid_y)

# Set up the median stopping rule as the pruning condition.
study = optuna.create_study(pruner=optuna.pruners.MedianPruner())
study.optimize(objective, n_trials=20)

运行结果:
运行结果
可以在输出信息中看到Setting status of trial#{} as TrialState.PRUNED.这意味着这些 trial 在他们完成迭代之前就被终止了。

用于Pruning的集成模块

为了能更加方便地实现 pruning, Optuna 为以下框架提供了集成模块。

  • XGBoost: optuna.integration.XGBoostPruningCallback
  • LightGBM: optuna.integration.LightGBMPruningCallback
  • Chainer: optuna.integration.ChainerPruningExtension
  • Keras: optuna.integration.KerasPruningCallback
  • TensorFlow optuna.integration.TensorFlowPruningHook
  • tf.keras optuna.integration.TFKerasPruningCallback
  • MXNet optuna.integration.MXNetPruningCallback
  • PyTorch Ignite optuna.integration.PyTorchIgnitePruningHandler
  • PyTorch Lightning optuna.integration.PyTorchLightningPruningCallback
  • FastAI optuna.integration.FastAIPruningCallback

例如,XGBoostPruningCallback在无需修改训练迭代逻辑的情况下引入了pruning。

pruning_callback = optuna.integration.XGBoostPruningCallback(trial, 'validation-error')
bst = xgb.train(param, dtrain, evals=[(dvalid, 'validation')], callbacks=[pruning_callback])

用户定义的采样器(Sampler)

可以使用用户定义的sample来实现:

  • 试验自己的采样算法
  • 实现具体任务对应的算法来改进优化性能,或者
  • 将其他的优化框架包装起来,整合进Optuna的流水线中

Sampler概述

Sampler负责产生要被用在trial中求值的参数值。在目标函数内,当一个suggest API(比如 suggest_uniform)被调用时,一个对应的分布对象(比如UniformDistribution)就会从内部被创建。Sampler则从该分布汇总采样一个参数值。该采样值会被返回给suggest API的调用者,进而在目标函数内被求值。

为了创建一个新的sample,自己所定义的类需要继承BaseSampler。该基类提供三个抽象方法:infer_relative_search_space(), sample_relative(), sample_independent()

从这些方法名可以看出,Optuna支持两种类型的采样过程:一种是relative sampling它考虑了单个trial内参数之间的相关性,另一种是independent sampling它对各个参数的采样是彼此独立的

在一个trial刚开始时,infer_relative_search_space()会被调用,它向该trial提供一个相对搜索空间。之后,sample_relative()会被触发,它从该搜索空间中对相对参数进行采样。在目标函数的执行过程中,sample_independent()用于对不属于该相对搜索空间的参数进行采样。

案例,实现模拟退火Sampler(SimulatedAnnealingSampler)

下面的代码根据Simulated Annealing (SA)定义类一个sampler:

def objective(trial):
    x = trial.suggest_uniform('x', -10, 10)
    y = trial.suggest_uniform('y', -5, 5)
    return x**2 + y

sampler = SimulatedAnnealingSampler()
study = optuna.create_study(sampler=sampler)
study.optimize(objective, n_trials=100)

在上面这个优化过程中,参数 x 和 y 的值都是由 SimulatedAnnealingSampler.sample_relative 方法采样得出的。
注意:严格意义上说,在第一个 trial 中,SimulatedAnnealingSampler.sample_independent 用于采样参数值。因为,如果没有已经完成的 trial 的话, SimulatedAnnealingSampler.infer_relative_search_space 中的 intersection_search_space() 是无法对搜索空间进行推断的。

使用Optuna对LGBM进行调参

定义Objective

import optuna
from lightgbm import LGBMRegressor
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn import datasets

wine = datasets.load_wine()
data = wine.data
target = wine.target

def objective(trial):
    X_train, X_test, y_train, y_test = train_test_split(data, target, train_size=0.3)
    param = {
        'metric': 'rmse',
        'random_state': 48,
        'n_estimators': 20000,
        '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_categorical('colsample_bytree', [0.3,0.4,0.5,0.6,0.7,0.8,0.9, 1.0]),
        'subsample': trial.suggest_categorical('subsample', [0.4,0.5,0.6,0.7,0.8,1.0]),
        'learning_rate': trial.suggest_categorical('learning_rate', [0.006,0.008,0.01,0.014,0.017,0.02]),
        'max_depth': trial.suggest_categorical('max_depth', [5, 7, 9, 11, 13, 15, 17, 20, 50]),
        'num_leaves' : trial.suggest_int('num_leaves', 1, 1000),
        'min_child_samples': trial.suggest_int('min_child_samples', 1, 300),
        'cat_smooth' : trial.suggest_int('cat_smooth', 1, 100)
    }
    lgb = LGBMRegressor(**param)
    lgb.fit(X_train, y_train, eval_set=[(X_test, y_test)], early_stopping_rounds=100, verbose=False)
    pred_lgb = lgb.predict(X_test)
    rmse = mean_squared_error(y_test, pred_lgb, squared=False)
    return rmse

调参try

trials

绘图

优化历史

optuna.visualization.plot_optimization_history(study)

optimization_history

并行化参数选择

optuna.visualization.plot_parallel_coordinate(study)

parallel

重要性参数

optuna.visualization.plot_param_importances(study)

参数重要性
最佳参数:

params = study.best_params
params['metric'] = 'rmse'
params
'''
{'reg_alpha': 0.002773386365643535,
 'reg_lambda': 0.041227320518631407,
 'colsample_bytree': 0.5,
 'subsample': 0.4,
 'learning_rate': 0.008,
 'max_depth': 13,
 'num_leaves': 363,
 'min_child_samples': 1,
 'cat_smooth': 38,
 'metric': 'rmse'}
'''

使用Optuna对XGBoost进行调参

定义Objective

import xgboost as xgb

def objective(trial):
    X_train, X_test, y_train, y_test = train_test_split(data, target, train_size=0.3, random_state=2023)
    param = {
        'lambda': trial.suggest_loguniform('lambda', 1e-3, 10.0),
        'alpha': trial.suggest_loguniform('alpha', 1e-3, 10.0),
        'colsample_bytree': trial.suggest_categorical('colsample_bytree', [0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]),
        'subsample': trial.suggest_categorical('subsample', [0.4, 0.5, 0.6, 0.7, 0.8, 1.0]),
        'learning_rate': trial.suggest_categorical('learning_rate',
                                                   [0.008, 0.009, 0.01, 0.012, 0.014, 0.016, 0.018, 0.02]),
        'n_estimators': 4000,
        'max_depth': trial.suggest_categorical('max_depth', [5, 7, 9, 11, 13, 15, 17, 20]),
        'random_state': trial.suggest_categorical('random_state', [24, 48, 2020]),
        'min_child_weight': trial.suggest_int('min_child_weight', 1, 300),
    }
    model = xgb.XGBRegressor(**param)
    model.fit(X_train, y_train, eval_set=[(X_test, y_test)], early_stopping_rounds=100, verbose=False)
    preds = model.predict(X_test)
    rmse = mean_squared_error(y_test, preds, squared=False)
    return rmse

调参try

study = optuna.create_study(direction='minimize')
n_trials=1
study.optimize(objective, n_trials=n_trials)
print('Number of finished trials:', len(study.trials))
print("------------------------------------------------")
print('Best trial:', study.best_trial.params)
print("------------------------------------------------")
print(study.trials_dataframe())
print("------------------------------------------------")

参数

绘图

optuna.visualization.plot_optimization_history(study).show()

optimization_history

optuna.visualization.plot_parallel_coordinate(study).show()

parallel

optuna.visualization.plot_slice(study).show()

plot_slice

optuna.visualization.plot_contour(study, params=['alpha',
                            #'max_depth',
                            'lambda',
                            'subsample',
                            'learning_rate',
                            'subsample']).show()

contour

params=study.best_params
params

'''
{'lambda': 0.6503382439329751,
 'alpha': 0.0073271487020984865,
 'colsample_bytree': 1.0,
 'subsample': 0.6,
 'learning_rate': 0.012,
 'max_depth': 9,
 'random_state': 2020,
 'min_child_weight': 34}
'''

参考资料

[1] 8个可以提高数据科学工作效率、节省宝贵时间的Python库
[2] Optuna — 超参自动化调整利器 学习笔记
[3] Optuna Tutorial

参考资料

[1] 8个可以提高数据科学工作效率、节省宝贵时间的Python库
[2] Optuna机器学习模型调参(LightGBM、XGBoost)
[3] optuna官网

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

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

相关文章

大前端—回顾2022年明星项目,展望2023发展前沿

导读 | 2022年是艰难的一年,不仅有互联网的寒冬、还有新冠疫情的洗礼。但是似乎这一切都阻挡不了JavaScript的内卷,一年不长不短的时间中,JavaScript从创新、性能、功能等多维度深度进化,给前端带来了诸多惊喜。本文基于github上流…

(十三)并发集合——ConcurrentSkipListMap/Set

ConcurrentSkipListMapConcurrentSkipListMap与TreeMap对应,相当于线程安全的TreeMap,key有序,TreeMap基于红黑树,ConcurrentSkipListMap基于跳表。无锁链表的问题用跳表而不用红黑树是因为目前计算机领域还未找到一种高效的、作用…

LabVIEW测试和调试Web服务

LabVIEW测试和调试Web服务发布Web服务至终端前,需要测试HTTP方法VI是否按照预期与客户端进行通信。可直接从LabVIEW项目将Web服务置于调试服务器上,从而允许客户端发送请求至HTTP方法VI。调试服务器提供类似沙盒的环境。1. (Windows) 右键单击我的电脑下…

JVM- 第二章-类加载子系统

类加载子系统 2. 类加载子系统 2.1. 内存结构概述2.2. 类加载器与类的加载过程 加载阶段链接阶段初始化阶段 2.3. 类加载器分类 2.3.1. 虚拟机自带的加载器2.3.2. 用户自定义类加载器 2.4. ClassLoader的使用说明2.5. 双亲委派机制2.6. 其他 2. 类加载子系统 2.1. 内存结构…

nacos

文章目录1、认识和安装nacos(单机安装)1.1、下载安装包1.2、解压1.3、端口配置1.4、启动1.5、访问2、nacos快速入门2.1、在父工程中添加依赖2.2、注释掉服务中原有的eureka依赖2.3、添加nacos的客户端依赖2.4、修改配置文件2.5、启动并测试2.6、总结3、n…

19、Java并发 Java wait() 和 notify() 方法

大家有没有发现,其实 「 一文秒懂 」 系列讲述的都是多线程并发开发的问题。这个话题太大了,估计没有上百篇文章都解释不清楚。 本文,我们来讲解下 Java 并发中的基础的基础,核心的核心,Java 并发编程中的最基本的机制…

为什么 APISIX Ingress 是比 Ingress NGINX 更好的选择?

作者容鑫,API7.ai 云原生技术工程师,Apache APISIX Committer。 本文将会对比两个比较流行的 Ingress controller 实现,希望能对读者进行 Ingress controller 选型中有所帮助。 Ingress NGINX 是 Kubernetes 社区实现的 Ingress controller&a…

高通量代谢组学四路筛选法,揭秘“神药”二甲双胍延长寿命的机制

百趣代谢组学分享—研究背景 目前据统计中国糖尿病患者人数达9700万以上,数量达到世界第一。这其中2型糖尿病占到了90%以上。二甲双胍是目前治疗2型糖尿病的一线“明星”药物,因其较少出现低血糖和体重增加副作用而受到广大患者和医生的青睐。代谢组学文…

Replicate Brogaard Stock Volatility Decomposition

文章目录IntroductionData and SampleDownload DataClean DataExtract Estimation Unit and Set Global VariablesImplement Brogaard DecompositionEstimate VAR Coefficients, Matrix BBB, ϵt\epsilon_tϵt​, Σe\Sigma_eΣe​, and Σϵ\Sigma_\epsilonΣϵ​Estimate 15-…

常用的前端大屏 适配方案

方案实现方式优点缺点vm vh1.按照设计稿的尺寸,将px按比例计算转为vw和vh1.可以动态计算图表的宽高,字体等,灵活性较高 2.当屏幕比例跟 ui 稿不一致时,不会出现两边留白情况1.每个图表都需要单独做字体、间距、位移的适配&#xf…

【寒假每日一题】AcWing 4509. 归一化处理

目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 三、知识风暴 1、cmath头文件相关函数 2、cout大法 一、题目 1、原题链接 4509. 归一化处理 - AcWing题库 2、题目描述 在机器学习中,对数据进行归一化处理…

【C++】list用法简单模拟实现

文章目录1. list的介绍及使用1.1 list基本概念1.2 list的构造1.3 list的迭代器使用1.4 list 赋值和交换1.5 list 插入和删除1.6 list容量大小操作1.7 list 数据存取2. list的模拟实现这次要模拟实现的类及其成员函数接口总览2.1 结点类的实现2.2 迭代器的模拟实现2.3 反向迭代器…

yolov1 论文精读 - You Only Look Once- Unified, Real-Time Object Detection-统一的实时目标检测

Abstract 我们提出了一种新的目标检测方法- YOLO。以前的目标检测工作重复利用分类器来完成检测任务。相反,我们将目标检测框架看作回归问题,从空间上分割边界框和相关的类别概率。单个神经网络在一次评估中直接从整个图像上预测边界框和类别概率。由于…

PDF体积太大怎么缩小?这两种方法轻松解决

在我们日常处理的文件中,PDF文件的体积已经算是比较小的文件了,但是随着工作时间增加,我们用到的PDF文件也越来越多,而且有些PDF文件的内容非常丰富,文件体积变得更大,这就不利于我们将文件传输给别人&…

人脸检测算法模型MTCNN

MTCNN,Multi-task convolutional neural network(多任务卷积神经网络),将人脸区域检测与人脸关键点检测放在了一起。总体可分为P-Net、R-Net、和O-Net三层网络结构。P-Net是快速生成候选窗口,R-Net进行高精度候选窗口的过滤和选择,O-Net是生成最终边界框和人脸关键点。该…

使用JDK的 keytool 生成JKS,修改查看JKS信息

什么是keytool keytool 是个密钥和证书管理工具。它使用户能够管理自己的公钥/私钥对及相关证书,在JDK 1.4以后的版本中都包含了这一工具,所以不用再上网去找keytool的安装,电脑如果安装有JDK1.4及以上,就可以直接使用。 第一步&…

TOOM舆情分析网络舆情监控平台研究现状

随着网络舆情迅速发展,国内的舆情监测行业也日渐完善,舆情监控平台在企业发展过程中发挥重要作用,但同样也是有问题存在的,接下来TOOM舆情分析网络舆情监控平台研究现状? 一、网络舆情监控平台 网络舆情监控平台是一种能够对网…

maven概述以及简单入门

目录 1、Maven概述 1.1、Maven是什么 1.2 依赖管理 1.3 maven管理资源存放地址 1.4 Maven的作用 2.Maven基础概念 2.1仓库概念 2.坐标概念 1、Maven概述 1.1、Maven是什么 在Javaweb开发中,需要使用大量的jar包,我们手动去导入; 如何…

Mask RCNN网络源码解读(Ⅵ) --- 自定义数据集读取:MS COCOPascal VOC

目录 1.如何在Mask R-CNN中读取有关COCO数据集的内容(my_dataset_coco.py) 1.1 CocoDetection类 1.1.1 初始化方法__init__ 1.1.2 __getitem__方法 1.1.3 parse_targets 2.如何在Mask R-CNN中读取有关Pascal VOC数据集的内容(my_datas…

docker搭建 java web服务

安装 Docker 只需通过以下命令即可安装 Docker 软件: >> rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm >> yum -y install docker-io可使用以下命令,查看 Docker 是否安装成功: …