本教程资料来自于:Tensorflow 搭建自己的神经网络 (莫烦 Python 教程)
- https://www.bilibili.com/video/av16001891?from=search&seid=6106673353000958940
- https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-03-A-CNN/
本小节主要简介卷积神经网络,卷积神经网络,在处理图片信息的时候很有优势,它和以往的多层神经网络不同的是,它和好保留了图片的列信息。
18 、卷积神经网络 CNN (深度学习)
应用范围:图形图像识别、视频分析、药物发现、自然语言处理、ALPHAGO
卷积神经网络是如何运作的,识别图片的例子:
升级网络由神经层组成,每一层神经层有很多神经元,神经元是神经网络识别的关键,每一种神经网络都有自己的输入和输出,当输入是图片的时候,是一对数字。
卷积神经网络(卷积 + 神经网络)
卷积:神经网络不再是对每一个像素输入的信息做处理,而是对图片上每一小块像素区域的处理。这种做法加快了图片信息的连续性,使得神经网络能看到图形而非一个点,这种做法同时也加深了,神经网络对图片的理解。
卷积神经网络有一个批量过滤器,持续不断在图片上滚动和收集图像的信息,每一次收集来的信息只是一小块像素信息,然后把收集来的信息进行整理,整理出来的信息有了实际上的一些呈现,这使得神经网络可以看到一些边缘的图片信息,然后以同样的不走,使用批量过滤器,扫过产生的边缘信息,神经网络利用这些边缘信息总结产生出更高级的信息结构。比如总结的边缘信息可以画出眼睛、鼻子等等。在经过几次批量过滤器,眼睛和鼻子这些信息就被提取出来,构成了人脸,然后在套用到全连接层softmax分类识别就好了。
神经网络
通过不断的扫描,来收集信息。把图片的厚度不断增加,长宽减少。
再次进行卷积,长宽不断压缩,高度不断增加。将压缩的图片信息,嵌入到普通分类神经层上,我们就能对这种图片进行分类了。
实际中卷积会丢失掉一部分信息,这时候池化pooling可以很好的解决这个问题。也就是说在卷积的时候我们不压缩长宽,尽量保留更多的信息,压缩的工作交给池化。这样附加的工作可以有效提高数据的准确性。
在卷积的时候不压缩长宽,尽量保留更多的信息。压缩的工作就交给了池化。这样附加的工作可以有效提高数据的准确性。
常用的搭建结构:
从下到上的搭建顺序:
- 1.图片(输入)
- 2.卷积层
- 3.池化 处理卷积信息
- 4.卷积层
- 5.池化 处理卷积信息(max pooling)
- 6.全连接层
- 7.全连接层 fully connected
- 8.分类器 classifier
CNN 卷积神经网络 1
https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-03-CNN1/
2562563 RGB 三原色
每个卷积核对应一个深度
不断压缩长和宽,增加厚度,利用厚度的信息把他变成一个分类器
卷积核 kernel patch 每一个小部分都会变成一个长度一个宽度,k厚度的数列。
Stride 抽离的跨度是多少。
跨两步进行收集信息。stride = 2
padding的两种方式
same padding 抽离后的长宽与之前一样
valid padding 抽离后的长宽缩小了
polling
该图片上面卷积的效果和下面卷积的效果看似一样实际上不一样,
上面直接将stride 设置成2进行抽取,
下面stride=1,然后在进行池化。
- max polling
- vaild polling
CNN 卷积神经网络 2
https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-04-CNN2/
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# number 1 to 10 data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
def compute_accuracy(v_xs, v_ys):
# 输出准确度
global prediction
y_pre = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
correct_prediction = tf.equal(tf.argmax(y_pre, 1), tf.argmax(v_ys, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
return result
def weight_variable(shape):
# 根据参数形状随机产生参数
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bais_vaiable(shape):
# 偏移量,b使用,常量0.1 一般使用正值
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W):
# 功能:卷积
# 定义卷积神经网络层
# x为输入的层,W为该层的连接权重
# 卷积窗口移动步长:stride[1, x_movement, y_movement, 1]
# Must have strides[0] = strides[3] = 1
# conn2d 实现卷积神经
# strides 步长 在Tesnorflow中它是4个长度的列表[1,,,1]第一个和最后一个元素必须等于1
# 第二个参数 在x方向(水平方向)跨度为 第三个参数 在y方向(竖直方向)跨度
# 卷积的方式:padding 有两种形式 SAME 和 VALID
# SAME padding 中多余出来的用0来填充,因为padding的大小不一定等于1
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x):
# 功能:池化
# 为了防止跨度太大,丢失信息过多,padding后要进行pooling处理,尽量保留更多的图片信息
# 移动的步长:stride[1, x_movement, y_movement, 1] 第一个和最后一个元素必须等于1
# kisze池化窗口的大小[1, height, weight, 1]
# pool和卷积很相似,但是他不用传入参数W
# 池化的方式: SAME 和 VALID
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
# define placeholder for inputs to network
xs = tf.placeholder(tf.float32, [None, 784]) # 28*28
ys = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)
# 图片的信息
# -1的含义是,我们自己不用去管这个维度的大小,在这里是指的是图片样例的个数
# 第四个参数:黑白图片是 1 彩色图片是3 RGB
x_image = tf.reshape(xs, [-1, 28, 28, 1])
# print(x_image.shape) # [n_sample, 28, 28, 1]
# 图片是个三维数据 28*28*1 黑白图片
# ********************* conv1 layer ********************* #
# 卷积1 + 池化1
W_conv1 = weight_variable([5, 5, 1, 32]) # patch 5*5, in size 1, out size 32
# feature_map = 32 卷积从图片中提取的特征个数
# 5*5 就是卷积核的大小、滤波器 filter
# insize=1 图片的厚度是1
b_conv1 = bais_vaiable([32])
# 卷积核的个数是32 产生的输出就是32 叠加起来的厚度就是32
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1)+b_conv1) # output size 28*28*32
# VALID padding 就不是32,而是24
# 激活函数:relu (非线性处理)
h_pool1 = max_pool_2x2(h_conv1) # output size 14*14*32
# tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
# strides 池化移动的步长为2,2 则长宽成为了原先的一半 pooling
# 卷积 和 池化 参数设置是两会事,卷积设为2 就从32变为24,池化就从24变为14
# 该层的输出值
# ********************* conv2 layer ********************* #
# 卷积2 + 池化2
W_conv2 = weight_variable([5, 5, 32, 64]) # patch 5*5, in size 32, out size 64
b_conv2 = bais_vaiable([64])
# h_pool1 conv1 layer输出的东西
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2)+b_conv2) # output size 14*14*64
h_pool2 = max_pool_2x2(h_conv2) # output size 7*7*64
# 以上卷积和池化的工作只是为了压缩举证特征值,不设计神经网络分类
# ********************* func1 layer ********************* #
W_fc1 = weight_variable([7*7*64, 1024]) # 把7*7*64(乘法) 变成 1024
b_fc1 = bais_vaiable([1024])
# [n_samples, 7, 7, 64] ->> [n_samples, 7*7*64]
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) # 把pooling后三维的数据变成一个一维的数据
# [n_samples, 7, 7, 64] 变到[n_samples, 7*7*64]
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 考虑到过拟合overfictting
# ********************* func2 layer ********************* #
# 传入1024,传出10(判断0,1,2,3,4...9,十个数字)
W_fc2 = weight_variable([1024, 10])
b_fc2 = bais_vaiable([10])
# 预测值
# softmax算法概率
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
# the error between prediction and real data
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction), reduction_indices=[1]))
# 1e-4 = 0.0001
# 优化没有使用梯度下降 , 对于庞大系统的参数优化就用AdamOptimizer
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
sess = tf.Session()
# important step
sess.run(tf.global_variables_initializer())
for i in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 1})
if i % 50 == 0:
print(compute_accuracy(mnist.test.images, mnist.test.labels))
lijuncheng@lijunchengdeMacBook-Pro ~/WORK/Code/TensorFlow $ cd /Users/lijuncheng/WORK/Code/TensorFlow ; env "PYTHONIOENCODING=UTF-8" "PYTHONUNBUFFERED=1"/Users/lijuncheng/anaconda3/bin/python3 /Users/lijuncheng/.vscode/extensions/ms-python.python-2018.6.0/pythonFiles/PythonTools/visualstudio_py_launcher_nodebug.py /Users/lijuncheng/WORK/Code/TensorFlow 58723 34806ad9-833a-4524-8cd6-18ca4aa74f14 RedirectOutput,RedirectOutput /Users/lijuncheng/WORK/Code/TensorFlow/python11.py
/Users/lijuncheng/anaconda3/lib/python3.6/site-packages/h5py/__init__.py:34:FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
from ._conv import register_converters as _register_converters
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
0.0996
0.7874
0.8648
0.9067
0.9262
0.9223
0.9323
0.9437
0.9478
0.9451
0.958
0.9609
0.9532
0.9638
0.9613
0.963
0.9634
0.9666
0.9668
0.967
[1] 44912 terminated env "PYTHONIOENCODING=UTF-8" "PYTHONUNBUFFERED=1" 58723
一直很琢磨不透这个代码风格提示器。醉了
Saver 保存读取
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# Save to file
# remember to define the same dtype and shape when restore
# 在保存的时候最好定义一下数据类型
W = tf.Variable([[1, 2, 3], [3, 4, 5]], dtype=tf.float32, name='weights')
# 保存已经得到权重数据 [[1, 2, 3], [3, 4, 5]]
b = tf.Variable([[1, 2, 4]], dtype=tf.float32, name='biases')
init = tf.global_variables_initializer()
# 全局变量初始化
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(init)
# .ckpt后缀
# 之前要先定义文件夹
save_path = saver.save(sess, "my_net/save_net.ckpt")
print("Save to path:", save_path)
lijuncheng@lijunchengdeMacBook-Pro ~/WORK/Code/TensorFlow $ cd /Users/lijuncheng/WORK/Code/TensorFlow ; env "PYTHONIOENCODING=UTF-8" "PYTHONUNBUFFERED=1" /Users/lijuncheng/anaconda3/bin/python /Users/lijuncheng/.vscode/extensions/ms-python.python-2018.6.0/pythonFiles/PythonTools/visualstudio_py_launcher_nodebug.py /Users/lijuncheng/WORK/Code/TensorFlow 60330 34806ad9-833a-4524-8cd6-18ca4aa74f14 RedirectOutput,RedirectOutput /Users/lijuncheng/WORK/Code/TensorFlow/python14.py
Save to path: my_net/save_net.ckpt
[1] 49379 terminated env "PYTHONIOENCODING=UTF-8" "PYTHONUNBUFFERED=1" 60330
提取保存的ckpt
import tensorflow as tf
import numpy as np
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# restore variables
# redefine the same shape and same type for your varibale
# 记住保存数据的形状 和 类型
# 定义空的框架 使用用nupmy方便
W = tf.Variable(np.arange(6).reshape((2, 3)), dtype=tf.float32, name='weights')
b = tf.Variable(np.arange(3).reshape((1, 3)), dtype=tf.float32, name='biases')
# 整个神经网络的框架也要重新定义,不能保存
# not need init step 不用定义 init = tf.global_variables_initializer() 全局初始化
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, "my_net/save_net.ckpt")
print("weight:", sess.run(W))
print("biases:", sess.run(b))
lijuncheng@lijunchengdeMacBook-Pro ~/WORK/Code/TensorFlow $ cd /Users/lijuncheng/WORK/Code/TensorFlow ; env "PYTHONIOENCODING=UTF-8" "PYTHONUNBUFFERED=1" /Users/lijuncheng/anaconda3/bin/python /Users/lijuncheng/.vscode/extensions/ms-python.python-2018.6.0/pythonFiles/PythonTools/visualstudio_py_launcher_nodebug.py /Users/lijuncheng/WORK/Code/TensorFlow 60536 34806ad9-833a-4524-8cd6-18ca4aa74f14 RedirectOutput,RedirectOutput /Users/lijuncheng/WORK/Code/TensorFlow/python12.py
weight: [[1. 2. 3.]
[3. 4. 5.]]
biases: [[1. 2. 4.]]
[1] 51475 terminated env "PYTHONIOENCODING=UTF-8" "PYTHONUNBUFFERED=1" 60536
lijuncheng@lijunchengdeMacBook-Pro ~/WORK/Code/TensorFlow $