Keras 的核心数据结构是 model,一种组织网络层的方式。最简单的模型是 Sequential 顺序模型,它由多个网络层线性堆叠。顺序模型是多个网络层的线性堆叠。对于更复杂的结构,你应该使用 Keras 函数式 API,它允许构建任意的神经网络图。
from keras.models import Sequential
model = Sequential()
可以简单地使用 .add() 来堆叠模型:
from keras.layers import Dense
model.add(Dense(units=64, activation='relu', input_dim=100))
model.add(Dense(units=10, activation='softmax'))
#下面这个例子和上面的代码等价:
model.add(Dense(units=64, activation='relu', input_shape=(100,0)))
model.add(Dense(units=10, activation='softmax'))
关于input_dim的简单介绍:
在keras中,数据是以张量的形式表示的,张量的形状称之为shape,表示从最外层向量逐步到达最底层向量的降维解包过程。比如,一个一阶的张量[1,2,3]的shape是(3,);
一个二阶的张量[[1,2,3],[4,5,6]]的shape是(2,3);一个三阶的张量[[[1],[2],[3]],[[4],[5],[6]]]的shape是(2,3,1)。
input_shape就是指输入张量的shape。例如,input_dim=784,说明输入是一个784维的向量,这相当于一个一阶的张量,它的shape就是(784,)。因此,input_shape=(784,)。
input_dim = input_shape(input_dim,)
input_dim, input_length = input_shape(input_length, input_dim)
通俗来说,input_length就是输入数据的个数,比如5000组数据,Input_dim就是数据的维度。比如一条数据内容是: “人人车” , one hot编码后是 [[1 0] [1 0] [0 1]]表示 ,则 batch_size = 3, input_dim = 2.
Dense方法的简单介绍;
keras.layers.Dense(units,
activation=None,
use_bias=True,
kernel_initializer='glorot_uniform',
bias_initializer='zeros',
kernel_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
kernel_constraint=None,
bias_constraint=None)
参数说明如下:
units:表示该层有几个神经元,也即代表该层的输出维度。
activation:表示该层使用的激活函数,下面是关于常用激活函数的简介:
softmax: 在多分类中常用的激活函数,是基于逻辑回归的。
Softplus:softplus(x)=log(1+e^x),近似生物神经激活函数,最近出现的。
Relu:近似生物神经激活函数,最近出现的。
tanh:双曲正切激活函数,也是很常用的。
sigmoid:S型曲线激活函数,最常用的。
hard_sigmoid:基于S型激活函数。
linear:线性激活函数,最简单的
use_bias:表示是否添加偏置项
kernel_initializer:权重初始化方法,相当于初始化w权重。
bias_initializer:偏置值初始化方法,初始化b权重。
kernel_regularizer:权重规范化函数,施加在权重w上的正则项。
bias_regularizer:偏置值规范化方法,施加在权重b上的正则项。
activity_regularizer:输出的规范化方法,施加在输出上的正则项。
kernel_constraint:权重变化限制函数,施加在权重w上的约束项。
bias_constraint:偏置值变化限制函数,施加在偏置b上的约束项。
在完成了模型的构建后, 可以使用 .compile() 来配置学习过程,它的功能是:编译创建好的模型,网络模型搭建完后,需要对网络的学习过程进行配置,否则在调用 fit 或 evaluate 时会抛出异常。:
model.compile(loss='categorical_crossentropy',
optimizer='sgd',
metrics=['accuracy'])
compile函数的参数说明:
model.compile(loss=‘目标函数’, optimizer=optimizer, metrics=[‘accuracy’])
1.目标函数,也叫损失函数,是网络中的性能函数,它是一个模型必备的两个参数之一。
目标函数由mse、mae、mape、msle、squared_hinge、hinge、binary_crossentropy、categorical_crossentrop、sparse_categorical_crossentrop等构成,下面,详述其中的mse、mae、mape、categorical_crossentrop、sparse_categorical_crossentrop。
2.optimizer
优化器optimizer:该参数可指定为已预定义的优化器名,如rmsprop、adagrad,或一个Optimizer类的对象。
3.指标列表metrics
对分类问题,我们一般将该列表设置为metrics=[‘accuracy’]。指标可以是一个预定义指标的名字,也可以是一个用户定制的函数指标函数应该返回单个张量。
完成上述步骤之后,可以在训练数据上迭代。
# x_train 和 y_train 是 Numpy 数组 -- 就像在 Scikit-Learn API 中一样。
model.fit(x_train, y_train, epochs=5, batch_size=32)
epoch指:训练过程中当一个完整的数据集通过了神经网络一次并且返回了一次,这个过程称为一个epoch,网络会在每个epoch结束时报告关于模型学习进度的调试信息。在神经网络中传递完整的数据集一次是不够的,对于有限的数据集(是在批梯度下降情况下),使用一个迭代过程,更新权重一次或者说使用一个epoch是不够的,需要将完整的数据集在同样的神经网络中传递多次,随着epoch次数增加,神经网络中的权重的更新次数也增加,模型从欠拟合变得过拟合。
batch_size指:Keras中参数更新是按批进行的,就是小批梯度下降算法,把数据分为若干组,称为batch。一组batch数据中包含的样本数量称为batch_size。
最后,对新生成的数据进行评估或者预测:
model.predict_classes(test)预测的是类别,打印出来的值就是类别号:
predict_test = model.predict_classes(X_test).astype('int')
print(predict_test)
[1 0 0 ... 1 0 0]
[2. 1. 1. ... 2. 1. 1.]
model.evaluate
输入数据和标签,输出损失和精确度.
# 评估模型
loss,accuracy = model.evaluate(X_test,Y_test)
print('\ntest loss',loss)
print('accuracy',accuracy)
model.predict(test)预测的是概率,即是是某个类别的概率:
predict_test = model.predict(X_test)
print(predict_test[0:3])
[[9.9992561e-01 6.9890179e-05 2.3676146e-06 1.9608513e-06 2.5582506e-07]
[9.9975246e-01 2.3708738e-04 4.9365349e-06 5.2166861e-06 3.3735736e-07]
[9.9942291e-01 5.5233808e-04 8.9857504e-06 1.5617061e-05 2.4388814e-07]]
几个example:
# 对于具有 10 个类的单输入模型(多分类分类):
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 生成虚拟数据
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(10, size=(1000, 1))
# 将标签转换为分类的 one-hot 编码
one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)
# 训练模型,以 32 个样本为一个 batch 进行迭代
model.fit(data, one_hot_labels, epochs=10, batch_size=32)
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout
# 生成虚拟数据
x_train = np.random.random((1000, 20))
y_train = np.random.randint(2, size=(1000, 1))
x_test = np.random.random((100, 20))
y_test = np.random.randint(2, size=(100, 1))
model = Sequential()
model.add(Dense(64, input_dim=20, activation='relu'))
model.add(Dropout(0.5))#神经元的激活值以0.5的概率停止工作
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(x_train, y_train,
epochs=20,
batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)
补充知识:
Dropout的作用:过拟合是很多机器学习的通病。如果模型过拟合,那么得到的模型几乎不能用。为了解决过拟合问题,一般会采用模型集成的方法,即训练多个模型进行组合。此时,训练模型费时就成为一个很大的问题,不仅训练多个模型费时,测试多个模型也是很费时。Dropout可以比较有效的缓解过拟合的发生,在一定程度上达到正则化的效果。
Dropout说的简单一点就是:我们在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作,这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征,如下图所示。
当前Dropout被大量利用于全连接网络,而且一般认为设置为0.5或者0.3,而在卷积网络隐藏层中由于卷积自身的稀疏化以及稀疏化的ReLu函数的大量使用等原因,Dropout策略在卷积网络隐藏层中使用较少。总体而言,Dropout是一个超参,需要根据具体的网络、具体的应用领域进行尝试。