keras搭建深度学习模型的一些小tips
定义模型两种方法:
1.sequential 类仅用于层的线性堆叠,这是目前最常用的网络架构 | 2.函数式API,用于层组成的有向无环图,让你可以构建任意形式的架构 |
1 from keras import models 2 from keras import layers 3 4 model = models.Sequential() 5 model.add(layers.Dense(32,activation='relu',input_shape=(784,))) 6 model.add(layers.Dense(10,activation='softmax')) |
1 input_tensor = layers.Input(shape=(784,)) 2 x = layers.Dense(32,activation='relu')(input_tensor) 3 output_tensor = layers.Dense(10,activation='softmax')(x) 4 model = models.Model(inputs = input_tensor,outputs = output_tensor)
|
训练神经网络模型:
model.summary:打印出模型的概况 model.fet_config:返回包含模型配置信息的python字典。模型也可已从他的config信息中获取。 config=model.get_config() model=Model.from_config(config) model=Sequential.from_config(config) model.get_layer:依据层名获取层对象 model.get_weights:返回模型权重张量的列表,类型为numpy array model.set_weights:从numpy array里面将权重载入给模型 model.to_join:返回代表模型的JSON字符串,仅仅包含网络结构,不包含权值 from models import model_from_json json_string=model.to_json() model=model_from_json(json_string) model.to_yaml,```model.to_json ````类似,同样可以产生YAML字符串重构模型 from models import model_from_yaml yaml_string = model.to_yaml() model=model_from_yaml(yaml_string) model.save_weights(filepath)将模型的权重保存到指定的路径,文件名是HDFS5 model.load_weights(filepath,by_name=False) 从HDFS中加载权重到模型中
【1】定义问题、收集数据集
处理二分类、多分类问题小tips
(1)二分类:神经网络中间层可以使用带有relu激活的Dense堆叠,网络的最后一层是只有一个单元并使用sigmoid激活的Dense层,网络输出应该是0-1范围内的标量,
表示概率值。
(2)多分类:
处理多分类问题的标签有两种方法
- 通过分类编码对标签进行编码,然后使用categorical_crossentropy损失函数
- 将标签编码为整数,然后使用sparse_categorical_crossentropy损失函数
如果需要将数据划分到许多类别中,应该避免使用太小的中间层,以免在网络中造成信息瓶颈
回归问题
回归问题使用的损失函数与分类问题不同,回归常用的损失函数是均方误差(MSE)
回归问题使用的评估指标与分类问题不同,回归常用的回归指标是平均绝对误差(MAE)
数据少时候的小tips
如果可用的数据很少,使用K折验证可以可靠地评估模型
如果可用的训练数据很少,最好使用隐藏层较少(通常只有一两个)的小型网络,以避免严重的过拟合
【2】选择衡量成功的指标
衡量成功的指标将指引你选择损失函数,即模型要优化什么
- 对于平衡分类问题(每个类别的可能性相同):使用精度和接收者操作特征曲线下面积(ROC AUC area under the receiver operatingcharacteristic curve)
- 对于类别不平衡问题:使用准确率和召回率
- 对于排序问题或多标签分类:使用平均准确率均值
【3】确定评估方法
确定评估方法
- 留出验证集:数据量大时可以采用这种方法
- K折交叉验证:如果留出验证的样本量太少,无法保证可靠性,那么选择用这种方法
- 重复的K折验证:如何可用的数据很少,同时模型评估又需要非常准确,那么应该使用这种方法
大多数情况下,第一种方法足以满足要求
评估模型的注意事项:
(1)数据代表性:数据划分为训练集和测试集之前,应该随机打乱数据;
(2)时间箭头:如果想要根据过去预测未来,那么在划分数据前不应该随机打乱数据,因为这么做会造成时间泄露:你的模型将在未来数据上得到有效训练。
在这种情况下,你应该始终确保测试集所有数据的时间都晚于训练集数据;
(3)数据冗余:如果数据中的某些数据点出现了两次,那么打乱数据并划分成训练集和验证集会导致训练集和验证集之间的冗余,
从效果上来看,你是在部分训练数据上评估模型,这很糟糕。应该确保训练集和验证集之间没有交集。
【4】准备数据
数据预处理
(1)向量化
(2)值标准化
取值较小:大部分值都应该在0-1之间
同质性:所有特征的取值范围都应该在大致相同的范围内
将每个特征分别标准化,使其平均值为0 x -= x.mean(axis=0) 2 x -= x.std(axis=0)
将每个特征分别标准化,使其标准差为1
(3)处理缺失值
在神经网络中,将缺失值设置为0是安全的,只要0不是一个有意义的值。网络能从数据中学到0意味着缺失数据,并且会忽略这个值。
如果测试数据中可能有缺失值,而网络是在没有缺失值的数据上训练的,那么网络不可能学会忽略缺失值。
在这种情况下, 你应该人为生成一些有缺失项的训练样本;多次复制一些训练样本,然后删除测试数据中可能缺失的某些特征。
【5】开发比基准更好的模型
要记住你所做的两个假设:
- 假设输出是可以根据输入进行预测的
- 假设可用的数据保护足够多的信息,足以学习输入和输出之间的关系
如果一切顺利,你还需要选择三个关键参数来构建第一个工作模型:
- 最后一层的激活:分类的例子在最后一层使用了sigmoid,回归的例子在最后一层没有使用激活
- 损失函数:二分类使用binary_crossentropy,回归的例子使用mse
- 优化配置:大多数时候,使用rmsprop及其默认的学习率是稳妥的
关于损失函数的选择,需要注意,直接优化配置成功的指标不一定总是可行的。有时,难以将指标转化为损失函数,
要知道,损失函数需要在小批量数据时即可计算(理想情况下,只有一个数据点时,损失函数也是可以计算的),
而且还必须是可微的(否则无法用反向传播来训练网络)。例如,广泛使用的分类指标ROC AUC就不能直接被优化,
因此在分类任务中,常见的做法是优化ROC AUC的替代指标,比如交叉熵。一般来说,交叉熵越小,ROC AUC越大
问题类型 | 最后一层激活 | 损失函数 |
二分类问题 | sigmoid | binary_crossentropy |
多分类、单标签问题 | softmax | categorical_crossentropy |
多分类、多标签问题 | sigmoid | binary_crossentropy |
回归到任意值 | 无 | mse |
回归到0-1范围内的值 | sigmoid | mse或binary_crossentropy |
【6】模型正则化与调节超参数
添加正则化
(1)L1 L2正则化
方式一 | 方式二 |
1 #可以用keras中下面的权重正则化来代替L2正则化
2 from keras import regularizers
3
4 regularizers.l1(0.001) #L1正则化
5 regularizers.l1_l2(l1=0.001,l2=0.001) #同时L1和L2正则化
|
1 from keras import regularizers
2
3 model = models.Sequential()
4 model.add(layers.Dense(16,activation='relu',kernel_regularizer=regularizers.l2(0.001),
|
(2)dropout正则化
训练数据 ---> layer_output *= np.random.randint(0,high=2,size=layer_output.shape)
测试数据 ---> layer_output *= 0.5
(3)尝试不同的架构:增加或减少层数
(4)尝试不同的超参数(比如每层的单元个数或优化器的学习率),以找到最佳配置
(5)反复做特征工程