Keras

Keras

keras简介

keras的模型

模型的定义

keras有两种类型的模型,序贯模型(Sequential)和函数式模型(Model),函数式模型应用更为广泛,序贯模型是函数式模型的一种特殊情况。

(a)Sequential顺序模型

单输入单输出,一条路通到底,层与层之间只有相邻关系,没有跨层连接。这种模型编译速度快,操作也比较简单

model = Sequential([
Dense(32, units=784),
Activation('relu'),
Dense(10),
Activation('softmax'),
])

也可以通过.add()方法一个个的将layer加入模型中:

# LeNet的定义示例:
def build_model():
    model = Sequential()
    model.add(Conv2D(6, (5, 5), padding='valid', activation = 'relu', kernel_initializer='he_normal', input_shape=(32,32,3)))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    model.add(Conv2D(16, (5, 5), padding='valid', activation = 'relu', kernel_initializer='he_normal'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    model.add(Flatten())
    model.add(Dense(120, activation = 'relu', kernel_initializer='he_normal'))
    model.add(Dense(84, activation = 'relu', kernel_initializer='he_normal'))
    model.add(Dense(10, activation = 'softmax', kernel_initializer='he_normal'))
    return model
(b)函数式Model类模型

多输入多输出,层与层之间任意连接。这种模型编译速度慢。
在函数式 API 中,给定一些输入张量和输出张量,可以通过以下方式实例化一个model:

# LeNet的定义示意
def build_model():
	input=Input(shape=(32,32,3))
	x = Conv2D(6, (5, 5), padding='valid', activation='relu', kernel_initializer='he_normal')(img_input)
	x = MaxPooling2D((2, 2), strides=(2, 2))(x)
	x = Conv2D(16, (5, 5), padding='valid', activation='relu', kernel_initializer='he_normal', name='conv211')(x)
	x = MaxPooling2D((2, 2), strides=(2, 2))(x)
	x = Flatten()(x)
	x = Dense(120, activation='relu', kernel_initializer='he_normal')(x)
	x = Dense(84, activation='relu', kernel_initializer='he_normal')(x)
	output = Dense(5, activation='softmax', kernel_initializer='he_normal')(x)
	model=Model(input,output)
	return model

模型的配置训练

compile配置模型

在训练模型之前,我们需要通过compile来对学习过程进行配置。compile接收三个参数:

优化器optimizer:该参数可指定为已预定义的优化器名,如rmsprop、adagrad,或一个Optimizer类的对象,详情见optimizers

损失函数loss:该参数为模型试图最小化的目标函数,它可为预定义的损失函数名,如categorical_crossentropy、mse,也可以为一个损失函数。详情见losses

指标列表metrics:对分类问题,我们一般将该列表设置为metrics=[‘accuracy’]。指标可以是一个预定义指标的名字,也可以是一个用户定制的函数.指标函数应该返回单个张量,或一个完成metric_name - > metric_value映射的字典.请参考性能评估

model.compile(optimizer='sgd',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
fit训练模型

Keras以Numpy数组作为输入数据和标签的数据类型。训练模型一般使用fit函数

model.fit(x_train, y_train,
          epochs=20,
          batch_size=128,
          validation_data)
predict模型预测

本函数按batch获得输入数据对应的输出,
函数的返回值是预测值的numpy array

model.predict(x, batch_size=32)
fit_generator

利用Python的生成器,逐个生成数据的batch并进行训练。生成器与模型将并行执行以提高效率。例如,该函数允许我们在CPU上进行实时的数据提升,同时在GPU上进行模型训练

model.fit_generator(datagen.flow(x_train,y_train,batch_size=batch_size),epochs=epochs,validation_data=(x_test,y_test))
def generate_arrays_from_file(path):
    while 1:
    f = open(path)
    for line in f:
        # create numpy arrays of input data
        # and labels, from each line in the file
        x1, x2, y = process_line(line)
        yield ({'input_1': x1, 'input_2': x2}, {'output': y})
    f.close()

model.fit_generator(generate_arrays_from_file('/my_file.txt'),
        steps_per_epoch=10000, epochs=10)

模型的保存和加载

你可以使用model.save(filepath)将Keras模型和权重保存在一个HDF5文件中,该文件将包含:

  1. 模型的结构,以便重构该模型
  2. 模型的权重
  3. 训练配置(损失函数,优化器等)
  4. 优化器的状态,以便于从上次训练中断的地方开始训练配置
from keras.models import load_model

model.save('my_model.h5')  # creates a HDF5 file 'my_model.h5'
del model  # deletes the existing model

# returns a compiled model
# identical to the previous one
model = load_model('my_model.h5')

如果需要保存模型的权重,可通过下面的代码利用HDF5进行保存。注意,在使用前需要确保你已安装了HDF5和其Python库h5py

model.save_weights('my_model_weights.h5')

如果你需要在代码中初始化一个完全相同的模型,请使用:

model.load_weights('my_model_weights.h5')

如果你需要加载权重到不同的网络结构(有些层一样)中,例如fine-tune或transfer-learning,你可以通过层名字来加载模型:

model.load_weights('my_model_weights.h5', by_name=True)

数据预处理与数据提升

keras集成数据库的引用

CIFAR10
from keras.datasets import cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
CIFAR100
from keras.datasets import cifar100
(x_train, y_train), (x_test, y_test) = cifar100.load_data(label_mode='fine')
MNIST
from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

图片生成器ImageDataGenerator

datagen = ImageDataGenerator(
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest')

参数
rotation_range是一个0~180的度数,用来指定随机选择图片的角度。
width_shiftheight_shift用来指定水平和竖直方向随机移动的程度,这是两个0~1之间的比例。
rescale值将在执行其他处理前乘到整个图像上,我们的图像在RGB通道都是0 ~ 255的整数,这样的操作可能使图像的值过高或过低,所以我们将这个值定为0~1之间的数。
shear_range是用来进行剪切变换的程度,参考剪切变换
zoom_range用来进行随机的放大
horizontal_flip随机的对图片进行水平翻转,这个参数适用于水平翻转不影响图片语义的时候
fill_mode用来指定当需要进行像素填充,如旋转,水平和竖直位移时,如何填充新出现的像素

使用.flow()的方法

model.fit_generator(datagen.flow(x_train, y_train, batch_size=32),
	epochs=epochs,validation_data=(x_test,y_test))

flow_from_directory(directory): 以文件夹路径为参数,生成经过数据提升/归一化后的数据,在一个无限循环中无限产生batch数据

train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        'data/train',
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        'data/validation',
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')

model.fit_generator(
        train_generator,
        steps_per_epoch=2000,
        epochs=50,
        validation_data=validation_generator,
        validation_steps=800)

keras的常用层

卷积层Conv2D

Conv2D(filters, kernel_size, strides=(1, 1), padding='valid',  dilation_rate=(1, 1), 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)

二维卷积层,即对图像的空域卷积。该层对二维输入进行滑动窗卷积,当使用该层作为第一层时,应提供input_shape参数。例如input_shape = (128,128,3)代表128*128的彩色RGB图像(data_format=‘channels_last’)

x = Conv2D(64, kernel_size=(3, 3), strides=(1, 1), padding='same', kernel_initializer=he_normal(),
               kernel_regularizer=regularizers.l2(weight_decay), use_bias=False)(img_input)

参数:

filters:卷积核的数目(即输出的维度)
kernel_size:单个整数或由两个整数构成的list/tuple,卷积核的宽度和长度。如为单个整数,则表示在各个空间维度的相同长度。
strides:单个整数或由两个整数构成的list/tuple,为卷积的步长。如为单个整数,则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation_rate均不兼容
padding:补0策略,为“valid”, “same”
。“valid”代表只进行有效的卷积,即对边界数据不处理。“same”代表保留边界处的卷积结果,通常会导致输出shape与输入shape相同。
activation:激活函数,为预定义的激活函数名(参考激活函数),或逐元素(element-wise)的Theano函数。如果不指定该参数,将不会使用任何激活函数(即使用线性激活函数:a(x)=x)
dilation_rate:单个整数或由两个个整数构成的list/tuple,指定dilated
convolution中的膨胀比例。任何不为1的dilation_rate均与任何不为1的strides均不兼容。
use_bias:布尔值,是否使用偏置项
kernel_initializer:权值初始化方法,为预定义初始化方法名的字符串,或用于初始化权重的初始化器。参考initializers
bias_initializer:权值初始化方法,为预定义初始化方法名的字符串,或用于初始化权重的初始化器。参考initializers
kernel_regularizer:施加在权重上的正则项,为Regularizer对象
bias_regularizer:施加在偏置向量上的正则项,为Regularizer对象
activity_regularizer:施加在输出上的正则项,为Regularizer对象
kernel_constraints:施加在权重上的约束项,为Constraints对象
bias_constraints:施加在偏置上的约束项,为Constraints对象

Dense层

Dense就是常用的全连接层,所实现的运算是output = activation(dot(input, kernel)+bias)。其中activation是逐元素计算的激活函数,kernel是本层的权值矩阵,bias为偏置向量,只有当use_bias=True才会添加。

x = Dense(120, activation='relu', kernel_initializer='he_normal')(x)

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:大于0的整数,代表该层的输出维度。
activation:激活函数,为预定义的激活函数名(参考激活函数),或逐元素(element-wise)的Theano函数。如果不指定该参数,将不会使用任何激活函数(即使用线性激活函数:a(x)=x)
use_bias: 布尔值,是否使用偏置项
kernel_initializer:权值初始化方法,为预定义初始化方法名的字符串,或用于初始化权重的初始化器。参考initializers
bias_initializer:偏置向量初始化方法,为预定义初始化方法名的字符串,或用于初始化偏置向量的初始化器。
kernel_regularizer:施加在权重上的正则项,为Regularizer对象
bias_regularizer:施加在偏置向量上的正则项,为Regularizer对象
activity_regularizer:施加在输出上的正则项,为Regularizer对象
kernel_constraints:施加在权重上的约束项,为Constraints对象
bias_constraints:施加在偏置上的约束项,为Constraints对象

Pooling层

MaxPooling2D

为空域信号施加最大值池化

x = MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding='valid')

pool_size:整数或长为2的整数tuple,代表在两个方向(竖直,水平)上的下采样因子,如取(2,2)将使图片在两个维度上均变为原长的一半。为整数意为各个维度值相同且为该数字。
strides:整数或长为2的整数tuple,或者None,步长值。
border_mode:‘valid’或者‘same’

AveragePooling2D

为空域信号施加平均值池化

x = AveragePooling2D(pool_size=(2, 2), strides=(1, 1), padding='valid')

批标准化Batch Normalization

该层在每个batch上将前一层的激活值重新规范化,即使得其输出数据的均值接近0,其标准差接近1

BatchNormalization(epsilon=1e-06, mode=0, axis=-1, momentum=0.9, weights=None, beta_init='zero', gamma_init='one')

epsilon:大于0的小浮点数,用于防止除0错误
mode:整数,指定规范化的模式,取0或1
axis:整数,指定当mode=0时规范化的轴。例如输入是形如(samples,channels,rows,cols)的4D图像张量,则应设置规范化的轴为1,意味着对每个特征图进行规范化
momentum:在按特征规范化时,计算数据的指数平均数和标准差时的动量

Activation层

激活函数可以通过设置单独的激活层实现,也可以在构造层对象时通过传递activation参数实现。

x=Activation('tanh')(x)

也可以通过传递一个逐元素运算的Theano/TensorFlow/CNTK函数来作为激活函数:

from keras import backend as K
def tanh(x):
    return K.tanh(x)
model.add(Dense(64, activation=tanh))
model.add(Activation(tanh))

预定义激活函数

softmax:对输入数据的最后一维进行softmax,输入数据应形如(nb_samples, nb_timesteps, nb_dims)(nb_samples,nb_dims)
elu
selu: 可伸缩的指数线性单元
softplus
softsign
relu
tanh
sigmoid
hard_sigmoid
linear

Dropout层

为输入数据施加Dropout。Dropout将在训练过程中每次更新参数时随机断开一定百分比(p)的输入神经元连接,Dropout层用于防止过拟合。

keras.layers.core.Dropout(p)

p:0~1的浮点数,控制需要断开的链接的比例

Flatten层

keras.layers.core.Flatten()

Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。

Merge层

Merge层提供了一系列用于融合两个层或两个张量的层对象和方法。以大写首字母开头的是Layer类,以小写字母开头的是张量的函数。小写字母开头的张量函数在内部实际上是调用了大写字母开头的层。

以两个层或两个层的输出张量相加为例,Add及add的用法:

Add
import keras

input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8, activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8, activation='relu')(input2)

Add:

added = keras.layers.Add()([x1, x2])  

add:

added = keras.layers.add([x1, x2])
Concatenate

该层接收一个列表的同shape张量,并返回它们的按照给定轴相接构成的向量。

keras.layers.Concatenate(axis=-1)

axis: 想接的轴

Dot

计算两个tensor中样本的张量乘积。例如,如果两个张量a和b的shape都为(batch_size, n),则输出为形如(batch_size,1)的张量,结果张量每个batch的数据都是a[i,:]和b[i,:]的矩阵(向量)点积。

keras.layers.Dot(axes, normalize=False)

axes: 整数或整数的tuple,执行乘法的轴。
normalize: 布尔值,是否沿执行成绩的轴做L2规范化,如果设为True,那么乘积的输出是两个样本的余弦相似性。

优化器optimizers

from keras import optimizers

sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=sgd)

可以在调用model.compile()之前初始化一个优化器对象,然后传入该函数(如上所示),也可以在调用model.compile()时传递一个预定义优化器名。在后者情形下,优化器的参数将使用默认值。

# pass optimizer by name: default parameters will be used
model.compile(loss='mean_squared_error', optimizer='sgd')

SGD

随机梯度下降法,支持动量参数,支持学习衰减率,支持Nesterov动量

keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)

lr:大或等于0的浮点数,学习率
momentum:大或等于0的浮点数,动量参数
decay:大或等于0的浮点数,每次更新后的学习率衰减值
nesterov:布尔值,确定是否使用Nesterov动量

RMSprop

除学习率可调整外,建议保持优化器的其他默认参数不变
该优化器通常是面对递归神经网络时的一个良好选择

keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-06)

lr:大或等于0的浮点数,学习率
rho:大或等于0的浮点数
epsilon:大或等于0的小浮点数,防止除0错误

Adagrad

建议保持优化器的默认参数不变

keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)

lr:大或等于0的浮点数,初始学习率
epsilon:大或等于0的小浮点数,防止除0错误

Adadelta

keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)

lr:大或等于0的浮点数,学习率
epsilon:大或等于0的小浮点数,防止除0错误
rho:大或等于0的浮点数
这里ρ是衰减系数,通过这个衰减系数,我们令每一个时刻的gt随之时间按照ρ指数衰减,这样就相当于我们仅使用离当前时刻比较近的gt信息,从而使得还很长时间之后,参数仍然可以得到更新。

Adam

keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)

lr:大或等于0的浮点数,学习率
beta_1/beta_2:浮点数, 0<beta<1,通常很接近1
epsilon:大或等于0的小浮点数,防止除0错误

目标函数objectives

目标函数,或称损失函数,是编译一个模型必须的两个参数之一:

model.compile(loss='mean_squared_error', optimizer='sgd')

可以通过传递预定义目标函数名字指定目标函数,也可以传递一个Theano/TensroFlow的符号函数作为目标函数,该函数对每个数据点应该只返回一个标量值,并以下列两个参数为参数:

y_true:真实的数据标签,Theano/TensorFlow张量

y_pred:预测值,与y_true相同shape的Theano或 TensorFlow张量

真实的优化目标函数是在各个数据点得到的损失函数值之和的均值

mean_squared_errormse
mean_absolute_errormae
mean_absolute_percentage_errormape
mean_squared_logarithmic_errormsle
squared_hinge
hinge
binary_crossentropy(亦称作对数损失,logloss)
categorical_crossentropy:亦称作多类的对数损失,注意使用该目标函数时,需要将标签转化为形如(nb_samples, nb_classes)的二值序列
sparse_categorical_crossentrop:如上,但接受稀疏标签。注意,使用该函数时仍然需要你的标签与输出值的维度相同,你可能需要在标签数据上增加一个维度:np.expand_dims(y,-1)
kullback_leibler_divergence:从预测值概率分布Q到真值概率分布P的信息增益,用以度量两个分布的差异.
poisson:即(predictions - targets * log(predictions))的均值
cosine_proximity:即预测值与真实标签的余弦距离平均值的相反数

注意: 当使用"categorical_crossentropy"作为目标函数时,标签应该为多类模式,即one-hot编码的向量,而不是单个数值. 可以使用工具中的to_categorical函数完成该转换.示例如下:

from keras.utils.np_utils import to_categorical

categorical_labels = to_categorical(int_labels, nb_classes=None)

回调函数Callback

def scheduler(epoch):
    if epoch < 40:
        return 0.1
    if epoch < 100:
        return 0.01
    if epoch < 150:
        return 0.001
    return 0.0001
class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.losses = []
    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))
        # epoch=logs.get('epoch')
        # print(logs.get('epochs'))
        print('batch'+str(batch)+'/'+'epoch'+str(count_epoch)+' = '+str(logs.get('loss')))
    def on_epoch_begin(self, epoch, logs={}):
        print('epoch'+str(epoch)+'  start to train')
        global count_epoch
        count_epoch=epoch
        return epoch
    def on_epoch_end(self, epoch, logs=None):
        vali_loss = logs.get('val_loss')
        # lossss.shape
        print('validation_loss'+' = '+str(vali_loss)+'--------'+'\n')
        vali_pic = self.validation_data
        print('\n')
        full_valid_loss.append(vali_loss)
        plt.ion()
        # plt.figure(1)
        # plt.draw()
        plt.plot(full_valid_loss,'r-')
        plt.pause(3)
        plt.close()

        gan.test_images(0)
        # logs.get('')
        # set callback
        tb_cb = TensorBoard(log_dir='./vgg19_newlog_def/', histogram_freq=0)
        change_lr = LearningRateScheduler(scheduler)
        history = LossHistory()

        cbks = [change_lr, tb_cb, history]

		model.fit(X_train, Y_train, batch_size=128, epochs=20, verbose=0, callbacks=cbks)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值