cnn神经网络可以用于数据拟合吗_代码详解:最全面的卷积神经网络介绍,都在这里了...
神經(jīng)網(wǎng)絡(luò)由具有權(quán)重和偏差的神經(jīng)元組成。通過(guò)在訓(xùn)練過(guò)程中調(diào)整這些權(quán)重和偏差,以提出良好的學(xué)習(xí)模型。每個(gè)神經(jīng)元接收一組輸入,以某種方式處理它,然后輸出一個(gè)值。如果構(gòu)建一個(gè)具有多層的神經(jīng)網(wǎng)絡(luò),則將其稱為深度神經(jīng)網(wǎng)絡(luò)。處理這些深度神經(jīng)網(wǎng)絡(luò)的人工智能學(xué)分支被稱為深度學(xué)習(xí)。
普通神經(jīng)網(wǎng)絡(luò)的主要缺點(diǎn)是其忽略了輸入數(shù)據(jù)的結(jié)構(gòu)。在將數(shù)據(jù)饋送到神經(jīng)網(wǎng)絡(luò)之前,所有數(shù)據(jù)都將轉(zhuǎn)換為一維數(shù)組。這適用于常規(guī)數(shù)據(jù),但在處理圖像時(shí)會(huì)遇到困難。
考慮到灰度圖像是2D結(jié)構(gòu),像素的空間排列有很多隱藏信息。若忽略這些信息,則將失去許多潛在的模式。這就是卷積神經(jīng)網(wǎng)絡(luò)(CNN)被引入圖像處理的原因。CNN在處理圖像時(shí)會(huì)考慮圖像的2D結(jié)構(gòu)。
CNN也是由具有權(quán)重和偏差的神經(jīng)元組成。這些神經(jīng)元接收輸入的數(shù)據(jù)并處理,然后輸出信息。神經(jīng)網(wǎng)絡(luò)的目標(biāo)是將輸入層中的原始圖像數(shù)據(jù)轉(zhuǎn)到輸出層中的正確類中。普通神經(jīng)網(wǎng)絡(luò)和CNN之間的區(qū)別在于使用的層類型以及處理輸入數(shù)據(jù)的方式。假設(shè)CNN的輸入是圖像,這允許其提取特定于圖像的屬性。這使得CNN在處理圖像方面更有效率。那么,CNN是如何構(gòu)建的?
CNN的體系結(jié)構(gòu)
當(dāng)使用普通神經(jīng)網(wǎng)絡(luò)時(shí),需要將輸入數(shù)據(jù)轉(zhuǎn)換為單個(gè)向量。該向量作為神經(jīng)網(wǎng)絡(luò)的輸入,然后向量穿過(guò)神經(jīng)網(wǎng)絡(luò)的各層。在這些層中,每個(gè)神經(jīng)元都與前一層中的所有神經(jīng)元相連接。值得注意的是,同層的神經(jīng)元互不連接。它們僅與相鄰層的神經(jīng)元相連。網(wǎng)絡(luò)中的最后一層是輸出層,它代表最終輸出。
若將這種結(jié)構(gòu)用于圖像處理,它將很快變得難以管理。例如,一個(gè)由256x256RGB圖像組成的圖像數(shù)據(jù)集。由于這是3維圖像,因此將有256 * 256 * 3 = 196,608個(gè)權(quán)重。請(qǐng)意,這僅適用于單個(gè)神經(jīng)元!每層都有多個(gè)神經(jīng)元,因此權(quán)重的數(shù)量迅速增加。這意味著在訓(xùn)練過(guò)程中,該模型將需要大量參數(shù)來(lái)調(diào)整權(quán)重。這就是該結(jié)構(gòu)復(fù)雜和耗時(shí)的原因。將每個(gè)神經(jīng)元連接到前一層中的每個(gè)神經(jīng)元,稱為完全連接,這顯然不適用于圖像處理。
CNN在處理數(shù)據(jù)時(shí)明確考慮圖像的結(jié)構(gòu)。CNN中的神經(jīng)元按三維排列——寬度、高度和深度。當(dāng)前層中的每個(gè)神經(jīng)元都連接到前一層輸出的小塊。這就像在輸入圖像上疊加NxN過(guò)濾器一樣。這與完全連接的層相反,完全連接層的每個(gè)神經(jīng)元均與前一層的所有神經(jīng)元相連。
由于單個(gè)過(guò)濾器無(wú)法捕獲圖像的所有細(xì)微差別,因此需要花費(fèi)數(shù)倍的時(shí)間(假設(shè)M倍)確保捕獲所有細(xì)節(jié)。這M個(gè)過(guò)濾器充當(dāng)特征提取器。如果查看這些過(guò)濾器的輸出,可以查看層的提取特征,如邊緣、角等。這適用于CNN中的初始層。隨著在神經(jīng)網(wǎng)絡(luò)層中的圖像處理的進(jìn)展,可看到后面的層將提取更高級(jí)別的特征。
CNN中的層類型
了解了CNN的架構(gòu),繼續(xù)看看用于構(gòu)建CNN各層的類型。CNN通常使用以下類型的層:
· 輸入層:用于原始圖像數(shù)據(jù)的輸入。
· 卷積層:該層計(jì)算神經(jīng)元與輸入中各種切片之間的卷積。
快速了解圖像卷積傳送門:
http://web.pdx.edu/~jduh/courses/Archive/geog481w07/Students/Ludwig_ImageConvolution.pdf。
卷積層基本上計(jì)算權(quán)重和前一層輸出的切片之間的點(diǎn)積。
· 激勵(lì)層:此圖層將激活函數(shù)應(yīng)用于前一圖層的輸出。該函數(shù)類似于max(0,x)。需要向該層神經(jīng)網(wǎng)絡(luò)增加非線性映射,以便它可以很好地概括為任何類型的功能。
· 池化層:此層對(duì)前一層的輸出進(jìn)行采樣,從而生成具有較小維度的結(jié)構(gòu)。在網(wǎng)絡(luò)中處理圖像時(shí),池化有助于只保留突出的部分。最大池是池化層最常用的,可在給定的KxK窗口中選擇最大值。
· 全連接層:此圖層計(jì)算最后一層的輸出分。輸出結(jié)果的大小為1x1xL,其中L是訓(xùn)練數(shù)據(jù)集中的類數(shù)。
從神經(jīng)網(wǎng)絡(luò)中的輸入層到輸出層時(shí),輸入圖像將從像素值轉(zhuǎn)換為最終的類得分。現(xiàn)已提出了許多不同的CNN架構(gòu),它是一個(gè)活躍的研究領(lǐng)域。模型的準(zhǔn)確性和魯棒性取決于許多因素- 層的類型、網(wǎng)絡(luò)的深度、網(wǎng)絡(luò)中各種類型的層的排列、為每層選擇的功能和訓(xùn)練數(shù)據(jù)等。
構(gòu)建基于感知器的線性回歸量
接下來(lái)是有關(guān)如何用感知器構(gòu)建線性回歸模型。
本文將會(huì)使用TensorFlow。它是一種流行的深度學(xué)習(xí)軟件包,廣泛用于構(gòu)建各種真實(shí)世界的系統(tǒng)中。在本節(jié),我們將熟悉它的工作原理。在使用軟件包前先安裝它。
安裝說(shuō)明傳送門:
https://http://www.tensorflow.org/get_started/os_setup。
確保它已安裝后,創(chuàng)建一個(gè)新的python程序并導(dǎo)入以下包:
import numpy as np import matplotlib.pyplot as plt import tensorflow as tf使模型適應(yīng)生成的數(shù)據(jù)點(diǎn)。定義要生成的數(shù)據(jù)點(diǎn)的數(shù)量:
# Define the number of points to generate num_points = 1200定義將用于生成數(shù)據(jù)的參數(shù)。使用線性模型: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)生成的噪音使數(shù)據(jù)發(fā)生變化:
# Generate some noise noise = np.random.normal(0.0, 0.04)使用以下等式計(jì)算y的值:
# Compute 'y' y = m*x + c + noise data.append([x, y])完成迭代后,將數(shù)據(jù)分成輸入和輸出變量:
# Separate x and y x_data = [d[0] for d in data] y_data = [d[1] for d in data繪制數(shù)據(jù):
# Plot the generated data plt.plot(x_data, y_data, 'ro') plt.title('Input data') plt.show()為感知器生成權(quán)重和偏差。權(quán)重由統(tǒng)一的隨機(jī)數(shù)生成器生成,并將偏差設(shè)置為零:
# 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定義訓(xùn)練過(guò)程使用的損失函數(shù)。優(yōu)化器將使損失函數(shù)的值盡可能地減小。
# Define how to compute the loss loss = tf.reduce_mean(tf.square(y - y_data))定義梯度下降優(yōu)化器并指定損失函數(shù):
# Define the gradient descent optimizer optimizer = tf.train.GradientDescentOptimizer(0.5) train = optimizer.minimize(loss)所有變量都已到位,但尚未初始化。接下來(lái):
# Initialize all the variables init = tf.initialize_all_variables()啟動(dòng)TensorFlow會(huì)話并使用初始化程序運(yùn)行它:
# Start the tensorflow session and run it sess = tf.Session() sess.run(init)開(kāi)始訓(xùn)練:
# Start iterating num_iterations = 10 for step in range(num_iterations): # Run the session sess.run(train)打印訓(xùn)練進(jìn)度。進(jìn)行迭代時(shí),損失參數(shù)將持續(xù)減少:
# Print the progress print('nITERATION', step+1) print('W =', sess.run(W)[0]) print('b =', sess.run(b)[0]) print('loss =', sess.run(loss))繪制生成的數(shù)據(jù)并在頂部覆蓋預(yù)測(cè)的模型。該情況下,模型是一條線:
# 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))設(shè)置繪圖的參數(shù):
# 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文件中給出。運(yùn)行代碼將看到以下屏幕截圖顯示輸入數(shù)據(jù):
如果關(guān)閉此窗口,將看到訓(xùn)練過(guò)程。第一次迭代看起來(lái)像這樣:
可看到,線路完全偏離模型。關(guān)閉此窗口以轉(zhuǎn)到下一個(gè)迭代:
這條線似乎更好,但它仍然偏離模型。關(guān)閉此窗口并繼續(xù)迭代:
看起來(lái)這條線越來(lái)越接近真實(shí)的模型。如果繼續(xù)像這樣迭代,模型會(huì)變得更好。第八次迭代看起來(lái)如下:
該線與數(shù)據(jù)擬合的很好。將在終端上看到以下內(nèi)容:
完成訓(xùn)練后,在終端上看到以下內(nèi)容:
使用單層神經(jīng)網(wǎng)絡(luò)構(gòu)建圖像分類器
如何使用TensorFlow創(chuàng)建單層神經(jīng)網(wǎng)絡(luò),并使用它來(lái)構(gòu)建圖像分類器?使用MNIST圖像數(shù)據(jù)集來(lái)構(gòu)建系統(tǒng)。它是包含手寫的數(shù)字圖像的數(shù)據(jù)集。其目標(biāo)是構(gòu)建一個(gè)能夠正確識(shí)別每個(gè)圖像中數(shù)字的分類器。
圖片來(lái)源:pexels.com創(chuàng)建新的python程序并導(dǎo)入以下包:
import argparse import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data定義一個(gè)解析輸入?yún)?shù)的函數(shù):
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函數(shù)并解析輸入?yún)?shù):
if __name__ == '__main__': args = build_arg_parser().parse_args()提取MNIST圖像數(shù)據(jù)。one_hot標(biāo)志指定將在標(biāo)簽中使用單熱編碼。這意味著如果有n個(gè)類,那么給定數(shù)據(jù)點(diǎn)的標(biāo)簽將是長(zhǎng)度為n的數(shù)組。此數(shù)組中的每個(gè)元素都對(duì)應(yīng)一個(gè)特定的類。要指定一個(gè)類,相應(yīng)索引處的值將設(shè)置為1,其他所有值為0:
# Get the MNIST data mnist = input_data.read_data_sets(args.input_dir, one_hot=True)數(shù)據(jù)庫(kù)中的圖像是28 x 28像素。需將其轉(zhuǎn)換為單維數(shù)組以創(chuàng)建輸入圖層:
# The images are 28x28, so create the input layer # with 784 neurons (28x28=784) x = tf.placeholder(tf.float32, [None, 784])創(chuàng)建具有權(quán)重和偏差的單層神經(jīng)網(wǎng)絡(luò)。數(shù)據(jù)庫(kù)中有10個(gè)不同的數(shù)字。輸入層中的神經(jīng)元數(shù)量為784,輸出層中的神經(jīng)元數(shù)量為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]))創(chuàng)建用于訓(xùn)練的等式:
# Create the equation for 'y' using y = W*x + b y = tf.matmul(x, W) + b定義損失函數(shù)和梯度下降優(yōu)化器:
# 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()創(chuàng)建TensorFlow會(huì)話并運(yùn)行:
# Create a session session = tf.Session() session.run(init)開(kāi)始訓(xùn)練過(guò)程。使用當(dāng)前批次運(yùn)行優(yōu)化器的批次進(jìn)行訓(xùn)練,然后繼續(xù)下一批次進(jìn)行下一次迭代。每次迭代的第一步是獲取下一批要訓(xùn)練的圖像:
# 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)在這批圖像上運(yùn)行優(yōu)化器:
# Train on this batch of images session.run(optimizer, feed_dict = {x: x_batch, y_loss: y_batch})訓(xùn)練過(guò)程結(jié)束后,使用測(cè)試數(shù)據(jù)集計(jì)算準(zhǔn)確度:
# 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文件中給出。如果運(yùn)行代碼,它會(huì)將數(shù)據(jù)下載到當(dāng)前文件夾中名為mnist_data的文件夾中。這是默認(rèn)選項(xiàng)。如果要更改它,可以使用輸入?yún)?shù)執(zhí)行此操作。運(yùn)行代碼后,將在終端上獲得以下輸出:
正如終端上打印所示,模型的準(zhǔn)確率為92.1%。
使用卷積神經(jīng)網(wǎng)絡(luò)構(gòu)建圖像分類器
上一節(jié)中的圖像分類器表現(xiàn)不佳。獲得92.1%的MNIST數(shù)據(jù)集相對(duì)容易。如何使用卷積神經(jīng)網(wǎng)絡(luò)(CNN)來(lái)實(shí)現(xiàn)更高的精度呢?下面將使用相同的數(shù)據(jù)集構(gòu)建圖像分類器,但使用CNN而不是單層神經(jīng)網(wǎng)絡(luò)。
創(chuàng)建一個(gè)新的python程序并導(dǎo)入以下包:
import argparse import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data定義一個(gè)解析輸入?yún)?shù)的函數(shù):
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定義一個(gè)函數(shù)來(lái)為每個(gè)層中的權(quán)重創(chuàng)建值:
def get_weights(shape): data = tf.truncated_normal(shape, stddev=0.1) return tf.Variable(data)定義一個(gè)函數(shù)來(lái)為每個(gè)層中的偏差創(chuàng)建值:
def get_biases(shape): data = tf.constant(0.1, shape=shape) return tf.Variable(data)定義一個(gè)函數(shù)以根據(jù)輸入形狀創(chuàng)建圖層:
def create_layer(shape): # Get the weights and biases W = get_weights(shape) b = get_biases([shape[-1]]) return W, b定義執(zhí)行2D卷積功能的函數(shù):
def convolution_2d(x, W): return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')定義一個(gè)函數(shù)來(lái)執(zhí)行2x2最大池操作:
def max_pooling(x): return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')定義main函數(shù)并解析輸入?yún)?shù):
if __name__ == '__main__': args = build_arg_parser().parse_args()提取MNIST圖像數(shù)據(jù):
# Get the MNIST data mnist = input_data.read_data_sets(args.input_dir, one_hot=True)使用784個(gè)神經(jīng)元?jiǎng)?chuàng)建輸入層:
# The images are 28x28, so create the input layer # with 784 neurons (28x28=784) x = tf.placeholder(tf.float32, [None, 784])接下來(lái)是利用圖像2D結(jié)構(gòu)的CNN。為4D張量,其中第二維和第三維指定圖像尺寸:
# Reshape 'x' into a 4D tensor x_image = tf.reshape(x, [-1, 28, 28, 1])創(chuàng)建第一個(gè)卷積層,為圖像中的每個(gè)5x5切片提取32個(gè)要素:
# Define the first convolutional layer W_conv1, b_conv1 = create_layer([5, 5, 1, 32])用前一步驟中計(jì)算的權(quán)重張量卷積圖像,然后為其添加偏置張量。然后,需要將整流線性單元(ReLU)函數(shù)應(yīng)用于輸出:
# 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 最大池運(yùn)算符應(yīng)用于上一步的輸出:
# Apply the max pooling operator h_pool1 = max_pooling(h_conv1)創(chuàng)建第二個(gè)卷積層計(jì)算每個(gè)5x5切片上的64個(gè)要素:
# Define the second convolutional layer W_conv2, b_conv2 = create_layer([5, 5, 32, 64])使用上一步中計(jì)算的權(quán)重張量卷積前一層的輸出,然后添加偏差張量。然后,需要將整流線性單元(ReLU)函數(shù)應(yīng)用于輸出:
# 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最大池運(yùn)算符應(yīng)用于上一步的輸出:
# Apply the max pooling operator h_pool2 = max_pooling(h_conv2)圖像尺寸減少到了7x7。創(chuàng)建一個(gè)包含1024個(gè)神經(jīng)元的完全連接層:
# 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])將前一層的輸出與完全連接層的權(quán)重張量相乘,然后為其添加偏置張量。然后,將整流線性單元(ReLU)函數(shù)應(yīng)用于輸出:
# 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)為了減少過(guò)度擬合,需要?jiǎng)?chuàng)建一個(gè)dropout圖層。為概率值創(chuàng)建一個(gè)TensorFlow占位符,該概率值指定在丟失期間保留神經(jīng)元輸出的概率:
# 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個(gè)輸出神經(jīng)元定義讀出層,對(duì)應(yīng)于數(shù)據(jù)集中的10個(gè)類。計(jì)算輸出:
# 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定義損失函數(shù)和優(yōu)化函數(shù):
# 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)定義如何計(jì)算準(zhǔn)確度:
# 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))初始化變量后創(chuàng)建并運(yùn)行會(huì)話:
# Create and run a session sess = tf.InteractiveSession() init = tf.initialize_all_variables() sess.run(init)開(kāi)始訓(xùn)練過(guò)程:
# 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次迭代打印準(zhǔn)確度進(jìn)度:
# 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)在當(dāng)前批處理上運(yùn)行優(yōu)化程序:
# Train on the current batch optimizer.run(feed_dict = {x: batch[0], y_loss: batch[1], keep_prob: 0.5})訓(xùn)練結(jié)束后,使用測(cè)試數(shù)據(jù)集計(jì)算準(zhǔn)確度:
# 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}))運(yùn)行代碼,將在終端上獲得以下輸出:
繼續(xù)迭代時(shí),精度會(huì)不斷增加,如以下屏幕截圖所示:
現(xiàn)在得到了輸出,可以看到卷積神經(jīng)網(wǎng)絡(luò)的準(zhǔn)確性遠(yuǎn)遠(yuǎn)高于簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)。
留言 點(diǎn)贊 關(guān)注
我們一起分享AI學(xué)習(xí)與發(fā)展的干貨
歡迎關(guān)注全平臺(tái)AI垂類自媒體 “讀芯術(shù)”
總結(jié)
以上是生活随笔為你收集整理的cnn神经网络可以用于数据拟合吗_代码详解:最全面的卷积神经网络介绍,都在这里了...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 只有一个显示器但是显示两个显示器_小米3
- 下一篇: 游戏角色坐标的保存间隔_使用C++编写飞