CNN基本介绍
- 卷积神经网络的概念最早出自19世纪60年代科学家提出的感受野(Receptive Field)。当时科学家对猫的视觉皮层细胞进行研究发现,每一个视觉神经元只会处理一小块的视觉图像,即感受野。
- CNN的最大特点在于卷积的权值共享结构,可以大幅度减少神经网络的参数量,防止过拟合同时又降低了神经网络模型的复杂度。
- 一般的卷积神经网络有多个卷基层构成,每个卷积层通常进行如下操作:
- 图像通过多个不同的卷积核的滤波,并加以偏置(bias),提取局部特征,每一个卷积核会映射出一个新的2D图像。
- 将前面的卷积核的滤波输出结果,进行非线性的激活函数处理。目前常见的是使用ReLU函数。
- 对激活函数的结果进行池化操作。
- 一个卷积核滤波得到的图像就是一类特征的映射,即一个Feature Map。
- 一个卷积层可以有多个不同的卷积核,而每一个卷积核都对应一个滤波后映射出的新图像,同一个新图像中每一个像素都来自完全相同的卷积核,这就是权值共享。
- eg:第一个卷积层C1包含6个卷积核,尺寸大小为5*5,即总共(5*5+1)*6个参数,其中1表示bias。
代码
import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)
sess = tf.InteractiveSession()
def weight_variable(shape):
init = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(init)
def bias_variable(shape):
init = tf.constant(0.1, shape=shape)
return tf.Variable(init)
"""
卷积
x: 代表输入
W: 卷积的参数
eg: [5, 5, 1, 32]
卷积核尺寸为5*5
图片channel为1,这里是灰度图片,如果RGB,值为3
卷积核的数量为32,也就是这个卷积层会提取多少特征
strides: 卷积模板移动步长,都为1表示不遗漏划过图片每一个点
表示步长:一个长度为4的一维列表,每个元素跟data_format互相对应,
表示在data_format每一维上的移动步长。当输入的默认格式为:“NHWC”,
则 strides = [batch , in_height , in_width, in_channels]。
其中 batch 和 in_channels 要求一定为1,即只能在一个样本的一个通
道上的特征图上进行移动,in_height , in_width表示卷积核在特征图的
高度和宽度上移动的布长,即 strideheight 和 stridewidth 。
padding: 边界的处理方式.
SAME简单地理解为以0填充边缘,但还有一个要求,左边(上边)补0的个数和右边(下边)补0的个数一样或少一个,
VALID表示采用不填充的方式,多余地进行丢弃。具体公式:
“SAME”: output_spatial_shape[i]=(input_spatial_shape[i] / strides[i])
“VALID”: output_spatial_shape[i]=((input_spatial_shape[i]-(spatial_filter_shape[i]-1)/strides[i])
"""
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
"""
ksize: 表示池化窗口的大小:一个长度为4的一维列表,一般为[1, height, width, 1],
因不想在batch和channels上做池化,则将其值设为1。
"""
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])
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)
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_f1 = weight_variable([7*7*64, 1024])
b_f1 = 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_f1) + b_f1)
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
W_f2 = weight_variable([1024, 10])
b_f2 = bias_variable([10])
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_f2) + b_f2)
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))
test_images = tf.placeholder(tf.float32, [None, 784])
test_labels = tf.placeholder(tf.float32, [None, 10])
tf.global_variables_initializer().run()
for i in range(3000):
batch = mnist.train.next_batch(50)
if (i%100 == 0):
train_accurancy = accuracy.eval(feed_dict={x: batch[0], y_: batch[1], keep_prob : 1.0})
print("step %d, traning accurancy %g" % (i, train_accurancy))
sess.run(train_step, feed_dict={x: batch[0], y_: batch[1], keep_prob : 0.5})
test_images = mnist.test.images[0:300, :]
test_labels = mnist.test.labels[0:300, :]
print("test accuracy %g" % accuracy.eval({x: test_images, y_: test_labels, keep_prob: 1.0}))
运行结果
step 0, traning accurancy 0.02
step 100, traning accurancy 0.8
step 200, traning accurancy 0.94
step 300, traning accurancy 0.86
step 400, traning accurancy 0.94
step 500, traning accurancy 0.96
step 600, traning accurancy 1
step 700, traning accurancy 0.92
step 800, traning accurancy 0.96
step 900, traning accurancy 0.96
step 1000, traning accurancy 0.98
step 1100, traning accurancy 0.96
step 1200, traning accurancy 1
step 1300, traning accurancy 1
step 1400, traning accurancy 1
step 1500, traning accurancy 0.98
step 1600, traning accurancy 0.98
step 1700, traning accurancy 0.96
step 1800, traning accurancy 0.98
step 1900, traning accurancy 0.96
step 2000, traning accurancy 0.94
step 2100, traning accurancy 0.92
step 2200, traning accurancy 0.98
step 2300, traning accurancy 0.98
step 2400, traning accurancy 0.96
step 2500, traning accurancy 1
step 2600, traning accurancy 0.96
step 2700, traning accurancy 1
step 2800, traning accurancy 1
step 2900, traning accurancy 0.98
test accuracy 0.99
代码
import tensorflow as tf
import cifar10, cifar10_input
import numpy as np
import time
max_steps = 3000
batch_size = 128
data_dir = '/tmp/cifar10_data/cifar-10-batches-bin'
def variable_with_weight_loss(shape, stddev, w1):
var = tf.Variable(tf.truncated_normal(shape, stddev=stddev))
if w1 is not None:
weight_loss = tf.multiply(tf.nn.l2_loss(var), w1, name='weight_loss')
tf.add_to_collection('losses', weight_loss)
return var
cifar10.maybe_download_and_extract()
images_train, labels_train = cifar10_input.distorted_inputs(data_dir=data_dir, batch_size=batch_size)
images_test, labels_test = cifar10_input.inputs(eval_data=True, data_dir=data_dir, batch_size=batch_size)
image_holder = tf.placeholder(tf.float32, [batch_size, 24, 24, 3])
label_holder = tf.placeholder(tf.int32, [batch_size])
weigth1 = variable_with_weight_loss(shape=[5, 5, 3, 64], stddev=5e-2, w1=0.0)
kernel1 = tf.nn.conv2d(image_holder, weigth1, [1, 1, 1, 1], padding='SAME')
bias1 = tf.Variable(tf.constant(0.0, shape=[64]))
conv1 = tf.nn.relu(tf.nn.bias_add(kernel1, bias1))
pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')
norml = tf.nn.lrn(pool1, 4, bias=1.0, alpha=0.001/9.0, beta=0.75)
weigth2 = variable_with_weight_loss(shape=[5, 5, 64, 64], stddev=5e-2, w1=0.0)
kernel2 = tf.nn.conv2d(norml, weigth2, [1, 1, 1, 1], padding='SAME')
bias2 = tf.Variable(tf.constant(0.0, shape=[64]))
conv2 = tf.nn.relu(tf.nn.bias_add(kernel2, bias2))
norm2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001/9.0, beta=0.75)
pool2 = tf.nn.max_pool(norm2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')
reshape = tf.reshape(pool2, [batch_size, -1])
dim = reshape.get_shape()[1].value
weight3 = variable_with_weight_loss(shape=[dim, 384], stddev=0.04, w1=0.004)
bias3 = tf.Variable(tf.constant(0.1, shape=[384]))
local3 = tf.nn.relu(tf.matmul(reshape, weight3) + bias3)
weight4 = variable_with_weight_loss(shape=[384, 192], stddev=0.04, w1=0.004)
bias4 = tf.Variable(tf.constant(0.1, shape=[192]))
local4 = tf.nn.relu(tf.matmul(local3, weight4) + bias4)
weight5 = variable_with_weight_loss(shape=[192, 10], stddev=1/192.0, w1=0.0)
bias5 = tf.Variable(tf.constant(0.1, shape=[10]))
logits = tf.add(tf.matmul(local4, weight5), bias5)
def loss(logits, labels):
labels = tf.cast(labels, tf.int64)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels, name='cross_entropy_per_wxample')
cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')
tf.add_to_collection('losses', cross_entropy_mean)
return tf.add_n(tf.get_collection('losses'), name='total_loss')
loss = loss(logits, label_holder)
train_op = tf.train.AdamOptimizer(1e-3).minimize(loss)
top_k_op = tf.nn.in_top_k(logits, label_holder, 1)
sess = tf.InteractiveSession()
tf.global_variables_initializer().run()
tf.train.start_queue_runners()
for step in range(200):
start_time = time.time()
image_batch, label_batch = sess.run([images_train, labels_train])
_, loss_value = sess.run([train_op, loss], feed_dict={image_holder: image_batch, label_holder: label_batch})
duration = time.time() - start_time
if (step % 100 == 0):
exmaples_per_sec = batch_size / duration
sec_per_batch = float(duration)
format_src = ('step %d, loss = %.2f(%.1f examlpes/sec, %.3f sec/batch)')
print(format_src % (step, loss_value, exmaples_per_sec, sec_per_batch))
num_examples = 1000
import math
num_iter = int(math.ceil(num_examples / batch_size))
true_count = 0
total_sample_count = num_iter * batch_size
step = 0
while step < num_iter:
image_batch, label_batch = sess.run([images_test, labels_test])
predicition = sess.run([top_k_op], feed_dict={image_holder: image_batch, label_holder: label_batch})
true_count += np.sum(predicition)
step += 1
precision = true_count / total_sample_count
print('precision = %.3f' % precision)
运行结果
step 0, loss = 4.67(48.7 examlpes/sec, 2.629 sec/batch)
step 100, loss = 1.89(242.1 examlpes/sec, 0.529 sec/batch)
step 200, loss = 1.95(224.8 examlpes/sec, 0.569 sec/batch)
step 300, loss = 1.61(243.5 examlpes/sec, 0.526 sec/batch)
step 400, loss = 1.45(237.7 examlpes/sec, 0.538 sec/batch)
step 500, loss = 1.45(268.5 examlpes/sec, 0.477 sec/batch)
step 600, loss = 1.43(245.8 examlpes/sec, 0.521 sec/batch)
step 700, loss = 1.17(227.3 examlpes/sec, 0.563 sec/batch)
step 800, loss = 1.38(215.6 examlpes/sec, 0.594 sec/batch)
step 900, loss = 1.45(260.5 examlpes/sec, 0.491 sec/batch)
step 1000, loss = 1.39(226.1 examlpes/sec, 0.566 sec/batch)
step 1100, loss = 1.38(266.3 examlpes/sec, 0.481 sec/batch)
step 1200, loss = 1.36(230.3 examlpes/sec, 0.556 sec/batch)
step 1300, loss = 1.19(217.4 examlpes/sec, 0.589 sec/batch)
step 1400, loss = 1.26(270.3 examlpes/sec, 0.474 sec/batch)
step 1500, loss = 1.16(277.0 examlpes/sec, 0.462 sec/batch)
step 1600, loss = 1.10(244.0 examlpes/sec, 0.525 sec/batch)
step 1700, loss = 1.23(272.3 examlpes/sec, 0.470 sec/batch)
step 1800, loss = 1.24(289.6 examlpes/sec, 0.442 sec/batch)
step 1900, loss = 1.07(274.2 examlpes/sec, 0.467 sec/batch)
step 2000, loss = 1.23(281.0 examlpes/sec, 0.456 sec/batch)
step 2100, loss = 1.23(278.8 examlpes/sec, 0.459 sec/batch)
step 2200, loss = 1.14(257.5 examlpes/sec, 0.497 sec/batch)
step 2300, loss = 0.94(261.4 examlpes/sec, 0.490 sec/batch)
step 2400, loss = 1.06(175.3 examlpes/sec, 0.730 sec/batch)
step 2500, loss = 1.15(230.4 examlpes/sec, 0.556 sec/batch)
step 2600, loss = 1.08(250.8 examlpes/sec, 0.510 sec/batch)
step 2700, loss = 1.15(253.3 examlpes/sec, 0.505 sec/batch)
step 2800, loss = 1.10(250.6 examlpes/sec, 0.511 sec/batch)
step 2900, loss = 1.10(220.0 examlpes/sec, 0.582 sec/batch)
precision = 0.738