吴恩达卷积神经网络笔记和课后作业python实现

一、卷积神经网络介绍

(一)卷积运算以及编程语言中的卷积运算符

在这里插入图片描述
6x6图像经过3x3的过滤器转变为4x4的图像

(二)垂直边缘检测

在这里插入图片描述
4x4图像中间有段亮一点的区域,对应检测到6×6图像中间的垂直边缘。

(三)关于边缘检测的更多内容

从亮到暗或从暗到亮的过渡带

在这里插入图片描述
垂直边缘检测和水平边缘检测
在这里插入图片描述
其他类型的过滤器
在这里插入图片描述

(四)padding

1.为何padding

padding的原因:
原本图像经过过滤器放缩(一层一层),变的越来越小,图像变小是一个原因,另一个原因是原本图像边缘信息损失。
n x n图像经过f x f过滤器转化为(n-f+1) x (n-f+1)图像
选择填充的步数p=padding
在这里插入图片描述

2.基于padding的两种常用卷积

Valid:不填充,即p=0
Same:填充的步数使得输入大小和输出大小相同
( n + 2 p − f + 1 ) (n+2p-f+1) (n+2pf+1) X ( n + 2 p − f + 1 ) = n (n+2p-f+1)=n (n+2pf+1)=n X n n n
得到 p = f − 1 2 p=\frac{f-1}{2} p=2f1
因此卷积核 f f f通常为奇数
在这里插入图片描述

(五)步长stride

在这里插入图片描述
给定n,f,p,s,计算输出图像大小
在这里插入图片描述
数学中的卷积和神经网络中的卷积不一样
数学中的卷积需要对过滤器顺时针旋转90度再镜像
神经网络中不需要这项操作
在这里插入图片描述

(六)三维卷积

6 x 6 x 1是指灰色图像
6 x 6 x 3是指彩色图像,3是通道数
在这里插入图片描述
三维卷积的计算
输入图像的通道数必须和过滤器的通道数保持一致。
过滤器的参数不同,得到不同的检测器。
在这里插入图片描述
如果同时想检测多个特征,比如既想检测垂直边缘特征,又想检测水平边缘特征,则可以使用多个滤波器。最后输出图像的通道数即是使用滤波器的个数。
在这里插入图片描述

(七)单层卷积网络

在这里插入图片描述
某一层卷积网络的工作原理
在这里插入图片描述

(八)简单卷积网络示例

在这里插入图片描述
卷积神经网络中常见的层
卷积层、池化层、 全连接层
在这里插入图片描述

(九)池化层

池化层的用处:缩减模型的大小,提高计算速度,同时提高提取特征的鲁棒性。
不需要用梯度下降学习参数,因为进行的是固定的运算。

对每个通道进行最大池化
在这里插入图片描述
平均池化
在神经网络中,最大池化要比平均池化用的多,但是在深度很深的神经网络中,会用到平均池化。
在这里插入图片描述
f=2,s=2表示输出图像的高和宽是输入图像的高和宽的一半,比较常用。
不需要学习参数,只要设置超级参数。
在这里插入图片描述

(十)全连接层(fully connected layer)

全连接层和普通神经网络是一样的

(十一)卷积网络示例

池化层不含参数W和b,所以不单独记为一层,而是和卷积层共同看作一层。
在这里插入图片描述
激活函数值下降的很快的话,会影响神经网络的性能。
在这里插入图片描述

(十一)为什么使用卷积神经网络

相比全连接层,卷积神经网络的两个特点
参数共享
连接稀疏

在这里插入图片描述

在这里插入图片描述

二、代码实现

这里使用的是keras

(一)导入数据集

import h5py

train_dataset=h5py.File('/Users/renjianmei/Downloads/深度学习/未命名文件夹/第三周/datasets/train_signs.h5', "r")
test_dataset = h5py.File('/Users/renjianmei/Downloads/深度学习/未命名文件夹/第三周/datasets/test_signs.h5', "r")

在这里插入图片描述
导入的h5py文件属于字典形式

(二)数据预处理

1.对X进行归一化处理

train_set_x=train_dataset['train_set_x'][:]
train_set_y=train_dataset['train_set_y'][:]
classes1=train_dataset['list_classes'][:]

test_set_x = test_dataset["test_set_x"][:]
test_set_y = test_dataset["test_set_y"][:]

#classes2 = test_dataset["list_classes"][:]     

对于图像数据,通常除以255进行归一化处理。

train_x=train_set_x/255
test_x=test_set_x/255

查看数据维度
在这里插入图片描述

train_y=train_set_y.reshape(train_set_y.shape[0],-1)
test_y=test_set_y.reshape(test_set_y.shape[0],-1)

在这里插入图片描述
在这里插入图片描述

(三)one_hot函数

def convert_to_one_hot(Y, C):
    """
    Y————标签变量,维度为(m,1)其中m为样本量
    C————类别数
    返回 Y————维度为(m,C)
    """
    Y = np.eye(C)[Y.reshape(-1)]
    
    return Y

1.对y进行ONE-HOT处理

train_y=convert_to_one_hot(train_y, len(classes1))
test_y=convert_to_one_hot(test_y,len(classes1) )

在这里插入图片描述

(四)keras构建卷积框架

Keras中文文档
Tensorflow官网

1.keras.models.Sequential()

是一个容器,描述了神经网络的网络结构,在Sequential()中的输入参数描述了从输入层到输出层的网络结构。输入参数即可直接写在Sequential()中,也可通过add()添加。通常为了便于读懂代码,使用add()来添加参数

import tensorflow as tf
from tensorflow import keras
model = keras.models.Sequential()   #描述各层网络  

2.model.add()

添加卷积层、池化层、全连接层

(1)卷积层keras.layers.Conv2D

卷积层过滤器的维度(高度,宽度,通道数,过滤器数)
这里指定为(3,3,n_c,32),n_c与输入层的通道数相同

model.add(keras.layers.Conv2D(filters=32,kernel_size=3,padding='same',activation='relu',input_shape=(64,64,3)))
    
    #filters: 卷积核(就是过滤器)的数目
    #kernel_size:过滤器的大小,即卷积核(过滤器)的高度和宽度,单个整数或由两个整数构成的list/tuple
    #strides: 卷积步长, 默认为 1
    #padding: 卷积如何处理边缘。补0策略,选项包括 ‘valid’ 和 ‘same’。默认为 ‘valid’。"valid"不填充
    #activation: 激活函数,通常设为 relu
    #input_shape: 指定输入层的高度,宽度和深度的元组(高度,宽度,通信数)

(2)最大池化层keras.layers.MaxPool2D()

最大池化层(2,2,n_c),n_c与输入层的通道数相同

model.add(keras.layers.MaxPool2D(pool_size=32,padding='same'))
    #pool_size:用于指定池窗口的大小.2个整数的元组/列表:(pool_height,pool_width),可以是单个整数,以指定所有空间维度的值相同.
    #strides:用于指定池操作的步幅
    #padding:一个字符串,表示填充方法,“valid”或“same”.
    #data_format:一个字符串,表示输入维度的顺序.支持channels_last(默认)和channels_first;
#channels_last对应于具有形状(batch, height, width, channels)的输入,而channels_first对应于具有形状(batch, channels, height, width)的输入.
    

(3)卷积层keras.layers.Conv2D

这里指定为(3,3,n_c,64),n_c与输入层的通道数相同

model.add(keras.layers.Conv2D(filters=64,kernel_size=3,padding='same',activation='relu'))

(4)最大池化层keras.layers.MaxPool2D()

最大池化层(2,2,n_c),n_c与输入层的通道数相同

model.add(keras.layers.MaxPool2D(pool_size=2))

(5)一维化keras.layers.Flatten()

model.add(keras.layers.Flatten())
    #用于将输入层的数据压成一维的数据,一般用在卷积层和全连接层之间,因为全连接层只能接收一维数据,卷积层可以处理二维数据
    #(m,n_h,n_w,n_c)------( m, n_h*n_w*n_c) 

(6)全连接层keras.layers.Dense()

 model.add(keras.layers.Dense(6,activation='softmax'))
    #输出大小:(batch_size, units)
"""
keras.layers.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: 正整数,输出空间维度。
    #activation:激活函数.如果不指定该参数,将不会使用任何激活函数(即使用线性激活函数:a(x)=x)
    #use_bias: 布尔值,该层是否使用偏置向量
    #kernel_initializer: kernel 权值矩阵的初始化器。
    #bias_initializer: 偏置向量的初始化器。
"""

output = activation(dot(input, kernel) + bias)
activation 是按逐个元素计算的激活函数
kernel 是由网络层创建的权值矩阵
bias 是其创建的偏置向量 (只在 use_bias 为 True 时才有用)。

3.模型编译model.compile()

model.compile()方法用于在配置训练方法时,告知训练时用的优化器、损失函数和准确率评测标准

model.compile(optimizer='Adam',
                  loss='mse',
                  metrics = ['categorical_accuracy'])

4.model.summary()

model.summary()输出模型各层的参数状况

 model.summary()

5.model.fit()

history = model.fit(x=X_train,y=Y_train,batch_size=64,epochs=num_epochs)
    # validation_split=0.0, #:浮点数0-1之间,用作验证集的训练数据的比例。模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。
    #  validation_data=None, #这个参数会覆盖 validation_split,即两个函数只能存在一个,它的输入为元组 (x_val,y_val),这作为验证数据。
     #  shuffle=True, #布尔值。是否在每轮迭代之前混洗数据

    #batch_size:整数,每次梯度更新的样本数。未指定,默认为32
    #epochs:整数,训练模型迭代次数
    #verbose:日志展示,整数,0:为不在标准输出流输出日志信息;1:显示进度条;2:每个epoch输出一行记录
    

6.model.evaluate()

score = model.evaluate(x=X_test,y=Y_test)
model.save('model.h5')
#model.save()保存了模型的图结构和模型的参数,保存模型的后缀是.hdf5  

综上代码为
输入数据(m,64,64,3) → p a d d i n g = ′ s a m e ′ 卷 积 层 ( 3 , 3 , 3 , 32 ) \xrightarrow[padding='same']{卷积层(3,3,3,32)} (3,3,3,32) padding=same(m,64,64,32) → 池 化 层 ( 2 , 2 , 32 ) \xrightarrow{池化层(2,2,32)} (2,2,32) (m,32,32,32) → p a d d i n g = ′ s a m e ′ 卷 积 层 ( 3 , 3 , 32 , 64 ) \xrightarrow[padding='same']{卷积层(3,3,32,64)} (3,3,32,64) padding=same(m,32,32,64) → 池 化 层 ( 2 , 2 , 32 ) \xrightarrow{池化层(2,2,32)} (2,2,32) (m,16,16,64) → 一 维 化 \xrightarrow{一维化} (m,16*16*64) → 全 连 接 层 \xrightarrow{全连接层} (m,6)$

model = keras.models.Sequential()   #描述各层网络


#1.卷积层(3,3,n_c,32),n_c与输入层的通道数相同
model.add(keras.layers.Conv2D(filters=32,kernel_size=3,padding='same',activation='relu',input_shape=(64,64,3)))


#2.最大池化层(2,2,n_c),n_c与输入层的通道数相同
model.add(keras.layers.MaxPool2D(pool_size=2))

#3.卷积层(3,3,n_c,64)
model.add(keras.layers.Conv2D(filters=64,kernel_size=3,padding='same',activation='relu'))

#4.池化层(2,2,n_c)
model.add(keras.layers.MaxPool2D(pool_size=2))

#5.
model.add(keras.layers.Flatten())
#(m,n_h,n_w,n_c)------( m, n_h*n_w*n_c)

#6.全连接层
model.add(keras.layers.Dense(6,activation='softmax'))
#输出大小:(batch_size, units)

model.compile(optimizer='Adam',
              loss='mse',
              metrics = ['categorical_accuracy'])

model.summary()


history = model.fit(x=train_x,y=train_y,batch_size=64,epochs=100)

score = model.evaluate(x=test_x,y=test_y)

model.save('model.h5')
#model.save()保存了模型的图结构和模型的参数,保存模型的后缀是.hdf5

输出结果为
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

print('测试集损失值:',str(score[0]*100)[:4]+'%')
print('测试集准确率:',str(score[1]*100)[:4]+'%')

在这里插入图片描述

在这里插入图片描述

plt.plot(np.squeeze(history.history['loss']))
plt.ylabel('loss')
plt.xlabel('iterations (per tens)')
plt.show()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值