精华内容
下载资源
问答
  • 2022-06-10 15:43:59

    MySQL非缓存参数变量介绍

    #修改back_log参数值:由默认的50修改为500.(每个连接256kb,占用:125M)
    back_log=500

    解释:
    如果MySql的连接数据达到max_connections时,新来的请求被退回、记录即back_log,此时tcp连接就会排队,所以mysql也记录了它,简单理解等待连接的请求个数。
    连接的数量超过back_log,将不被授予连接资源。将会报:unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待连接进程时.
    back_log值不能超过TCP/IP连接的侦听队列的大小,若超过则无效。可以把它理解为处在tcp协议层的一个连接统计功能函数。
    查看当前系统的TCP/IP连接的侦听队列的大小命令:
    cat /proc/sys/net/ipv4/tcp_max_syn_backlog目前系统为1024。
    查看当前数量
    show variables like 'back_log'; 

    #修改wait_timeout参数值,由默认的8小时,修改为30分钟。
    wait_timeout=1800

    理解:
    MySQL客户端的数据库连接闲置最大时间值,一般设置为多数用户使用系统从开始到结束所用的时间为合适。
    说得比较通俗一点,就是当你的MySQL连接闲置超过一定时间后将会被强行关闭。MySQL默认的wait-timeout  值为8个小时。
    show variables like 'wait_timeout'查看结果值;。
    show processlist 如果经常发现MYSQL中有大量的进程长时间停留,则需要 修改wait-timeout值了。
    interactive_timeout:服务器关闭交互式连接前等待活动的秒数。这两个参数必须配合使用,当连接时间同时达到这两个参数则被关闭,否则单独设置wait_timeout无效

    #修改max_connections参数值,由默认的151。(它是四层比较靠下级的参数,重度影响性能)
    max_connections=3000

    解释:
    max_connections是指MySql的最大连接数,如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,当然这建立在机器能支撑的情况下,因为如果连接数越多,介于MySql会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。可以过'conn%'通配符查看当前状态的连接数量,以定夺该值的大小。
    MySQL服务器允许的最大连接数16384;
    查看系统当前最大连接数:
    show variables like 'max_connections';

    #修改max_user_connections值,由默认的0。(它是四层比较靠上级的参数,轻度影响性能)
    max_user_connections=800

    解释
    max_user_connections是指每个数据库最大连接的用户。
    针对某一个账号的所有客户端并行连接到MYSQL服务的最大并行连接数。简单说是指同一个账号能够同时连接到mysql服务的最大连接数。设置为0表示不限制。
    目前默认值为:0不受限制。
    这儿顺便介绍下Max_used_connections:它是指从这次mysql服务启动到现在,同一时刻并行连接数的最大值。它不是指当前的连接情况,而是一个比较值。如果在过去某一个时刻,MYSQL服务同时有1000个请求连接过来,而之后再也没有出现这么大的并发请求时,则Max_used_connections=1000.请注意与show variables 里的max_user_connections的区别。默认为0表示无限大。
    查看max_user_connections值
    show variables like 'max_user_connections';

    #修改thread_concurrency值,由目前默认的8,修改为64
    thread_concurrency=64

    解释:
    thread_concurrency的值的正确与否, 对mysql的性能影响很大, 在多个cpu(或多核)的情况下,错误设置了thread_concurrency的值, 会导致mysql不能充分利用多cpu(或多核), 出现同一时刻只能一个cpu(或核)在工作的情况。
    thread_concurrency应设为CPU核数的2倍. 
    查看命令:
    show variables like 'thread_concurrency';

    #添加skip-name-resolve,默认被注释掉,没有该参数,一般也不用,都是直接IP连接。
    skip-name-resolve

    skip-name-resolve:禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求!

    #skip-networking,默认被注释掉。没有该参数。
    解释:
    skip-networking建议被注释掉,不要开启
    开启该选项可以彻底关闭MySQL的TCP/IP连接方式,无法正常连接!

    MySQL缓存变量介绍

    #key_buffer_size,本系统目前为384M,可修改为400M
    key_buffer_size=400M

    解释:   key_buffer_size是用于索引块的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写),对MyISAM(MySQL表存储的一种类型,可以百度等查看详情)表性能影响最大的一个参数。如果你使它太大,系统将开始换页并且真的变慢了。严格说是它决定了数据库索引处理的速度,尤其是索引读的速度。对于内存在4GB左右的服务器该参数可设置为256M或384M.

    命令查得:show status like 'key_read%';
    +-------------------+-------+

    | Variable_name     | Value |

    +-------------------+-------+

    | Key_read_requests | 28535 |

    | Key_reads         | 269   |

    +-------------------+-------+
    可知道有28535个请求,有269个请求在内存中没有找到直接从硬盘读取索引.
    未命中缓存的概率为:0.94%=269/28535*100%.  一般未命中概率在0.1之下比较好。目前已远远大于0.1,证明效果不好。若命中率在0.01以下,则建议适当的修改key_buffer_size值。


    #innodb_buffer_pool_size(默认128M)
    innodb_buffer_pool_size=1024M(1G)

    解释:
    innodb_buffer_pool_size:主要针对InnoDB表性能影响最大的一个参数。功能与Key_buffer_size一样。
    另外InnoDB和 MyISAM 存储引擎不同, MyISAM 的 key_buffer_size 只能缓存索引键,而 innodb_buffer_pool_size 却可以缓存数据块和索引键。适当的增加这个参数的大小,可以有效的减少 InnoDB 类型的表的磁盘 I/O 。
    当我们操作一个 InnoDB 表的时候,返回的所有数据或者去数据过程中用到的任何一个索引块,都会在这个内存区域中走一遭。
    命令查得:show status like 'Innodb_buffer_pool_read%';

    比如查看当前系统中系统中

    | Innodb_buffer_pool_read_requests      | 1283826 |

    | Innodb_buffer_pool_reads              | 519     |

    +---------------------------------------+---------+
    其命中率99.959%=(1283826-519)/1283826*100%  命中率越高越好。

    #innodb_additional_mem_pool_size(默认8M)
    innodb_additional_mem_pool_size=20M

    解释:
    innodb_additional_mem_pool_size 设置了InnoDB存储引擎用来缓存数据结构,所以当我们一个MySQL数据类型非常多的时候,是需要适当调整该参数的大小以确保所有数据都能存放在内存中提高访问效率的。
    这个参数大小是否足够还是比较容易知道的,因为当过小的时候,MySQL会记录Warning信息到数据库的error log中,这时候你就知道该调整这个参数大小了。
    查看当前系统mysql的error日志  cat  /var/lib/mysql/机器名.error 发现有很多waring警告。所以要调大为20M.
    根据MySQL手册,对于2G内存的机器,推荐值是20M。
    32G内存的 100M

    #innodb_log_buffer_size(默认8M)
    innodb_log_buffer_size=20M

    解释:
    innodb_log_buffer_size  这是InnoDB存储引擎的事务日志所使用的缓冲区。类似于Binlog Buffer,InnoDB在写事务日志的时候,为了提高性能,也是先将信息写入Innofb Log Buffer中,当满足innodb_flush_log_trx_commit参数所设置的相应条件(或者日志缓冲区写满)之后,才会将日志写到文件 (或者同步到磁盘)中。可以通过innodb_log_buffer_size 参数设置其可以使用的最大内存空间。
    InnoDB 将日志写入日志磁盘文件前的缓冲大小。理想值为 1M 至 8M。大的日志缓冲允许事务运行时不需要将日志保存入磁盘而只到事务被提交(commit)。 因此,如果有大的事务处理,设置大的日志缓冲可以减少磁盘I/O。 在 my.cnf中以数字格式设置。
    默认是8MB,一般来说不建议超过32MB

    #innodb_flush_log_trx_commit
    参数对InnoDB Log的写入性能有非常关键的影响,默认值为1。该参数可以设置为0,1,2

    解释:
    0:log buffer中的数据将以每秒一次的频率写入到log file中,且同时会进行文件系统到磁盘的同步操作,但是每个事务的commit并不会触发任何log buffer 到log file的刷新或者文件系统到磁盘的刷新操作;
    1:在每次事务提交的时候将log buffer 中的数据都会写入到log file,同时也会触发文件系统到磁盘的同步;
    2:事务提交会触发log buffer到log file的刷新,但并不会触发磁盘文件系统到磁盘的同步。此外,每秒会有一次文件系统到磁盘同步操作。
    实际测试发现,该值对插入数据的速度影响非常大,设置为2时插入10000条记录只需要2秒,设置为0时只需要1秒,而设置为1时则需要229秒。因此,MySQL手册也建议尽量将插入操作合并成一个事务,这样可以大幅提高速度。根据MySQL手册,在存在丢失最近部分事务的危险的前提下,可以把该值设为0。

    #query_cache_size(默认32M)
    query_cache_size=40M

    解释:
    query_cache_size: 主要用来缓存MySQL中的ResultSet,也就是一条SQL语句执行的结果集,所以仅仅只能针对select语句。根据MySQL用户手册,使用查询缓冲最多可以达到238%的效率。
    当然,Query Cache也有一个致命的缺陷,那就是当某个表的数据有任何任何变化,都会导致所有引用了该表的select语句在Query Cache中的缓存数据失效。所以,当我们的数据变化非常频繁的情况下,使用Query Cache可能会得不偿失
    Query Cache的使用需要多个参数配合,其中最为关键的是query_cache_size和query_cache_type,前者设置用于缓存 ResultSet的内存大小,后者设置在何场景下使用Query Cache。在以往的经验来看,如果不是用来缓存基本不变的数据的MySQL数据库,query_cache_size一般256MB是一个比较合适的大小。当然,这可以通过计算Query Cache的命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))来进行调整。 query_cache_type可以设置为0(OFF),1(ON)或者2(DEMOND),分别表示完全不使用query cache,除显式要求不使用query cache(使用sql_no_cache)之外的所有的select都使用query cache,只有显示要求才使用query cache(使用sql_cache)。如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲. 如果Qcache_hits的值也非常大,则表明查询缓冲使用非常频繁,此时需要增加缓冲大小;
    根据命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))进行调整,一般不建议太大,256MB可能已经差不多了,大型的配置型静态数据可适当调大.
    可以通过命令:show status like 'Qcache_%';查看目前系统Query catch使用大小

    | Qcache_hits             | 1892463  |

    | Qcache_inserts          | 35627  

    命中率98.17%=1892463/(1892463 +35627 )*100

    更多相关内容
  • 在本文中,我们将深入研究超...这里简单介绍准备数据集的步骤,因为本文的主要内容是超参数优化,所以这部分只是简单介绍流程,一般情况下,流程如下: 我们所有训练、验证和测试集的形状是: 现在,我们将使用 Ker

    在本文中,我们将深入研究超参数优化。

    为了方便起见本文将使用 Tensorflow 中包含的 Fashion MNIST[1] 数据集。该数据集在训练集中包含 60,000 张灰度图像,在测试集中包含 10,000 张图像。每张图片代表属于 10 个类别之一的单品(“T 恤/上衣”、“裤子”、“套头衫”等)。因此这是一个多类分类问题。

    这里简单介绍准备数据集的步骤,因为本文的主要内容是超参数的优化,所以这部分只是简单介绍流程,一般情况下,流程如下:

    • 加载数据。
    • 分为训练集、验证集和测试集。
    • 将像素值从 0–255 标准化到 0–1 范围。
    • One-hot 编码目标变量。
    #load data
    (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
    
    # split into train, validation and test sets
    train_x, val_x, train_y, val_y = train_test_split(train_images, train_labels, stratify=train_labels, random_state=48, test_size=0.05)
    (test_x, test_y)=(test_images, test_labels)
    
    # normalize pixels to range 0-1
    train_x = train_x / 255.0
    val_x = val_x / 255.0
    test_x = test_x / 255.0
    
    #one-hot encode target variable
    train_y = to_categorical(train_y)
    val_y = to_categorical(val_y)
    test_y = to_categorical(test_y)
    

    我们所有训练、验证和测试集的形状是:

    print(train_x.shape)  #(57000, 28, 28)
    print(train_y.shape)  #(57000, 10)
    print(val_x.shape)    #(3000, 28, 28)
    print(val_y.shape)    #(3000, 10)
    print(test_x.shape)   #(10000, 28, 28)
    print(test_y.shape)   #(10000, 10)
    

    现在,我们将使用 Keras Tuner 库 [2]:它将帮助我们轻松调整神经网络的超参数:

    pip install keras-tuner
    

    Keras Tuner 需要 Python 3.6+ 和 TensorFlow 2.0+

    超参数调整是机器学习项目的基础部分。有两种类型的超参数:

    • 结构超参数:定义模型的整体架构(例如隐藏单元的数量、层数)
    • 优化器超参数:影响训练速度和质量的参数(例如学习率和优化器类型、批量大小、轮次数等)

    为什么需要超参数调优库?我们不能尝试所有可能的组合,看看验证集上什么是最好的吗?

    这肯定是不行的因为深度神经网络需要大量时间来训练,甚至几天。如果在云服务器上训练大型模型,那么每个实验实验都需要花很多的钱。

    因此,需要一种限制超参数搜索空间的剪枝策略。

    keras-tuner提供了贝叶斯优化器。它搜索每个可能的组合,而是随机选择前几个。然后根据这些超参数的性能,选择下一个可能的最佳值。因此每个超参数的选择都取决于之前的尝试。根据历史记录选择下一组超参数并评估性能,直到找到最佳组合或到达最大试验次数。我们可以使用参数“max_trials”来配置它。

    除了贝叶斯优化器之外,keras-tuner还提供了另外两个常见的方法:RandomSearch 和 Hyperband。我们将在本文末尾讨论它们。

    接下来就是对我们的网络应用超参数调整。我们尝试两种网络架构,标准多层感知器(MLP)和卷积神经网络(CNN)。

    首先让我们看看基线 MLP 模型是什么:

    model_mlp = Sequential()
    model_mlp.add(Flatten(input_shape=(28, 28)))
    model_mlp.add(Dense(350, activation='relu'))
    model_mlp.add(Dense(10, activation='softmax'))
    print(model_mlp.summary())
    model_mlp.compile(optimizer="adam",loss='categorical_crossentropy')
    

    调优过程需要两种主要方法:

    hp.Int():设置超参数的范围,其值为整数 - 例如,密集层中隐藏单元的数量:

    model.add(Dense(units = hp.Int('dense-bot', min_value=50, max_value=350, step=50))
    

    hp.Choice():为超参数提供一组值——例如,Adam 或 SGD 作为最佳优化器?

    hp_optimizer=hp.Choice('Optimizer', values=['Adam', 'SGD'])
    

    在我们的 MLP 示例中,我们测试了以下超参数:

    • 隐藏层数:1-3
    • 第一密集层大小:50–350
    • 第二和第三密集层大小:50–350
    • Dropout:0、0.1、0.2
    • 优化器:SGD(nesterov=True,momentum=0.9) 或 Adam
    • 学习率:0.1、0.01、0.001

    代码如下:

    model = Sequential()
    
    model.add(Dense(units = hp.Int('dense-bot', min_value=50, max_value=350, step=50), input_shape=(784,), activation='relu'))
    
    for i in range(hp.Int('num_dense_layers', 1, 2)):
      model.add(Dense(units=hp.Int('dense_' + str(i), min_value=50, max_value=100, step=25), activation='relu'))
      model.add(Dropout(hp.Choice('dropout_'+ str(i), values=[0.0, 0.1, 0.2])))
    
    model.add(Dense(10,activation="softmax"))
    
    hp_optimizer=hp.Choice('Optimizer', values=['Adam', 'SGD'])
    
    if hp_optimizer == 'Adam':
        hp_learning_rate = hp.Choice('learning_rate', values=[1e-1, 1e-2, 1e-3])
    elif hp_optimizer == 'SGD':
        hp_learning_rate = hp.Choice('learning_rate', values=[1e-1, 1e-2, 1e-3])
        nesterov=True
        momentum=0.9
    

    这里需要注意第 5 行的 for 循环:让模型决定网络的深度!

    最后,就是运行了。请注意我们之前提到的 max_trials 参数。

    model.compile(optimizer = hp_optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
    
    tuner_mlp = kt.tuners.BayesianOptimization(
        model,
        seed=random_seed,
        objective='val_loss',
        max_trials=30,
        directory='.',
        project_name='tuning-mlp')
    tuner_mlp.search(train_x, train_y, epochs=50, batch_size=32, validation_data=(dev_x, dev_y), callbacks=callback)
    

    我们得到结果

    这个过程用尽了迭代次数,大约需要 1 小时才能完成。我们还可以使用以下命令打印模型的最佳超参数:

    best_mlp_hyperparameters = tuner_mlp.get_best_hyperparameters(1)[0]
    print("Best Hyper-parameters")
    best_mlp_hyperparameters.values
    

    现在我们可以使用最优超参数重新训练我们的模型:

    model_mlp = Sequential()
    
    model_mlp.add(Dense(best_mlp_hyperparameters['dense-bot'], input_shape=(784,), activation='relu'))
    
    for i in range(best_mlp_hyperparameters['num_dense_layers']):
      model_mlp.add(Dense(units=best_mlp_hyperparameters['dense_' +str(i)], activation='relu'))
      model_mlp.add(Dropout(rate=best_mlp_hyperparameters['dropout_' +str(i)]))
      
    model_mlp.add(Dense(10,activation="softmax"))
    
    model_mlp.compile(optimizer=best_mlp_hyperparameters['Optimizer'], loss='categorical_crossentropy',metrics=['accuracy'])
    history_mlp= model_mlp.fit(train_x, train_y, epochs=100, batch_size=32, validation_data=(dev_x, dev_y), callbacks=callback)
    

    或者,我们可以用这些参数重新训练我们的模型:

    model_mlp=tuner_mlp.hypermodel.build(best_mlp_hyperparameters)
    
    history_mlp=model_mlp.fit(train_x, train_y, epochs=100, batch_size=32, 
                               validation_data=(dev_x, dev_y), callbacks=callback)
    

    然后测试准确率

    mlp_test_loss, mlp_test_acc = model_mlp.evaluate(test_x,  test_y, verbose=2)
    print('\nTest accuracy:', mlp_test_acc)
    
    # Test accuracy: 0.8823
    

    与基线的模型测试精度相比:

    基线 MLP 模型:86.6 %最佳 MLP 模型:88.2 %。测试准确度的差异约为 3%!

    下面我们使用相同的流程,将MLP改为CNN,这样可以测试更多参数。

    首先,这是我们的基线模型:

    model_cnn = Sequential()
    model_cnn.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
    model_cnn.add(MaxPooling2D((2, 2)))
    model_cnn.add(Flatten())
    model_cnn.add(Dense(100, activation='relu'))
    model_cnn.add(Dense(10, activation='softmax'))
    model_cnn.compile(optimizer="adam", loss='categorical_crossentropy', metrics=['accuracy'])
    

    基线模型 包含卷积和池化层。对于调优,我们将测试以下内容:

    1. 卷积、MaxPooling 和 Dropout 层的“块”数
    2. 每个块中 Conv 层的过滤器大小:32、64
    3. 转换层上的有效或相同填充
    4. 最后一个额外层的隐藏层大小:25-150,乘以 25
    5. 优化器:SGD(nesterov=True,动量=0.9)或 Adam
    6. 学习率:0.01、0.001
    model = Sequential()
    
    model = Sequential()
    model.add(Input(shape=(28, 28, 1)))
    
    for i in range(hp.Int('num_blocks', 1, 2)):
        hp_padding=hp.Choice('padding_'+ str(i), values=['valid', 'same'])
        hp_filters=hp.Choice('filters_'+ str(i), values=[32, 64])
    
        model.add(Conv2D(hp_filters, (3, 3), padding=hp_padding, activation='relu', kernel_initializer='he_uniform', input_shape=(28, 28, 1)))
        model.add(MaxPooling2D((2, 2)))
        model.add(Dropout(hp.Choice('dropout_'+ str(i), values=[0.0, 0.1, 0.2])))
    
    model.add(Flatten())
    
    hp_units = hp.Int('units', min_value=25, max_value=150, step=25)
    model.add(Dense(hp_units, activation='relu', kernel_initializer='he_uniform'))
    
    model.add(Dense(10,activation="softmax"))
    
    hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3])
    hp_optimizer=hp.Choice('Optimizer', values=['Adam', 'SGD'])
    
    if hp_optimizer == 'Adam':
        hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3])
    elif hp_optimizer == 'SGD':
        hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3])
        nesterov=True
        momentum=0.9
    

    像以前一样,我们让网络决定它的深度。最大迭代次数设置为 100:

    model.compile( optimizer=hp_optimizer,loss='categorical_crossentropy', metrics=['accuracy'])
    
    tuner_cnn = kt.tuners.BayesianOptimization(
        model,
        objective='val_loss',
        max_trials=100,
        directory='.',
        project_name='tuning-cnn')
    

    结果如下:

    在这里插入图片描述

    得到的超参数

    在这里插入图片描述

    最后使用最佳超参数训练我们的 CNN 模型:

    model_cnn = Sequential()
    
    model_cnn.add(Input(shape=(28, 28, 1)))
    
    for i in range(best_cnn_hyperparameters['num_blocks']):
      hp_padding=best_cnn_hyperparameters['padding_'+ str(i)]
      hp_filters=best_cnn_hyperparameters['filters_'+ str(i)]
    
      model_cnn.add(Conv2D(hp_filters, (3, 3), padding=hp_padding, activation='relu', kernel_initializer='he_uniform', input_shape=(28, 28, 1)))
      model_cnn.add(MaxPooling2D((2, 2)))
      model_cnn.add(Dropout(best_cnn_hyperparameters['dropout_'+ str(i)]))
    
    model_cnn.add(Flatten())
    model_cnn.add(Dense(best_cnn_hyperparameters['units'], activation='relu', kernel_initializer='he_uniform'))
    
    model_cnn.add(Dense(10,activation="softmax"))
    
    model_cnn.compile(optimizer=best_cnn_hyperparameters['Optimizer'], 
                                                     loss='categorical_crossentropy', 
                                                     metrics=['accuracy'])
    print(model_cnn.summary())
    
    history_cnn= model_cnn.fit(train_x, train_y, epochs=50, batch_size=32, validation_data=(dev_x, dev_y), callbacks=callback)
    

    检查测试集的准确率:

    cnn_test_loss, cnn_test_acc = model_cnn.evaluate(test_x,  test_y, verbose=2)
    print('\nTest accuracy:', cnn_test_acc)
    
    # Test accuracy: 0.92
    

    与基线的 CNN 模型测试精度相比:

    1. 基线 CNN 模型:90.8 %
    2. 最佳 CNN 模型:92%

    我们看到优化模型的性能提升!

    除了准确性之外,我们还可以看到优化的效果很好,因为:

    在每种情况下都选择了一个非零的 Dropout 值,即使我们也提供了零 Dropout。这是意料之中的,因为 Dropout 是一种减少过拟合的机制。有趣的是,最好的 CNN 架构是标准CNN,其中过滤器的数量在每一层中逐渐增加。这是意料之中的,因为随着后续层的增加,模式变得更加复杂(这也是我们在学习各种模型和论文时被证明的结果)需要更多的过滤器才能捕获这些模式组合。

    以上例子也说明Keras Tuner 是使用 Tensorflow 优化深度神经网络的很好用的工具。

    我们上面也说了本文选择是贝叶斯优化器。但是还有两个其他的选项:

    RandomSearch:随机选择其中的一些来避免探索超参数的整个搜索空间。但是,它不能保证会找到最佳超参数

    Hyperband:选择一些超参数的随机组合,并仅使用它们来训练模型几个 epoch。然后使用这些超参数来训练模型,直到用尽所有 epoch 并从中选择最好的。

    最后数据集地址和keras_tuner的文档如下

    https://avoid.overfit.cn/post/c3f904fab4f84914b8a1935f8670582f

    作者:Nikos Kafritsas

    展开全文
  • 深度学习训练算法通常没有这两种奢侈的性质。深度学习模型的训练算法通常是迭代的,因此要求使用者指定一些开始迭代的初始点。此外,训练深度模型是一个足够困难的问题,以至于大多数算法都很大程度地受到初始化选择...

    有些优化算法本质上是非迭代的,只是求解一个解点。有些其他优化算法本质上是迭代的,但是应用于这一类的优化问题时,能在可接受的时间内收敛到可接受的解,并且与初始值无关。深度学习训练算法通常没有这两种奢侈的性质。深度学习模型的训练算法通常是迭代的,因此要求使用者指定一些开始迭代的初始点。此外,训练深度模型是一个足够困难的问题,以至于大多数算法都很大程度地受到初始化选择的影响。初始点能够决定算法是否收敛,有些初始点十分不稳定,使得该算法会遭遇数值困难,并完全失败。当学习收敛时,初始点可以决定学习收敛得多块,以及是否收敛到一个代价高或低的点。此外,差不多代价的点可以具有区别极大的泛化误差,初始点也可以影响泛化。

    现代的初始化策略是简单的、启发式的。设定改进的初始化策略是一项困难的任务,因为神经网络优化至今还未被很好地理解。大多数初始化策略基于在神经网络初始化时实现一些很好的性质。然而,我们并没有很好地理解这些性质中的哪些会在学习开始进行后的哪些情况下得以保持。进一步的难点是,有些初始点从优化的观点看或许是有利的,但是从泛化的观点看是不利的。我们对于初始点如何影响泛化的理解是相当原始的,几乎没有提供如何选择初始点的任何指导。

    也许完全确知的唯一特性是初始参数需要在不同单元间“破坏对称性”。如果具有相同激活函数的两个隐藏单元连接到相同的输入,那么这些单元必须具有不同的初始参数。如果它们具有相同的初始参数,然后应用到确定性损失和模型的确定性学习算法将一直以相同的方式更新这两个单元。即使模型或训练算法能够使用随机性为不同的单元计算不同的更新(例如使用Dropout的训练),通常来说,最好还是初始化每个单元使其和其他单元计算不同的函数。这或许有助于确保没有输入模式丢失在前向传播的零空间中,没有梯度模式丢失在反向传播的零空间中。每个单元计算不同函数的目标促使了参数的随机初始化。我们可以明确地搜索一大组彼此互不相同的基函数,但这经常会导致明显的计算代价。例如,如果我们有和输出一样多的输入,可以使用Gram-Schmidt正交化于初始的权重矩阵,保证每个单元计算彼此非常不同的函数。在高维空间上使用高熵分布来随机初始化,计算代价小并且不太可能分配单元计算彼此相同的函数。

    通常情况下,我们可以为每个单元的偏置设置启发式挑选的常数,仅随机初始化权重。额外的参数(例如用于编码预测条件方差的参数)通常和偏差一样设置为启发式选择的常数。我们几乎总是初始化模型的权重为高斯或均匀分布中随机抽取的值。高斯或均匀分布的选择似乎不会有很大的差别,但也没有被详尽地研究。然而,初始分布的大小确实对优化过程的结果和网络泛化能力都有很大的影响。更大的初始权重具有更强的破坏对称性的作用,有助于避免冗余的单元。它们也有助于避免在每层线性成分的前向或反向传播中丢失信号——矩阵中更大的值在矩阵乘法中有更大的输出。如果初始权重太大,那么会在前向传播或反向传播中产生爆炸的值。在循环网络中,很大的权重也可能导致混沌(对于输入中很小的扰动非常敏感,导致确定性前向传播过程表现随机)。在一定程度上,梯度爆炸问题可以通过梯度截断来缓解(执行梯度下降步骤之前设置梯度的阈值)。较大的权重也会产生使得激活函数饱和的值,导致饱和单元的梯度完全丢失。这些竞争因素决定了权重的理想初始大小。

    关于如何初始化网络,正则化和优化有着非常不同的观点。优化观点建议权重应该足够大以成功传播信息,但是正则化希望其小一点。诸如随机梯度下降这类对权重较小的增量更新,趋于停止在更靠近初始参数的区域(不管是由于卡在低梯度的区域,还是由于触发了基于过拟合的提前终止准则)的优化算法倾向于最终参数应接近于初始参数。在某些模型上,提前终止的梯度下降等价于权重衰减。在一般情况下,提前终止的梯度下降和权重衰减不同,但是提供了一个宽松的类比去考虑初始化的影响。我们可以将初始化参数 θ \theta θ θ 0 \theta_0 θ0类比于强置均值为 θ 0 \theta_0 θ0的高斯先验 p ( θ ) p(\theta) p(θ)。从这个角度来看,选择 θ 0 \theta_0 θ0接近0是有道理的。这个先验表明,单元间彼此互不交互比交互更有可能。只有在目标函数的似然项表达出对交互很强的偏好时,单元才会交互。此外,如果我们初始化 θ 0 \theta_0 θ0为很大的值,那么我们的先验指定了哪些单元应互相交互,以及它们应如何交互。

    有些启发式方法可用于选择权重的初始大小。一种初始化 m m m个输入和 n n n输出的全连接层的权重的启发式方法是从分布 W i , j ∼ U ( − 1 m , 1 m ) W_{i, j}\sim U(-\frac{1}{\sqrt{m}}, \frac{1}{\sqrt{m}}) Wi,jU(m 1,m 1)中采样权重,而Glorot andBengio建议使用标准初始化(Normalized Initialization):
    W i , j ∼ U ( − 6 m + n , 6 m + n ) W_{i, j}\sim U(-\frac{6}{\sqrt{m+n}}, \frac{6}{\sqrt{m+n}}) Wi,jU(m+n 6,m+n 6)

    后一种启发式方法初始化所有的层,折衷于使其具有相同激活方差和使其具有相同梯度方差之间。这假设网络是不含非线性的链式矩阵乘法,据此推导得出。现实的神经网络显然会违反这个假设,但很多设计于线性模型的策略在其非线性对应中的效果也不错。

    Saxe等人推荐初始化为随机正交矩阵,仔细挑选负责每一层非线性缩放或增益因子 g g g。他们得到了用于不同类型的非线性激活函数的特定缩放因子。这种初始化方案也是启发于不含非线性的矩阵相乘序列的深度网络。在该模型下,这个初始化方案保证了达到收敛所需的训练迭代总数独立于深度。

    增加缩放因子 g g g将网络推向网络前向传播时激活范数增加,反向传播时梯度范数增加的区域。Sussillo表明,正确设置缩放因子足以训练深达1000层的网络,而不需要使用正交初始化。这种方法的一个重要观点是,在前馈网络中,激活和梯度会在每一步前向传播或反向传播中增加或缩小,遵循随机游走行为。这是因为前馈网络在每一层使用了不同的权重矩阵。如果该随机游走调整到保持范数,那么前馈网络能够很大程度地避免相同权重矩阵用于每层的梯度消失与爆炸问题。

    可惜,这些初始权重的最佳准则往往不会带来最佳效果。这可能有三种不同的原因。首先,我们可能使用了错误的标准——它实际上并不利于保持整个网络信号的范数。其次,初始化时强加的性质可能在学习开始进行后不能保持。最后,该标准可能成功提高了优化速度,但意外地增大了泛化误差。在实践中,我们通常需要将权重范围视为超参数,其最优值大致接近,但并不完全等于理论预测。

    数值范围准则的一个缺点是,设置所有的初始权重具有相同的标准差,例如 1 m \frac{1}{\sqrt{m}} m 1,会使得层很大时每个单一权重会变得极其小。Martens提出了一种被称为稀疏初始化(Sparse Initialization)的替代方案,每个单元初始化为恰好有 k k k个非零权重。这个想法保持该单元输入的总数量独立于输入数目 m m m,而不使单一权重元素的大小随 m m m缩小。稀疏初始化有助于实现单元之间在初始化时更具多样性。但是,获得较大取值的权重也同时被加了很强的先验。因为梯度下降需要很长时间缩小“不正确”的大值,这个初始化方案可能会导致某些单元出问题,例如Maxout单元有几个过滤器,互相之间必须仔细调整。

    如果计算资源允许,将每层权重的初始数值范围设为超参数通常是个好主意,如随机搜索,挑选这些数值范围。是否选择使用密集或稀疏初始化也可以设为一个超参数。作为替代,我们可以手动搜索最优初始范围。一个好的挑选初始数值范围的经验法则是观测单个小批量数据上的激活或梯度的幅度或标准差。如果权重太小,那么当激活值在小批量上前向传播于网络时,激活值的幅度会缩小。通过重复识别具有小得不可接受的激活值的第一层,并提高其权重,最终有可能得到一个初始激活全部合理的网络。如果学习在这点上仍然很慢,观测梯度的幅度或标准差可能也会有所帮助。这个过程原则上是自动的,且通常计算量低于基于验证集误差的超参数优化,因为它是基于初始模型在单批数据上的行为反馈,而不是在验证集上训练模型的反馈。由于这个协议很长时间都被启发式使用,最近Mishkin and Matas更正式地研究了该协议。

    目前为止,我们关注在权重的初始化上。幸运的是,其他参数的初始化通常更容易。设置偏置的方法必须和设置权重的方法协调。设置偏置为零通常在大多数权重初始化方案中是可行的。存在一些我们可能设置偏置为非零值的情况:

    • 如果偏置是作为输出单元,那么初始化偏置以获取正确的输出边缘统计通常是有利的。要做到这一点,我们假设初始权重足够小,该单元的输出仅由偏置决定。这说明设置偏置为应用于训练集上输出边缘统计的激活函数的逆。例如,如果输出是类上的分布,且该分布是高度偏态分布,第 i i i类的边缘概率由某个向量 c c c的第 i i i个元素给定,那么我们可以通过求解方程 softmax ( b ) = c \text{softmax}(b)=c softmax(b)=c来设置偏置向量 b b b。这不仅适用于分类器,也适用于其它的模型,例如自编码器和玻尔兹曼机。这些模型拥有输出类似于输入数据x的网络层,非常有助于初始化这些层的偏置以匹配 x x x上的边缘分布。
    • 有时,我们可能想要选择偏置以避免初始化引起太大饱和。例如,我们可能会将ReLU的隐藏单元设为0.1而非0,以避免ReLU在初始化时饱和。尽管这种方法违背不希望偏置具有很强输入的权重初始化准则。例如,不建议使用随机游走初始化。
    • 有时,一个单元会控制其他单元能否参与到等式中。在这种情况下,我们有一个单元输出 u u u,另一个单元 h ∈ [ 0 , 1 ] h\in[0,1] h[0,1],那么我们可以将 h h h视作门,以决定 u h ≈ 1 uh\approx1 uh1还是 u h ≈ 0 uh≈0 uh0。在这种情形下,我们希望设置偏置 h h h,使得在初始化的大多数情况下 h ≈ 1 h\approx 1 h1。否则, u u u没有机会学习。例如,Jozefowicz等人提议设置LSTM模型遗忘门的偏置为1。

    另一种常见类型的参数是方差或精确度参数。例如,我们用以下模型进行带条件方差估计的线性回归:
    p ( y ∣ x ) = N ( y ∣ x T x + b , 1 β ) p(y|x)=N(y|x^Tx+b, \frac{1}{\beta}) p(yx)=N(yxTx+b,β1)

    其中 β \beta β是精确度参数。通常我们能安全地初始化方差或精确度参数为1。另一种方法假设初始权重足够接近零,设置偏置可以忽略权重的影响,然后设定偏置以产生输出的正确边缘均值,并将方差参数设置为训练集输出的边缘方差。

    除了这些初始化模型参数的简单常数或随机方法,还有可能使用机器学习初始化模型参数。我们还可以用无监督模型训练出来的参数来初始化监督模型。我们也可以在相关问题上使用监督训练。即使是在一个不相关的任务上运行监督训练,有时也能得到一个比随机初始化具有更快收敛率的初始值。这些初始化策略有些能够得到更快的收敛率和更好的泛化误差,因为它们编码了模型初始参数的分布信息。其他策略显然效果不错的原因主要在于它们设置参数为正确的数值范围,或是设置不同单元计算互相不同的函数。

    展开全文
  • 贝叶斯优化: 一更好的超参数调优方式

    万次阅读 多人点赞 2018-10-08 13:24:03
    本文受 浅析 Hinton 最近提出的 Capsule 计划 启发,希望以更通俗的方式推广机器学习算法,让数学基础和编程能力的人能够乐享其中。 目前人工智能和深度学习越趋普及,大家可以使用开源的Scikit-learn、...

    简介

    本文受 浅析 Hinton 最近提出的 Capsule 计划 启发,希望以更通俗的方式推广机器学习算法,让有数学基础和编程能力的人能够乐享其中。

    目前人工智能和深度学习越趋普及,大家可以使用开源的Scikit-learn、TensorFlow来实现机器学习模型,甚至参加Kaggle这样的建模比赛。那么要想模型效果好,手动调参少不了,机器学习算法如SVM就有gamma、kernel、ceof等超参数要调,而神经网络模型有learning_rate、optimizer、L1/L2 normalization等更多超参数可以调优。

    很多paper使用一个新的模型可以取得state of the art的效果,然后提供一组超参数组合方便读者复现效果,实际上这些超参数都是“精挑细选”得到的,背后有太多效果不好的超参数尝试过程被忽略,大家也不知道对方的超参数是如何tune出来的。因此,了解和掌握更好的超参数调优方法在科研和工程上是很有价值的,本文将介绍一种更好的超参数调优方式,也就是贝叶斯优化(Bayesian Optimization),以及开源调参服务Advisor的使用介绍。

    超参数介绍

    首先,什么是超参数(Hyper-parameter)?这是相对于模型的参数而言(Parameter),我们知道机器学习其实就是机器通过某种算法学习数据的计算过程,通过学习得到的模型本质上是一些列数字,如树模型每个节点上判断属于左右子树的一个数,或者逻辑回归模型里的一维数组,这些都称为模型的参数。

    那么定义模型属性或者定义训练过程的参数,我们称为超参数,例如我们定义一个神经网络模型有9527层网络并且都用RELU作为激活函数,这个9527层和RELU激活函数就是一组超参数,又例如我们定义这个模型使用RMSProp优化算法和learning rate为0.01,那么这两个控制训练过程的属性也是超参数。

    显然,超参数的选择对模型最终的效果有极大的影响。如复杂的模型可能有更好的表达能力来处理不同类别的数据,但也可能因为层数太多导致梯度消失无法训练,又如learning rate过大可能导致收敛效果差,过小又可能收敛速度过慢。

    那么如何选择合适的超参数呢,不同模型会有不同的最优超参数组合,找到这组最优超参数大家会根据经验、或者随机的方法来尝试,这也是为什么现在的深度学习工程师也被戏称为“调参工程师”。根据No Free Lunch原理,不存在一组完美的超参数适合所有模型,那么调参看起来是一个工程问题,有可能用数学或者机器学习模型来解决模型本身超参数的选择问题吗?答案显然是有的,而且通过一些数学证明,我们使用算法“很有可能”取得比常用方法更好的效果,为什么是“很有可能”,因为这里没有绝对只有概率分布,也就是后面会介绍到的贝叶斯优化。

    自动调参算法

    说到自动调参算法,大家可能已经知道了Grid search(网格搜索)、Random search(随机搜索),还有Genetic algorithm(遗传算法)、Paticle Swarm Optimization(粒子群优化)、Bayesian Optimization(贝叶斯优化)、TPE、SMAC等。

    这里补充一个背景,机器学习模型超参数调优一般认为是一个黑盒优化问题,所谓黑盒问题就是我们在调优的过程中只看到模型的输入和输出,不能获取模型训练过程的梯度信息,也不能假设模型超参数和最终指标符合凸优化条件,否则的话我们通过求导或者凸优化方法就可以求导最优解,不需要使用这些黑盒优化算法,而实际上大部分的模型超参数也符合这个场景。其次是模型的训练过程是相对expensive的,不能通过快速计算获取大量样本,我们知道DeepMind用增强学习模型DQN来打Atari游戏,实际上每一个action操作后都能迅速取得当前的score,这样收集到大量样本才可以训练复杂的神经网络模型,虽说我们也可以用增强学习来训练超参数调优的模型,但实际上一组超参数要训练一个模型需要几分钟、几小时、几天甚至几个月的时间,无法快速获取这么多样本数据,因此需要有更“准确和高效”的方法来调优超参数。

    像遗传算法和PSO这些经典黑盒优化算法,我归类为群体优化算法,也不是特别适合模型超参数调优场景,因为需要有足够多的初始样本点,并且优化效率不是特别高,本文也不再详细叙述。

    目前业界用得比较多的分别是Grid search、Random search和Bayesian Optimization。网格搜索很容易理解和实现,例如我们的超参数A有2种选择,超参数B有3种选择,超参数C有5种选择,那么我们所有的超参数组合就有2 * 3 * 5也就是30种,我们需要遍历这30种组合并且找到其中最优的方案,对于连续值我们还需要等间距采样。实际上这30种组合不一定取得全局最优解,而且计算量很大很容易组合爆炸,并不是一种高效的参数调优方法。

    业界公认的Random search效果会比Grid search好,Random search其实就是随机搜索,例如前面的场景A有2种选择、B有3种、C有5种、连续值随机采样,那么每次分别在A、B、C中随机取值组合成新的超参数组合来训练。虽然有随机因素,但随机搜索可能出现效果特别差、也可能出现效果特别好,在尝试次数和Grid search相同的情况下一般最值会更大,当然variance也更大但这不影响最终结果。在实现Random search时可以优化,过滤随机可能出现过的超参数组合,不需要重复计算。

    实际上Grid search和Random search都是非常普通和效果一般的方法,在计算资源有限的情况下不一定比建模工程师的个人经验要好,接下来介绍的Bayesian Optimization就是“很可能”比普通开发者或者建模工程师调参能力更好的算法。首先贝叶斯优化当然用到了贝叶斯公式,这里不作详细证明了,它要求已经存在几个样本点(同样存在冷启动问题,后面介绍解决方案),并且通过高斯过程回归(假设超参数间符合联合高斯分布)计算前面n个点的后验概率分布,得到每一个超参数在每一个取值点的期望均值和方差,其中均值代表这个点最终的期望效果,均值越大表示模型最终指标越大,方差表示这个点的效果不确定性,方差越大表示这个点不确定是否可能取得最大值非常值得去探索。因此实现贝叶斯优化第一步就是实现高斯过程回归算法,并且这里可以通过类似SVM的kernel trick来优化计算,在后面的开源项目Advisor介绍中我们就使用Scikit-learn提供的GaussianProgressRegressor,最终效果如下图,在只有3个初始样本的情况下我们(通过100000个点的采样)计算出每个点的均值和方差。

    从曲线可以看出,中间的点均值较大,而且方差也比较大,很有可能这个点的超参数可以训练得到一个效果指标好的模型。那为什么要选均值大和方差大的点呢?因为前面提到均值代表期望的最终结果,当然是越大越好,但我们不能每次都挑选均值最大的,因为有的点方差很大也有可能存在全局最优解,因此选择均值大的点我们成为exploritation(开发),选择方差大的点我们称为exploration(探索)。那么究竟什么时候开发什么时候探索,并且开发和探索各占多少比例呢?不同的场景其实是可以有不同的策略的,例如我们的模型训练非常慢,只能再跑1组超参数了,那应该选择均值较大的比较有把握,如果我们计算力还能可以跑1000次,那么就不能放弃探索的机会应该选择方差大的,而至于均值和方差比例如何把握,这就是我们要定义的acquisition function了。acquisition function是一个权衡exploritation和exploration的函数,最简单的acquisition function就是均值加上n倍方差(Upper condence bound算法),这个n可以是整数、小数或者是正数、负数,更复杂的acquisition function还有Expected improvement、Entropy search等等。在原来的图上加上acquisition function曲线,然后我们求得acquisition function的最大值,这是的参数值就是贝叶斯优化算法推荐的超参数值,是根据超参数间的联合概率分布求出来、并且均衡了开发和探索后得到的结果。

    因此如果我们使用贝叶斯优化,那么我们下一个点就取中间偏左的点,使用这个点代表的超参数来训练模型,并且得到这个模型在这住超参数组合下的效果指标。有了新的指标,贝叶斯优化模型的样本就从3个变成了4个,这样可以重新计算超参数之间的后验概率分布和acquisition function,效果如下图。

    从均值和方差曲线看出,目前右边的点均值不低,并且方差是比较大,直观上我们认为探索右边区域的超参数是“很可能”有价值的。从acquisition function曲线我们也可以看出,右边的点在考虑了开发和探索的情况下有更高的值,因此我们下一个超参数推荐就是右边星号的点。然后我们使用推荐的超参数继续训练,得到新的模型效果指标,加入到高斯过程回归模型里面,得到新的均值-方差曲线和acquisition function曲线。

    通过不断重复上述的步骤,我们的曲线在样本极少的情况下也可以毕竟最终真实的曲线。当然上面的图是在一个黑盒优化问题上模拟的,因此我们知道真实的曲线形状,现实的机器学习模型的超参数间不一定能画出完整的曲线,但通过符合联合高斯概率分布的假设,还有高斯过程回归、贝叶斯方程等数学证明,我们可以从概率上找到一个“很可能”更好的超参数,这是比Grid search或者Random search更有价值的方法。

    注意,前面提到的Bayesian Optimization等超参数优化算法也是有超参数的,或者称为超超参数,如acquisition function的选择就是可能影响超参数调优模型的效果,但一般而言这些算法的超超参数极少甚至无须调参,大家选择业界公认效果比较好的方案即可。

    Google Vizier

    前面已经介绍了Grid search、Random search和Bayesian Optimization等算法,但并不没有完,因为我们要使用这些自动调参算法不可能都重新实现一遍,我们应该关注于自身的机器学习模型实现而直接使用开源或者易用的调参服务。

    近期Google就开放了内部调参系统Google Vizier的论文介绍,感兴趣可以在这里阅读paper https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/46180.pdf

    与开源的hyperopt、optunity不同,Vizier是一个service而不是一个library,也就是算法开发者不需要自己部署调参服务或者管理参数存储,只需要选择合适的调参算法,如贝叶斯优化,然后Vizier就会根据模型的一些历史指标推荐最优的超参数组合给开发者,直接使用这些超参数会比自己瞎猜或者遍历参数组合得到的效果更好。当然开发者可以使用Vizier提供的Algorithm Playground功能实现自己的自动调参算法,还有内置一些EarlyStopAlgorithm也可以提前发现一些“没有前途”的调优任务提前结束剩下计算资源。

    目前Google Vizier已经支持Grid search、Random search已经改良过的Bayesian optimization,为什么是改良过的呢?前面提到贝叶斯优化也需要几个初始样本点,这些样本点一般通过随机搜索要产生,这就有冷启动的代价了,Google将不同模型的参数都归一化进行统一编码,每个任务计算的GaussianProcessRegressor与上一个任务的GaussianProcessRegressor计算的残差作为目标来训练,对应的acquisition function也不是简单的均值乘以n倍方差了,这相当于用了迁移学习模型的概念,从paper的效果看基本解决了冷启动的问题,这个模型被称为(Stacked)Batch Gaussian Process Bandit。

    Google Vizier除了实现很好的参数推荐算法,还定义了Study、Trial、Algorithm等非常好的领域抽象,这套系统也直接应用到Google CloudML的HyperTune subsystem中,开发者只需要写一个JSON配置文件就可以在Google Cloud上自动并行多任务调参了。

    Advisor开源项目

    Google Vizier是目前我看过最赞的超参数自动调优服务,可惜的是它并没有开源,外部也只有通过Google CloudML提交的任务可以使用其接口,不过其合理的基础架构让我们也可以重现一个类似的自动调参服务。

    Advisor就是一个Google Vizier的开源实现,不仅实现了和Vizier完全一致的Study、Trial、Algorithm领域抽象,还提供Grid search、Random search和Bayesian optimization等算法实现。使用Advisor很简单,我们提供了API、SDK、Web以及命令行等多种访问方式,并且已经集成Scikit-learn、XGBoost和TensorFlow等开源机器学习框架,基本只要写一个Python函数定义好模型输入和指标就可以实现任意的超参数调优(黑盒优化)功能。

    Advisor使用Python实现,基于Scikit-learn的GPR实现了贝叶斯优化等算法,也欢迎更多开发者参与,开源地址 tobegit3hub/advisor 。

    Advisor在线服务

    hypertune.cn 是我们提供的在线超参数推荐服务,也是体验Advisor调参服务的最好入口,在网页上我们就可以使用所有的Grid search、Random search、Bayesian optimization等算法功能了。

    首先打开 http://hypertune.cn , 目前我们已经支持使用Github账号登录,由于还没有多租户权限隔离因此不需要登录也可以访问全局信息。在首页我们可以查看所有的Study,也就是每一个模型训练任务的信息,也可以在浏览器上直接创建Study。

    这里需要用户定义Study configuration,也就是模型超参数的search space,和Google Vizier一样我们支持Double、Integer、Discrete和Categorical四种类型的超参数定义,基本涵盖了数值型、字符串、连续型以及离散型的任意超参数类别,更详细的例子如下图。

    定义好Study好,我们可以进入Study详情页,直接点击“Generate Suggestions”按钮生成推荐的超参数组合,这会根据用户创建Study选择的调参算法(如BayesianOptimization)来推荐,底层就是基于Scikit-learn实现的联合高斯分布、高斯过程回归、核技巧、贝叶斯优化等算法实现。

    当然我们也可以使用Grid search、Random search等朴素的搜索算法,生成的Trial就是使用的该超参数组合的一次运行,默认是没有objective value的,我们可以在外部使用该超参数进行模型训练,然后把auc、accuracy、mean square error等指标在网页上回填到参数推荐服务,下一次超参数推荐就会基于已经训练得到模型数据,进行更优化、权衡exploritation和exploration后的算法推荐。对于Eearly stop算法,我们还需要每一步的性能指标,因此用户可以提供Training step以及对应的Objective value,进行更细化的优化。

    除了提供在网页上集成推荐算法,我们也集成了Scikit-learn、XGBoost和TensorFlow等框架,在命令行只要定义一个函数就可以自动实现创建Study、获取Trial以及更新Trial metrics等功能,参考 https://github.com/tobegit3hub/advisor/tree/master/examples 。对于贝叶斯优化算法,我们还提供了一维特征的可视化工具,像上面的图一样直观地感受均值、方差、acquisition function的变化,参考 https://github.com/tobegit3hub/advisor/tree/master/visualization 。

    总结

    本文介绍了一种更好的超参数调优方法,也就是贝叶斯优化算法,并且介绍了Google内部的Vizier调参服务以及其开源实现Advisor项目。通过使用更好的模型和工具,可以辅助机器学习工程师的建模流程,在学术界和工业界取得更多、更大的突破。

    如果你有更好的超参数推荐算法,不妨留言,我们有能力实现并且让更多人用上 :)

    展开全文
  • 使用Optuna进行超参数优化

    千次阅读 2021-11-03 10:36:27
    参数优化是一项艰巨的任务。 但是使用 Optuna 等工具可以轻松应对。 在这篇文章中,我将展示如何使用 Optuna 调整 CatBoost 模型的超参数。 Optuna 的超参数调整可视化 超参数 常规参数是在训练期间通过机器学习...
  • 公众号标题:神经网络中的优化方法之学习率衰减和动态梯度方向 引言 神经网络中的网络优化和正则化问题介绍主要分为一,二...无论是神经网络还是机器学习都会存在很多的超参数,在神经网络中,常见的超参数有: 网...
  • Hyperopt 参数优化

    万次阅读 多人点赞 2018-08-28 20:02:03
    Hyperopt(Hyper-parameter Optimization)用于模型选择和参数优化参数选择在训练模型时是一个很关键的部分。然而存在这样的问题,一方面参数选择背后包含着一定的数学原理,对于新手来说难上手;另一方面,一个...
  • [机器学习] 超参数优化介绍

    万次阅读 多人点赞 2019-04-18 10:47:53
    如果方式可以帮助工程师找到最优的参数组合,那一定大有裨益,贝叶斯超参优化就是其中的一。如果是单单罗列公式,可能会显得乏味,就用一些思考带上公式为大家分享。 目前在研究Automated Machine Learning...
  • 参数优---贝叶斯优化及其改进(PBT优化

    万次阅读 多人点赞 2020-01-08 21:14:34
    自动机器学习超参数调整(贝叶斯优化)—介绍了例子 贝叶斯优化(Bayesian Optimization)深入理解 贝叶斯优化(BayesianOptimization) 简介 所谓优化,实际上就是一个求极值的过程,数据科学的很多时候就是求极值...
  • 天在做讲课资料的时候遇到一个比较坑的问题。一般来说调用拷贝构造函数分三情况 1.当用类一个对象去初始化另一个对象时。 2.如果函数形参是类对象。 3.如果函数返回值是类对象,函数执行完成返回调用时。 ...
  • 史上最强Tomcat8性能优化

    万次阅读 多人点赞 2019-10-25 15:33:32
    文章目录授人以鱼不如授人以渔目的服务器资源Tomcat配置优化Linux环境安装运行Tomcat8AJP连接执行器(线程池)3运行模式部署测试用的web项目查看服务器信息部署web应用使用Apache JMeter进行性能测试下载安装修改...
  • [机器学习] --- 参数优化与模型选择

    千次阅读 2018-07-07 17:06:16
    # SVM的三个超参数:C为惩罚因子,kernel为核函数类型,gamma为核函数的额外参数(对于不同类型的核函数不同的含义) # 别于传统的网格搜索(GridSearch),这里只需要给出最优参数的概率分布即可,而不需要按照...
  • 神经网络的参数优化方法

    万次阅读 多人点赞 2018-10-23 14:05:42
    著名: 本文是从 Michael Nielsen的电子书Neural Network and Deep Learning的深度学习那一章的卷积神经网络的参数优化方法的一些总结和摘录,并不是我自己的结论和做实验所得到的结果。我想Michael的实验结果更...
  • OpenCV中的SVM参数优化

    万次阅读 多人点赞 2014-08-19 10:31:18
    SVM(支持向量机)是机器学习算法里用得最多的算法。... 网上讲opencv中SVM使用的文章很多,但讲SVM参数优化的文章却很少。所以在这里不重点讲怎么使用SVM,而是谈谈怎样通过opencv自带的库优化SVM中的参数
  • 在本文的前部分中,我获取了Fitbit的睡眠数据并对其进行预处理,将这些数据分为训练集、验证集和测试集,除此之外,我还训练了三不同的机器学习模型并比较了它们的性能。 在第2部分中,我们看到使用随机森林和...
  • 贝叶斯优化神经网络参数The purpose of this work is to optimize the neural network model hyper-parameters to estimate facies classes from well logs. I will include some codes in this paper but for a ...
  • sql优化常用的几方法

    千次阅读 2022-03-06 05:45:01
    type列,连接类型。一个好的SQL语句至少要达到range级别。杜绝出现all级别。 key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式。 key_len列,索引长度。 rows列,扫描行数。该值是个预估值...
  • java 传递参数两种方式

    万次阅读 多人点赞 2015-10-19 15:39:28
    Java中没有指针,所以也没有引用传递了,仅仅值传递不过可以通过对象的方式来实现引用传递 类似java没有多继承 但可以用多次implements 接口实现多继承的功能  值传递:方法调用时,实际参数把它的值传递给对应...
  • 卷积神经网络(CNN)的参数优化方法

    万次阅读 多人点赞 2019-06-08 19:32:17
    积神经网络的参数优化方法——调整网络结构是关键!!!你只需不停增加层,直到测试误差不再减少. 著名:本文是从 Michael Nielsen的电子书Neural Network and Deep Learning的深度学习那一章的卷积神经网络的参数...
  • 尽管我们在运行时能够确定value是一个List集合,但是却无法获得该集合中存储的是哪种类型的数据元素,这就是因为泛型类的类型实参类型被擦除,被Object类型代替或上界形参约束类型代替。但是如何去正确检查value...
  • sql优化常用的几方法,19最有效的sql优化技巧 本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下: 1、EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划。 下面来个简单的示例,标注(1...
  • 数据库优化的八方式

    千次阅读 多人点赞 2020-07-24 22:23:40
    1.选取最适用的字段属性 ...对于某些文本字段,例如性别,我们可以把它定义为ENUM类型,因为在mysql中,ENUM类型会被当作数据类型来处理,而数值类型数据被处理起来速度比文本类型快得多。另一个提高效率
  • jvm优化——运行参数

    千次阅读 2020-04-12 23:46:53
    1.1、三种参数类型 jvm的参数类型分为三,分别是: 1、标准参数: 标准参数的意思是说一般比较稳定,在以后jvm的版本中都会做保留一般不会改变 -help -version 2、-X参数(非标准参数): 非标准参数的意思是说不...
  • 【Unity】中GC优化XLua下的各种值类型

    千次阅读 2017-02-17 15:35:21
    Unity下的C#GC Alloc(下面简称gc)是个大问题,而嵌入一个动态类型的Lua后,它们之间的交互很容易就产生gc,各种Lua方案也把这作为性能优化的重点。这些优化说穿了其实不复杂。 元凶在这里 先看看这个函数 ...
  • python数据类型(数字Numbers)

    千次阅读 2021-01-29 05:43:14
    优化一、定义整型对象age = 10#type()给出参数的数据类型,print()终端输出参数的值print(type(age))# 二、在计算机里除了十进制以外,还有二进制、八进制、十六进制。blog二进制:以0b开头,如'0b1011',转二进制...
  • 由于超参数的选择对模型最终的效果可能极大的影响,为了使模型达到更好的效果,通常会面临超参数调优问题。但如何选择合适的超参数并没有一个明确的指导,并且同一模型面对随时间变化的数据,其超参数的选择都可能...
  • iOS之性能优化·UITableView深度优化

    万次阅读 2021-10-23 16:20:59
    UITableView 的优化主要从四个方面入手: 提前计算并缓存好高度(布局),因为 tableView:heightForRowAtIndexPath: 是调用最频繁的方法; 滑动时按需加载,防止卡顿。这个在大量图片展示,网络加载的时候很...
  • 使用阿里云rds for MySQL数据库(就是MySQL5.6版本),个用户上网记录表6个月的数据量近2000万,保留最近一年的数据量达到4000万,查询速度极慢,日常卡死。严重影响业务。 问题前提:老系统,当时设计系统的人...
  • 参数优化,这些策略了解一下!

    千次阅读 2018-10-15 08:40:00
    授权转自机器之心整天 babysitting 深度学习模型是不是很心累?这篇文章或许能帮到你。本文讨论了高效搜索深度学习模型最佳超参数集的动机和策略。作者在 FloydH...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 506,838
精华内容 202,735
关键字:

优化参数一般有两种类型

友情链接: chuankou.rar