Professional Documents
Culture Documents
经典卷积神经网络(上)
学习目标 狗熊会 | 深度学习入门
1 . LeNet-5 的网络结构及其代码实现;
2 . AlexNet 的网络结构及其代码实现;
3 . VGG 的网络结构及其代码实现;
4 . Batch Normalization 的原理与应用技巧;
5 . Data Augmentation 的原理与应用技巧。
狗熊会|聚数据英才,助产业振兴
PART 8.1
LeNet-5
狗熊会|聚数据英才,助产业振兴
8.1.1 LeNet-5 网络结构 狗熊会 | 深度学习入门
LeNet-5 介绍:
由 Yann LeCun (杨立昆)于 1998 年提出的一种经典的卷积网络结构。
第一个成功应用于数字识别问题的卷积神经网络。
LeNet-5 网络结构:共 7 层
输入层
卷积层
池化层
卷积层
池化层
全连接层
输出层
狗熊会|聚数据英才,助产业振兴
8.1.2 案例: LeNet-5 手写数字识 狗熊会 | 深度学习入门
别
MNIST 数据集展示: mnist.load_data() 加载数据集
数据预处理 输出:
(60000, 28,
LeNet-5 代码实现
28)
LeNet-5 编译运行
from Keras.datasets import mnist
(X0,Y0),(X1,Y1) =
mnist.load_data()
print(X0.shape)
from matplotlib import pyplot as
plt
plt.figure()
fig,ax = plt.subplots(2,5)
ax=ax.flatten()
for i in range(10):
Im=X0[Y0==i][0]
ax[i].imshow(Im)
plt.show();
狗熊会|聚数据英才,助产业振兴
8.1.2 案例: LeNet-5from
手写数字识
Keras.utils import 狗熊会 | 深度学习入门
别
np_utils
N0=X0.shape[0];N1=X1.shape[0]
MNIST 数据集展示 print([N0,N1])
X0 =
数据预处理 X0.reshape(N0,28,28,1)/255
X1 =
LeNet-5 代码实现 X1.reshape(N1,28,28,1)/255
YY0 =
LeNet-5 编译运行
np_utils.to_categorical(Y0)
YY1 =
np_utils.to_categorical(Y1)
print(YY1)
输出:
[60000, 10000]
[[0 0 0 ... 1 0 0]
[0 0 1 ... 0 0 0]
[0 1 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]]
狗熊会|聚数据英才,助产业振兴
8.1.2 案例: LeNet-5 手写数字识 狗熊会 | 深度学习入门
别
MNIST 数据集展示
from Keras.layers import
数据预处理 Conv2D,Dense,Flatten,Input,MaxPooling2D
LeNet-5 代码实现 from Keras import Model
狗熊会|聚数据英才,助产业振兴
8.1.2 案例: LeNet-5 手写数字识 狗熊会 | 深度学习入门
别 输出维度 参数个数
MNIST 数据集展示
数据预处理 输入层
LeNet-5 代码实现 卷积层
模型结构展示 1
池化层
LeNet-5 编译运行 1
卷积层
池化层2
2
拉直操作
全连接层 1
全连接层 2
全连接层 3
狗熊会|聚数据英才,助产业振兴
8.1.2 案例: LeNet-5 手写数字识 狗熊会 | 深度学习入门
别
MNIST 数据集展示
数据预处理
LeNet-5 代码实现
LeNet-5 编译运行
通过 model.compile 实现
model.compile(loss='categorical_crossentropy', optimizer='adam',
metrics=['accuracy'])
model.fit(X0, YY0, epochs=10, batch_size=200, validation_data=[X1,YY1])
狗熊会|聚数据英才,助产业振兴
Input X 卷积计算 激活 池化 卷积计算 激活 池化
𝑒𝑥𝑝 ( 𝑥𝑘 )
𝑦 𝑘=
∑ 𝑒𝑥𝑝( 𝑥 𝑘)
𝑘
x
y=
def softmax(x) def cross_entropy_error(y,t)
交叉熵 exp_x=np.exp(x) delta=1e-7
t= sum_exp_x=np.sum(exp_x) return -
y=exp_x/sum_exp_x np.sum(t*np.log(y+delta))
L=- return y
真值 t
Input X 卷积计算 激活 池化 卷积计算 激活 池化
反向传播
交叉熵
正向传播
真值 t
Input X 卷积计算 激活 池化 卷积计算 激活 池化
𝑒𝑥𝑝 ( 𝑥𝑘 )
𝑦 𝑘=
∑ 𝑒𝑥𝑝( 𝑥 𝑘)
𝑘
x
𝜕𝐿
y= =1 𝜕 𝐿 . 𝜕 𝐿 ={ 𝜕 𝐿 } class SoftmaxWithLoss:
𝜕𝐿 𝜕 𝑋 𝜕 𝐿 𝜕𝑥 𝑗 def __init__(self):
损失 - 交叉 self.loss=None
𝜕𝐿 𝜕𝐿
t= 熵 𝑑𝑜𝑢𝑡 ={ } self.y=None
𝜕 𝑋 𝜕𝑥𝑗 self.t=None
L=-
真值 t def forward(self,x,t):
self.t=t
self.y=softmax(x)
def softmax(x): self.loss=cross_entropy_error(self.y,self.t)
exp_x=np.exp(x) return self.loss
sum_exp_x=np.sum(exp_x)
y=exp_x/sum_exp_x def backward(self,dout=1):
return y batch_size=self.t.shape[0]
dx=(self.y-self.t)/batch_size
def cross_entropy_error(y,t):
delta=1e-7 return dx
return -np.sum(t*np.log(y+delta))
Input X 卷积计算 激活 池化 卷积计算 激活 池化
𝑒𝑥𝑝 ( 𝑥𝑘 )
𝑦 𝑘=
∑ 𝑒𝑥𝑝( 𝑥 𝑘)
𝑘
x XX
Output y 激活 仿射变换 激活 仿射变换 激活 仿射变换
y=
𝜕𝐿
=1
𝜕𝐿 𝜕𝐿 𝜕𝐿 𝜕 𝑋
损失 - 交叉 = .
熵
𝜕 𝑋𝑋 𝜕 𝑋 𝜕 𝑋𝑋
t=
𝜕𝐿 𝜕𝐿 𝜕 𝑋
L=- = .
真值 t 𝜕𝑊 𝜕 𝑋 𝜕𝑊
𝜕𝐿 𝜕𝐿 𝜕𝐿 𝜕𝐿 𝜕𝐿 𝜕𝑋 X=W.XX+B
. ={ } = . W .XX
𝜕 𝑋 𝜕 𝐿 𝜕𝑥 𝑗 𝜕𝐵 𝜕 𝑋 𝜕𝐵
XX x
𝑑𝑜𝑢𝑡
𝜕𝐿
={
𝜕𝐿
}
𝜕𝐿
=𝑑𝑜𝑢𝑡 .
𝜕𝑋
W
DOT
仿射变换
+
𝜕 𝑋 𝜕𝑥𝑗 𝜕 𝑋𝑋 𝜕 𝑋𝑋
𝜕𝐿 𝜕𝑋
=𝑑𝑜𝑢𝑡 . B
𝜕𝑊 𝜕𝑊
𝜕𝐿 𝜕𝑋
=𝑑𝑜𝑢𝑡 .
𝜕𝐵 𝜕𝐵
𝜕𝐿 𝜕𝐿 𝜕 𝑋 𝜕𝐿 𝜕𝑋
= . =𝑑𝑜𝑢𝑡 .
X=W.XX+B 𝜕 𝑋𝑋 𝜕 𝑋 𝜕 𝑋𝑋 𝜕 𝑋𝑋 𝜕 𝑋𝑋
XX
W .XX 𝜕𝐿 𝜕𝐿 𝜕 𝑋 𝜕𝐿 𝜕𝑋
= . =𝑑𝑜𝑢𝑡 .
W
DOT
仿射变换
+ 𝜕𝑊
𝜕𝐿
=
𝜕 𝑋 𝜕𝑊
𝜕𝐿 𝜕𝑋
.
𝜕𝑊
𝜕𝐿
=𝑑𝑜𝑢𝑡 .
𝜕𝑊
𝜕𝑋
𝜕𝐵 𝜕 𝑋 𝜕𝐵 𝜕𝐵 𝜕𝐵
B 𝜕𝐿 𝜕𝐿 𝜕 𝑋
= . =𝑊 ‘
𝜕 𝑋𝑋 𝜕 𝑋 𝜕 𝑋𝑋
𝜕𝐿 𝜕𝐿 𝜕 𝑋 𝜕𝐿
= . = 𝑋𝑋 ’ .
𝜕𝑊 𝜕 𝑋 𝜕𝑊 𝜕𝑋
𝜕𝐿 𝜕𝐿 𝜕𝑋
= .
𝜕𝐵 𝜕 𝑋 𝜕𝐵
class Affine:
def __init__(self,w,b):
self.w=w
self.b=b
self.xx=None
self.dw=None
self.db=None
def forward(self,xx,t):
self.xx=xx
out=np.dot(xx,self.w)+self.b
return out
def backward(self,dout):
dxx=np.dot(dout,self.w.T)
self.dw=np.dot(self.xx.T,dout)
self.db=np.sum(dout,axis=0)
return dxx
W .XX X=W.XX+B
XX
W
DOT +
B
𝜕𝐿 𝜕𝐿 𝜕 𝑋 𝜕𝐿 𝜕𝑋 𝜕𝐿 𝜕𝐿 𝜕 𝑋
= . =𝑑𝑜𝑢𝑡 . = . =𝑊 ‘
𝜕 𝑋𝑋 𝜕 𝑋 𝜕 𝑋𝑋 𝜕 𝑋𝑋 𝜕 𝑋𝑋 𝜕 𝑋𝑋 𝜕 𝑋 𝜕 𝑋𝑋
𝜕𝐿 𝜕𝐿 𝜕 𝑋 𝜕𝐿 𝜕𝑋 𝜕𝐿 𝜕𝐿 𝜕 𝑋 𝜕𝐿
= . =𝑑𝑜𝑢𝑡 . = . = 𝑋𝑋 ’ .
𝜕𝑊 𝜕 𝑋 𝜕𝑊 𝜕𝑊 𝜕𝑊 𝜕𝑊 𝜕 𝑋 𝜕𝑊 𝜕𝑋
𝜕𝐿 𝜕𝐿 𝜕𝑋 𝜕𝐿 𝜕𝑋 𝜕𝐿 𝜕𝐿 𝜕𝑋
= . =𝑑𝑜𝑢𝑡 . = .
𝜕𝐵 𝜕 𝑋 𝜕𝐵 𝜕𝐵 𝜕𝐵 𝜕𝐵 𝜕 𝑋 𝜕𝐵
Input X 卷积计算 激活 池化 卷积计算 激活 池化
𝑒𝑥𝑝 ( 𝑥𝑘 )
𝑦 𝑘=
∑ 𝑒𝑥𝑝( 𝑥 𝑘) x
𝑘
𝜕𝐿 𝜕𝐿 𝜕𝐿 𝜕𝐿 class Affine:
y= =1 𝜕 𝑋 . 𝜕 𝐿 ={ 𝜕𝑥 }class SoftmaxWithLoss: def __init__(self,w,b):
𝜕𝐿 𝑗 def __init__(self):
self.w=w
损失 - 交叉 self.loss=None
self.b=b
t= 熵 self.y=None
self.xx=None
self.t=None
L=- self.dw=None
真值 t def forward(self,x,t):
self.db=None
self.t=t
def forward(self,xx,t):
self.y=softmax(x)
self.xx=xx
def softmax(x): out=np.dot(xx,self.w)+self.b
exp_x=np.exp(x) self.loss=cross_entropy_error(self.y,self.t)
sum_exp_x=np.sum(exp_x) return self.loss return out
y=exp_x/sum_exp_x def backward(self,dout=1): def backward(self,dout):
return y dxx=np.dot(dout,self.w.T)
batch_size=self.t.shape[0]
def cross_entropy_error(y,t): dx=(self.y-self.t)/batch_size self.dw=np.dot(self.xx.T,dout)
delta=1e-7 return dx self.db=np.sum(dout,axis=0)
return -np.sum(t*np.log(y+delta)) return dxx
方法 __init__() 是一个特殊的方法,包含?个形参 。在这个方法的定义中,
形参 self 必不可少,还必须位于其他形参的前面。因为 Python 调用这个
__init__() 方法来创建 实例时,将自动传入实参 self 。每个与类相关联的
方法调用都自动传递实参 self ,它是一个指向实例本身 的引用,让实例能
够访问类中的属性和方法。
class Lenet5:
def __init__(self, input_dim=(1, 32, 32),
conv_param={'filter_num1':6, 'filter_size1':3,'filter_num2':16, 'filter_size2':3, 'pad':1, 'stride':1},
hidden_size1=120,hidden_size2=84, output_size=10, weight_init_std=0.01):
filter_num1 = conv_param['filter_num1']
filter_size1 = conv_param['filter_size1']
filter_num2 = conv_param['filter_num2']
filter_size2 = conv_param['filter_size2']
filter_pad = conv_param['pad']
filter_stride = conv_param['stride']
input_size = input_dim[1]
conv_output_size1 = (input_size - filter_size1 + 2*filter_pad) / filter_stride + 1
pool_output_size1 = (conv_output_size1 - 2) / 2 + 1
conv_output_size2 = (pool_output_size1 - filter_size2 + 2*filter_pad) / filter_stride + 1
pool_output_size2 = int((((conv_output_size2 - 2) / 2 + 1)**2)*filte r_num2)
self.params = {}
self.params['W1'] = weight_init_std * np.random.randn(filter_num1, input_dim[0], filter_size1, filter_size1)
self.params['b1'] = np.zeros(filter_num1)
self.params['W2'] = weight_init_std * np.random.randn(filter_num2, filter_num1, filter_size2, filter_size2)
self.params['b2'] = np.zeros(filter_num2)
self.params['W3'] = weight_init_std *np.random.randn(pool_output_size2, hidden_size1)
self.params['b3'] = np.zeros(hidden_size1)
self.params['W4'] = weight_init_std * np.random.randn(hidden_size1, hidden_size2)
self.params['b4'] = np.zeros(hidden_size2)
self.params['W5'] = weight_init_std * np.random.randn(hidden_size2, output_size)
self.params['b5'] = np.zeros(output_size)
self.layers = OrderedDict()
self.layers['Conv1'] = common.Convolution(self.params['W1'], self.params['b1'],conv_param['stride'], conv_param['pad'])
self.layers['Relu1'] = common.Relu()
self.layers['Pool1'] = common.MaxPooling(pool_h=2, pool_w=2, stride=2)
self.layers['Conv2'] = common.Convolution(self.params['W2'], self.params['b2'],conv_param['stride'], conv_param['pad'])
self.layers['Relu2'] = common.Relu()
self.layers['Pool2'] = common.MaxPooling(pool_h=2, pool_w=2, stride=2)
self.layers['Affine1'] = common.Affine(self.params['W3'], self.params['b3'])
self.layers['Relu3'] = common.Relu()
self.layers['Affine2'] = common.Affine(self.params['W4'], self.params['b4'])
self.layers['Relu4'] = common.Relu()
self.layers['Affine3'] = common.Affine(self.params['W5'], self.params['b5'])
self.last_layer = common.SoftmaxWithCrossEntropy()
def predict(self, x): def accuracy(self, x, t, batch_size=100):
for layer in self.layers.values(): # 从独热编码转回数字编码
x = layer.forward(x) if t.ndim != 1 : t = np.argmax(t, axis=1)
return x acc = 0.0
for i in range(int(x.shape[0] / batch_size)):
def loss(self, x, t): tx = x[i*batch_size:(i+1)*batch_size]
y = self.predict(x) tt = t[i*batch_size:(i+1)*batch_size]
return self.last_layer.forward(y, t) y = self.predict(tx)
y = np.argmax(y, axis=1)
acc += np.sum(y == tt)
狗熊会|聚数据英才,助产业振兴
8.2.1 AlexNet 网络结构 狗熊会 | 深度学习入门
AlexNet 介绍:
ImageNet 竞赛冠军获得者 Hinton 和他的学生 Krizhevsky Alex 于 2012 年设计。
ImageNet 竞赛中第一个使用卷积神经网络的参赛者。
AlexNet 网络结构: 8 层
卷积层
池化层
卷积层
池化层
卷积层
卷积层
卷积层
池化层
输出层:三个全连接层
狗熊会|聚数据英才,助产业振兴
8.2.2 AlexNet 创新点 狗熊会 | 深度学习入门
AlexNet 创新点:
成功使用 ReLU 作为 CNN 的激活函数;
使用 Dropout 随机忽略一部分神经元,避免模型过拟合;
在 CNN 中使用重叠的最大值池化 ( 步长小于卷积核 ) ;
提出局部响应归一化层( Local Response Normalization , LRN ),后逐渐被 BN ( Batch
Normalization )代替;
使用 CUDA 加速神经网络的训练,利用了 GPU 强大的计算能力;
采用了数据增强( Data Augmentation )技术,达到增加样本量的目的。
狗熊会|聚数据英才,助产业振兴
8.2.2 AlexNet 创新点 狗熊会 | 深度学习入门
AlexNet 创新点:
成功使用 ReLU 作为 CNN 的激活函数;
使用 Dropout 随机忽略一部分神经元,避免模型过拟合;
在 CNN 中使用重叠的最大值池化 ( 步长小于卷积核 ) ;
克服梯度消失的问题
提出局部响应归一化层( Local Response Normalization , LRN ),后逐渐被 BN ( Batch
加快训练速度
Normalization )代替;
使用 CUDA 加速神经网络的训练,利用了 GPU 强大的计算能力;
采用了数据增强( Data Augmentation )技术,达到增加样本量的目的。
狗熊会|聚数据英才,助产业振兴
8.2.2 AlexNet 创新点 狗熊会 | 深度学习入门
Dropout :指深度学习训练过程中,对于神经网络训练单元,按照一定的概率将其
从网络中移除,注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一
个 mini-batch 都在训练不同的网络
狗熊会|聚数据英才,助产业振兴
8.2.2 AlexNet 创新点 狗熊会 | 深度学习入门
AlexNet 创新点:
成功使用 ReLU 作为 CNN 的激活函数;
使用 Dropout 随机忽略一部分神经元,避免模型过拟合;
在 CNN 中使用重叠的最大值池化 ( 步长小于卷积核 ) ;
提出局部响应归一化层( Local Response Normalization , LRN ),后逐渐被 BN ( Batch
Normalization )代替;
使用 CUDA 加速神经网络的训练,利用了 GPU 强大的计算能力;
采用了数据增强( Data Augmentation )技术,达到增加样本量的目的。
狗熊会|聚数据英才,助产业振兴
8.2.2 AlexNet 创新点 狗熊会 | 深度学习入门
神经网络在开始的时候并 为了获得更多的数据,微
不是那么聪明。比如,一 小的改变:旋转( flips )、
个欠训练的神经网络会认 移位( translations )、旋
转( rotations )等微小的
为这三个如下的网球是不
改变
同、独特的图片。
狗熊会|聚数据英才,助产业振兴
8.2.3 案例:中文字体识别——隶书和行楷 狗熊会 | 深度学习入门
数据准备
二分类问题
对数据的存储目录结构是有特殊要求
构造数据生成器
AlexNet 代码实现
AlexNet 编译运行
狗熊会|聚数据英才,助产业振兴
8.2.3 案例:中文字体识别——隶书和行楷 狗熊会 | 深度学习入门
数据准备
构造数据生成器:一种特有的数据读入方法。按照特定的目录结构和要求把相应少量的、多批次的数据读
入内存,做相应的数据分析。
代价:时间的延长和效率的降低
优点:有限的内存资源的支持下,处理非常大的数据
代码: ImageDataGenerator()
AlexNet 代码实现
AlexNet 编译运行
狗熊会|聚数据英才,助产业振兴
8.2.3 案例:中文字体识别——隶书和行楷 狗熊会 | 深度学习入门
数据准备
构造数据生成器
from Keras.preprocessing.image import ImageDataGenerator
数据生成器 IMSIZE=227
validation_generator = ImageDataGenerator(rescale=1./255).flow_from_directory(
AlexNet 代码实现 './data_alex/ChineseStyle/test/',
target_size=(IMSIZE, IMSIZE),
AlexNet 编译运行 batch_size=200,
class_mode='categorical')
train_generator = ImageDataGenerator(rescale=1./255).flow_from_directory(
'./data_alex/ChineseStyle/train',
target_size=(IMSIZE, IMSIZE),
batch_size=200,
class_mode='categorical')
狗熊会|聚数据英才,助产业振兴
8.2.3 案例:中文字体识别——隶书和行楷 狗熊会 | 深度学习入门
狗熊会|聚数据英才,助产业振兴
8.2.3 案例:中文字体识别——隶书和行楷 狗熊会 | 深度学习入门
狗熊会|聚数据英才,助产业振兴
8.2.3 案例:中文字体识别——隶书和行楷 狗熊会 | 深度学习入门
输出维度 参数个数
数据准备
构造数据生成器
AlexNet 代码实现
模型结构展示
AlexNet 编译运行
Dropout 操作
狗熊会|聚数据英才,助产业振兴
8.2.3 案例:中文字体识别——隶书和行楷 狗熊会 | 深度学习入门
数据准备
构造数据生成器
AlexNet 代码实现
AlexNet 编译运行
from Keras.optimizers import Adam
model.compile(loss='categorical_crossentropy',optimizer=Adam(lr=0.001),metrics=['accuracy
'])
model.fit_generator(train_generator,epochs=20,validation_data=validation_generator)
狗熊会|聚数据英才,助产业振兴
PART 8.3
VGG
狗熊会|聚数据英才,助产业振兴
8.3.1 VGG 网络结构 狗熊会 | 深度学习入门
VGG 介绍
牛津大学计算机视觉组和 DeepMind 公
司共同研发的一种深度卷积神经网络
VGG 网络结构: 6 种
从左到右深度越来越深
加粗体表示新增的层
所有网络结构都包含 5 组卷积操作,每组卷积
包含一定数量的卷积层——可以看作一个五阶
段的卷积特征提取。
狗熊会|聚数据英才,助产业振兴
8.3.1 VGG 网络结构 狗熊会 | 深度学习入门
狗熊会|聚数据英才,助产业振兴
8.3.2 案例:加利福尼亚理工学院鸟类数据库分类 狗熊会 | 深度学习入门
数据准备与处理
数据生成器生成训练集与测试集
VGG16 代码实现 from Keras.preprocessing.image import ImageDataGenerator
VGG16 编译运行 IMSIZE = 224
train_generator = ImageDataGenerator(
VGG16 + BN 代码实现 rescale=1. / 255).flow_from_directory(
'./data_vgg/train',
target_size=(IMSIZE, IMSIZE),
batch_size=100,
class_mode='categorical')
validation_generator = ImageDataGenerator(
rescale=1. / 255).flow_from_directory(
'./data_vgg/test',
target_size=(IMSIZE, IMSIZE),
batch_size=100,
class_mode='categorical')
狗熊会|聚数据英才,助产业振兴
8.3.2 案例:加利福尼亚理工学院鸟类数据库分类 狗熊会 | 深度学习入门
数据准备与处理 plt.figure()
fig, ax = plt.subplots(2, 5)
数据生成器生成训练集与测试集
fig.set_figheight(6)
图像展示 fig.set_figwidth(15)
ax = ax.flatten()
VGG16 代码实现 X, Y = next(validation_generator)
for i in range(10):
VGG16 编译运行
ax[i].imshow(X[i, :, :, ])
VGG16 + BN 代码实现
狗熊会|聚数据英才,助产业振兴
8.3.2 案例:加利福尼亚理工学院鸟类数据库分类 狗熊会 | 深度学习入门
数据准备与处理
VGG16 代码实现
VGG16 结构展示
VGG16 编译运行
VGG16 + BN 代码实现
狗熊会|聚数据英才,助产业振兴
8.3.2 案例:加利福尼亚理工学院鸟类数据库分类 狗熊会 | 深度学习入门
数据准备与处理
VGG16 代码实现
VGG16 编译运行
VGG16 + BN 代码实现
狗熊会|聚数据英才,助产业振兴
8.3.2 案例:加利福尼亚理工学院鸟类数据库分类 狗熊会 | 深度学习入门
数据准备与处理
VGG16 代码实现
VGG16 编译运行
VGG16 + BN 代码实现
为了提高分类的准确率,可以尝试在每一层进行 Batch Normalization 的操作
x = BatchNormalization(axis=3)
代码示例: (x)
狗熊会|聚数据英才,助产业振兴
PART 8.4
Batch Normalization 的技巧
狗熊会|聚数据英才,助产业振兴
8.4.1 Batch Normalization 的核心思想 狗熊会 | 深度学习入门
存在问题:感官系统失效了。
狗熊会|聚数据英才,助产业振兴
8.4.1 Batch Normalization 的核心思想 狗熊会 | 深度学习入门
Batch :只使用训练集中的一小部分样本对模型权重进行一次反向传播的参数更新,这一小部分样本被称
作 batch ,也称之为批次。
狗熊会|聚数据英才,助产业振兴
8.4.2 带有 BN 的逻辑回归 狗熊会 | 深度学习入门
数据准备与展示
from keras.preprocessing.image import ImageDataGenerator
猫狗图像分类数据
IMSIZE=128
数据生成器生成训练集与测试集
带有 BN 的逻辑回归模型 validation_generator =
ImageDataGenerator(rescale=1./255).flow_from_directory(
'./data_bn/CatDog/validation',
target_size=(IMSIZE, IMSIZE),
batch_size=200,
class_mode='categorical')
train_generator =
ImageDataGenerator(rescale=1./255).flow_from_directory(
'./data_bn/CatDog/train',
target_size=(IMSIZE, IMSIZE),
batch_size=200,
class_mode='categorical')
狗熊会|聚数据英才,助产业振兴
8.4.2 带有 BN 的逻辑回归 狗熊会 | 深度学习入门
数据准备与展示
猫狗图像分类数据
数据生成器生成训练集与测试集
展示图像
带有 BN 的逻辑回归模型
狗熊会|聚数据英才,助产业振兴
8.4.2 带有 BN 的逻辑回归 狗熊会 | 深度学习入门
数据准备与展示
带有 BN 的逻辑回归模型
狗熊会|聚数据英才,助产业振兴
8.4.2 带有 BN 的逻辑回归 狗熊会 | 深度学习入门
数据准备与展示
带有 BN 的逻辑回归模型
模型结构展示
狗熊会|聚数据英才,助产业振兴
8.4.2 带有 BN 的逻辑回归 狗熊会 | 深度学习入门
数据准备与展示
带有 BN 的逻辑回归模型
模型结构展示
带有 BN 的逻辑回归模型与拟合
狗熊会|聚数据英才,助产业振兴
8.4.3 带有 BN 的宽模型 狗熊会 | 深度学习入门
宽模型用了很多个卷积核,即较深的卷积通道。
具体代码和 8.4.2 章节的逻辑回归差不多,唯一的区别是增加了两行:
卷积操作。使用 100 个大小为的卷积核进行 valid 卷积;
池化操作,进行规格大小为的最大值池化。
狗熊会|聚数据英才,助产业振兴
8.4.4 带有 BN 的深度模型 狗熊会 | 深度学习入门
这个模型中,卷积核的个数减少,但是模型的层数增加。
BN 总结:
Batch Normalization 在很多情况下确实是帮助巨大的,但并不是对所有情况都有帮助。在什么情况
下 Batch Normalization 能够让结果变好,在什么情况下没有帮助是不清楚的,是值得我们思考和
研究的。
狗熊会|聚数据英才,助产业振兴
PART 8.5
Data Augmentation 的技巧
狗熊会|聚数据英才,助产业振兴
8.5 Data Augmentation 的技巧 狗熊会 | 深度学习入门
狗熊会|聚数据英才,助产业振兴
8.5.1 Data Augmentation 的核心思想 狗熊会 | 深度学习入门
人和计算机处理图像不同。原来的图像被
拉伸、变换或旋转,对计算机而言都是一
个全新的矩阵。
计算机对图像数据用矩阵形式表达不充分。
把一张图像变成矩阵的过程中,是有信息
损失的,而这些损失的信息很宝贵,有可
能帮助我们把模型做得更好。
狗熊会|聚数据英才,助产业振兴
8.5 狗熊会 | 深度学习入门
狗熊会|聚数据英才,助产业振兴
8.5.2 案例:猫狗分类 狗熊会 | 深度学习入门
数据生成器生成测试集
利用数据增强技术生成的训练集
展示数据增强后的图像
模型搭建
模型的编译与拟合
from keras.preprocessing.image import ImageDataGenerator
IMSIZE=128
validation_generator = ImageDataGenerator(rescale=1./255).flow_from_directory(
'./data_bn/CatDog/validation',
target_size=(IMSIZE, IMSIZE),
batch_size=200,
class_mode='categorical')
狗熊会|聚数据英才,助产业振兴
8.5.2 案例:猫狗分类 狗熊会 | 深度学习入门
数据生成器生成测试集
利用数据增强技术生成的训练集 train_generator = ImageDataGenerator(
rescale=1./255,
shear_range 表示拉伸变换; shear_range=0.5,
rotation_range=30,
rotation_range 用于定义图像左右旋转; zoom_range=0.2,
zoom_range 用于定义图像放大或者缩小的比例; width_shift_range=0.2,
height_shift_range=0.2,
width_shift_range 表示水平方向上平移的尺度; horizontal_flip=True).flow_from_directory(
'./data_bn/CatDog/train',
height_shift_range 表示垂直方向上平移的尺度; target_size=(IMSIZE, IMSIZE),
horizontal_flip=True 表示允许水平方向的翻转。 batch_size=200,
class_mode='categorical')
展示数据增强后的图像
模型搭建
模型的编译与拟合
狗熊会|聚数据英才,助产业振兴
8.5.2 案例:猫狗分类 狗熊会 | 深度学习入门
数据生成器生成测试集 plt.figure()
fig,ax = plt.subplots(2,5)
利用数据增强技术生成的训练集 fig.set_figheight(6)
fig.set_figwidth(15)
展示数据增强后的图像 ax=ax.flatten()
模型搭建 X,Y=next(train_generator)
for i in range(10): ax[i].imshow(X[i,:,:,:])
模型的编译与拟合
狗熊会|聚数据英才,助产业振兴
8.5.2 案例:猫狗分类 狗熊会 | 深度学习入门
数据生成器生成测试集 IMSIZE=128
from keras.layers import BatchNormalization,Conv2D,Dense,Flatten,Input,
利用数据增强技术生成的训练集 MaxPooling2D
from keras import Model
展示数据增强后的图像
n_channel=100
模型搭建 input_layer=Input([IMSIZE,IMSIZE,3])
x=input_layer
模型的编译与拟合 x=BatchNormalization()(x)
for _ in range(7):
x=BatchNormalization()(x)
x=Conv2D(n_channel,[2,2],padding='same',activation='relu')(x)
x=MaxPooling2D([2,2])(x)
x=Flatten()(x)
x=Dense(2,activation='softmax')(x)
output_layer=x
model=Model(input_layer,output_layer)
model.summary()
狗熊会|聚数据英才,助产业振兴
8.5.2 案例:猫狗分类 狗熊会 | 深度学习入门
数据生成器生成测试集
利用数据增强技术生成的训练集
展示数据增强后的图像
模型搭建
模型结构展示
模型的编译与拟合
狗熊会|聚数据英才,助产业振兴
8.5.2 案例:猫狗分类 狗熊会 | 深度学习入门
数据生成器生成测试集
利用数据增强技术生成的训练集
展示数据增强后的图像
模型搭建
模型的编译与拟合
狗熊会|聚数据英才,助产业振兴
课后习题 狗熊会 | 深度学习入门
课后习题
1 .请给出不少于 3 个基于图像的分类问题,并简要描述出 和 。
2 . LeNet-5 虽然是一个非常经典的模型,但是不是意味着模型中的一些设定不能修改呢?比如卷积
核的数量、大小、层数等,请尝试修改,看看模型精度会有什么变化。
3 .本章介绍了 3 个经典的卷积神经网络的应用案例,请任选一个数据集,以一个逻辑回归模型作为
benchmark ,将其预测精度与其他 CNN 模型对比。
4 .本章学习了一些经典的 CNN 神经网络,尝试把原来的一些经典卷积神经网络使用 Batch
Normalization 改造,提高它的预测精度。有的经典神经网络已经考虑了 BN 技巧,那么那些没有考
虑到的,请读者尝试一下,看看效果是变好了,还是变差了。
5 .思考如果不做数据加强, 8.5.2 节的案例结果会怎么样?
狗熊会|聚数据英才,助产业振兴
THANK YOU 狗熊会
狗熊会|聚数据英才,助产业振兴