吴恩达深度学习 | (19) 卷积神经网络专项课程第二周编程作业

吴恩达深度学习专项课程的所有实验均采用iPython Notebooks实现,不熟悉的朋友可以提前使用一下Notebooks。本周的实验包括两个小实验:实验1主要介绍了一种更高级的深度学习框架Keras的一些用法,并使用Keras构建了一个简单的卷积神经网络,完成图像2分类任务,相比于Tensorflow,Keras是一种更高级别的抽象,用法相对来说更简单方便,开发效率非常高。虽然Keras具有很大的优势,但是对于某些复杂的模型,可能还是需要使用tensorflow,所以建议两种深度学习框架都要熟练掌握;实验2利用Keras搭建了一个50层的深度残差网络,一般来说深层网络会有非常严重的梯度消失问题,但是残差网络可以减缓这个问题,使网络层数可以达到100多层。本小节的实验较详细的介绍了残差网络的机制和原理,并使用Keras实现了残差网络中两种典型的构件,并最终将这些构件组合起来,搭建一个复杂的深层残差网络实现一个图像的多分类任务。残差网络作为目前最先进的卷积神经网络,效果非常突出,希望好好掌握并用到自己的实际分类任务中。

目录

一、实验1:Keras Tutorial

1.实验综述

2.导入必要的包

3.Happy House数据集

4.使用Keras构建模型

5.结论

6.用自己的图片做测试

7.Keras中的其他有用函数

8.实验1完整代码

 

二、Residual Networks(残差网络)

1.实验综述

2.导入必要的包

3.非常深的神经网络的问题

4.构建残差网络

5.使用Keras构建第一个ResNet模型(50层)

6.用自己的图像进行测试

7.实验2完整代码


一、实验1:Keras Tutorial

1.实验综述

2.导入必要的包

import numpy as np
import keras
from keras import layers
from keras.layers import Input, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D
from keras.layers import AveragePooling2D, MaxPooling2D, Dropout, GlobalMaxPooling2D, GlobalAveragePooling2D
from keras.models import Model
from keras import optimizers,losses
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras.applications.imagenet_utils import preprocess_input
import pydot
import graphviz
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
from keras.utils import plot_model
from kt_utils import *

import keras.backend as K
K.set_image_data_format('channels_last')
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow

%matplotlib inline

3.Happy House数据集

  • 载入数据集并预处理
#载入数据集
X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()

# 对数据集中的图像进行规范化
X_train = X_train_orig/255.
X_test = X_test_orig/255.

# 对标签进行转型 从行向量变为列向量(2维数组表示) 每行代表一个样本
Y_train = Y_train_orig.T
Y_test = Y_test_orig.T

print ("number of training examples = " + str(X_train.shape[0]))
print ("number of test examples = " + str(X_test.shape[0]))
print ("X_train shape: " + str(X_train.shape))
print ("Y_train shape: " + str(Y_train.shape))
print ("X_test shape: " + str(X_test.shape))
print ("Y_test shape: " + str(Y_test.shape))

4.使用Keras构建模型

# GRADED FUNCTION: HappyModel

def HappyModel(input_shape):
    """
    使用Keras实现HappyModel(构建CNN模型)
    
    Arguments:
    input_shape -- 数据集中一张输入图像的维度(height,width,channels)

    Returns:
    model -- 一个Model(),Keras 模型实例
    """
    #使用之前提到的网络架构
    X_input = Input(input_shape)
    
    X = ZeroPadding2D((3,3))(X_input)
    
    #****卷积层****
    #卷积操作
    X = Conv2D(32,(7,7),strides=(1,1),name = 'conv0')(X)
    #BN
    X = BatchNormalization(axis = 3,name = 'bn0')(X)
    #ReLU
    X = Activation('relu')(X)
    
    #池化层
    X = MaxPooling2D((2,2),name = 'max_pool')(X)
    
    #flattened
    X = Flatten()(X)
    #接一个全联接层(输出层) 2分类输出层只有一个单元 使用sigmoid激活函数
    X = Dense(1,activation='sigmoid',name = 'fc')(X)
    
    model = Model(inputs = X_input,outputs = X,name = 'Happyhouse Model')
    
    
    return model

  • 第一步 构建模型
happyModel = HappyModel((64,64,3))
  • 第二步 编译模型

 编译模型以配置训练过程. 明智地选择 compile() 的三个参数. 提示:HappyHouse问题是一个2分类问题。

happyModel.compile(optimizer=optimizers.Adam(),loss = 'binary_crossentropy',metrics=['accuracy'])
  • 第三步 训练模型

选择epochs和mini-batch size。

happyModel.fit(x = X_train,y = Y_train,epochs=20,batch_size=16)

  • 第四步 测试/验证模型
preds = happyModel.evaluate(x = X_test,y=Y_test)
print()
print ("Loss = " + str(preds[0]))
print ("Test Accuracy = " + str(preds[1]))

  • 总结

5.结论

6.用自己的图片做测试

#图像相对路径  
img_path = 'images/my_image.jpg'
#可视化图片
img = image.load_img(img_path, target_size=(64, 64))
imshow(img)

#读取图片 预处理 作为训练好的模型的输入
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x) 
#打印模型预测结果
print(happyModel.predict(x))

7.Keras中的其他有用函数

happyModel.summary()

plot_model(happyModel, to_file='HappyModel.png')
SVG(model_to_dot(happyModel).create(prog='dot', format='svg'))

8.实验1完整代码

实验1完整代码

二、Residual Networks(残差网络)

1.实验综述

2.导入必要的包

import numpy as np
#导入Keras中的内建函数
from keras import layers
from keras.layers import Input, Add, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D
from keras.models import Model, load_model
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras.applications.imagenet_utils import preprocess_input
from keras.utils.vis_utils import model_to_dot
from keras.utils import plot_model
from keras.initializers import glorot_uniform
#resnets_utils.py定义了本次实验需要的辅助函数 
from resnets_utils import *
#用于绘制模型框架
import pydot
from IPython.display import SVG
#读取和可视化图像
import scipy.misc
from matplotlib.pyplot import imshow
%matplotlib inline

import keras.backend as K
K.set_image_data_format('channels_last')
K.set_learning_phase(1)

3.非常深的神经网络的问题

4.构建残差网络

  • Identity block

# GRADED FUNCTION: identity_block

def identity_block(X, f, filters, stage, block):
    """
    实现Figure 3中所示的identity block
    
    Arguments:
    X -- 输入tensor的维度  四维数组 (m, n_H_prev, n_W_prev, n_C_prev)
    f -- 整数 ,主路径中第2个组件 卷积操作使用的filter大小
    filters -- Python整数列表,定义了各个卷积操作所使用的filters数量
    stage -- 整数,用于命名各个层,取决于他们在神经网络中的位置
    block -- 字符串/字符,s, 用于命名各个层,取决于他们在神经网络中的位置
    
    Returns:
    X -- identity block的输出  四维数组 (m, n_H, n_W, n_C)
    """
    
    # 定义块的名字
    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'
    
    # 取出3个卷积层使用的filters
    F1, F2, F3 = filters
    
    # 保存输入值 需要加到主路径3个组件的输出上
    X_shortcut = X
    
    # 主路径的第一个组件
    X = Conv2D(filters = F1, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2a', kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)
    X = Activation('relu')(X)
    

    
    # 主路径的第二个组件
    X = Conv2D(filters = F2,kernel_size = (f,f),strides=(1,1),padding='same',name = conv_name_base + '2b',kernel_initializer = glorot_uniform(seed = 0))(X)
    X = BatchNormalization(axis = 3,name = bn_name_base + '2b')(X) #axis = 3 代表channels axis
    X = Activation('relu')(X)

    # 主路径的第三个组件
    X = Conv2D(filters=F3,kernel_size=(1,1),strides=(1,1),padding='valid',name = conv_name_base+'2c',kernel_initializer=glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3,name = bn_name_base+'2c')(X)

    # 最后一步:将shortcut和三个组件的输出加起来 再通过ReLU
    X = layers.add([X,X_shortcut]) #确保2者维度相同
    X = Activation('relu')(X)
    
    
    return X
  • convolutional block

# GRADED FUNCTION: convolutional_block

def convolutional_block(X, f, filters, stage, block, s = 2):
    """
     实现 Figure 4所示的convolutional block
    
    X -- 输入tensor的维度  四维数组 (m, n_H_prev, n_W_prev, n_C_prev)
    f -- 整数 ,主路径中第2个组件 卷积操作使用的filter大小
    filters -- Python整数列表,定义了各个卷积操作所使用的filters数量
    stage -- 整数,用于命名各个层,取决于他们在神经网络中的位置
    block -- 字符串/字符,s, 用于命名各个层,取决于他们在神经网络中的位置
    s -- 整数,定义了主路径第一个卷积操作和shortcut中的卷积操作所使用的步长
    
    Returns:
    X -- convolutional block的输出  四维数组 (m, n_H, n_W, n_C)
    """
    
    # 定义块的名字
    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'
    
    # 各个卷积层的filters
    F1, F2, F3 = filters
    
    # 保存输入值
    X_shortcut = X


    ##### 主路径 #####
    # 主路径第一个组件
    X = Conv2D(F1, (1, 1), strides = (s,s), name = conv_name_base + '2a', kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)
    X = Activation('relu')(X)
    
   

    # 主路径第2个组件
    X = Conv2D(filters=F2,kernel_size=(f,f),strides=(1,1),padding='same',name = conv_name_base+'2b',kernel_initializer=glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis=3,name = bn_name_base+'2b')(X)
    X = Activation('relu')(X)

    # 主路径第3个组件
    X = Conv2D(filters=F3,kernel_size=(1,1),strides=(1,1),padding='valid',name=conv_name_base+'2c',kernel_initializer=glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis=3,name=bn_name_base+'2c')(X)

    ##### SHORTCUT PATH #### 
    X_shortcut = Conv2D(filters=F3,kernel_size=(1,1),strides=(s,s),padding='valid',name=conv_name_base+'1',kernel_initializer=glorot_uniform(seed=0))(X_shortcut)
    X_shortcut = BatchNormalization(axis=3,name=bn_name_base+'1')(X_shortcut)

    # 将shortcut和值和主路径的值加起来,然后通过ReLu激活函数
    X = layers.add([X_shortcut,X])
    X = Activation('relu')(X)
    
    
    return X

5.使用Keras构建第一个ResNet模型(50层)

# GRADED FUNCTION: ResNet50

def ResNet50(input_shape = (64, 64, 3), classes = 6):
    """
    实现上图中的50层的深度残差网络,结构如下:
    CONV2D -> BATCHNORM -> RELU -> MAXPOOL -> CONVBLOCK -> IDBLOCK*2 -> CONVBLOCK -> IDBLOCK*3
    -> CONVBLOCK -> IDBLOCK*5 -> CONVBLOCK -> IDBLOCK*2 -> AVGPOOL -> TOPLAYER

    Arguments:
    input_shape -- 数据集中一张图片的维度
    classes -- 分类类别数

    Returns:
    model -- a Model() Keras模型实例
    """
    
    # 定义输入数据的tensor(placeholder [None,64,64,3])
    X_input = Input(input_shape)

    
    # Zero-Padding
    X = ZeroPadding2D((3, 3))(X_input)
    
    # Stage 1
    X = Conv2D(64, (7, 7), strides = (2, 2), name = 'conv1', kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = 'bn_conv1')(X)
    X = Activation('relu')(X)
    X = MaxPooling2D((3, 3), strides=(2, 2))(X)

    # Stage 2
    X = convolutional_block(X, f = 3, filters = [64, 64, 256], stage = 2, block='a', s = 1)
    X = identity_block(X, 3, [64, 64, 256], stage=2, block='b')
    X = identity_block(X, 3, [64, 64, 256], stage=2, block='c')



    # Stage 3 
    X = convolutional_block(X,f=3,filters=[128,128,512],s=2,block='a',stage=3)
    X = identity_block(X,f=3,filters=[128,128,512],block='b',stage=3)
    X = identity_block(X,f=3,filters=[128,128,512],block='c',stage=3)
    X = identity_block(X,f=3,filters=[128,128,512],block='d',stage=3)

    # Stage 4 
    X = convolutional_block(X,f=3,filters=[256,256,1024],s=2,block='a',stage=4)
    X = identity_block(X,f=3,filters=[256,256,1024],block='b',stage=4)
    X = identity_block(X,f=3,filters=[256,256,1024],block='c',stage=4)
    X = identity_block(X,f=3,filters=[256,256,1024],block='d',stage=4)
    X = identity_block(X,f=3,filters=[256,256,1024],block='e',stage=4)
    X = identity_block(X,f=3,filters=[256,256,1024],block='f',stage=4)

    # Stage 5 
    X = convolutional_block(X,f=3,filters=[512,512,2048],s=2,block='a',stage=5)
    X = identity_block(X,f=3,filters=[512,512,2048],block='b',stage=5)
    X = identity_block(X,f=3,filters=[512,512,2048],block='c',stage=5)

    # AVGPOOL
    X = AveragePooling2D((2,2),name='avg_pool')(X)
    

    # output layer
    X = Flatten()(X)
    X = Dense(classes, activation='softmax', name='fc' + str(classes), kernel_initializer = glorot_uniform(seed=0))(X)
    
    
    # Create model
    model = Model(inputs = X_input, outputs = X, name='ResNet50')

    return model
  • 数据集预处理

#加载数据集
X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()

# 规范化
X_train = X_train_orig/255.
X_test = X_test_orig/255.

# 把标签转换为one-hot编码 
Y_train = convert_to_one_hot(Y_train_orig, 6).T #每一行代表一个样本的标签
Y_test = convert_to_one_hot(Y_test_orig, 6).T

print ("number of training examples = " + str(X_train.shape[0]))
print ("number of test examples = " + str(X_test.shape[0]))
print ("X_train shape: " + str(X_train.shape))
print ("Y_train shape: " + str(Y_train.shape))
print ("X_test shape: " + str(X_test.shape))
print ("Y_test shape: " + str(Y_test.shape))

至此,我们已经定义好了计算图,接下来进行Keras的四个步骤:

#第一步 创建模型
model = ResNet50(input_shape=(64,64,3),classes=6)
#第二步 编译模型
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])
#第三步 训练模型
model.fit(X_train,Y_train,epochs = 20,batch_size=32)

#第四步 查看模型在测试/开发集上的表现
preds = model.evaluate(X_test, Y_test)
print ("Loss = " + str(preds[0]))
print ("Test Accuracy = " + str(preds[1]))

6.用自己的图像进行测试

img_path = 'images/my_image.jpg'
img = image.load_img(img_path, target_size=(64, 64))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
print('Input image shape:', x.shape)
my_image = scipy.misc.imread(img_path)
imshow(my_image)
print("class prediction vector [p(0), p(1), p(2), p(3), p(4), p(5)] = ")
print(model.predict(x))
  • 查看模型各个层的细节
model.summary() #查看模型细节

  • 绘制模型架构
plot_model(model, to_file='model.png')
SVG(model_to_dot(model).create(prog='dot', format='svg'))
  • 总结

7.实验2完整代码

实验2完整代码

 

 

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值