加入收藏 | 设为首页 |

大明宫-手把手教你运用卷积神经网络构建图画分类器

海外新闻 时间: 浏览:198 次
全文共8600字,估计学习时长40分钟或更长

图片来历:pexels.com


神经网络由具有权重和误差的神经元组成。经过在练习进程中调整这些权重和误差,以提出杰出的学习模型。每个神经元接纳一组输入,以某种方法处理它,然后输出一个值。假如构建一个具有多层的神经网络,则将其称为深度神经网络。处理这些深度神经网络的人工智能学分支被称为深度学习。



一般神经网络的首要缺陷是其疏忽了输入数据的结构。在将数据馈送到神经网络之前,一切数据都将转换为一维数组。这适用于大明宫-手把手教你运用卷积神经网络构建图画分类器惯例数据,但在处理图画时会遇到困难。

考虑到灰度图画是2D结构,像素的空间摆放有许多躲藏信息。若疏忽这些信息,则将失掉许多潜在的形式。这便是卷积神经网络(CNN)被引进图画处理的原因。CNN在处理图画时会考虑图画的2D结构。

CNN也是由具有权重和误差的神经元组成。这些神经元接纳输入的数据并处理,然后输出信息。神经网络的方针是将输入层中的原始图画数据转到输出层中的正确类中。一般神经网络和CNN之间的差异在于运用的层类型以及处理输入数据的方法。假定CNN的输入是图画,这答应其提取特定于图画的特点。这使得CNN在处理图画方面更有功率。那么,CNN是怎么构建的?

CNN的体系结构


当运用一般神经网络时,需求将输入数据转换为单个向量。该向量作为神经网络的输入,然后向量穿过神经网络的各层。在这些层中,每个神经元都与前一层中的一切神经元相衔接。值得注意的是,同层的神经元互不衔接。它们仅与相邻层的神经元相连。网络中的终究一层是输出层,它代表终究输出。

若将这种结构用于图画处理,它将很快变得难以办理。例如,一个由256x256RGB图画组成的图画数据集。因为这是3维图画,因而将有256 * 256 * 3 = 196,608个权重。请意,这仅适用于单个神经元!每层都有多个神经元,因而权重的数量敏捷添加。这意味着在练习进程中,该模型将需求很多参数来调整权重。这便是该结构杂乱和耗时的原因。将每个神经元衔接到前一层中的每个神经元,称为彻底衔接,这明显不适用于图画处理。

CNN在处理数据时清晰考虑图画的结构。CNN中的神经元按三维摆放——宽度、高度和深度。当时层中的每个神经元都衔接到前一层输出的小块。这就像在输入图画上叠加NxN过滤器相同。这与彻底衔接的层相反,彻底衔接层的每个神经元均与前一层的一切神经元相连。

因为单个过滤器无法捕获图画的一切细微差别,因而需求花费数倍的时刻(假定M倍)保证捕获一切细节。这M个过滤器充任特征提取器。假如检查这些过滤器的输出,能够检查层的提取特征,如边际、角等。这适用于CNN中的初始层。跟着在神经网络层中的图画处理的开展,可看到后边的层将提取更高等级的特征。


CNN中的层类型


了解了CNN的架构,持续看看用于构建CNN各层的类型。CNN一般运用以下类型的层:

输入层:用于原始图画数据的输入。

卷积层:该层核算神经元与输入中各种切片之间的卷积。


卷积层基本上核算权重和前一层输出的切片之间的点积。

鼓励层:此图层将激活函数应用于前一图层的输出。该函数类似于max(0,x)。需求向该层神经网络添加非线性映射,以便它能够很好地归纳为任何类型的功用。

池化层:此层对前一层的输出进行采样,然后生成具有较小维度的结构。在网络中处理图画时,池化有助于只保存杰出的部分。最大池是池化层最常用的,可在给定的KxK窗口中挑选最大值。

全衔接层:此图层核算终究一层的输出分。输出成果的巨细为1x1xL,其间L是练习数据会集的类数。

从神经网络中的输入层到输出层时,输入图画将从像素值转换为终究的类得分。现已提出了许多不同的CNN架构,它是一个活泼的研讨范畴。模型的准确性和鲁棒性取决于许多要素- 层的类型、网络的深度、网络中各种类型的层的摆放、为每层挑选的功用和练习数据等。


构建依据感知器的线性回归量


接下来是有关怎么用感知器构建线性回归模型。

本文将会运用TensorFlow。它是一种盛行的深度学习软件包,广泛用于构建各种实在国际的体系中。在本节,咱们whistle将了解它的作业原理。在运用软件包前先装置它。


保证它已装置后,创立一个新的python程序并导入以下包:

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


使模型习惯生成的数据点。界说要生成的数据点的数量:

# Define the number of points to generate 
num_points = 1200


界说将用于生成数据的参数。运用线性模型:y =mx + c:

# Generate the data based on equation y = mx + c 
data = []
m = 0.2
c = 0.5
for i in range(num_points):
# Generate 'x'
x = np.random.normal(0.0, 0.8)


生成的噪音使数据发生变化:

# Generate some noise 
noise = np.random.normal(0.0, 0.04)


运用以下等式核算y的值:

# Compute 'y' 
y = m*x + c + noise
data.append([x, y])


完结迭代后,将数据分红输入和输出变量:

# Separate x and y 
x_data = [d[0] for d in data]
y_data = [d[1] for d in data


制作数据:

# Plot the generated data 
plt.plot(x_data, y_data, 'ro')
plt.title('Input data')
plt.show()


为感知器生成权重和误差。权重由一致的随机数生成器生成,并将误差设置为零:

# Generate weights and biases 
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))


运用TensorFlow变量界说等式:

# Define equation for 'y' 
y = W * x_data + b


界说练习进程运用的丢掉函数。优化器将使丢掉函数的值尽可能地减小。

# Define how to compute the loss 
loss = tf.reduce_mean(tf.square(y - y_data))


界说梯度下降优化器并指定丢掉函数:

# Define the gradient descent optimizer 
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)


一切变量都已到位,但没有初始化。接下来:

# Initialize all the variables 
init = tf.initialize_all_variables()


发动TensorFlow会话并运用初始化程序运转它:

# Start the tensorflow session and run it 
sess = tf.Session()
sess.run(init)


开端练习:

# Start iterating 
num_iterations = 10
for step in range(num_iterations):
# Run the session
sess.run(train)


打印练习进展。进行迭代时,丢掉参数将持续削减:

# Print the progress 
print('\nITERATION', step+1)
print('W =', sess.run(W)[0])
print('b =', sess.run(b)[0])
print('loss =', sess.run(loss))


制作生成的数据并在顶部掩盖猜测的模型。该情况下,模型是一条线:

# Plot the input data 
plt.plot(x_data, y_data, 'ro')
# Plot the predicted output line
plt.plot(x_data, sess.run(W) * x_data + sess.run(b))


设置绘图的参数:

# Set plotting parameters 
plt.xlabel('Dimension 0')
plt.ylabel('Dimension 1')
plt.title('Iteration ' + str(step+1) + ' of ' + str(num_iterations))
plt.show()


完好代码在linear_regression.py文件中给出。运转代码将看到以下屏幕截图显现输入数据:



假如封闭此窗口,将看到练习进程。第一次迭代看起来像这样:

可看到,线路彻底违背模型。封闭此窗口以转到下一个迭代:



这条线好像更好,但它依然违背模型。封闭此窗口并持续迭代:



看起来这条线越来越挨近实在的模型。假如持续像这样迭代,模型会变得更好。第八次迭代看起来如下:

该线与数据拟合的很好。将在终端上看到以下内容:



完结练习后,在终端上看到以下内容:



运用单层神经网络构建图画分类器

怎么运用TensorFlow创立单层神经网络,并运用它来构建图画分类器?运用MNIST图画数据集来构建体系。它是包括手写的数字图画的数据集。其方针是构建一个能够正确辨认每个图画中数字的分类器。


图片来历:pexels.com


创立新的python程序并导入以下包:

import argparse 
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data


界说一个解析输入参数的函数:

def build_arg_parser():
parser = argparse.ArgumentParser(description='Build a classifier using
\MNIST data')
parser.add_argument('--input-dir', dest='input_dir', type=str,
default='./mnist_data', help='Directory for storing data')
return parser


界说main函数并解析输入参数:

if __name__ == '__main__': 
args = build_arg_parser().parse_args()


提取MNIST图画数据。one_hot标志指定将在标签中运用单热编码。这意味着假如有n个类,那么给定数据点的标签将是长度为n的数组。此数组中的每个元素都对应一个特定的类。要指定一个类,相应索引处的值将设置为1,其他一切值为0:

# Get the MNIST data 
mnist = input_data.read_data_sets(args.input_dir, one_hot=True)


数据库中的图画是28 x 28像素。需将其转换为单维数组以创立输入图层:

# The images are 28x28, so create the input layer 
# with 784 neurons (28x28=784)
x = tf.placeholder(tf.float32, [None, 784])


创立具有权重和误差的单层神经网络。数据库中有10个不同的数字。输入层中的神经元数量为784,输出层中的神经元数量为10:

# Create a layer with weights and biases. There are 10 distinct 
# digits, so the output layer should have 10 classes
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))


创立用于练习的等式:

# Create the equation for 'y' using y = W*x + b 
y = tf.matmul(x, W) + b


界说丢掉函数和梯度下降优化器:

# Define the entropy loss and the gradient descent optimizer 
y_loss = tf.placeholder(tf.float32, [None, 10])
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_loss))
optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss)


初始化一切变量:

# Initialize all the variables 
init = tf.initialize_all_variables()


创立TensorFlow会话并运转:

# Create a session 
session = tf.Session()
session.run(init)


开端练习进程。运用当时批次运转优化器的批次进行练习,然后持续下一批次进行下一次迭代。每次迭代的第一步是获取下一批要练习的图画:

# Start training 
num_iterations = 1200
batch_size = 90
for _ in range(num_iterations):
# Get the next batch of images
x_batch, y_batch = mnist.train.next_batch(batch_size)


在这批图画上运转优化器:

# Train on 大明宫-手把手教你运用卷积神经网络构建图画分类器this batch of images 
session.run(optimizer, feed_dict = {x: x_batch, y_loss: y_batch})


练习进程完毕后,运用测试数据集核算准确度:

# Compute the accuracy using test data 
predicted = tf.equal(tf.argmax(y, 1), tf.argmax(y_loss, 1))
accuracy = tf.reduce_mean(tf.cast(predicted, tf.float32))
print('\nAccuracy =', session.run(accuracy, feed_dict = {
x: mnist.test.images,
y_loss: mnist.test.labels}))


完好代码在single_layer.py文件中给出。假如运转代码,它会将数据下载到当时文件夹中名为mnist_data的文件夹中。这是默许选项。假如要更改它,能够运用输入参数履行此操作。运转代码后,将在终端上取得以下输出:



正如终端上打印所示,模型的准确率为92.1%。


运用卷积神经网络构建图画分类器


上一节中的图画分类器体现欠安。取得92.1%的MNIST数据集相对简略。怎么运用卷积神经网络(CNN)来完成更高的精度呢?下面将运用相同的数据集构建图画分类器,但运用CNN而不是单层神经网络。

创立一个新的python程序并导入以下包:

import argparse 
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data


界说一个解析输入参数的函数:

def build_arg_parser(): 
parser = argparse.ArgumentParser(description='Build 大明宫-手把手教你运用卷积神经网络构建图画分类器a CNN classifier \
using MNIST data')
parser.add_argument('--input-dir', dest='input_dir', type=str,
default='./mnist_data', help='Directory for storing data')
return parser


界说一个函数来为每个层中的权重创立值:

def get_weights(shape): 
data = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(data)


界说一个函数来为每个层中的误差创立值:

def get大明宫-手把手教你运用卷积神经网络构建图画分类器_biases(shape): 
data = tf.constant(0.1, shape=shape)
return tf.Variable(data)


界说一个函数以依据输入形状创立图层:

def create_layer(shape): 
# Get the weights and biases
W = get_weights(shape)
b = get_biases([shape[-1]])

return W, b


界说履行2D卷积功用的函数:

def convolution_2d(x, W): 
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1],
padding='SAME')


界说一个函数来履行2x2最大池操作:

def max_pooling(x): 
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')


界说main函数并解析输入参数:

if __name__ == '__main__': 
args = build_arg_parser().parse_args()


提取MNIST图画数据:

# Get the MNIST da大明宫-手把手教你运用卷积神经网络构建图画分类器ta 
mnist = input_data.read_data_sets(args.input_dir, one_hot=True)


运用784个神经元创立输入层:

# The images are 28x28, so create the input layer 
# with 784 neurons (28x28=784)
x = tf.placeholder(tf.float32, [None, 784])


接下来是运用图画2D结构的CNN。为4D张量,其间第二维和第三维指定图画尺度:

# Reshape 'x' into a 4D tensor 
x_image = tf.reshape(x, [-1, 28, 28, 1])


创立第一个卷积层,为图画中的每个5x5切片提取32个要素:

# Define the first convolutional layer 
W_conv1, b_conv1 = create_layer([5, 5, 1, 32])


用前一进程中核算的权重张量卷积图画,然后为其添加偏置张量。然后,需求将整流线性单元(ReLU)函数应用于输出:

# Convolve the image with weight tensor, add the 
# bias, and then apply the ReLU function
h_conv1 = tf.nn.relu(convolution_2d(x_image, W_conv1) + b_conv1)


将2x2 最大池运算符应用于上一步的输出:

# Apply the max pooling operator 
h_pool1大明宫-手把手教你运用卷积神经网络构建图画分类器 = max_pooling(h_conv1)


创立第二个卷积层核算每个5x5切片上的64个要素:

# Define the second convolutional layer 
W_conv2, b_conv2 = create_layer([5, 5, 32, 64])


运用上一步中核算的权重张量卷积前一层的输出,然后添加误差张量。然后,需求将整流线性单元(ReLU)函数应用于输出:

# Convolve the output of previous layer with the 
# weight tensor, add the bias, and then apply
# the ReLU function
h_conv2 = tf.nn.relu(convolution_2d(h_pool1, W_conv2) + b_conv2)


将2x2最大池运算符应用于上一步的输出:

# Apply the max pooling operator 
h_pool2 = max_pooling(h_conv2)


图画尺度削减到了7x7。创立一个包括1024个神经元的彻底衔接层:

# Define the fully connected layer 
W_fc1, b_fc1 = create_layer([7 * 7 * 64, 1024])


重塑上一层的输出:

# Reshape the output of the previous layer 
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])


将前一层的输出与彻底衔接层的权重张量相乘,然后为其添加偏置张量。然后,将整流线性单元(ReLU)函数应用于输出:

# Multiply the output of previous layer by the 
# weight tensor, add the bias, and then apply
# the ReLU function
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)


为了削减过度拟合,需求创立一个dropout图层。为概率值创立一个TensorFlow占位符,该概率值指定在丢掉期间保存神经元输出的概率:

# Define the dropout layer using a probability placeholder 
# for all the neurons
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)


运用10个输出神经元界说读出层,对应于数据会集的10个类。核算输出:

# Define the readout layer (output layer) 
W_fc2, b_fc2 = create_layer([1024, 10])
y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2


界说丢掉函数和优化函数:

# Define the entropy loss and the optimizer 
y_loss = tf.placeholder(tf.float32, [None, 10])
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_conv, y_loss))
optimizer = tf.train.AdamOptimizer(1e-4).minimize(loss)


界说怎么核算准确度:

# Define the accuracy computation 
predicted = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_loss, 1))
accuracy = tf.reduce_mean(tf.cast(predicted, tf.float32))


初始化变量后创立并运转会话:

# Create and run a session 
sess = tf.InteractiveSession()
init = tf.initialize_all_variables()
sess.run(init)


开端练习进程:

# Start training 
num_iterations = 21000
batch_size = 75
print('\nTraining the model….')
for i in range(num_iterations):
# Get the next batch of images
batch = mnist.train.next_batch(batch_size)


每50次迭代打印准确度进展:

# Print progress 
if i % 50 == 0:
cur_accuracy = accuracy.eval(feed_dict = {
x: batch[0], y_loss: batch[1], keep_prob: 1.0})
print('Iteration', i, ', Accuracy =', cur_accuracy)


在当时批处理上运转优化程序:

# Train on the current batch 
optimizer.run(feed_dict = {x: batch[0], y_loss: batch[1], keep_prob: 0.5})


练习完毕后,运用测试数据集核算准确度:

# Compute accuracy using test data 
print('Test accuracy =', accuracy.eval(feed_dict = {
x: mnist.test.images, y_loss: mnist.test.labels,
keep_prob: 1.0}))


运转代码,将在终端上取得以下输出:

持续迭代时,精度会不断添加,如以下屏幕截图所示:



现在得到了输出,能够看到卷积神经网络的准确性远远高于简略的神经网络。

留言 点赞 重视

咱们一同共享AI学习与开展的干货

欢迎重视全渠道AI垂类自媒体 “读芯术”