深度学习框架tensorflow实战(实现卷积神经网络)

卷积神经网络

提前了解~~

卷积层和池化层

相当于对原来的图像做了一个特征提取
卷积和激活一般都是联系在一起的,卷积后图像大小可以不变,每一次卷积就对应一次激活~~
但池化可以进行特征降维(常用的有Max pooling,Average pooling)

全连接层

把卷积层提取的特征再组合在一起,然后再用组合到一起的特征再进行分类
对全连接层(fully connected layer)的通俗理解:https://blog.csdn.net/qq_39521554/article/details/81385159

import tensorflow as tf
import random
import numpy as np
import matplotlib.pyplot as plt
import datetime

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("data/", one_hot=True)

输入层和输出层

tf.reset_default_graph() 用于清除默认图形堆栈并重置全局默认图形.说白了,就是每轮要清除无效的计算图。
注意:要放在 tf.Session() 前面

shape = [None, 28,28,1] 大部分情况下,处理的图像都是正方形,科学家证明过的,正方形比长方形好~,1指的是黑白图像,1个通道就行,RGB就得写3,3个通道。
None其实就是batchSize

tf.reset_default_graph() 
sess = tf.InteractiveSession()
x = tf.placeholder("float", shape = [None, 28,28,1]) #shape in CNNs is always None x height x width x color channels
y_ = tf.placeholder("float", shape = [None, 10]) #shape is always None x number of classes

定义卷积层参数

从下面图像可以看到,这里定义的是一个3乘3大小的卷积核
在这里插入图片描述
[5, 5, 1, 32]: 这层卷积层总共设置32个神经元,也就是有32个卷积核去分别关注32个特征。窗口的大小是5×5,所以指向每个卷积层的权重也是5×5,因为图片是黑白色的,只有一个颜色通道,所以总共只有1个面,故每个卷积核都对应一组551的权重。

W_conv1 = tf.Variable(tf.truncated_normal([5, 5, 1, 32], stddev=0.1))#shape is filter x filter x input channels x output channels
b_conv1 = tf.Variable(tf.constant(.1, shape = [32])) #shape of the bias just has to match output channels of the filter

定义卷积层,池化层操作

在这里插入图片描述
input: 一个4维Tensor(N,H,W,C). 类型必须是以下几种类型之一: half, float32, float64.
filter: 卷积核. 类型和input必须相同,4维tensor, [filter_height, filter_width, in_channels, out_channels],如[5,5,3,32]
strides: 在input上切片采样时,每个方向上的滑窗步长,必须和format指定的维度同阶,如[1, 2, 2, 1],横,纵向步长为2
padding: 指定边缘填充类型: “SAME”, “VALID”. SAME表示卷积后图片保持不变,VALID则会缩小。

h_conv1 = tf.nn.conv2d(input=x, filter=W_conv1, strides=[1, 1, 1, 1], padding='SAME') + b_conv1  #卷积操作
h_conv1 = tf.nn.relu(h_conv1)       #卷积完后用非线性激活函数进行映射
h_pool1 = tf.nn.max_pool(h_conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')  #池化操作
'''
可以用函数表达
'''
def conv2d(x, W):
    return tf.nn.conv2d(input=x, filter=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')

第二次卷积

两次的卷积,
第一次以图像输入 28乘28乘1通道 ,以 14乘14乘32通道 输出
第二次以第一次的图输出 14乘14乘32 通道 为输入, 以 7乘7乘64通道 输出

32是输入了32张图,前面是只有黑白,也就1张图嘛,第三个参数必定和输入挂钩
64指的是神经元

#Second Conv and Pool Layers
W_conv2 = tf.Variable(tf.truncated_normal([5, 5, 32, 64], stddev=0.1)) #第二个卷积核
b_conv2 = tf.Variable(tf.constant(.1, shape = [64]))
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)            #第二次池化

两个全连接层

两次全连接
第一次,以卷积输出 7乘7乘64通道 全连接为 连接成为一个一维向量1024个数据,
第二次,以第一次的一维向量1024个元素输入,全连接为10个元素,
10个元素就对应,输出的每一维都是图片y属于该类别的概率。

一次池化减二分之一,经过了两次变成7乘7

此时,图片是7x7的大小。我们在这里加入一个有1024个神经元的全连接层。之后把刚才池化后输出的张量reshape成一个一维向量,再将其与权重相乘,加上偏置项,再通过一个ReLU激活函数。

#First Fully Connected Layer                     
W_fc1 = tf.Variable(tf.truncated_normal([7 * 7 * 64, 1024], stddev=0.1))
b_fc1 = tf.Variable(tf.constant(.1, shape = [1024]))
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])        #把一个矩阵reshape成一个条,-1会自动适应,其实在这里就是1啦
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

#Dropout Layer
keep_prob = tf.placeholder("float")      #指定一个保留率
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)   #杀死部分神经元,防止过拟合

#Second Fully Connected Layer
W_fc2 = tf.Variable(tf.truncated_normal([1024, 10], stddev=0.1))
b_fc2 = tf.Variable(tf.constant(.1, shape = [10]))

#Final Layer
y = tf.matmul(h_fc1_drop, W_fc2) + b_fc2

利用的是跟前面回归一样的分类器

crossEntropyLoss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = y_, logits = y))
trainStep = tf.train.AdamOptimizer().minimize(crossEntropyLoss)#会自适应调节学习率,一次比一次小,比梯度下降优化器更好
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
sess.run(tf.global_variables_initializer())

batchSize = 50
for i in range(1000):
    batch = mnist.train.next_batch(batchSize)
    trainingInputs = batch[0].reshape([batchSize,28,28,1])
    trainingLabels = batch[1]
    if i%100 == 0:
        trainAccuracy = accuracy.eval(session=sess, feed_dict={x:trainingInputs, y_: trainingLabels, keep_prob: 1.0})
        print ("step %d, training accuracy %g"%(i, trainAccuracy))
    trainStep.run(session=sess, feed_dict={x: trainingInputs, y_: trainingLabels, keep_prob: 0.5})

输出结果:

step 0, training accuracy 0.1
step 100, training accuracy 0.94
step 200, training accuracy 0.98
step 300, training accuracy 1
step 400, training accuracy 0.98
step 500, training accuracy 0.96
step 600, training accuracy 0.94
step 700, training accuracy 0.98
step 800, training accuracy 0.98
step 900, training accuracy 0.98
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wujiekd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值