使用tensorflow2.4.0和keras的2.4.3对应的版本,这样我们才可以使用tensorboard
1,理解神经网络
-
人工神经网络(ANN)
-
人工神经网络是深度学习的核心,他们用途广泛,功能强大且可扩展,使其非常适合大型和高度复杂的机器学习任务
-
高度复杂的计算可以通过相当简单的神经元网络来执行,生物神经网络(BNN)的架构仍然是活跃的主题
-
人工神经元的逻辑计算—就是人工神经元的计算基本单元
- 人工神经元:它具有一个或者多个二进制(开/关)输入和一个输出。当超过一定数量的输入,神经元就会处于激活状态,然后人工神经元会经过逻辑计算将结果输出
- 单个神经元的逻辑运算方法有4个,“=”,“AND”,“OR”,“NOT”
- 单个神经元只能执行一个运行,但是如果多个神经元组合在一起就可以解决复杂的问题
- 一个神经元是有输入的,多个神经元合作时,下一个神经元的输入只能是上一个神经元的输出,单个神经元的运算期间是不能妨碍的,彼此之间相互独立
- 人工神经元是对输入值直接进行逻辑运算,中途不经过任何的变化,对于单个神经元来说,我们输入的是二进制数据
- 人工神经元输入的只能是二进制开/关值
-
单层感知器(TLU)–注意是单层,而不是一个
就是只有一行TLU的人工神经元,这一行可以有多个TLU也可以只有一个TLU,这样都叫做单层
2.单层感知器案例(TLU)
#单层感知器的小案例----用perceptron类,实现单个TLU网络
import numpy as np
from sklearn.datasets import load_iris
from sklearn.linear_model import Perceptron
iris = load_iris()
x = iris.data[:,(2,3)] #获取花的2.长度和宽度特征列
y = (iris.target==0).astype(np.int) #目标列
per_clf = Perceptron() #创建一个单层的TLU对象
per_clf.fit(x,y) #输入x和y
y_pred=per_clf.predict([[2,0.5]]) #输入需要预测的值
print(y_pred)
print(y) #查看目标列都是什么
-
通过上面的小案例我们可以知道,感知器的学习算法非常类似于随机梯度下降,实际上perceptron类等效于使用具有以下超参数的
SGDClassifier()参数如下: loss="perceptron", learning_rate="constant", etao=1(学习率), penalty=None(无正则化)
-
与逻辑回归不一样,感知器是不输出分类概率的,是直接输出类别,他们会基于硬阈值进行预测,这是逻辑回归胜过感知器的原因,因为逻辑回归可以输出类别,也可以输出分类概率,而感知器只能是输出类别
-
单层感知器的缺点
即其无法解决复杂的问题-----我们可以堆叠多层感知器来消除这个问题(叠加多个层),所得的ANN称为多层感知器(MLP),可以解决XOR问题
3.多层感知器(MLP)理解-安装tensorflow
我们要使用keras实现MLP(多层感知器)
1.须知
keras是高级深度学习API,可以让你轻松构建,训练,评估和执行各种神经网络,其文档可以从https://keras.io/获得
tensorflow现在与自身的keras捆绑在一起了,tf.keras,它仅仅支持tensorflow作为后端底层运算,kears是高级的,只是调用使用tensorflow封装好的包
2.安装
安装tensorflow2.0以上版本步骤(注意我们安装tensorlfow与keras版本要对应,相互兼容)
1.创建一个专门的虚拟环境
2.安装tensorflow命令
1.cpu版本 :pip3 install -u tensorflow
2.gpu版本;pip3 install -u tensorflow-gpu使用tensorflow2.4.0和keras的2.4.3对应的版本,这样我们才可以使用tensorboard
查看是否安装成功
#查看安装版本 import tensorflow as tf from tensorflow import keras print(f"tensorlfow的版本为:{tf.__version__}") #看tensorflow版本 print(f"keras的版本:{keras.__version__ }") #查看keras版本,他们的版本要对应
4.多层感知器(MLP)分类案例
使用顺序的API构建图像分类器案例
一般的神经网络都是一种有监督学习的算法
4.1加载数据集并进行数据集划分
使用的是Fashion MNINST数据集,它是MNIST的直接替代品与其具有完全相同的格式**(70000张灰度图,每一幅是28*28像素,有10个类)**但是这些图像代表的是时尚物品,而不是手写数字,因此每个类更有多样性,问题比MNIST更具有挑战性
当使用keras而不是sklearn来加载KMIST或FashionMNIST时,一个重要的区别是每个图像都表示为28x28阵列,而不是尺寸为784(28*28=784)的一维阵列,此外像素强度表示为整数(0到255)而不是浮点数(0.0到255.0)
#注意下:
#神经网络在训练时输入的特征数据必须在(0,1)之间,也就是必须经过处理才可以当做输入,
#目标列的话也需要变成数字,不需要将目标列缩放到(0,10)之间,只要是数字就行
import keras
####1.获取数据集
fashion_mnist = keras.datasets.fashion_mnist
(x_train_full,y_train_full),(x_test,y_test) = fashion_mnist.load_data()
#加载数据的格式:前面的元祖是训练集,后面的元祖是测试集,元祖中的第一个是特征列,第二个是目标列,目标列里面存的只是0-9之间的数字
x_train_full.shape #查看训练集的特征列的形状
x_train_full.dtype #查看训练集特征列里面的数据类型
####2.将训练集划分成训练集和验证集
#由于我们要使用梯度下降来训练神经网络,因此必须按比例缩放输入特征,为了简单起见,我们将像素强度除以255.0(将他们转换为浮点数),将像素强度降低到0-1范围内
x_valid,x_train = x_train_full[:5000]/255.0,x_train_full[5000:]/255.0
#将前5000个图片分配给验证集的特征集,后面的图片分配给训练集的特征集,并且将特征列缩放到(0,1)之间
y_valid,y_train = y_train_full[:5000],y_train_full[5000:]
#验证集和训练集的目标列,不用进行特征缩放
#由于目标列存的只是0-9之间的数字,并不知道每一个数字代表的是什么意思,接下来就是我们为每一个数字赋予一定的有意义类别
class_names = ["Tshirt/top","Trouser","Pullover","Dress","Coat","Sandal","Shirt","Sneaker","Bag","Ankle boot"]
class_names[y_train[0]]
#y_train[0]返回的是目标列的数字,用在class_names这里就是索引
4.2创建模型
使用序列API创建模型
第一种方式,没有用序列化列表
#---第一个
model = keras.models.Sequential()
#----第二个,并且设置输入的图像格式是(28,28),其中特征列的数值范围是在(0,1)之间
model.add(keras.layers.Flatten(input_shape=[28,28]))
#----第三个,第一个隐藏层
model.add(keras.layers.Dense(300,activation="relu"))
#----第四个,第二个第二个隐藏
model.add(keras.layers.Dense(100,activation="relu"))
#---第五个,输出层,10是我们一共有10个类别,激活函数使用softmax
model.add(keras.layers.Dense(10,activation="softmax"))
model.summary()
-
创建了一个Sequential模型(序列化),这是用于神经网络的最简单的Keras模型,它仅由顺序连接的单层堆栈组成,这称为顺序API
-
我们构建模型的第一层,并将其放入循序model中(add),第一层是Flatten层,它的作用是将每个输入的图像转换成一维数组:如果接收到的输入数据X,则计算X.reshape(-1,1).该层没有任何参数,他只是在那里做一些简单的预处理,由于它是模型的第一层,因此应该指定input_shape,就是输入实例的形状,其中不包含批处理大小,仅仅是实例的形状
-
我们添加具有300个神经元的Dense隐藏层,它使用relu激活函数。每个Dense层管理自己的权重矩阵,其中包含神经元及其输入之间的所有连接权重。他还管理偏执项的一个向量(每个神经元一个),当它收到一些输入数据时,它会进行计算
-
我们添加第二100个神经元的Dense隐藏层,还是使用relu激活函数
-
我们添加一个10个神经元的Dense输出层(每个目标类别一个神经元,因为有10个类别,所以就填入10个),使用softmax激活函数(因为这个类是排他的)
-
summary():summary是总结的意思会显示模型的所有层,包括每一个层的名字(我们一般不会给层定名字,一般都是系统自定义的),每一个层输出的形状(None表示可以批处理任意大小),每一层的参数数量,参数可以理解我们输入的特征(如图像)
最后的结果- Total params:整个模型的参数总数,就是param列的总和
- Trainable params:整个模型中,可以训练的参数
- Non-trainable params;在整个模型中,不可以训练的参数
我们从summary展示的图中可以看出,模型提供了足够的参数来拟合数据,但这也意味着模型存在过拟合的风险,尤其是在你没有大量训练数据的情况下
理解
#获取模型每一层的列表,可以按其索引获取层,也可以按名称获取层
model.layers #显示全部层列表
#按索引获取层--获取第一层隐藏层
hidden1 = model.layers[1] #层的索引从0开始,第一层是输入层,第二层开始才是隐藏层
print(hidden1.name) #显示隐藏层的名字
#访问层的权重参数和偏执
weights,biases = hidden1.get_weights() #获取第一个隐藏层的权重参数和偏置,weights是权重参数,biases是偏置
print(f"第一个隐藏层的权重参数为{weights}")
print(f"第一个隐藏层的偏置参数为{biases}")
#可以使用get_weights()和set_weights()访问层的所有参数,对于密集层,这包括连接权重和偏执项
- 密集层随机初始化了连接权重,这是打破对称性所必须的,并且偏置项被初始化为零,如果要使用其他初始化方法,则可以在创建层时设置kernel_initializer或者bias_initializer
- 权重矩阵的形状取决于输入的个数,这就是在Sequential模型中创建第一层是建议指定input_shape的原因,但是如果你不指定输入形状,那也是可以的,keras会等到知道输入形状后才真正构建模型,当你向其提供实际数据时(如在训练期间)或者在调用其build方法时,就会发生这种情况。在真正构建模型之前,所有层都没有权重,而且你也无法执行某些操作(如保存模型),因此,如果在创建模型时知道输入形状,最好指定它
注意:
我们指定activation="relu"等效于指定activation = keras.activation.relu,
keras.activations软件包中提供了其他的激活函数,需要的时候可以自己查查
第二种方式创建序列化模型
model = keras.models.Sequential([
keras.layers.Flatten(input_shape=[28,28]),
keras.layers.Dense(300,activation="relu") ,
keras.layers.Dense(100,activation="relu") ,
keras.layers.Dense(10,activation="softmax")
])
model.summary()
理解同上,只不过使用了**Sequential()**更加方便而已
4.3编译模型
model.compile(
loss = "sparse_categorical_crossentropy",
optimizer="sgd",
metrics=["accuracy"]
)
- compile()的作用是指定损失函数和要使用的优化器,并且你可以选择在训练和评估期间要计算的指标
- loss:是损失函数,决定我们对预测目标判断的方式
- 使用"sparse_categorical_crossentropy"损失,是因为我们具有稀疏标签(即对于每个实例,只有一个目标索引,在这种情况下为0到9),并且这些类是互斥的,
- 如果每个实例对应的每个类都有一个目标概率,则我们应该用“categorical_crossentropy”损失。
- 如果我们正在执行二进制分类(带有一个或多个二进制标签),则在输出层使用“sigmod"激活函数,而不是“softmax函数,并且使用”binary_crossentropy“。
- 如果将稀疏标签(即类索引)转换为独热向量标签,使用keras.utils.to_categorical()函数,反之则使用np.argmax()函数和axis=1
- optimizer:优化器
- 我们使用
sgd
简单的梯度下降来训练模型,优化器肯定是优化模型的用的,使用SGD优化器时,调整学习率很重要,因此通常需要使用optimizer=keras.optimizers.SGD(lr=??)
来设置学习率,而不是使用optimizer=“SGD”(默认lr等于0.01)来设置学习率。神经网络其实也是对数值的一个更改更替,使用梯度下降正好可以解决这个问题
- 我们使用
- metrics:是一个在训练期间的评估期间设置的一个计算指标,可以用这个指标进行评估,我们这里设置准确率来作为评价指标
4.4训练和评估模型
history = model.fit(x_train,y_train, #输入训练集的特征列和目标列
epochs=30, #我们要训练几个轮次,默认该值为1
validation_data=(x_valid,y_valid), #添加验证集数据,里面是验证的特征列和目标列)
#结果展示的解释
#Epoch;是当前处在第几个轮次中,Epoch下面的数字是当前处理的实例
#loss:是在训练集上面的损失,accuracy:是在训练集上面的准确率
#val_loss:是在验证集上面的损失,val_accuracy:是在验证集上面的准确率
history.params #查看训练期间我们设置的参数,history是程序自带的,不用管
history.epoch #查看我们的轮次
history.history #查看每一个轮次的loss,val_loss,accuracy,val_accuracy,
- keras在每个轮次结束时会测量本轮次上的损失和我们设置的其他指标,这对于查看模型的实际效果非常有用
- 如果训练集上面的性能好于验证集,则模型可能存在过拟合训练集
- 你可以在fit()中设置validation_split = 0.1,就是使用初始训练集的后10%作为验证集,不用在自己输入切分验证集了
- 如果训练集非常不平衡,有些类的实例非常多,而有些类的实例非常少,那么在调用fit方法时,设置class_weight参数会很有用,这会给代表性不足的类更大的权重,给代表性过多的类更小的权重
- 如果你需要每个实例的权重,在fit中设置sample_weight参数,如果class_weight和sample_weight都在fit中设置了,kears会把他们相乘,然后获取权重
- 如果某些实例由专家标记,而另一些实例使用众包平台标记,则按实例权重可能会很有用:你可能希望为前者赋予更多的权重,你还可以通过将其作为validation_data元祖的第三项添加到验证集中来提供样本权重(但不提供类权重)
4.5绘制可视化图表
绘制训练过程中的可视化图表–不用改,以后直接用
import pandas as pd
import matplotlib.pyplot as plt
pd.DataFrame(history.history).plot(figsize=(8,5)) #绘制折线图
plt.grid(True)
plt.gca().set_ylim(0,1)
plt.show()
图像分析
图像分析:
- 在训练期间:
- 训练集准确率和验证集准确率都在稳步提高,而训练集损失和验证集损失则在下降,而且验证曲线与训练曲线非常接近,这意味着没有太多的过拟合,在这种特殊的情况下,该模型看起来在验证集上表现要好于训练开始在训练集上的表现。但事实并非如此:确实,验证误差是在每个轮次结束时计算的,而训练误差是使用每个轮次的运行平均值计算的。因此训练曲线应该向左移动半个轮次,如果你这样做,你会看到训练和验证曲线在训练开始时几乎重叠(绘制曲线时,应该将其移动半个轮次),训练集的性能最终会超过验证性能,就像通常情况下训练足够长的时间一样,你可以说模型尚未完全收敛,因为验证损失仍在下降,因此你可能应该继续训练,这就像再次调用fit方法那样简单,因为keras只是从他停止的地方继续训练(你应该能够达到接近89%的验证准确率)
- 如果你对模型的性能不太满意,则应该回头调整超参数
- 首先检查的是学习率,如果这样做没有用,尝试使用另一个优化器(并在更改任何超参数后,始终重新调整学习率)
- 如果性能仍然不佳,则尝试调整模型的超参数(如层数,每层的神经元个数,每个隐藏层的激活函数类型)
- 其次你还可以调整其他超参树,如批处理大小(可以在fit中使用batch_ize参数,默认为32)
3.对模型的验证精度满意后,应该在“测试集”上对其进行评估泛化误差,然后再将模型部署到生产环境中
4.6在测试集上面进行预测泛化
model.evaluate(x_test,y_test)
#第一个结果是损失
#第二个结果是正确率
注意
在测试集上面获得比在验证集上面略低的性能是很常见的,因为超参数是在验证集上面而不是测试集上面进行调优的,切记不要调整测试集上面的超参数,否则你对泛化误差的估计将过于乐观
4.6使用模型对新特征预测
第一种预测方式:predict()方法
#我们使用predict方法对新实例进行预测,由于没有实际的新实例,因此我们将仅使用测试集的前三个实例
x_new = x_test[:3] #获取测试集的前三个实例的特征列
y_proba = model.predict(x_new) #预测出一个实例属于每个类别的概率,他们的和为1
y_proba.round(2) #是一个类似于表格的形式表达
# print(y_proba) #直接是列表的形式
第二种预测方式predict_classes()
#如果你只关心估计概率最高的类(即使该概率非常低)则可以使用pre_dict_classes()
y_pred = model.predict_classes(x_new)
print(y_pred) #直接输出预测概率最高的类别
5.多层感知器(MLP)回归案例
5.1加载数据集并进行数据集划分
导入数据集,并对数据集进行划分为训练集,验证集,测试集,并且比例缩放所有特征
#我们的目的是预测加州的住房问题,并使用回归神经网络解决它,我们使用的数据集更加简单,它仅包含数字特征,并且没有缺失值
from sklearn.datasets import fetch_california_housing #数据集
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
housing = fetch_california_housing()
#划分训练集和测试集
x_train_full,x_test,y_train_full,y_test = train_test_split(housing.data,housing.target)
#划分训练集和验证集
x_train,x_valid,y_train,y_valid = train_test_split(x_train_full,y_train_full)
#缩放特征
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train) #对训练集转换
x_valid = scaler.transform(x_valid) #对验证集进行转换
x_test = scaler.transform(x_test) #对测试集进行转换,
#对于神经网络来说,无论是训练集,测试集还是验证集的特征列都需要缩放到(0,1)之间,然而对于他们的目标列,我们则需要将他们变成数字
5.2构建模型
model = keras.models.Sequential([
keras.layers.Dense(30,activation="relu",input_shape=x_train.shape[1:]), #注意神经网络做回归时的做法,留意一下
keras.layers.Dense(1) #我们只是预测一个值,所以输出神经元就1个
])
5.3编译模型
model.compile(
loss="mean_squared_error", #选择损失函数,回归一般有两个,mse或rmse
optimizer="sgd"
)
5.4训练和评估模型
history = model.fit(
x_train,y_train,
epochs=20,
validation_data=(x_valid,y_valid)
)
5.5绘制可视化图表
注意history这个变量,是5.4中的变量
import pandas as pd
import matplotlib.pyplot as plt
pd.DataFrame(history.history).plot(figsize=(8,5)) #绘制折线图
plt.grid(True)
plt.gca().set_ylim(0,1)
plt.show()
5.6用测试集进行预测泛化
mse_test = model.evaluate(x_test,y_test)
5.7使用模型对新的案例进行预测
x_new = x_test[:3]
y_pred=model.predict_classes(x_new)
print(y_pred)
我们使用顺序API来构建训练,评估和使用回归MLP进行预测与我们进行分类非常相似,主要区别是输出层只有一个神经元(因为我们只预测一个单值),并且不使用激活函数,而是损失函数是均方误差。
由于数据集噪音很大,我们只使用比以前少的神经元的当个隐藏层,以避免过拟合
6.保存和加载模型(H5格式)
6.1保存模型
model是我们上面搭建的神经网络模型
#指定固定的保存路径--保存的路径不要有汉语
model.save("C:/Users/hanhan/Desktop/machine-learning/shen-jin-wang-luo/my.h5")
print("保存成功")
#默认保存路劲--当前的项目中
model.save("my_model.h5")
keras使用HDF5格式保存模型的结构(包括每一层的超参数)和每一层的所有模型参数值(例如连接权重和偏执),它还可以保存优化器(包括其超参数及其可能具有的任何状态)
通常你有一个训练模型并保存模型的脚本,以及一个或多个加载模型并使用其进行预测的脚本(或web服务)
6.2加载模型
#加载指定位置的模型
import keras
model1 = keras.models.load_model("C:/Users/hanhan/Desktop/machine-learning/shen-jin-wang-luo/my.h5")
#加载项目中的模型
model = keras.models.load_model("my_model.h5")
对于tf2.0版本的,我们需要更换h5py,我们先
pip uninstall h5py
删除,然后使用其安装pip install h5py==2.10 -i https://pypi.doubanio.com/simple
否则会查询str问题
当使用顺序API或函数API时,这上面的加载模型和保存模型是可以使用的,但是对于子类化的API,他将不起作用,虽然使用子类API不起作用,但是你至少可以使用
save_weights()
和load_weights()
来保存和还原模型参数,但是你需要自己保存和还原其他所有内容
7.回调函数
7.1为什么会有回调函数
如果训练持续几个小时该怎么办?这是很常见的,尤其是在大型数据集上进行训练时。
我们的解决办法是在这种情况下,如果可以在训练时保存模型,而且在训练过程中定期保护检查点,以免在计算机崩溃时,丢失所有内容
7.2使用回调函数
fit()方法接受一个callbacks参数,该参数使你可以指定keras在训练开始和结束时,每个轮次的开始和结束时(甚至在处理每个批量之前和之后),将调用的对象列表,如:在训练期间
ModelCheckpoint
回调会定期保存模型的检查点,默认情况下,在每个轮次时,检查一次
#这里我们省略过模型的建模过程
checkpoint_cb = keras.callbacks.ModelCheckpoint("my_model.h5") #ModelCheckpoint会定期保存模型的检查点--其实是保存模型用的--上面的模型已经建好并且也使用了compile()
history = model.fit(
x_train,y_train,epoch=10,
callbacks = [checkpoint_cb] #在fit方法中添加回调函数
)
此外如果在训练期间想要使用验证集,则可以在创建
ModelCheckpoint
时,设置save_best_only=True
,该参数表示:只有在验证集上的模型性能达到目前最好时,他才会保存模型,这样你就不必担心训练时间太长而过拟合训练:只需要还原训练后保存的最后一个模型,这就是验证集中的最佳模型,以下代码是实现提前停止的简单方法
checkpoint_cb = keras.callbacks.ModelCheckpoint("my_model.h5",save_best_only=True) #第一个参数是定期保存的模型,第二参数是设置在验证集上面表现最好
history = model.fit(x_train,y_train,epchs=10,
validation = (x_valid,y_valid), #传入验证集
callbacks = [checkpoint_cb], #传入回调函数
)
model = keras.models.load_model("my_model.h5")
实现提前停止法的另外一种方法是使用
EarlyStopping
回调,如果在多个轮次的(由参数patience控制)验证集上面没有任何的进展,他将实现中断,并且可以选择回滚到最佳模型,你可以将两个回调结合起来以保存模型的检查点(以防止计算机崩溃),并在没有更多进展时尽早中断训练(以免浪费时间和资源)
early_stopping_cb = keras.callbacks.EarlyStopping(patience=10, #设置在验证集上多少个轮次
restore_best_weights=True)
history = model.fit(
x_train,y_train,epochs=100,
validation = (x_valid,y_valid),
callbacks=[checkpoint_cb,early_stopping_cb] #可以与前面一样,添加两个,这种情况还不错
)
#可以将轮次patience设置为较大的值,因为训练将在没有更多进展时,自动停止,在这种情况下,无须还原保存的最佳模型,因为EasyStoping回调将跟踪最佳权重,并在训练结束时为你还原它
#keras.callbacks包中还有许多其他的回调函数
#如果需要额外的控制,则可以轻松编写自己定义的回调函数,下面是案例
class huidiaoming(keras.callbacks.Callback):
def hanshu(selfs):\
# 下面就是自己定义的函数了
8.寻找最佳的超参数组合
简单的尝试超参数的许多组合,看看哪个在验证集上面更好
我们使用
RandomizedsearchCV
网格搜索寻找最佳的超参数组合
8.1定义模型
#定义一个模型函数
def build_model(n_hidden=1,n_neurons=30,learning_rate=3e-3,input_shape=[8]):
model =keras.models.Sequential()
model.add(keras.layers.InputLayer(input_shape=input_shape) ) #建立输入层
for layer in range(n_hidden):#设置隐藏层n_hideen就是有几个隐藏层
model.add(keras.layers.Dense(n_neurons,activation="relu"))
model.add(keras.layers.Dense(1))#建立一个输出层
optimizer = keras.optimizers.SGD(lr=learning_rate)
model.compile(loss="mse",optimizer=optimizer)
return model
#以build_model为对象,创建一个kerasregressor对象
keras_reg = keras.wrappers.scikit_learn.KerasRegressor(build_model) #我们建立的模型build_model传入,我们在创建kerasregressor对象时,并没有传入任何的参数,因此build_model里面的参数(n_hidden。。)就成了kerasregressor里面的默认参数了,其实这个方法是回到了sklearn了,因此我们可以使用fit方法训练,使用score()方法进行评估,使用predict方法进行预测了,其实就是scklearn
8.2设置随机网格搜索-RandomizedsearchCV
#设置随机网格搜素--RandomizedsearchCV
from scipy.stats import reciprocal
from sklearn.model_selection import RandomizedSearchCV
param_distribs={
"n_hidden":[0,1,2,3],#设置build_model中的隐藏层数
"n_neurons":np.arange(1,100),#设置每一层的神经元数
"learning_rate":reciprocal(3e-4,3e-2) #设置学习率
}
rnd_search_cv = RandomizedSearchCV(keras_reg,param_distribs,n_iter=10,cv=3)
8.3训练模型
#训练rnd_search_cvr
rnd_search_cv.fit(x_train,y_train,epochs=10,
validation_data=(x_valid,y_valid),
callbacks =[keras.callbacks.EarlyStopping(patience=10)])
8.4评估模型
#利用score方法进行评估,因为我们的模型变成了kerasregressor
score=keras_reg.score(x_test,y_test)
print(score)
#得分越高越好
8.5预测
#predict方法进行预测
y_pred=keras_reg.predict(x_new)
#显示最好的参数组合
rnd_search_cv.best_params_
#随机搜索的分数,越大越好
rnd_search_cv.best_score_
#创建最好的模型对象
model1 = rnd_search_cv.best_estimator_.model
随机搜索可能持续数小时,具体时间取决于硬件,数据集的大小,模型的复杂性以及n_iter和cv的值,当结束时,你可访问的最佳参数,最佳分数和经过训练的keras模型
网格搜索完成以后,你现在可以保存模型了,在测试集上面进行评估,如果对它的性能满意,可以将其部署到生产或环境中,使用随机搜索并不困难,他可以很好的解决许多相当简单的问题,但是当训练速度很慢时,(对于具有较大数据集的更复杂的问题),此方法将仅探索超参数空间的一小部分,你可以通过手动协助搜索过程来部分缓解此问题:首先使用宽范围的超参数值快速进行随机搜索,然后使用以第一次运行中找到的最佳值为中心,用较小范围的值运行另一个搜索,以此类推,该方法有望放大一组好的超参数,但是这是非常耗时的,也不能最好的利用时间