【机器学习概述】第四篇下、深度学习-补充

补充

一、关于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_sizestrides 表示为数字或元组。

在模型中将卷积层当做第一层级(出现在输入层之后)时,必须提供另一个 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;相反,我们将使用该可执行文件根据所提供的参数研究卷积层的维度如何变化。


维度.png

注意卷积层的形状是如何变化的。对应的是输出内容中的 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()

运行可看到:


池化层参数.png

用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


    alexnet.png
  • VGG


    VGG.png
  • ResNet


    ResNet.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 包括: 理解卷积神经网络 使用数据增强缓解过拟合 使用预训练卷积网络做特征提取 微调预训练网络模型 可视化卷积网络...
    七八音阅读 1,793评论 0 2
  • 理论知识: 一、Perception algorithm感知器算法,英文wiki: 感知机是生物神经细胞的简单抽象...
    喔蕾喔蕾喔蕾蕾蕾阅读 1,515评论 0 0
  • 今天和昨天一样,一觉4小时醒来3点多,我就睡不着了,起来煎了六个蛋 三条培根 6点56分,我们到了报三天拉斯维加斯...
    A盈盈一笑阅读 168评论 0 0
  • 昨天和满义聊到有位同事的爱人因病过世了,还很年轻,感觉很可惜。 他沉默了一会儿说:如果我走在你前面,刚开始你肯定也...
    三妆主阅读 255评论 0 1
  • 空中没有一片云,没有一点风,头顶上一轮烈日,所有的人都没精打采地、懒洋洋地躲在房里,吹着空调。 天气闷热得要命,一...
    D035牛牛_佛山阅读 189评论 2 10