TensorFlow实现CNN案例笔记
Posted 龙鸣丿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TensorFlow实现CNN案例笔记相关的知识,希望对你有一定的参考价值。
本文收集了各个资源的TensorFlow实现CNN案例,为了方便学习,如对版权有冒犯,敬请告知及时删除~
目录
CNN知识图谱:
TensorFlow实现CNN
基于TensorFlow实现一个简单的CNN结构用以对图片进行分类python
案例1
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/",one_hot = True)
sess = tf.InteractiveSession()
def weight_variable(shape):
initial = tf.truncated_normal(shape,stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1,shape = shape)
return tf.Variable(initial)
def conv2d(x,W):
return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
x = tf.placeholder(tf.float32,[None,784])
y_ = tf.placeholder(tf.float32,[None,10])
x_image = tf.reshape(x,[-1,28,28,1])
# Conv1 Layer
W_conv1 = weight_variable([5,5,1,32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
# Conv2 Layer
W_conv2 = weight_variable([5,5,32,64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1,W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
W_fc1 = weight_variable([7*7*64,1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1) + b_fc1)
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
W_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2) + b_fc2)
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv),reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1),tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
tf.global_variables_initializer().run()
for i in range(20000):
batch = mnist.train.next_batch(50)
if i % 1000 == 0:
train_accuracy = accuracy.eval(feed_dict=x:batch[0],y_:batch[1],keep_prob:1.0)
print("step %d, training accuracy %g"%(i,train_accuracy))
train_step.run(feed_dict=x:batch[0],y_:batch[1],keep_prob:0.5)
print("test accuracy %g"%accuracy.eval(feed_dict=x:mnist.test.images,y_:mnist.test.labels,keep_prob:1.0))
案例2
# -*- coding: UTF-8 -*-
import numpy as np
import tensorflow as tf
# 下载并载入 MNIST 手写数字库(55000 * 28 * 28)55000 张训练图像
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('mnist_data', one_hot=True)
# one_hot 独热码的编码(encoding)形式
# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 的十位数字
# 0 : 1000000000
# 1 : 0100000000
# 2 : 0010000000
# 3 : 0001000000
# 4 : 0000100000
# 5 : 0000010000
# 6 : 0000001000
# 7 : 0000000100
# 8 : 0000000010
# 9 : 0000000001
# None 表示张量(Tensor)的第一个维度能够是任何长度
# 除以 255 是为了作 归一化(Normalization),把灰度值从 [0, 255] 变成 [0, 1] 区间
# 归一话能够让以后的优化器(optimizer)更快更好地找到偏差最小值
input_x = tf.placeholder(tf.float32, [None, 28 * 28]) / 255. # 输入
output_y = tf.placeholder(tf.int32, [None, 10]) # 输出:10个数字的标签
# -1 表示自动推导维度大小。让计算机根据其余维度的值
# 和总的元素大小来推导出 -1 的地方的维度应该是多少
input_x_images = tf.reshape(input_x, [-1, 28, 28, 1]) # 改变形状以后的输入
# 从 Test(测试)数据集里选取 3000 个手写数字的图片和对应标签
test_x = mnist.test.images[:3000] # 图片
test_y = mnist.test.labels[:3000] # 标签
# 构建咱们的卷积神经网络:
# 第 1 层卷积
conv1 = tf.layers.conv2d(
inputs=input_x_images, # 形状 [28, 28, 1]
filters=32, # 32 个过滤器,输出的深度(depth)是32
kernel_size=[5, 5], # 过滤器在二维的大小是 (5 * 5)
strides=1, # 步长是 1
padding='same', # same 表示输出的大小不变,所以须要在外围补零 2 圈
activation=tf.nn.relu # 激活函数是 Relu
) # 形状 [28, 28, 32]
# 第 1 层池化(亚采样)
pool1 = tf.layers.max_pooling2d(
inputs=conv1, # 形状 [28, 28, 32]
pool_size=[2, 2], # 过滤器在二维的大小是(2 * 2)
strides=2 # 步长是 2
) # 形状 [14, 14, 32]
# 第 2 层卷积
conv2 = tf.layers.conv2d(
inputs=pool1, # 形状 [14, 14, 32]
filters=64, # 64 个过滤器,输出的深度(depth)是64
kernel_size=[5, 5], # 过滤器在二维的大小是 (5 * 5)
strides=1, # 步长是 1
padding='same', # same 表示输出的大小不变,所以须要在外围补零 2 圈
activation=tf.nn.relu # 激活函数是 Relu
) # 形状 [14, 14, 64]
# 第 2 层池化(亚采样)
pool2 = tf.layers.max_pooling2d(
inputs=conv2, # 形状 [14, 14, 64]
pool_size=[2, 2], # 过滤器在二维的大小是(2 * 2)
strides=2 # 步长是 2
) # 形状 [7, 7, 64]
# 平坦化(flat)。降维
flat = tf.reshape(pool2, [-1, 7 * 7 * 64]) # 形状 [7 * 7 * 64, ]
# 1024 个神经元的全链接层
dense = tf.layers.dense(inputs=flat, units=1024, activation=tf.nn.relu)
# Dropout : 丢弃 50%(rate=0.5)
dropout = tf.layers.dropout(inputs=dense, rate=0.5)
# 10 个神经接层,元的全连这里不用激活函数来作非线性化了
logits = tf.layers.dense(inputs=dropout, units=10) # 输出。形状 [1, 1, 10]
# 计算偏差(先用 Softmax 计算百分比几率,
# 再用 Cross entropy(交叉熵)来计算百分比几率和对应的独热码之间的偏差)
loss = tf.losses.softmax_cross_entropy(onehot_labels=output_y, logits=logits)
# Adam 优化器来最小化偏差,学习率 0.001
train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
# 精度。计算 预测值 和 实际标签 的匹配程度
# 返回 (accuracy, update_op), 会建立两个 局部变量
accuracy = tf.metrics.accuracy(
labels=tf.argmax(output_y, axis=1),
predictions=tf.argmax(logits, axis=1),)[1]
# 建立会话
sess = tf.Session()
# 初始化变量:全局和局部
init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init)
# 训练 5000 步。这个步数能够调节
for i in range(5000):
batch = mnist.train.next_batch(50) # 从 Train(训练)数据集里取 “下一个” 50 个样本
train_loss, train_op_ = sess.run([loss, train_op], input_x: batch[0], output_y: batch[1])
if i % 100 == 0:
test_accuracy = sess.run(accuracy, input_x: test_x, output_y: test_y)
print("第 步的 训练损失=:.4f, 测试精度=:.2f".format(i, train_loss, test_accuracy))
# 测试:打印 20 个预测值 和 真实值
test_output = sess.run(logits, input_x: test_x[:20])
inferred_y = np.argmax(test_output, 1)
print(inferred_y, '推测的数字') # 推测的数字
print(np.argmax(test_y[:20], 1), '真实的数字') # 真实的数字
# 关闭会话
sess.close()
案例3
深度学习之卷积神经网络CNN及tensorflow代码实现示例_cxmscb的博客-CSDN博客_卷积神经网络代码
案例4
Tensorflow搭建CNN实现验证码识别 - AwesomeTang - 博客园
完整代码:
https://github.com/AwesomeTang/Captcha_CNN
案例4
1. 实现:
实现卷积编码和反卷积解码的自编码网络
MNIST数据集
CNN卷积操作 | 输入图像shape | **函数 | 卷积核shape | 步长 | 输出图像shape |
---|---|---|---|---|---|
第一层卷积 | [batch,28,28,1] | LeakReLU | [3,3,1,16] | [1,2,2,1] | [batch,14,14,16] |
第二层卷积 | [batch,14,14,16] | LeakReLU | [3,316,32] | [1,2,2,1] | [batch,7,7,32] |
第三层卷积 | [batch,7,7,32] | LeakReLU | [3,3,32,64] | [1,2,2,1] | [batch,4,4,64] |
第四层卷积 | [batch,4,4,64] | LeakReLU | [2,2,64,64] | [1,2,2,1] | [batch,2,2,64] |
CNN反卷积操作 | 输入图像shape | **函数 | 卷积核shape | 步长 | 输出图像shape |
---|---|---|---|---|---|
第一层反卷积 | [batch,2,2,64] | LeakReLU | [2,2,1,16] | [1,2,2,1] | [batch,4,4,64] |
第二层反卷积 | [batch,4,4,64] | LeakReLU | [3,316,32] | [1,2,2,1] | [batch,7,7,32] |
第三层反卷积 | [batch,7,7,32] | LeakReLU | [3,3,32,64] | [1,2,2,1] | [batch,14,14,16] |
第四层反卷积 | [batch,14,14,16] | LeakReLU | [3,3,64,64] | [1,2,2,1] | [batch,28,28,1] |
主网络 | ||||
---|---|---|---|---|
获取输入 | 占位符 | 类型:tf.float32 | shape:[batch,28,28,1] | |
前向结构 | 获取卷积输出 | [batch,2,2,64] | ||
获取反卷积输出 | [batch,28,28,1] | |||
后向结构 | 损失 | 反卷积输出 | 输入数据 | 均值平方差 |
优化器 | tf.train.AdamOptimizer() |
- MNIST数据集
- 每次从训练集取100张图片
- 因获取图片shape为【100,784】,转换为【100,28,28,1】
- 获取损失
- 每训练20次,输出损失
- 从测试集中取100张图片,输入进网络,获取解码后的图片,并输出
测试网络 | 形状:shape | batch=100 |
---|---|---|
获取测试集 | 样本:[batch,784] | |
更改样本集的形状 | 样本:[batch,28,28,1] | |
向主网络中传入数据 | 样本:[batch,28,28,1] | |
获取解码器输出数据 | 预测数据:[batch,28,28,1] | |
输出一张真实图片 | ||
输出一张解码图片 |
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
import matplotlib.pyplot as plt
mnist = input_data.read_data_sets(r'E:\\PycharmProjects\\TensorflowTest\\MNIST_data',one_hot=True)
# 卷积操作
class Convolution:
def __init__(self):
# 输入:[100,28,28,1]
# 输出:(100, 14, 14, 16)
self.filter1 = tf.Variable(tf.truncated_normal([3,3,1,16], stddev=0.1))
self.b1 = tf.Variable(tf.zeros([16]))
# 输出:(100, 7, 7, 32)
self.filter2 = tf.Variable(tf.truncated_normal([3,3,16,32], stddev=0.1))
self.b2 = tf.Variable(tf.zeros([32]))
# 输出:(100, 4, 4, 64)
self.filter3 = tf.Variable(tf.truncated_normal([3,3,32,64], stddev=0.1))
self.b3 = tf.Variable(tf.zeros([64]))
def forward(self,in_x):
conv1 = tf.nn.leaky_relu(tf.add(tf.nn.conv2d(in_x,
self.filter1,
[1,2,2,1],
padding='SAME'), self.b1))
conv2 = tf.nn.leaky_relu(tf.add(tf.nn.conv2d(conv1,
self.filter2,
[1,2,2,1],
padding='SAME'), self.b2))
conv3 = tf.nn.leaky_relu(tf.add(tf.nn.conv2d(conv2,
self.filter3,
[1,2,2,1],
padding='SAME'), self.b3))
return conv3
# 反卷积操作
class Deconvolution:
def __init__(self):
# 输入:[100,4,4,64] 输出:[100,7,7,32]
self.filter3 = tf.Variable(tf.truncated_normal([3, 3, 32, 64], stddev=0.1))
self.b3 = tf.Variable(tf.zeros([32]))
# 输出:[100,14,14,16]
self.filter2 = tf.Variable(tf.truncated_normal([3, 3, 16, 32], stddev=0.1))
self.b2 = tf.Variable(tf.zeros([16]))
# 输出:[100,28,28,1]
self.filter1 = tf.Variable(tf.truncated_normal([3, 3, 1, 16], stddev=0.1))
self.b1 = tf.Variable(tf.zeros([1]))
self.strides=[1,2,2,1]
def forward(self,conv_layer):
deconv1 = tf.nn.leaky_relu(tf.nn.conv2d_transpose(conv_layer,
self.filter3,
[100,7,7,32],
strides=self.strides), self.b3)
deconv2 = tf.nn.leaky_relu(tf.nn.conv2d_transpose(deconv1,
self.filter2,
[100,14,14,16],
strides=self.strides), self.b2)
deconv3 = tf.nn.leaky_relu(tf.nn.conv2d_transpose(deconv2,
self.filter1,
[100,28,28,1],
strides=self.strides), self.b1)
return deconv3
# 主网络
class Net:
def __init__(self):
self.conv = Convolution()
self.deconv = Deconvolution()
self.in_x = tf.placeholder(dtype=tf.float32, shape=[None, 28, 28, 1])
self.forward()
self.backward()
def forward(self):
self.conv_layer = self.conv.forward(self.in_x)
self.deconv_layer = self.deconv.forward(self.conv_layer)
def backward(self):
self.loss = tf.reduce_mean((self.deconv_layer-self.in_x)**2)
self.opt = tf.train.AdamOptimizer().minimize(self.loss)
5. 训练网络:获取损失和解码图
if __name__ == '__main__':
net = Net()
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
saver = tf.train.Saver()
plt.ion()
loss_sum = []
for epoch in range(10000):
xs,_ = mnist.train.next_batch(100)
train_xs = np.reshape(xs, [100, 28, 28, 1])
loss, _ = sess.run([net.loss, net.opt],feed_dict=net.in_x: train_xs)
if epoch % 20 ==0:
saver.save(sess,r'E:\\PycharmProjects\\TensorflowTest\\log\\CNNAEtrain1.ckpt')
test_xs,_ = mnist.train.next_batch(100)
test_xs = np.reshape(test_xs, [100,28, 28,1])
photo_x = np.reshape(sess.run(net.deconv_layer, feed_dict=net.in_x: test_xs)[1],[28,28])
loss_sum.append(loss)
print('loss: ', loss)
plt.imshow(photo_x)
plt.pause(0.1)
plt.figure("CNN_AE_Loss图")
plt.plot(loss_sum,label='CNN_AE_Loss')
plt.legend()
plt.show()
6. 代码结果输出:
loss: 0.10667889
loss: 0.0795733
loss: 0.051609386
loss: 0.030548936
8. 效果展示:
9. 测试网络:
f __name__ == '__main__':
net = Net()
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
saver = tf.train.Saver()
saver.restore(sess, r'E:\\PycharmProjects\\TensorflowTest\\log\\CNNAEtrain1.ckpt')
test_xs, _ = mnist.train.next_batch(100)
test_xs = np.reshape(test_xs, [100, 28, 28, 1])
photo_x = np.reshape(sess.run(net.deconv_layer, feed_dict=net.in_x: test_xs)[1], [28, 28])
photo_xs = np.reshape(test_xs[1], [28, 28])
plt.figure('原始图片')
plt.imshow(photo_xs)
plt.show()
plt.figure('生成图片')
plt.imshow(photo_x)
plt.show()
Tensorflow和CNN:
一、CNN的引入:
1.1 传统神经网络(人工全连接网络)存在的问题(当处理图片问题):
1.)权值太多,计算量太大
2.)权值太多,需要大量的样本进行训练
经验之谈:样本数据量大小是未知参数(权值)的5~30倍。
如:输入一张黑白28*28图片,假设隐层是15个神经元,则参数:784*15=11760个。 如果输入是彩色的,则参数是:3 *784 *15个。输入格式:一维向量。
二、CNN(Convolutional Neural Network)结构:
2.1. 网络实例图:
2.2. 知识图谱:
2.3. 网络层次:
● 输入层:用于数据的输入
● 卷积层:使用卷积核进行特征提取和特征映射
● 激励层:由于卷积也是一种线性运算,因此需要增加非线性映射
● 池化层:进行下采样,对特征图稀疏处理,减少数据运算量。
● 全连接层:通常在CNN的尾部进行重新拟合,减少特征信息的损失
● 输出层:用于输出结果
当然中间还可以使用一些其他的功能层:
● 归一化层(Batch Normalization):在CNN中对特征的归一化
● 切分层:对某些(图片)数据的进行分区域的单独学习
● 融合层:对独立进行特征学习的分支进行融合
2.4. 模块分析:
- 输入层:全连接输入的是一维向量,CNN保留了图片本身的结构。黑白28 *28,输入是28*28的二维神经元。
RGB时输入:
- 卷积层:
理解:卷积层的神经元是只与前一层的部分神经元节点相连,每一条相连的线对应一个权重 w 。
Padding:SAME PADDING和VALID PADDING
作用:使得原信号特征增强,并降低噪音(如,用增强边缘的卷积去处理图像,处理后,边缘特征增强);
局部感知*参数共享*多核*下采样*多层卷积(层数多,提取的特征越全局化);
(1.)局部感受野和权值共享:局部?(特征的局部):颜色局部,文理局部,形状局部
假设输入的是一个 28×28 的的二维神经元,我们定义5×5 的 一个 local receptive fields(感受视野),即 隐藏层的神经元与输入层的5×5个神经元相连,这个5*5的区域就称之为Local Receptive Fields。
作用:减少了神经网络需训练参数的个数
定义:一个点用其周围的点像素值加权平均代替
意义:加权叠加
作用: 消除噪声,特征增强
实用:平滑
注意:滤波(尺寸不变)和卷积的区别
(2.)Feature Map
定义: 一张图(矩阵)经过卷积核(kernal)卷积运算之后得到的一张新的图(矩阵)。
角度:(同一层)一张图片多种角度的描述。
具体: 用多种不同的卷积核对图像进行卷积Filteri,得到不同核上的响应,作为图像的特征。
下层核:主要是一些简单的边缘检测器(simple cell);
上层核:主要是一些简单核的叠加(complex cell)
如:
同一层:
Fliter1 的w1,b1 运算后提取的是 形状边缘的特征: feature map1
Fliter2 的w2,b2 运算后提取的是 颜色深浅的特征: feature map2
下一层:
Fliter3 的w3,b3 运算后提取的是 直线形状的特征: feature map3
Fliter4 的w4,b4 运算后提取的是 弧线形状的特征: feature map4
Fliter5 的w5,b5 运算后提取的是 红色深浅的特征: feature map5
Fliter6 的w6,b6 运算后提取的是 绿色深浅的特征: feature map6
- 池化层:
Padding:SAME PADDING和VALID PADDING
方式:mean-pooling和max-pooling
作用:降维,还能改善过拟合
卷积和池化都是特征提取
- (端到端)步骤
原始图(input 图)—>卷积和池化输出的是Feature Map—>光栅化—>多层感知机预测(全连接,分类器)—>output
光栅化目的:光栅化后得到的是一个一维的向量为了与传统的多层感知机全连接,最后一个池化层S(完成对原始数据的特征提取)后—>S层的特征数据向量化,连接到相应的分类器。分类器如:SoftMax、BP网络、SVM、等
2.5 训练:
定义:参数调优能识别特定的特征,这个过程叫做训练;
不需要人为的修改:卷积核初始化是随机的,是一个自学习的过程,向最优发展;
需要人为的修改:卷积核的个数,步长等;
训练开始,卷积层的滤波器是完全随机,不会对任何特征**(不能检测任何特征)。所以,反馈修改参数等,达到CNN最优化的检测特定模式。如定义损失函数L,让L反馈给整个网络,修改参数,让Loss最小(使得L变化收敛“碗”)。在训练CNN时,实际上是在训练一系列滤波器,这些滤波器对特定模式有高的**,以达到CNN分类/检测的目的。
Tensorflow——卷积神经网络(CNN)
卷积神经网络
主要应用于计算机视觉相关任务,但它能处理的任务并不局限于图像,其实语音识别也是可以使用卷积神经网络。
工作概述
卷积层 conv2d
参数:ksize 卷积核大小 strides 卷积核移动跨度 padding 边缘填充
非线性层 relu/sigmiod/tanh
池化(下采样)层 pooling2d
- 最大池化
2.平均池化
全连接层 Dense:w*x+b
卷积
卷积是指将卷积应用到某个张量的所有点上,通过将卷积核在输入的张量上滑动而生成经过滤波处理的张量。
卷积完成的是对图像特征的提取或者说信息匹配,当一个包含某些特征的图像经过一个卷积核时,一些卷积核被激活,输出特定信号。
整体结构
一句话概括:把图像变小(减小维度)变厚(特征提取)
卷积神经网络需要四维的图片数据(数量,宽度,高度,通道数)
示例:
import tensorflow as tf
print(\\'Tensorflow version:\\'.format(tf.__version__))
# 测试gpu是否可以使用
tf.test.is_gpu_available()
from tensorflow import keras
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
# 加载fashion_mnist数据集
fashion_mnist = keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels) = fashion_mnist.load_data()
# 对图片数据进行扩维
train_images = np.expand_dims(train_images,-1) # 在最后一个维度上进行扩张
test_images = np.expand_dims(test_images,-1) # 在最后一个维度上进行扩张
建立模型
model= tf.keras.Sequential() # 顺序模型
# 第一层使用卷积层,卷积层提取图片特征的能力强 32-fliter个数 (3,3)-卷积核大小,一般使用3*3或5*5 input_shape-图片大小
model.add(tf.keras.layers.Conv2D(64,(3,3),input_shape=train_images.shape[1:],activation=\\'relu\\',padding=\\'same\\'))
model.add(tf.keras.layers.Conv2D(64,(3,3),activation=\\'relu\\',padding=\\'same\\'))
# 最大池化层
model.add(tf.keras.layers.MaxPool2D())
# 抑制过拟合
model.add(tf.keras.layers.Dropout(0.5))
# 卷积核以2的指数增长
model.add(tf.keras.layers.Conv2D(128,(3,3),activation=\\'relu\\',padding=\\'same\\'))
model.add(tf.keras.layers.Conv2D(128,(3,3),activation=\\'relu\\',padding=\\'same\\'))
# 最大池化层
model.add(tf.keras.layers.MaxPool2D())
# 抑制过拟合
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Conv2D(256,(3,3),activation=\\'relu\\',padding=\\'same\\'))
model.add(tf.keras.layers.Conv2D(256,(3,3),activation=\\'relu\\',padding=\\'same\\'))
# 抑制过拟合
model.add(tf.keras.layers.Dropout(0.5))
# 全局平均池化:得到一个二维的数据
model.add(tf.keras.layers.GlobalAveragePooling2D())
# Dense 输出层:输出一个维度为10的数据 softmax:输出概率值
model.add(tf.keras.layers.Dense(256,activation=\\'relu\\'))
model.add(tf.keras.layers.Dense(10,activation=\\'softmax\\'))
model.summary()
# 对模型进行配置
model.compile(optimizer=\\'adam\\',
loss=\\'sparse_categorical_crossentropy\\',
metrics=[\\'acc\\'])
# 训练
history = model.fit(train_images,train_labels,epochs=30,validation_data = (test_images,test_labels))
history.history.keys()
plt.plot(history.epoch,history.history.get(\\'acc\\'),label=\\'acc\\')
plt.plot(history.epoch,history.history.get(\\'val_acc\\'),label=\\'val_acc\\')
plt.legend()
plt.plot(history.epoch,history.history.get(\\'loss\\'),label=\\'loss\\')
plt.plot(history.epoch,history.history.get(\\'val_loss\\'),label=\\'val_loss\\')
plt.legend()
TensorFlow 2.0 教程
TensorFlow 2.0 教程_Doit_行之的博客-CSDN博客_tensorflow2.0教程视频
https://github.com/czy36mengfei/tensorflow2_tutorials_chinese
tensorflow2-基础CNN网络
1.构造数据
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape((-1,28,28,1))
x_test = x_test.reshape((-1,28,28,1))
print(x_train.shape, ' ', y_train.shape)
print(x_test.shape, ' ', y_test.shape)
(60000, 28, 28, 1) (60000,)
(10000, 28, 28, 1) (10000,)
import matplotlib.pyplot as plt
plt.imshow(x_train[0])
plt.show()
2.构造网络
model = keras.Sequential()
model.add(layers.Conv2D(input_shape=(x_train.shape[1], x_train.shape[2], x_train.shape[3]),
filters=32, kernel_size=(3,3), strides=(1,1), padding='valid',
activation='relu'))
全连接层
model.add(layers.Flatten())
model.add(layers.Dense(32, activation='relu'))
# 分类层
model.add(layers.Dense(10, activation='softmax'))
3.模型配置
model.compile(optimizer=keras.optimizers.Adam(),
# loss=keras.losses.CategoricalCrossentropy(), # 需要使用to_categorical
loss=keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy'])
model.summary()
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_2 (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 5408) 0
_________________________________________________________________
dense_2 (Dense) (None, 32) 173088
_________________________________________________________________
dense_3 (Dense) (None, 10) 330
=================================================================
Total params: 173,738
Trainable params: 173,738
Non-trainable params: 0
_________________________________________________________________
4.模型训练
history = model.fit(x_train, y_train, batch_size=64, epochs=5, validation_split=0.1)
Train on 54000 samples, validate on 6000 samples
Epoch 1/5
54000/54000 [==============================] - 11s 197us/sample - loss: 0.0589 - accuracy: 0.9825 - val_loss: 0.0963 - val_accuracy: 0.9785
Epoch 2/5
54000/54000 [==============================] - 11s 195us/sample - loss: 0.0500 - accuracy: 0.9849 - val_loss: 0.0957 - val_accuracy: 0.9777
Epoch 3/5
54000/54000 [==============================] - 11s 197us/sample - loss: 0.0429 - accuracy: 0.9867 - val_loss: 0.0881 - val_accuracy: 0.9798
Epoch 4/5
54000/54000 [==============================] - 11s 199us/sample - loss: 0.0381 - accuracy: 0.9877 - val_loss: 0.0811 - val_accuracy: 0.9817
Epoch 5/5
54000/54000 [==============================] - 11s 200us/sample - loss: 0.0340 - accuracy: 0.9890 - val_loss: 0.0910 - val_accuracy: 0.9795
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.legend(['training', 'valivation'], loc='upper left')
plt.show()
res = model.evaluate(x_test, y_test)
10000/10000 [==============================] - 1s 73us/sample - loss: 0.1255 - accuracy: 0.9733
卷积神经网络(CNN)简易教程
让我们先来了解一下我们的大脑是如何识别物体的。我们将学习什么是CNN, CNN如何利用大脑的启发进行物体识别,CNN是如何工作的。
让我们来了解一下我们的大脑是如何识别图像的
根据诺贝尔奖获得者Hubel和Wiesel教授的说法,视觉区域V1由简单细胞和复杂细胞组成。简单的单元有助于特征检测,而复杂的单元则结合了来自小空间邻域的多个这样的局部特征。空间池有助于实现平移不变特征。
当我们看到一个新的图像时,我们可以从左到右和从上到下扫描图像,以了解图像的不同特征。我们的下一步是结合我们扫描的不同的局部特征来对图像进行分类。CNN就是这样工作的
平移不变特征是什么意思?
图像的不变性意味着,即使图像旋转、大小不同或在不同照明下观看,对象也将被识别为同一对象。
这有助于对象识别,因为图像表示对图像变换(如平移、旋转或小变形等)保持不变。
我们使用卷积神经网络进行图像识别和分类。
让我们了解什么是CNN,以及我们如何使用它。
CNN是什么?
CNN是Convolutional Neural Network卷积神经网络的缩写,卷积神经网络是一种专门用来处理数据的神经网络,它的输入形状类似于二维的矩阵图像。
CNN通常用于图像检测和分类。图像是二维的像素矩阵,我们在其上运行CNN来识别图像或对图像进行分类。识别一个图像是一个人,还是一辆车,或者只是一个地址上的数字。
和神经网络一样,CNN也从大脑中获取启发。我们使用Hubel和Wiesel提出的对象识别模型。
卷积是什么?
卷积是一种数学运算,其中我们有一个输入I和一个参数核K来产生一个输出。
让我们用图像来解释。
我们有一个图像“x”,它是一个具有不同颜色通道(红色、绿色和蓝色RGB)的二维像素矩阵,我们有一个特征检测器或核“w”,然后应用数学运算后得到的输出称为特征图
这个数学运算有助于计算两个信号的相似度。
我们可能有一个特征检测器或滤波器来识别图像中的边缘,所以卷积运算将有助于我们识别图像中的边缘。
我们通常假设卷积函数在除存储值的有限点集外的任何地方都为零。
I是二维数组,K是核卷积函数
因为卷积是可交换的,我们可以把上面的方程重新写一下,如下图所示。我们这样做是为了便于在机器学习中实现,因为m和n的有效值范围变化较小。这是大多数神经网络使用的互相关函数。
以上是互相关函数
那么,我们如何在CNN中实现它呢?
我们实现它的方式是通过卷积层
卷积层是CNN的核心构件,它有助于特征检测。
核K是一组可学习的过滤器,与图像相比,它在空间上很小,但是可以扩展到整个输入图像的深度。
理解这一点的一个简单方法是,如果你是一名侦探,你在黑暗中看到一幅很大的图像或一幅画,你将如何识别图像?
你将使用你的手电筒和扫描整个图像。这正是我们在卷积层中所做的。
核K是一个特征检测器,它相当于图像I上的手电筒,我们正在尝试检测特征并创建多个特征图来帮助我们识别或分类图像。
我们有多个特征探测器,以帮助像边缘检测,识别不同的形状,弯曲或不同的颜色等事情。
这一切是如何运作的?
让我们取一幅3通道5×5矩阵的图像(RGB), 3通道3×3的特征检测器(RGB),然后以步长为1来扫描图像上的特征检测器。
当我在图像上应用特征检测时,输出矩阵或特征图的维数是多少?
特征图的维数与输入图像的大小(W)、特征检测器的大小(F)、步长(S)和图像的填充大小(P)有关
$(W−F+2p)/S + 1$
在我们的例子中,W是输入图像的大小,为5。
F是特征检测器接受域大小,在我们的例子中,为3
步长(S)为1,图像上使用的填充大小(P)为0。
因此,我们的特征图维度为(5-3+0)/1+1=3。
因此特征图将是一个3*3的矩阵,有3个通道(RGB)。
下面一步一步进行解释
我们看到5×5的输入图像被简化为3×3的特征图,通道为3(RGB)
我们使用多个特征检测器来寻找边缘,我们可以使用特征检测器来锐化图像或模糊图像。
如果我们不想减少特征图的维数,那么我们可以使用如下所示的填充0
在这种情况下应用相同的公式,我们得到
$(W−F + 2 p) / S + 1 => (5 - 3 +2)/1 + 1= 5$,
现在输出的尺寸将是5×5,带有3个颜色通道(RGB)。
让我们看看这一切是如何运作的
如果我们有一个3×3的特征检测器或滤波器,一个偏置单元,那么我们首先应用如下所示的线性变换
输出=输入*权重+偏差
参数个数 = (3 * 3 * 3)+1 = 28
对于100个特征检测器或过滤器,参数的数量将是2800。
在每一个线性函数的卷积运算之后,我们应用ReLU**函数。ReLU**函数在卷积层中引入了非线性。
它将特征图中的所有负像素值替换为零。
下图是应用ReLU**函数后的特征图变换。
现在我们已经完成了局部区域的特征检测,我们将结合所有这些来自空间邻域的特征检测来构建图像。
记住你是一个在黑暗中扫描图像的侦探,你现在已经从左到右、从上到下扫描了图像。现在我们需要结合所有的特征来识别图像
池化
我们现在应用池来获得平移不变性。
平移的不变性意味着当我们少量改变输入时,合并的输出不会改变。这有助于检测输入中常见的特征,如图像中的边缘或图像中的颜色
我们使用最大池函数,它提供了比最小或平均池更好的性能。
当我们使用最大池时,它总结了整个邻居的输出。与原来的特征图相比,我们现在有更少的单元。
在我们的例子中,我们使用一个2x2的框扫描所有的特征图,并找到最大值。
现在我们知道卷积网络由以下构成
- 并行的多重卷积,输出是线性**函数
- 卷积层中应用非线性函数ReLU
- 使用像最大池这样的池函数来汇总附近位置的统计信息。这有助于“平移不变性”
- 我们将结果展平,然后将其输入到全连接神经网络
下图是完整的卷积神经网络
卷积使用了三个重要的思想
- 稀疏的交互
- 参数共享
- 等变表示
稀疏交互或稀疏权值是通过使用小于输入图像的核或特征检测器来实现的。
如果我们有一个大小为256 * 256的输入图像,那么就很难检测到图像中的边缘,因为其可能只占图像中像素的一个更小的子集。如果我们使用更小的特征检测器,那么当我们专注于局部特征识别时,就可以很容易地识别边缘。
另一个优点是计算输出所需的操作更少,从而提高了统计效率。
参数共享用于控制CNN中使用的参数或权值的数量。
在传统的神经网络中,每个权值只使用一次,但是在CNN中,我们假设如果一个特征检测器可以用来计算一个空间位置,那么它可以用来计算一个不同的空间位置。
当我们在CNN中共享参数时,它减少了需要学习的参数的数量,也减少了计算需求。
等变表示
这意味着目标检测对光照、位置的变化是不变的,而内部表示对这些变化是等方差的
深度学习分类实践-tensorflow2实现CNN
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
def gen_datasets():
'''
generate train datasets and testing datasets from mnist data
:return:
x_train, y_train,
x_test, y_test
'''
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
print(x_train.shape, '', y_train.shape)
print(x_test.shape, '', y_test.shape)
return (x_train, y_train), (x_test, y_test)
# 1.准备数据
(x_train, y_train), (x_test, y_test) = gen_datasets()
x_train = x_train.reshape((-1, 28, 28, 1))
x_test = x_test.reshape((-1, 28, 28, 1))
# 2.构建模型
model = keras.Sequential([
layers.Conv2D(input_shape=(x_train.shape[1], x_train.shape[2], x_train.shape[3]), filters=32,
kernel_size=(3, 3), strides=(1, 1), padding='valid', activation='relu'),
layers.MaxPool2D(pool_size=(2, 2)),
layers.Flatten(),
layers.Dense(32, activation='relu'),
layers.Dense(10, activation='softmax')
])
model.summary()
# 3.训练模型
model.compile(optimizer=keras.optimizers.Adam(),
# loss=keras.losses.CategoricalCrossentropy(), # 需要使用to_categorical
loss=keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy'])
history = model.fit(x_train, y_train, batch_size=64, epochs=100, verbose=1)
plt.plot(history.history['accuracy'])
plt.legend(['training'], loc='upper left')
plt.show()
# 4.评估模型
result = model.evaluate(x_test, y_test)
print("loss=%s,accuracy=%s" % (result[0], result[1]))
其他资源:
我要自学网:
B站等
TensorFlow2学习九、实现基础CNN_编程圈子的博客-CSDN博客
以上是关于TensorFlow实现CNN案例笔记的主要内容,如果未能解决你的问题,请参考以下文章
基于Tensorflow卷积神经网络(CNN)的人脸年龄和性别检测系统
基于Tensorflow卷积神经网络(CNN)的人脸年龄和性别检测系统
基于Tensorflow卷积神经网络(CNN)的人脸年龄和性别检测系统
人脸检测及识别python实现系列——卷积神经网络(CNN)入门