简单的卷积神经网络(CNN)的搭建

卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。与普通神经网络非常相似,它们都由具有可学习的权重和偏置常量(biases)的神经元组成。每个神经元都接收一些输入,并做一些点积计算,输出是每个分类的分数,普通神经网络里的一些计算技巧到这里依旧适用。

卷积神经网络通常包含以下几种层:

  • 卷积层(Convolutional layer),卷积神经网路中每层卷积层由若干卷积单元组成,每个卷积单元的参数都是通过反向传播算法优化得到的。卷积运算的目的是提取输入的不同特征,第一层卷积层可能只能提取一些低级的特征如边缘、线条和角等层级,更多层的网络能从低级特征中迭代提取更复杂的特征。
  • 线性整流层(Rectified Linear Units layer, ReLU layer),这一层神经的活性化函数(Activation function)使用线性整流(Rectified Linear Units, ReLU)f(x)=max(0,x)。
  • 池化层(Pooling layer),通常在卷积层之后会得到维度很大的特征,将特征切成几个区域,取其最大值或平均值,得到新的、维度较小的特征。
  • Drop out, 通常我们在训练Covnets时,会随机的丢弃一部分训练获得的参数,这样可以在一定程度上来防止过度拟合
  • 全连接层( Fully-Connected layer), 把所有局部特征结合变成全局特征,用来计算最后每一类的得分。

下面是代码部分,今天我将使用Covnets去完成一件非常非常简单的图像分类任务。这里我们将对 CIFAR-10 数据集 中的图片进行分类。该数据集包含飞机、猫狗和其他物体。

首先,我们先获得数据集 (或者直接从 https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz )这里直接下载

 1 from urllib.request import urlretrieve
 2 from os.path import isfile, isdir
 3 from tqdm import tqdm
 4 import tarfile
 5
 6 cifar10_dataset_folder_path = ‘cifar-10-batches-py‘
 7
 8 class DLProgress(tqdm):
 9     last_block = 0
10
11     def hook(self, block_num=1, block_size=1, total_size=None):
12         self.total = total_size
13         self.update((block_num - self.last_block) * block_size)
14         self.last_block = block_num
15
16 if not isfile(tar_gz_path):
17     with DLProgress(unit=‘B‘, unit_scale=True, miniters=1, desc=‘CIFAR-10 Dataset‘) as pbar:
18         urlretrieve(
19             ‘https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz‘,
20             tar_gz_path,
21             pbar.hook)
22
23 if not isdir(cifar10_dataset_folder_path):
24     with tarfile.open(tar_gz_path) as tar:
25         tar.extractall()
26         tar.close()

在数据载入之后,我们需要对我们的图片预处理下,因为现在的像素点是0-255之间,我们需要把图片的像素点的值变成0-1之间,这样方便在后面的计算

 1 def normalize(x):
 2     """
 3     Normalize a list of sample image data in the range of 0 to 1
 4     : x: List of image data.  The image shape is (32, 32, 3)
 5     : return: Numpy array of normalize data
 6     """
 7     a = 0
 8     b = 1
 9     grayscale_min = 0
10     grayscale_max = 255
11     return a + (((x - grayscale_min) * (b - a))/(grayscale_max - grayscale_min))

因为CIFAR数据集里面有10类不同的图片,现在我们需要使用ONE-HOT的方法来给图片打上标签

 1 def one_hot_encode(x):
 2     """
 3     One hot encode a list of sample labels. Return a one-hot encoded vector for each label.
 4     : x: List of sample Labels
 5     : return: Numpy array of one-hot encoded labels
 6     """
 7     d = {0:[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 8      1:[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 9      2:[0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
10      3:[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
11      4:[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
12      5:[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
13      6:[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
14      7:[0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
15      8:[0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
16      9:[0, 0, 0, 0, 0, 0, 0, 0, 0, 1]}
17
18     map_list = []
19     for item in x:
20         map_list.append(d[item])
21     target = np.array(map_list)
22
23     return target

下面,我们就开始构建我们的Covnets了,首先,我们需要构建placeholder来储存我们的训练图片,训练数据的one-hot标签的编码以及我们dropout时候的概率值

 1 import tensorflow as tf
 2
 3 def neural_net_image_input(image_shape):
 4     """
 5     Return a Tensor for a batch of image input
 6     : image_shape: Shape of the images
 7     : return: Tensor for image input.
 8     """
 9     x = tf.placeholder(tf.float32,[None, image_shape[0], image_shape[1],image_shape[2]],‘x‘)
10     return x
11
12
13 def neural_net_label_input(n_classes):
14     """
15     Return a Tensor for a batch of label input
16     : n_classes: Number of classes
17     : return: Tensor for label input.
18     """
19     y = tf.placeholder(tf.float32,[None, n_classes],‘y‘)
20     return y
21
22
23 def neural_net_keep_prob_input():
24     """
25     Return a Tensor for keep probability
26     : return: Tensor for keep probability.
27     """
28     keep_prob = tf.placeholder(tf.float32,None,‘keep_prob‘)
29     return keep_prob

接着 我们来构建Covnets中最核心的 卷积层+最大池化层(这里我们用最大池化)

 1 def conv2d_maxpool(x_tensor, conv_num_outputs, conv_ksize, conv_strides, pool_ksize, pool_strides):
 2     """
 3     Apply convolution then max pooling to x_tensor
 4     :param x_tensor: TensorFlow Tensor
 5     :param conv_num_outputs: Number of outputs for the convolutional layer
 6     :param conv_ksize: kernal size 2-D Tuple for the convolutional layer
 7     :param conv_strides: Stride 2-D Tuple for convolution
 8     :param pool_ksize: kernal size 2-D Tuple for pool
 9     :param pool_strides: Stride 2-D Tuple for pool
10     : return: A tensor that represents convolution and max pooling of x_tensor
11     """
12     ## Weights and Bias
13     weight = tf.Variable(tf.truncated_normal([conv_ksize[0],conv_ksize[1],
14                                               x_tensor.get_shape().as_list()[-1],conv_num_outputs],stddev=0.1))
15     bias = tf.Variable(tf.zeros(conv_num_outputs))
16     ## Apply Convolution
17     conv_layer = tf.nn.conv2d(x_tensor,weight,strides = [1,conv_strides[0],conv_strides[1],1], padding=‘SAME‘)
18     ## Add Bias
19     conv_layer = tf.nn.bias_add(conv_layer,bias)
20     ## Apply Relu
21     conv_layer = tf.nn.relu(conv_layer)
22
23     return tf.nn.max_pool(conv_layer,
24                           ksize=[1,pool_ksize[0],pool_ksize[1],1],
25                           strides=[1,pool_strides[0],pool_strides[1],1],
26                           padding=‘SAME‘)

实现 flatten 层,将 x_tensor 的维度从四维张量(4-D tensor)变成二维张量。输出应该是形状(部分大小(Batch Size),扁平化图片大小(Flattened Image Size))

 1 def flatten(x_tensor):
 2     """
 3     Flatten x_tensor to (Batch Size, Flattened Image Size)
 4     : x_tensor: A tensor of size (Batch Size, ...), where ... are the image dimensions.
 5     : return: A tensor of size (Batch Size, Flattened Image Size).
 6     """
 7     # Get the shape of tensor
 8     shape = x_tensor.get_shape().as_list()
 9     # Compute the dim for image
10     dim = np.prod(shape[1:])
11     # reshape the tensor
12
13     return tf.reshape(x_tensor, [-1,dim])

在网络的最后一步,我们需要做一个全连接层 + 输出层,然后输出一个1*10的结果(10种结果的概率)

 1 def fully_conn(x_tensor, num_outputs):
 2     """
 3     Apply a fully connected layer to x_tensor using weight and bias
 4     : x_tensor: A 2-D tensor where the first dimension is batch size.
 5     : num_outputs: The number of output that the new tensor should be.
 6     : return: A 2-D tensor where the second dimension is num_outputs.
 7     """
 8     weight = tf.Variable(tf.truncated_normal([x_tensor.get_shape().as_list()[-1], num_outputs],stddev=0.1))
 9     bias = tf.Variable(tf.zeros([num_outputs]))
10
11     fc = tf.reshape(x_tensor,[-1, weight.get_shape().as_list()[0]])
12     fc = tf.add(tf.matmul(fc,weight), bias)
13     fc = tf.nn.relu(fc)
14
15     return fc
16
17 def output(x_tensor, num_outputs):
18     """
19     Apply a output layer to x_tensor using weight and bias
20     : x_tensor: A 2-D tensor where the first dimension is batch size.
21     : num_outputs: The number of output that the new tensor should be.
22     : return: A 2-D tensor where the second dimension is num_outputs.
23     """
24
25     weight_out = tf.Variable(tf.truncated_normal([x_tensor.get_shape().as_list()[-1],num_outputs],stddev=0.1))
26     bias_out = tf.Variable(tf.zeros([num_outputs]))
27
28     out = tf.reshape(x_tensor, [-1, weight_out.get_shape().as_list()[0]])
29     out = tf.add(tf.matmul(out,weight_out),bias_out)
30
31     return out

在我们都完成基本的元素之后,我们这个时候来构建我们的网络

 1 def conv_net(x, keep_prob):
 2     """
 3     Create a convolutional neural network model
 4     : x: Placeholder tensor that holds image data.
 5     : keep_prob: Placeholder tensor that hold dropout keep probability.
 6     : return: Tensor that represents logits
 7     """
 8
 9     conv1 = conv2d_maxpool(x, 32,(5,5),(2,2),(4,4),(2,2))
10
11     conv2 = conv2d_maxpool(conv1, 128, (5,5),(2,2),(2,2),(2,2))
12
13     conv3 = conv2d_maxpool(conv2, 256, (5,5),(2,2),(2,2),(2,2))
14
15
16     #   flatten(x_tensor)
17
18     flatten_layer = flatten(conv3)
19
20     #   fully_conn(x_tensor, num_outputs)
21
22     fc = fully_conn(flatten_layer, 1024)
23
24     #    Set this to the number of classes
25     # Function Definition from Above:
26     #   output(x_tensor, num_outputs)
27
28     output_layer = output(fc, 10)
29
30     return output_layer
31
32
33 ##############################
34 ## Build the Neural Network ##
35 ##############################
36
37 # Remove previous weights, bias, inputs, etc..
38 tf.reset_default_graph()
39
40 # Inputs
41 x = neural_net_image_input((32, 32, 3))
42 y = neural_net_label_input(10)
43 keep_prob = neural_net_keep_prob_input()
44
45 # Model
46 logits = conv_net(x, keep_prob)
47
48 # Name logits Tensor, so that is can be loaded from disk after training
49 logits = tf.identity(logits, name=‘logits‘)
50
51 # Loss and Optimizer
52 cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))
53 optimizer = tf.train.AdamOptimizer().minimize(cost)
54
55 # Accuracy
56 correct_pred = tf.equal(tf.argmax(logits, 1), tf.argmax(y, 1))
57 accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32), name=‘accuracy‘)

在网络构建完成后,我们可以开始把我们的数据喂进去,训练我们的模型了

这里我随便设置下Hyper-Paramter

1 epochs = 30
2 batch_size = 256
3 keep_probability = 0.5

还需要设置下,在训练的过程中,我们一直需要看到测试集的accuracy来观测我们训练的情况

 1 def print_stats(session, feature_batch, label_batch, cost, accuracy):
 2     """
 3     Print information about loss and validation accuracy
 4     : session: Current TensorFlow session
 5     : feature_batch: Batch of Numpy image data
 6     : label_batch: Batch of Numpy label data
 7     : cost: TensorFlow cost function
 8     : accuracy: TensorFlow accuracy function
 9     """
10     loss = sess.run(cost, feed_dict = {
11         x:feature_batch,
12         y:label_batch,
13         keep_prob:1.
14     })
15
16     valid_acc = sess.run(accuracy,feed_dict = {
17         x:valid_features,
18         y:valid_labels,
19         keep_prob:1.
20     })
21
22     print(‘Loss: {:>10.4f} Validation Accuracy: {:.6f}‘.format(
23                 loss,
24                 valid_acc))

模型训练

 1 save_model_path = ‘./image_classification‘
 2
 3 print(‘Training...‘)
 4 with tf.Session() as sess:
 5     # Initializing the variables
 6     sess.run(tf.global_variables_initializer())
 7
 8     # Training cycle
 9     for epoch in range(epochs):
10         # Loop over all batches
11         n_batches = 5
12         for batch_i in range(1, n_batches + 1):
13             for batch_features, batch_labels in helper.load_preprocess_training_batch(batch_i, batch_size):
14                 train_neural_network(sess, optimizer, keep_probability, batch_features, batch_labels)
15             print(‘Epoch {:>2}, CIFAR-10 Batch {}:  ‘.format(epoch + 1, batch_i), end=‘‘)
16             print_stats(sess, batch_features, batch_labels, cost, accuracy)
17
18     # Save Model
19     saver = tf.train.Saver()
20     save_path = saver.save(sess, save_model_path)

贴上我在训练的最后的验证集的准确率

Epoch 29, CIFAR-10 Batch 4:  Loss:     0.0139 Validation Accuracy: 0.625600
Epoch 29, CIFAR-10 Batch 5:  Loss:     0.0090 Validation Accuracy: 0.631000
Epoch 30, CIFAR-10 Batch 1:  Loss:     0.0138 Validation Accuracy: 0.638800
Epoch 30, CIFAR-10 Batch 2:  Loss:     0.0192 Validation Accuracy: 0.627400
Epoch 30, CIFAR-10 Batch 3:  Loss:     0.0055 Validation Accuracy: 0.633400
Epoch 30, CIFAR-10 Batch 4:  Loss:     0.0114 Validation Accuracy: 0.641800
Epoch 30, CIFAR-10 Batch 5:  Loss:     0.0050 Validation Accuracy: 0.647400

还不错,50%以上了,如果瞎猜 只有10%的

当然了,我们的模型的效率可以进一步提高,比如我们进一步去选择更合适的超参数,或者加入一些其他的技巧。

http://rodrigob.github.io/are_we_there_yet/build/classification_datasets_results.html#43494641522d3130

这里有个链接,是大家利用这个数据集训练的结果,现在最高的已经96.53%了,看看大佬们是怎么做的吧。。。。

原文地址:https://www.cnblogs.com/chenyusheng0803/p/9030679.html

时间: 2024-11-04 01:14:59

简单的卷积神经网络(CNN)的搭建的相关文章

卷积神经网络(CNN)的简单实现(MNIST)

卷积神经网络(CNN)的基础介绍见http://blog.csdn.net/fengbingchun/article/details/50529500,这里主要以代码实现为主. CNN是一个多层的神经网络,每层由多个二维平面组成,而每个平面由多个独立神经元组成. 以MNIST作为数据库,仿照LeNet-5和tiny-cnn( http://blog.csdn.net/fengbingchun/article/details/50573841 ) 设计一个简单的7层CNN结构如下: 输入层Inpu

深度学习之卷积神经网络CNN及tensorflow代码实现示例

一.CNN的引入 在人工的全连接神经网络中,每相邻两层之间的每个神经元之间都是有边相连的.当输入层的特征维度变得很高时,这时全连接网络需要训练的参数就会增大很多,计算速度就会变得很慢,例如一张黑白的 28×28 的手写数字图片,输入层的神经元就有784个,如下图所示: 若在中间只使用一层隐藏层,参数 w 就有 784×15=11760 多个:若输入的是28×28 带有颜色的RGB格式的手写数字图片,输入神经元就有28×28×3=2352 个-- .这很容易看出使用全连接神经网络处理图像中的需要训

《神经网络与深度学习》(五) 卷积神经网络CNN及tensorflow代码实现示例

转自:http://blog.csdn.net/cxmscb/article/details/71023576 一.CNN的引入 在人工的全连接神经网络中,每相邻两层之间的每个神经元之间都是有边相连的.当输入层的特征维度变得很高时,这时全连接网络需要训练的参数就会增大很多,计算速度就会变得很慢,例如一张黑白的 28×28 的手写数字图片,输入层的神经元就有784个,如下图所示: 若在中间只使用一层隐藏层,参数 w 就有 784×15=11760 多个:若输入的是28×28 带有颜色的RGB格式的

卷积神经网络CNN总结

从神经网络到卷积神经网络(CNN)我们知道神经网络的结构是这样的: 那卷积神经网络跟它是什么关系呢?其实卷积神经网络依旧是层级网络,只是层的功能和形式做了变化,可以说是传统神经网络的一个改进.比如下图中就多了许多传统神经网络没有的层次. 卷积神经网络的层级结构      ? 数据输入层/ Input layer ? 卷积计算层/ CONV layer ? ReLU激励层 / ReLU layer ? 池化层 / Pooling layer ? 全连接层 / FC layer 1.数据输入层该层要

卷积神经网络(CNN)模型结构

卷积神经网络(CNN)模型结构 转载:http://www.cnblogs.com/pinard/p/6483207.html 看到的一片不错的文章,先转过来留着,怕以后博主删了.哈哈哈 在前面我们讲述了DNN的模型与前向反向传播算法.而在DNN大类中,卷积神经网络(Convolutional Neural Networks,以下简称CNN)是最为成功的DNN特例之一.CNN广泛的应用于图像识别,当然现在也应用于NLP等其他领域,本文我们就对CNN的模型结构做一个总结. 在学习CNN前,推荐大家

人工智能之卷积神经网络(CNN)

前言:人工智能机器学习有关算法内容,请参见公众号“科技优化生活”之前相关文章.人工智能之机器学习主要有三大类:1)分类;2)回归;3)聚类.今天我们重点探讨一下卷积神经网络(CNN)算法. ^_^ 20世纪60年代,Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性,继而提出了卷积神经网络CNN(Convolutional Neural Networks). 1980年,K.Fukushima提出的新识别机是卷积神经网络

卷积神经网络(CNN)学习笔记1:基础入门

卷积神经网络(CNN)学习笔记1:基础入门 Posted on 2016-03-01   |   In Machine Learning  |   9 Comments  |   14935  Views 概述 卷积神经网络(Convolutional Neural Network, CNN)是深度学习技术中极具代表的网络结构之一,在图像处理领域取得了很大的成功,在国际标准的ImageNet数据集上,许多成功的模型都是基于CNN的.CNN相较于传统的图像处理算法的优点之一在于,避免了对图像复杂的

深度学习(一) 卷积神经网络CNN

Contents 图像数据集基础 全连接神经网络解决图片问题的弊端(前世) 卷积神经网络的今生 网络结构 卷积操作 池化操作 小结 图像数据集基础 数字图像划分为彩色图像.灰度图像.二值图像和索引图像几种.其中,像素是构成图像的基本单位,例如一张28×28像素的图片,即表示横向有28个像素点,纵向有28个像素点. 最常用的彩色图像和灰度图像: 彩色图像:每个像素由RGB三个分量来表示,即红绿蓝.每个分量介于(0,255).那么,对于一个28×28的彩色图像,便可以由三个表示RGB颜色分量的28×

卷积神经网络CNN

本文学习笔记的部分内容參考zouxy09的博客,谢谢!http://blog.csdn.net/zouxy09/article/details/8775360 什么是卷积 卷积假设改名为"加权平均积",就会非常好理解了.卷积的离散形式就是经常使用的加权平均.而连续形式则可理解为对连续函数的加权平均.假如我们观測或计算出一组数据.但数据因为受噪音的污染并不光滑.我们希望对其进行人工处理. 那么.最简单的方法就是加权平均.实际上加权平均是两个序列在做离散卷积,当中一个序列是权重,还有一个序