补充
一、关于vector的转置
numpy转置一维行变量array时:
print(features)
> array([ 0.49671415, -0.1382643 , 0.64768854])
print(features.T)
> array([ 0.49671415, -0.1382643 , 0.64768854])
print(features[:, None])
> array([[ 0.49671415],
[-0.1382643 ],
[ 0.64768854]])
numpy转置二维array时:
np.array(features, ndmin=2)
> array([[ 0.49671415, -0.1382643 , 0.64768854]])
np.array(features, ndmin=2).T
> array([[ 0.49671415],
[-0.1382643 ],
[ 0.64768854]])
二、keras
序列模型
from keras.models import Sequential
#Create the Sequential model
model = Sequential()
keras.models.Sequential 类是神经网络模型的封装容器。它会提供常见的函数,例如 fit()
、evaluate()
和 compile()
。我们将介绍这些函数(在碰到这些函数的时候)。我们开始研究模型的层吧。
层
Keras 层就像神经网络层。有全连接层、最大池化层和激活层。你可以使用模型的 add() 函数添加层。例如,简单的模型可以如下所示:
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Flatten
#创建序列模型
model = Sequential()
#第一层 - 添加有128个节点的全连接层以及32个节点的输入层
model.add(Dense(128, input_dim=32))
或者:
model.add(Flatten(input_shape=X_train.shape[1:]))
Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小
#第二层 - 添加 softmax 激活层
model.add(Activation('softmax'))
#第三层 - 添加dropout层
model.add(Dropout(0.2))
#第三层 - 添加全连接层
model.add(Dense(10))
#第四层 - 添加 Sigmoid 激活层
model.add(Activation('sigmoid'))
上面两个可以结合到一起
model.add(Dense(10, activation='sigmoid'))
Keras 将根据第一层自动推断后续所有层的形状。这意味着,你只需为第一层设置输入维度。
上面的第一层 model.add(Dense(input_dim=32)) 将维度设为 32(表示数据来自 32 维空间)。第二层级获取第一层级的输出,并将输出维度设为 128 个节点。这种将输出传递给下一层级的链继续下去,直到最后一个层级(即模型的输出)。可以看出输出维度是 10。
构建好模型后,我们就可以用以下命令对其进行编译。我们将损失函数指定为我们一直处理的 categorical_crossentropy。我们还可以指定优化程序,稍后我们将了解这一概念,暂时将使用 adam。最后,我们可以指定评估模型用到的指标。我们将使用准确率。
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics = ['accuracy'])
我们可以使用以下命令来查看模型架构:
model.summary()
然后使用以下命令对其进行拟合,指定 epoch 次数和我们希望在屏幕上显示的信息详细程度。
然后使用fit命令训练模型并通过 epoch 参数来指定训练轮数(周期),每 epoch 完成对整数据集的一次遍历。 verbose 参数可以指定显示训练过程信息类型,这里定义为 0 表示不显示信息。
model.fit(X, y, nb_epoch=1000, verbose=0)
注意:在 Keras 1 中,nb_epoch 会设置 epoch 次数,但是在 Keras 2 中,变成了 epochs。
最后,我们可以使用以下命令来评估模型:
model.evaluate()
callback回调
callback回调下有很多,比如上面所说的early stop,还有最常用的checkpoint,我们通过checkpoint来记录我们的训练过程,或者是最好的权重
from keras.callbacks import ModelCheckpoint
# train the model
checkpointer = ModelCheckpoint(filepath='mnist.model.best.hdf5',
verbose=1, save_best_only=True)
hist = model.fit(X_train, y_train, batch_size=128, epochs=10,
validation_split=0.2, callbacks=[checkpointer],
verbose=1, shuffle=True)
ModelCheckpoint checkpoint的内容以及存储地址,
filepath checkpoint 保存路径
ModelCheckpoint - verbose 日志显示,0为不在标准输出流输出日志信息,1为输出进度条记录
save_best_only 是否只存最好的权重
validation_split 验证集百分比
callbacks 回调有哪些
shuffle 打乱数据集
fit - verbose 日志显示,0为不在标准输出流输出日志信息,1为输出进度条记录,2为每个epoch输出一行记录
当然checkpoint有保存,那么自然有提取
model.load_weights()
参数内加路径即可。
Keras 中的卷积层
要在 Keras 中创建卷积层,你首先必须导入必要的模块:
from keras.layers import Conv2D
然后,你可以通过使用以下格式创建卷积层:
Conv2D(filters, kernel_size, strides, padding, activation='relu', input_shape)
参数
必须传递以下参数:
-
filters
- 过滤器数量。 -
kernel_size
- 指定(方形)卷积窗口的高和宽的数字。
你可能还需要调整其他可选参数:
-
strides
- 卷积 stride。如果不指定任何值,则strides
设为1
。 -
padding
- 选项包括'valid'
和'same'
。如果不指定任何值,则padding
设为'valid'
。same是用零填充边缘来满足strides的移动,而valid是说卷积框不超出input范围。 -
activation
- 通常为'relu'
。如果未指定任何值,则不应用任何激活函数。强烈建议你向网络中的每个卷积层添加一个 ReLU 激活函数。
注意:可以将 kernel_size
和 strides
表示为数字或元组。
在模型中将卷积层当做第一层级(出现在输入层之后)时,必须提供另一个 input_shape
参数:
-
input_shape
- 指定输入的高度、宽度和深度(按此顺序)的元组。
注意:如果卷积层不是网络的第一个层级,请勿包含 input_shape
参数。
你还可以设置很多其他元组参数,以便更改卷积层的行为。要详细了解这些参数,建议参阅官方文档。
- 示例 1*
假设我要构建一个 CNN,输入层接受的是 200 x 200 像素(对应于高 200、宽 200、深 1 的三维数组)的灰度图片。然后,假设我希望下一层级是卷积层,具有 16 个过滤器,每个宽和高分别为 2。在进行卷积操作时,我希望过滤器每次跳转 2 个像素。并且,我不希望过滤器超出图片界限之外;也就是说,我不想用 0 填充图片。要构建该卷积层,我将使用下面的代码:
Conv2D(filters=16, kernel_size=2, strides=2, activation='relu', input_shape=(200, 200, 1))
示例 2
假设我希望 CNN 的下一层级是卷积层,并将示例 1 中构建的层级作为输入。假设新层级是 32 个过滤器,每个的宽和高都是 3。在进行卷积操作时,我希望过滤器每次移动 1 个像素。我希望卷积层查看上一层级的所有区域,因此不介意过滤器在进行卷积操作时是否超过上一层级的边缘。然后,要构建此层级,我将使用以下代码:
Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')
示例 3
如果在线查看代码,经常会在 Keras 中见到以下格式的卷积层:
Conv2D(64, (2,2), activation='relu')
在这种情况下,有 64 个过滤器,每个的大小是 2x2,层级具有 ReLU 激活函数。层级中的其他参数使用默认值,因此卷积的 stride 为 1,填充设为 'valid'。
维度
和神经网络一样,我们按以下步骤在 Keras 中创建 CNN:首先创建一个序列模型。
使用 .add() 方法向该网络中添加层级。
from keras.models import Sequential
from keras.layers import Conv2D
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=2, strides=2, padding='valid',
activation='relu', input_shape=(200, 200, 1)))
model.summary()
我们不会训练该 CNN;相反,我们将使用该可执行文件根据所提供的参数研究卷积层的维度如何变化。
注意卷积层的形状是如何变化的。对应的是输出内容中的 Output Shape 下的值。在上图中,None 对应的是批次大小,卷积层的高度为 100,宽度为 100,深度为 16。
公式:卷积层中的参数数量
卷积层中的参数数量取决于 filters、kernel_size 和 input_shape 的值。我们定义几个变量:
- K - 卷积层中的过滤器数量
- F - 卷积过滤器的高度和宽度
- D_in - 上一层级的深度
注意:K = filters,F = kernel_size。类似地,D_in 是 input_shape 元组中的最后一个值。
因为每个过滤器有 FFD_in 个权重,卷积层由 K 个过滤器组成,因此卷积层中的权重总数是 KFFD_in。因为每个过滤器有 1 个偏差项,卷积层有 K 个偏差。因此,卷积层中的参数数量是 KFFD_in + K。
公式:卷积层的形状
卷积层的形状取决于 kernel_size、input_shape、padding 和 stride 的值。我们定义几个变量:
- K - 卷积层中的过滤器数量
- F - 卷积过滤器的高度和宽度
- H_in - 上一层级的高度
- W_in - 上一层级的宽度
注意:K = filters、F = kernel_size,以及S = stride。类似地,H_in 和 W_in 分别是 input_shape 元组的第一个和第二个值。
卷积层的深度始终为过滤器数量 K。
如果 padding = 'same',那么卷积层的空间维度如下:
- height = ceil(float(H_in) / float(S))
- width = ceil(float(W_in) / float(S))
如果 padding = 'valid',那么卷积层的空间维度如下:
height = ceil(float(H_in - F + 1) / float(S))
width = ceil(float(W_in - F + 1) / float(S))
Keras 中的最大池化层
要在 Keras 中创建最大池化层,你必须首先导入必要的模块:
from keras.layers import MaxPooling2D
然后使用以下格式创建卷积层:
MaxPooling2D(pool_size, strides, padding)
参数
你必须包含以下参数:
- pool_size - 指定池化窗口高度和宽度的数字。
你可能还需要调整其他可选参数:
- strides - 垂直和水平 stride。如果不指定任何值,则 strides 默认为 pool_size。
- padding - 选项包括 'valid' 和 'same'。如果不指定任何值,则 padding 设为 'valid'。
注意:可以将 pool_size 和 strides 表示为数字或元组。
示例
假设我要构建一个 CNN,并且我想通过在卷积层后面添加最大池化层,降低卷积层的维度。假设卷积层的大小是 (100, 100, 15),我希望最大池化层的大小为 (50, 50, 15)。要实现这一点,我可以在最大池化层中使用 2x2 窗口,stride 设为 2,代码如下:
MaxPooling2D(pool_size=2, strides=2)
如果你想将 stride 设为 1,但是窗口大小依然保留为 2x2,则使用以下代码:
MaxPooling2D(pool_size=2, strides=1)
检查最大池化层的维度
from keras.models import Sequential
from keras.layers import MaxPooling2D
model = Sequential()
model.add(MaxPooling2D(pool_size=2, strides=2, input_shape=(100, 100, 15)))
model.summary()
运行可看到:
用keras构建CN模型
和神经网络一样,我们通过首先创建一个序列
模型来创建一个 CNN。
from keras.models import Sequential
导入几个层,包括熟悉的神经网络层,以及在这节课学习的新的层。
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
和神经网络一样,通过使用 .add()
方法向网络中添加层级:
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=2, padding='same', activation='relu', input_shape=(32, 32, 3)))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=32, kernel_size=2, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=64, kernel_size=2, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Flatten())
model.add(Dense(500, activation='relu'))
model.add(Dense(10, activation='softmax'))
该网络以三个卷积层(后面跟着最大池化层)序列开始。前 6 个层级旨在将图片像素数组输入转换为所有空间信息都丢失、仅保留图片内容信息的数组 。然后在 CNN 的第七个层级将该数组扁平化为向量。后面跟着两个密集层,旨在进一步说明图片中的内容。最后一层针对数据集中的每个对象类别都有一个条目,并具有一个 softmax 激活函数,使其返回概率。
注意:在该视频中,你可能注意到卷积层表示为 Convolution2D
,而不是 Conv2D
。对于 Keras 2.0 来说,二者都可以,但是最好使用 Conv2D
。
注意事项
- 始终向 CNN 中的
Conv2D
层添加 ReLU 激活函数。但是网络的最后层级除外,密集
层也应该具有 ReLU 激活函数。 - 在构建分类网络时,网络中的最后层级应该是具有 softmax 激活函数的
密集
层。最后层级的节点数量应该等于数据集中的类别总数。
图像增强
具体使用方法如下,首先需要创建图像增强生成器ImageDataGenerator,随机旋转图片,移动图片,翻转图片,最后要fit我们的训练图片。
from keras.preprocessing.image import ImageDataGenerator
# create and configure augmented image generator
datagen_train = ImageDataGenerator(
width_shift_range=0.1, # randomly shift images horizontally (10% of total width)
height_shift_range=0.1, # randomly shift images vertically (10% of total height)
horizontal_flip=True) # randomly flip images horizontally
# fit augmented image generator on data
datagen_train.fit(x_train)
使用图像增强后,模型的训练也需要进行变动,
1、fit变为fit_generator,只要通过ImageDataGenerator类来生成增强图像,就一定需要将fit改为fit_generator
2、datagen_train.flow,这个flow是使数据生成器创建一批批增强图像,参数中要有训练数据,训练数据的label,和设定一批图像的数量
3、steps_per_epoch,表示每个epoch的步长,通常会设定为数据集中的样本数量除以批次大小,对应代码的话, x_train.shape[0] 对应的是训练数据集 x_train 中的独特样本数量。通过将 steps_per_epoch 设为此值,我们确保模型在每个 epoch 中看到 x_train.shape[0] 个增强图片。
from keras.callbacks import ModelCheckpoint
batch_size = 32
epochs = 100
# train the model
checkpointer = ModelCheckpoint(filepath='aug_model.weights.best.hdf5', verbose=1,
save_best_only=True)
model.fit_generator(datagen_train.flow(x_train, y_train, batch_size=batch_size),
steps_per_epoch=x_train.shape[0] // batch_size,
epochs=epochs, verbose=2, callbacks=[checkpointer],
validation_data=(x_valid, y_valid),
validation_steps=x_valid.shape[0] // batch_size)
三、突破性的CNN架构
-
AlexNet
-
VGG
-
ResNet