1、通过np.loadtxt加载xls或者CSV中的数据集。不同模型不同数据类型在数据输入上有些许差异,所在往往需要自己重写数据载入。相关数据的提取可以参考:
https://blog.csdn.net/zx520113/article/details/84556489
,TensorFlow
https://blog.csdn.net/zx520113/article/details/84557459
,CSV,Keras
dataset = np.loadtxt('test.csv', delimiter=',')
#返回的数据是一个二维数组,每一维代表一个数据和标签,标签的位置放在数组开头还是结尾自己定义
x = dataset[:, 0 : n]
y = dataset[:, n]
#通过数组切分实现数据提取,n为数据长度
2、通过train_test_split实现数据随机切分,将数据随机划分为训练子集和测试子集,并返回划分好的训练集测试集样本和训练集测试集标签。
from keras.models import Sequential
from keras.layers import Dense
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import StratifiedKFold
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import train_test_split
x_train, x_validation, Y_train, Y_validation = train_test_split(x, Y, test_size=0.2, random_state=seed)
#通过利用sklearn中的train_test_split函数实现数据集分割
#train_data:被划分的样本特征集
#train_target:被划分的样本标签
#test_size:如果是浮点数,在0-1之间,表示样本占比;如果是整数的话就是样本的数量
#random_state:是随机数的种子,就是x的个数,有多长
3、基本的Model搭建,8个输入,两个隐藏层,一个隐藏层为16,与之相连接的隐藏层为8,一个输出层
# 创建模型,8个输入,两个隐藏层,一个输出层
model = Sequential()
model.add(Dense(units=16, input_dim=8, activation='relu'))#第一层隐藏元16个
model.add(Dense(units=8, activation='relu'))#第二层隐藏元8个
model.add(Dense(units=1, activation='sigmoid'))#输出层一个神经元
# 编译模型
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# 训练模型
model.fit(x=x, y=Y, epochs=150, batch_size=10)
model的建立通过model.add实现,建立好模型后,通过model.compile设置相关参数,第一个参数是损失函数;第二个岑姝是优化器选择,常用Adam;第三个参数是性能评估模。可以查看Keras中文文档:https://keras-cn.readthedocs.io/en/latest/other/metrics/。
对建立好的模型进行传参,通过model.fit实现数据输入,fit(x, y, batch_size=32, nb_epoch=10, verbose=1, callbacks=[], validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None)。其中x是输入数据;y是标签数据;batch_size梯度下降时每个batch包含的样本数; nb_epoch训练次数;verbose日志显示,0为不在标准输出流输出日志信息,1为输出进度条记录,2为每个epoch输出一行记录;callbacks回调函数;validation_split指定训练集的一定比例数据作为验证集。
为了评估模型参数,可以在fit中设置validation_split=0.2打印,或者通过scores = model.evaluate(x=x, y=y)打印分数评估模型。
如何将模型构造和训练单独构造呢?
#在这里构建一个模型,这样写可以测试不同模型谁的准确性更高
def model():
model = Sequential()
model.add(Dense(units=16, input_dim=8, activation='relu'))
model.add(Dense(units=8, activation='relu'))
model.add(Dense(units=1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
model = KerasClassifier(build_fn=model, epochs=150, batch_size=10, verbose=0)
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(model, x, y, cv=kfold)
print(results.mean())
4、随机数种子
设定随机数种子,保证结果的可重现性,通过np.random.seed(10)设置随机数种子。
5、常用的优化器:SGD、Adagrad、Adadelta、Adam、 Adamax、Nadam。
其中SGD和Adam优化器是最为常用的两种,SGD根据每个batch的数据计算一次局部的 估计,最小化代价函数。学习速率决定了每次步进的大小,因袭我们需要选择一个合适的学习率进行 调优。学习速录太大会破坏导致不收敛,速率太小收敛速度慢。因袭SGD通常训练时间更长,但是在 好的初始化和学习率调度方案的情况下,结果更可靠。Adam优化器结合了Adagrad善于处理稀疏梯度 和RMSprop善于处理非常稳定目标的优点,能够自动调整学习速率,收敛速度更快,在复杂网络中表现更优。
6、常用的激活函数:sigmoid、tanh、relu、leaky relu、elu、softmax等。
采用sigmoid激活函数计算量较大,而且sigmoid饱和区变换缓慢,求导趋近于0,导致梯度消失。 sigmoid函数的输出值恒大于0,这会导致模型训练的收敛速度变慢。 tanh它解决了zero-centered的输出问题,然而,gradient vanishing的问题和幂运算的问题仍然存在。 relu从公式上可以看出,解决了gradient vanishing问题并且计算简单更容易优化, 但是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新(Dead ReLU Problem); leaky relu有relu的所有优点,外加不会有Dead ReLU问题,但是在实际操作当中, 并没有完全证明leaky relu总是好于relu。 elu也是为解决relu存在的问题而提出,elu有relu的基本所有优点,但计算量稍大, 并且没有完全证明elu总是好于relu。
激活函数的数学表达式:sigmod、tanh、Relu以及近似Relu的一种激活函数。
7、Kears训练好模型的保存和读取
def get_model(filename='model',choosemodel='json'):
"""
载入训练好的模型json
:param filename:模型名
:return: model:返回模型
"""
if choosemodel=='json':
from keras.models import model_from_json
model = model_from_json(open(filename+'.json').read())
model.load_weights(filename+'.h5')
print("Get json model!")
return model
elif choosemodel=='yaml':
from keras.models import model_from_yaml
model=model_from_yaml(open(filename+'.yaml').read())
model.load_weights(filename+'.h5')
print("Get yaml model!")
return model
def save_model(model,filename='model',choosemodel='json'):
"""
保存训练好的模型json
:param model: 传入模型
:param filename: 保存模型名
:return: None
"""
if choosemodel=='json':
json_string = model.to_json()
open(filename+'.json','w').write(json_string)
model.save_weights(filename+'.h5', overwrite=True)
print("Save json model!")
elif choosemodel=='yaml':
yaml_string=model.to_yaml()
open(filename+'.yaml','w').write(yaml_string)
model.save_weights(filename+'.h5',overwrite=True)
print("Save yaml model!")
8、使用数据对载入的模型进行预测
使用predict进行预测,直接输入数据进行预测,会返回scores,打印出来可以查看结果。
scores=model.predict(x,batch_size=50,verbose=1)
如果是使用evaluate评估模型,需要输入测试数据和标签,返回scores,可以打印查看结果。
# 使用这种方式需要重新编译模型
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
scores = model.evaluate(x=x, y=Y, verbose=0)
print('\n%s : %.2f%%' % (model.metrics_names[1], scores[1]*100))
9、通过matplotlib绘制训练模型梯度
需要传入history,history=model.fit(),fit中的相关参数和之前的一样,historylist是history.history.keys()打印出来的数组值;图形绘制是通过matpplotlib实现,plt的相关操作可以参考:https://blog.csdn.net/zx520113/article/details/84103437
def plt_model(history,historylist=['val_loss','val_acc','loss','acc']):
"""
绘制model的相关参数,准确度和损失的训练梯度走势
:param history: 传入model.fit()
:param historylist: history.history.keys()的参数数组
:return: 绘制显示结果
"""
# print(history.history.keys())#可以通过打印查看historylist的值
from matplotlib import pyplot as plt
def pltshow(modeltest,val_modeltest):
plt.plot(history.history[modeltest])
plt.plot(history.history[val_modeltest])
plt.title('model'+modeltest)
plt.ylabel(modeltest)
plt.xlabel('epoch')
plt.legend(['train','validation'],loc='upper left')
plt.show()
historylen=len(historylist)
end=int(historylen/2)
for i in range(end):
"""绘制参数"""
pltshow(historylist[i],historylist[end+i])
#将图像保存到当前目录,保存地址也可以自己指定
plt.savefig(str(i)+'.jpg')
#清除关闭当前绘制界面,避免图像重叠
plt.close()
10、给model添加Dropout和lrate
通常神经网络中使用20%-50%的Dropout,20%是一个很好的起点,Dropout可以在模型训练中起到抗干扰作用。
model.add(Dropout(rate=0.2)),添加Dropout损失。
学习率,合适的学习率能够提高随机梯度下降算法的性能,减少训练时间。学习率决定参数移动到最优值时的速度,如果学习率过大,很有可能越过最优值;学习率过小,优化的效率低,长时间无法收敛,训练时间长。通过LearningRateScheduler回调使用预定义的回调函数来实现学习率的指数衰减。
#计算学习率
def step_decay(epoch):
"""初始学习率为0.1,每10个步长降低50%"""
from math import pow,floor
init_lrate=0.1
drop=0.5
epochs_drop=10
lrate=init_lrate*pow(drop,floor(1+epoch)/epochs_drop)
print("学习率",lrate)
return lrate
def Create_Drpoutandlrate_model(init='glorot_uniform'):
"""加入损失函数的模型"""
# 创建模型
model = Sequential()
model.add(Dense(16, input_dim=8, activation='relu',kernel_initializer=init))#第一层隐藏元12个
model.add(Dropout(rate=0.2))
model.add(Dense(8, activation='relu',kernel_initializer=init))#第二层隐藏元8个
model.add(Dropout(rate=0.2))
model.add(Dense(1, activation='softmax',kernel_initializer=init))#输出层一个神经元
#定义Dropout
sgd=SGD(lr=0.01,momentum=0.8,decay=0.0,nesterov=False)
# 编译模型
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
return model
lrate=LearningRateScheduler(step_decay)
print("**",lrate)
model=KerasClassifier(build_fn=Create_Drpoutandlrate_model,epochs=150,batch_size=5,verbose=1,callbacks=[lrate])
model.fit(x,y)
在深度学习使用中,学习率衰减通常会考虑到提高初始学习率,更大的学习率,在开始学习时会快速更新权重值,而且随着学习率的衰减可以自动调整学习率,这可以提高梯度下降的性能。使用大动量,有助于优化算法在学习率缩小到小值时,继续向正确的方向更新权重值。
更多的Keras学习可以参考Keras官方文档(中文和英文):
https://keras-cn.readthedocs.io/en/latest/
https://keras.io/