激活函数Activations
激活函数可以通过设置单独的激活层实现,也可以在构造层对象时通过传递activation
参数实现。
from keras.layers.core import Activation, Dense
model.add(Dense(64))
model.add(Activation('tanh'))
等价于
model.add(Dense(64, activation='tanh'))
也可以通过传递一个逐元素运算的Theano/TensorFlow函数来作为激活函数:
from keras import backend as Kdef tanh(x):
return K.tanh(x)
model.add(Dense(64, activation=tanh))
model.add(Activation(tanh)
(nb_samples, nb_timesteps, nb_dims)
或(nb_samples,nb_dims)
对于简单的Theano/TensorFlow不能表达的复杂激活函数,如含有可学习参数的激活函数,可通过高级激活函数实现,如PReLU,LeakyReLU等
回调函数是一组在训练的特定阶段被调用的函数集,你可以使用回调函数来观察训练过程中网络内部的状态和统计信息。通过传递回调函数列表到模型的.fit()
中,即可在给定的训练阶段调用该函数集中的函数。
【Tips】虽然我们称之为回调“函数”,但事实上Keras的回调函数是一个类,回调函数只是习惯性称呼
keras.callbacks.CallbackList(callbacks=[], queue_length=10)
keras.callbacks.Callback()
这是回调函数的抽象类,定义新的回调函数必须继承自该类
keras.models.Model
对象,为正在训练的模型的引用回调函数以字典logs
为参数,该字典包含了一系列与当前batch或epoch相关的信息。
目前,模型的.fit()
中有下列参数会被记录到logs
中:
logs
将包含训练的正确率和误差,acc
和loss
,如果指定了验证集,还会包含验证集正确率和误差val_acc)
和val_loss
,val_acc
还额外需要在.compile
中启用metrics=['accuracy']
。logs
包含size
,即当前batch的样本数logs
包含loss
,若启用accuracy
则还包含acc
keras.callbacks.BaseLogger()
该回调函数用来对每个epoch累加metrics
指定的监视指标的epoch平均值
该回调函数在每个Keras模型中都会被自动调用
keras.callbacks.ProgbarLogger()
该回调函数用来将metrics
指定的监视指标输出到标准输出上
keras.callbacks.History()
该回调函数在Keras模型上会被自动调用,History
对象即为fit
方法的返回值
keras.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=False, mode='auto')
该回调函数将在每个epoch后保存模型到filepath
filepath
可以是格式化的字符串,里面的占位符将会被epoch
值和传入on_epoch_end
的logs
关键字所填入
例如,filename
若为```weights.{epoch:02d-{val_loss:.2f}}.hdf5,则会生成对应epoch和验证集loss的多个文件。
True
时,将只保存在验证集上性能最好的模型save_best_only=True
时决定性能最佳模型的评判准则,例如,当监测值为val_acc
时,模式应为max
,当检测值为val_loss
时,模式应为min
。在auto
模式下,评价准则由被监测值的名字自动推断。keras.callbacks.EarlyStopping(monitor='val_loss', patience=0, verbose=0, mode='auto')
当监测值不再改善时,该回调函数将中止训练
patience
个epoch后停止训练。min
模式下,如果检测值停止下降则中止训练。在max
模式下,当检测值不再上升则停止训练。keras.callbacks.RemoteMonitor(root='http://localhost:9000')
该回调函数用于向服务器发送事件流,该回调函数需要requests
库
root + '/publish/epoch/end/'
。发送方法为HTTP POST,其data
字段的数据是按JSON格式编码的事件字典。keras.callbacks.LearningRateScheduler(schedule)
该回调函数是学习率调度器
keras.callbacks.TensorBoard(log_dir='./logs', histogram_freq=0)
该回调函数是一个可视化的展示器
TensorBoard是TensorFlow提供的可视化工具,该回调函数将日志信息写入TensorBorad,使得你可以动态的观察训练和测试指标的图像以及不同层的激活值直方图。
如果已经通过pip安装了TensorFlow,我们可通过下面的命令启动TensorBoard:
tensorboard --logdir=/full_path_to_your_logs
更多的参考信息,请点击这里
我们可以通过继承keras.callbacks.Callback
编写自己的回调函数,回调函数通过类成员self.model
访问访问,该成员是模型的一个引用。
这里是一个简单的保存每个batch的loss的回调函数:
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'))
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'))
model = Sequential()
model.add(Dense(10, input_dim=784, init='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
history = LossHistory()
model.fit(X_train, Y_train, batch_size=128, nb_epoch=20, verbose=0, callbacks=[history])print history.losses# outputs'''
[0.66047596406559383, 0.3547245744908703, ..., 0.25953155204159617, 0.25901699725311789]
from keras.callbacks import ModelCheckpoint
model = Sequential()
model.add(Dense(10, input_dim=784, init='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')'''
saves the model weights after each epoch if the validation loss decreased
'''checkpointer = ModelCheckpoint(filepath="/tmp/weights.hdf5", verbose=1, save_best_only=True)
model.fit(X_train, Y_train, batch_size=128, nb_epoch=20, verbose=0, validation_data=(X_test, Y_test), callbacks=[checkpointer])
初始化方法定义了对Keras层设置初始化权重的方法
不同的层可能使用不同的关键字来传递初始化方法,一般来说指定初始化方法的关键字是init
,例如:
model.add(Dense(64, init='uniform'))
shape[0]=shape[1]
)shape[0]=shape[1]
),参考Saxe et al.指定初始化方法传入的可以是一个字符串(必须与上面某种预定义方法匹配),也可以是一个可调用的对象.如果传入可调用的对象,则该对象必须包含两个参数:shape
(待初始化的变量的shape)和name
(该变量的名字),该可调用对象必须返回一个(Keras)变量,例如K.variable()
返回的就是这种变量,下面是例子:
from keras import backend as Kimport numpy as npdef my_init(shape, name=None):
value = np.random.random(shape) return K.variable(value, name=name)
model.add(Dense(64, init=my_init))
你也可以按这种方法使用keras.initializations
中的函数:
from keras import initializationsdef my_init(shape, name=None):
return initializations.normal(shape, scale=0.01, name=name)
model.add(Dense(64, init=my_init))
正则项在优化过程中层的参数或层的激活值添加惩罚项,这些惩罚项将与损失函数一起作为网络的最终优化目标
惩罚项基于层进行惩罚,目前惩罚项的接口与层有关,但Dense, TimeDistributedDense, MaxoutDense, Covolution1D, Covolution2D
具有共同的接口。
这些层有三个关键字参数以施加正则项:
W_regularizer
:施加在权重上的正则项,为WeightRegularizer
对象b_regularizer
:施加在偏置向量上的正则项,为WeightRegularizer
对象activity_regularizer
:施加在输出上的正则项,为ActivityRegularizer
对象from keras.regularizers import l2, activity_l2
model.add(Dense(64, input_dim=64, W_regularizer=l2(0.01), activity_regularizer=activity_l2(0.01)))
keras.regularizers.WeightRegularizer(l1=0., l2=0.)
keras.regularizers.ActivityRegularizer(l1=0., l2=0.)
keras.regularizers
支持以下缩写
【Tips】正则项通常用于对模型的训练施加某种约束,L1正则项即L1范数约束,该约束会使被约束矩阵/向量更稀疏。L2正则项即L2范数约束,该约束会使被约束的矩阵/向量更平滑,因为它对脉冲型的值有很大的惩罚。【@Bigmoyan】
来自constraints
模块的函数在优化过程中为网络的参数施加约束
Dense, TimeDistributedDense, MaxoutDense, Covolution1D, Covolution2D
具有共同的接口。
这些层通过一下关键字施加约束项
W_constraint
:对主权重矩阵进行约束b_constraint
:对偏置向量进行约束from keras.constraints import maxnorm
model.add(Dense(64, W_constraint = maxnorm(2)))
Kera的应用模块Application提供了带有预训练权重的Keras模型,这些模型可以用来进行预测、特征提取和finetune
模型的预训练权重将下载到~/.keras/models/
并在载入模型时自动载入
应用于图像分类的预训练权重训练自ImageNet:
所有的这些模型都兼容Theano和Tensorflow,并会自动基于~/.keras/keras.json
的Keras的图像维度进行自动设置。例如,如果你设置image_dim_ordering=tf
,则加载的模型将按照TensorFlow的维度顺序来构造,即“Width-Height-Depth”的顺序
from keras.applications.resnet50 import ResNet50from keras.preprocessing import imagefrom keras.applications.resnet50 import preprocess_input, decode_predictions
model = ResNet50(weights='imagenet')
img_path = 'elephant.jpg'img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = model.predict(x)
print('Predicted:', decode_predictions(preds))# print: [[u'n02504458', u'African_elephant']]
from keras.applications.vgg16 import VGG16from keras.preprocessing import imagefrom keras.applications.vgg16 import preprocess_input
model = VGG16(weights='imagenet', include_top=False)
img_path = 'elephant.jpg'img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
features = model.predict(x)
from keras.applications.vgg19 import VGG19from keras.preprocessing import imagefrom keras.applications.vgg19 import preprocess_inputfrom keras.models import Model
base_model = VGG19(weights='imagenet')
model = Model(input=base_model.input, output=base_model.get_layer('block4_pool').output)
img_path = 'elephant.jpg'img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
block4_pool_features = model.predict(x)
from keras.applications.inception_v3 import InceptionV3from keras.preprocessing import imagefrom keras.models import Modelfrom keras.layers import Dense, GlobalAveragePooling2Dfrom keras import backend as K# create the base pre-trained modelbase_model = InceptionV3(weights='imagenet', include_top=False)# add a global spatial average pooling layerx = base_model.output
x = GlobalAveragePooling2D()(x)# let's add a fully-connected layerx = Dense(1024, activation='relu')(x)# and a logistic layer -- let's say we have 200 classespredictions = Dense(200, activation='softmax')(x)# this is the model we will trainmodel = Model(input=base_model.input, output=predictions)# first: train only the top layers (which were randomly initialized)# i.e. freeze all convolutional InceptionV3 layersfor layer in base_model.layers:
layer.trainable = False# compile the model (should be done *after* setting layers to non-trainable)model.compile(optimizer='rmsprop', loss='categorical_crossentropy')# train the model on the new data for a few epochsmodel.fit_generator(...)# at this point, the top layers are well trained and we can start fine-tuning# convolutional layers from inception V3. We will freeze the bottom N layers# and train the remaining top layers.# let's visualize layer names and layer indices to see how many layers# we should freeze:for i, layer in enumerate(base_model.layers):
print(i, layer.name)# we chose to train the top 2 inception blocks, i.e. we will freeze# the first 172 layers and unfreeze the rest:for layer in model.layers[:172]:
layer.trainable = Falsefor layer in model.layers[172:]:
layer.trainable = True# we need to recompile the model for these modifications to take effect# we use SGD with a low learning ratefrom keras.optimizers import SGD
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy')# we train our model again (this time fine-tuning the top 2 inception blocks# alongside the top Dense layersmodel.fit_generator(...)
from keras.applications.inception_v3 import InceptionV3from keras.layers import Input# this could also be the output a different Keras model or layerinput_tensor = Input(shape=(224, 224, 3)) # this assumes K.image_dim_ordering() == 'tf'model = InceptionV3(input_tensor=input_tensor, weights='imagenet', include_top=True)
keras.applications.vgg16.VGG16(include_top=True, weights='imagenet', input_tensor=None)
Keras 模型对象
预训练权重由牛津VGG组发布的预训练权重移植而来,基于Creative Commons Attribution License
keras.applications.vgg19.VGG19(include_top=True, weights='imagenet', input_tensor=None)
Keras 模型对象
预训练权重由牛津VGG组发布的预训练权重移植而来,基于Creative Commons Attribution License
keras.applications.resnet50.ResNet50(include_top=True, weights='imagenet', input_tensor=None)
Keras 模型对象
预训练权重由Kaiming He发布的预训练权重移植而来,基于MIT License
keras.applications.inception_v3.InceptionV3(include_top=True, weights='imagenet', input_tensor=None)
Keras 模型对象
预训练权重由我们自己训练而来,基于MIT License
该数据库具有50,000个32*32的彩色图片作为训练集,10,000个图片作为测试集。图片一共有10个类别。
from keras.datasets import cifar10
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
两个Tuple
X_train
和X_test
是形如(nb_samples, 3, 32, 32)的RGB三通道图像数据,数据类型是无符号8位整形(uint8)
Y_train
和 Y_test
是形如(nb_samples,)标签数据,标签的范围是0~9
该数据库具有50,000个32*32的彩色图片作为训练集,10,000个图片作为测试集。图片一共有100个类别,每个类别有600张图片。这100个类别又分为20个大类。
from keras.datasets import cifar100
(X_train, y_train), (X_test, y_test) = cifar100.load_data(label_mode='fine')
两个Tuple,(X_train, y_train), (X_test, y_test)
,其中
本数据库含有来自IMDB的25,000条影评,被标记为正面/负面两种评价。影评已被预处理为词下标构成的序列。方便起见,单词的下标基于它在数据集中出现的频率标定,例如整数3所编码的词为数据集中第3常出现的词。这样的组织方法使得用户可以快速完成诸如“只考虑最常出现的10,000个词,但不考虑最常出现的20个词”这样的操作
按照惯例,0不代表任何特定的词,而用来编码任何未知单词
from keras.datasets import imdb
(X_train, y_train), (X_test, y_test) = imdb.load_data(path="imdb_full.pkl",
nb_words=None,
skip_top=0,
maxlen=None,
test_split=0.1)
seed=113,
start_char=1,
oov_char=2,
index_from=3)
'~/.keras/datasets/'+path
),则载入。否则数据将下载到该目录下nb_words
或skip_top
限制而cut掉的单词将被该字符代替start_char
的特殊占位符)将从这个下标开始两个Tuple,(X_train, y_train), (X_test, y_test)
,其中
nb_words
,则序列中可能的最大下标为nb_words-1
。如果指定了maxlen
,则序列的最大可能长度为maxlen
本数据库包含来自路透社的11,228条新闻,分为了46个主题。与IMDB库一样,每条新闻被编码为一个词下标的序列。
from keras.datasets import reuters
(X_train, y_train), (X_test, y_test) = reuters.load_data(path="reuters.pkl",
nb_words=None,
skip_top=0,
maxlen=None,
test_split=0.2,
seed=113,
start_char=1,
oov_char=2,
index_from=3)
参数的含义与IMDB同名参数相同,唯一多的参数是: test_split
,用于指定从原数据中分割出作为测试集的比例。该数据库支持获取用于编码序列的词下标:
word_index = reuters.get_word_index(path="reuters_word_index.pkl")
上面代码的返回值是一个以单词为关键字,以其下标为值的字典。例如,word_index['giraffe']
的值可能为1234
数据库将会被下载到'~/.keras/datasets/'+path
本数据库有60,000个用于训练的28*28的灰度手写数字图片,10,000个测试图片
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
两个Tuple,(X_train, y_train), (X_test, y_test)
,其中
数据库将会被下载到'~/.keras/datasets/'+path