1.1.2 定义网络结构
1.1.2 定义网络结构
一般认为,深度学习训练好的模型包括两部分,一个是对网络结构的描述,或者称为对网络结构的定义;另外一个是每层网络的具体参数值,这两部分加起来才是一个完整的深度学习模型。完成数据预处理后,就需要定义网络结构,或者说对我们的问题进行数学建模。
假设可以通过一条直线,把黑客和正常用户区分开,即我们认为这个二分类问题是线性问题,如图1-1所示。设特征向量为x,对应的标签为y,使用一个线性函数定义整个网络:
y=w*x+b
其中w和b就是模型的参数,训练模型的过程就是迭代求解w和b的过程,通常x是一个多维向量,所以w和b通常也是多维向量。当完成了网络的定义后,输入x就可以获得确定的y,这一过程称为前向计算过程,或者称为前向传播。面对更加复杂的问题,需要使用更加复杂的层来定义网络。定义网络时的常用层包括:dense层、activation层、dropout层、flatten层、reshape层和permute层等。
图1-1 区分正常用户和黑客的二分类问题
1. dense层
dense层是最常见的网络层,用于构建一个全连接。一个典型的全连接结构由输入、求和、激活、权重矩阵、偏置和输出组成,如图1-2所示,训练的过程就是不断获得最优的权重矩阵和偏置(bias)的过程。
图1-2 全连接结构示意图
了解了全连接的结构后,也不难理解创建dense层的几个参数了,例如:
keras.layers.core.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(激活函数)详细介绍请参见activation层的相关内容。
? use_bias表示是否使用偏置。
2. activation层
actiration层对一个层的输出施加激活函数,常见的激活函数包括以下几种。
(1)relu
relu函数当输入小于0时为0,当输入大于0时等于输入。使用代码绘制relu的图像,获得图像(见图1-3)。
def relu(x):
if x > 0:
return x
else:
return 0
def func4():
x = np.arange(-5.0, 5.0, 0.02)
y=[]
for i in x:
yi=relu(i)
y.append(yi)
plt.xlabel('x')
plt.ylabel('y relu(x)')
plt.title('relu')
plt.plot(x, y)
plt.show()
图1-3 relu函数
(2)leakyrelu
leakyrelu函数是从relu函数发展而来的,当输入小于0时为输入乘以一个很小的系数,比如0.1,当输入大于0时等于输入。使用代码绘制leakyrelu的图像,获得图像(见图1-4)。
def leakyrelu(x):
if x > 0:
return x
else:
return x*0.1
def func5():
x = np.arange(-5.0, 5.0, 0.02)
y=[]
for i in x:
yi=leakyrelu(i)
y.append(yi)
plt.xlabel('x')
plt.ylabel('y leakyrelu(x)')
plt.title('leakyrelu')
plt.plot(x, y)
plt.show()
图1-4 leakyrelu图像
(3)tanh
tanh也称为双切正切函数,取值范围为[–1,1]。tanh在特征相差明显时的效果会很好,在循环过程中会不断扩大特征效果。tanh的定义如下:
使用代码绘制tanh的图像,获得图像(见图1-5)。
x = np.arange(-5.0, 5.0, 0.02)
y=(np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
plt.xlabel('x')
plt.ylabel('y tanh(x)')
plt.title('tanh')
plt.plot(x, y)
plt.show()
图1-5 tanh图像
(4)sigmoid
sigmoid可以将一个实数映射到(0,1)的区间,可以用来做二分类。sigmoid的定义如下:
使用代码绘制sigmoid的图像,获得图像(见图1-6)。
图1-6 sigmoid图像
x = np.arange(-5.0, 5.0, 0.02)
y=1/(1+np.exp(-x))
plt.xlabel('x')
plt.ylabel('y sigmoid(x)')
plt.title('sigmoid')
plt.plot(x, y)
plt.show()
activation层可以单独使用,也可以作为其他层的参数,比如创建一个输入大小为784,节点数为32,激活函数为relu的全连接层的代码为:
model.add(dense(32, input_shape=(784,)))
model.add(activation('relu'))
等价于下列代码:
model.add(dense(32, activation='relu',input_shape=(784,)))
3. dropout层
在深度学习中,动辄几万的参数需要训练,非常容易造成过拟合,通常为了避免过拟合,会在每次训练的时候随机选择一定的节点,使它们临时失效,形象的比喻是,好比每次识别图像的时候,随机地挡住一些像素,遮挡适当比例的像素不会影响图像的识别,但是却可以比较有效地抑制过拟合。dropout层的定义如下:
keras.layers.core.dropout(rate, noise_shape=none, seed=none)
其中,常用的参数就是rate,表示临时失效的节点的比例,经验值为0.2~0.4比较合适。
4. embedding层
embedding层负责将输入的向量按照一定的规则改变维度,有点类似于word2vec的处理方式,把词可以映射到一个指定维度的向量中,其函数定义如下:
keras.layers.embedding(input_dim, output_dim,
embeddings_initializer='uniform', embeddings_regularizer=none,
activity_regularizer=none, embeddings_constraint=none, mask_zero=false,
input_length=none)
其中比较重要的参数为:
? input_dim:输入的向量的维度。
? output_dim:输出的向量的维度。
? embeddings_initializer:初始化的方式,通常使用glorot_normal或者uniform。
5. flatten层
flatten层用来将输入压平,即把多维的输入一维化。
6. permute层
permute层将输入的维度按照给定模式进行重排。一个典型场景就是在keras处理图像数据时,需要根据底层是tensorflow还是theano调整像素的顺序。在tensorflow中图像保存的顺序是(width,height,channels)而在theano中则为(channels,width,height),比如mnist图像,在tensorflow中的大小就是(28,28,1),而在theano中是(1,28,28)。示例代码如下:
if k.image_dim_ordering() == 'tf':
# (width, height, channels)
model.add(permute((2, 3, 1), input_shape=input_shape))
elif k.image_dim_ordering() == 'th':
# (channels, width, height)
model.add(permute((1, 2, 3), input_shape=input_shape))
else:
raise runtimeerror('unknown image_dim_ordering.')
7. reshape层
reshape层用于将输入shape转换为特定的shape。函数定义如下代码所示:
keras.layers.core.reshape(target_shape)
其中target_shape为希望转换成的形状,比如图片的大小为(1,28,28,1),但是网络的输入大小为(1,784)时就需要使用reshape层。
一般认为,深度学习训练好的模型包括两部分,一个是对网络结构的描述,或者称为对网络结构的定义;另外一个是每层网络的具体参数值,这两部分加起来才是一个完整的深度学习模型。完成数据预处理后,就需要定义网络结构,或者说对我们的问题进行数学建模。
假设可以通过一条直线,把黑客和正常用户区分开,即我们认为这个二分类问题是线性问题,如图1-1所示。设特征向量为x,对应的标签为y,使用一个线性函数定义整个网络:
y=w*x+b
其中w和b就是模型的参数,训练模型的过程就是迭代求解w和b的过程,通常x是一个多维向量,所以w和b通常也是多维向量。当完成了网络的定义后,输入x就可以获得确定的y,这一过程称为前向计算过程,或者称为前向传播。面对更加复杂的问题,需要使用更加复杂的层来定义网络。定义网络时的常用层包括:dense层、activation层、dropout层、flatten层、reshape层和permute层等。
图1-1 区分正常用户和黑客的二分类问题
1. dense层
dense层是最常见的网络层,用于构建一个全连接。一个典型的全连接结构由输入、求和、激活、权重矩阵、偏置和输出组成,如图1-2所示,训练的过程就是不断获得最优的权重矩阵和偏置(bias)的过程。
图1-2 全连接结构示意图
了解了全连接的结构后,也不难理解创建dense层的几个参数了,例如:
keras.layers.core.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(激活函数)详细介绍请参见activation层的相关内容。
? use_bias表示是否使用偏置。
2. activation层
actiration层对一个层的输出施加激活函数,常见的激活函数包括以下几种。
(1)relu
relu函数当输入小于0时为0,当输入大于0时等于输入。使用代码绘制relu的图像,获得图像(见图1-3)。
def relu(x):
if x > 0:
return x
else:
return 0
def func4():
x = np.arange(-5.0, 5.0, 0.02)
y=[]
for i in x:
yi=relu(i)
y.append(yi)
plt.xlabel('x')
plt.ylabel('y relu(x)')
plt.title('relu')
plt.plot(x, y)
plt.show()
图1-3 relu函数
(2)leakyrelu
leakyrelu函数是从relu函数发展而来的,当输入小于0时为输入乘以一个很小的系数,比如0.1,当输入大于0时等于输入。使用代码绘制leakyrelu的图像,获得图像(见图1-4)。
def leakyrelu(x):
if x > 0:
return x
else:
return x*0.1
def func5():
x = np.arange(-5.0, 5.0, 0.02)
y=[]
for i in x:
yi=leakyrelu(i)
y.append(yi)
plt.xlabel('x')
plt.ylabel('y leakyrelu(x)')
plt.title('leakyrelu')
plt.plot(x, y)
plt.show()
图1-4 leakyrelu图像
(3)tanh
tanh也称为双切正切函数,取值范围为[–1,1]。tanh在特征相差明显时的效果会很好,在循环过程中会不断扩大特征效果。tanh的定义如下:
使用代码绘制tanh的图像,获得图像(见图1-5)。
x = np.arange(-5.0, 5.0, 0.02)
y=(np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
plt.xlabel('x')
plt.ylabel('y tanh(x)')
plt.title('tanh')
plt.plot(x, y)
plt.show()
图1-5 tanh图像
(4)sigmoid
sigmoid可以将一个实数映射到(0,1)的区间,可以用来做二分类。sigmoid的定义如下:
使用代码绘制sigmoid的图像,获得图像(见图1-6)。
图1-6 sigmoid图像
x = np.arange(-5.0, 5.0, 0.02)
y=1/(1+np.exp(-x))
plt.xlabel('x')
plt.ylabel('y sigmoid(x)')
plt.title('sigmoid')
plt.plot(x, y)
plt.show()
activation层可以单独使用,也可以作为其他层的参数,比如创建一个输入大小为784,节点数为32,激活函数为relu的全连接层的代码为:
model.add(dense(32, input_shape=(784,)))
model.add(activation('relu'))
等价于下列代码:
model.add(dense(32, activation='relu',input_shape=(784,)))
3. dropout层
在深度学习中,动辄几万的参数需要训练,非常容易造成过拟合,通常为了避免过拟合,会在每次训练的时候随机选择一定的节点,使它们临时失效,形象的比喻是,好比每次识别图像的时候,随机地挡住一些像素,遮挡适当比例的像素不会影响图像的识别,但是却可以比较有效地抑制过拟合。dropout层的定义如下:
keras.layers.core.dropout(rate, noise_shape=none, seed=none)
其中,常用的参数就是rate,表示临时失效的节点的比例,经验值为0.2~0.4比较合适。
4. embedding层
embedding层负责将输入的向量按照一定的规则改变维度,有点类似于word2vec的处理方式,把词可以映射到一个指定维度的向量中,其函数定义如下:
keras.layers.embedding(input_dim, output_dim,
embeddings_initializer='uniform', embeddings_regularizer=none,
activity_regularizer=none, embeddings_constraint=none, mask_zero=false,
input_length=none)
其中比较重要的参数为:
? input_dim:输入的向量的维度。
? output_dim:输出的向量的维度。
? embeddings_initializer:初始化的方式,通常使用glorot_normal或者uniform。
5. flatten层
flatten层用来将输入压平,即把多维的输入一维化。
6. permute层
permute层将输入的维度按照给定模式进行重排。一个典型场景就是在keras处理图像数据时,需要根据底层是tensorflow还是theano调整像素的顺序。在tensorflow中图像保存的顺序是(width,height,channels)而在theano中则为(channels,width,height),比如mnist图像,在tensorflow中的大小就是(28,28,1),而在theano中是(1,28,28)。示例代码如下:
if k.image_dim_ordering() == 'tf':
# (width, height, channels)
model.add(permute((2, 3, 1), input_shape=input_shape))
elif k.image_dim_ordering() == 'th':
# (channels, width, height)
model.add(permute((1, 2, 3), input_shape=input_shape))
else:
raise runtimeerror('unknown image_dim_ordering.')
7. reshape层
reshape层用于将输入shape转换为特定的shape。函数定义如下代码所示:
keras.layers.core.reshape(target_shape)
其中target_shape为希望转换成的形状,比如图片的大小为(1,28,28,1),但是网络的输入大小为(1,784)时就需要使用reshape层。