日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 卷积神经网络 >内容正文

卷积神经网络

cnn卷积神经网络_卷积神经网络(CNN)原理及应用

發布時間:2025/3/20 卷积神经网络 81 豆豆
生活随笔 收集整理的這篇文章主要介紹了 cnn卷积神经网络_卷积神经网络(CNN)原理及应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、CNN原理

卷積神經網絡(CNN)主要是用于圖像識別領域,它指的是一類網絡,而不是某一種,其包含很多不同種結構的網絡。不同的網絡結構通常表現會不一樣。從CNN的一些典型結構中,可以看到這些網絡創造者非常有創造力,很多結構都非常巧妙,有機會再介紹現今主流的一些典型結構。 現在我們先來簡單介紹一下卷積神經網絡的原理。

Very Deep Convolutional Networks for Large-Scale Image Recognition(2014), arXiv: 1409.1556:

所有CNN最終都是把一張圖片轉化為特征向量,特征向量就相當于這張圖片的DNA。就像上圖VGG網絡一樣,通過多層的卷積,池化,全連接,降低圖片維度,最后轉化成了一個一維向量。這個向量就包含了圖片的特征,當然這個特征不是肉眼上的圖片特征,而是針對于神經網絡的特征。

之所以用VGG舉例,因為他的網絡結構非常簡潔,清晰,相當好理解,簡單介紹一下:

  • 他的輸入是一張224x224 的三通道圖片,經過兩層卷積之后,圖片維度不變,通道數增加到了64。
  • 之后那個紅色的層是最大池化(max pooling)把圖片維度變成了112x112。后續就是不斷重復步驟1,2。
  • 當變成1維向量之后,經過全連接(fully connected)加ReLU激活,softmax處理之后,變成了一個包含1000個數字的特征向量。
  • 以上就是CNN所做的事情。

    二、 CNN如何訓練

    1. 卷積神經網絡的前向傳播過程

    在前向傳播過程中,輸入的圖形數據經過多層卷積層的卷積和池化處理,提出特征向量,將特征向量傳入全連接層中,得出分類識別的結果。當輸出的結果與我們的期望值相符時,輸出結果。

    1.1 前向傳播中的卷積操作

    • 用一個小的權重矩陣去覆蓋輸入數據,對應位置加權相乘,其和作為結果的一個像素點;
    • 這個權重在輸入數據上滑動,形成一張新的矩陣:

    • 這個權重矩陣稱為卷積核(convolution kernel);
    • 其覆蓋位置稱為感受野(receptive field);
    • 參數共享;
    • 滑動的像素數量叫做步長(stride):

    • 以卷積核的邊還是中心點作為開始/結束的依據,決定了卷積的補齊(padding)方式。上面的圖片是valid方式(這種方式新的矩陣維度可能會降低),而same方式則會在圖像邊緣用0補齊(這種方式圖像維度不會降低):

    • 如果輸入通道不只一個,那么卷積核是三階的。所有通道的結果累加:

    如圖:

    1.2 前向傳播中的池化操作

    池化又稱為降采樣(down_sampling),類型:

  • 最大池化(max pooling):在感受野內取最大值輸出;
  • 平均池化(average pooling):在感受野內取平均值進行輸出;
  • 其他如L2池化等。
  • 理解:

    • 一個選擇框,將輸入數據某個范圍(矩陣)的所有數值進行相應計算,得到一個新的值,作為結果的一個像素點;
    • 池化也有步長和補齊的概念,但是很少使用,通常選擇框以不重疊的方式,在padding=0的輸入數據上滑動,生成一張新的特征圖:

    1.3 前向傳播中的全連接

    特征圖進過卷積層和下采樣層的特征提取之后,將提取出來的特征傳到全連接層中,通過全連接層,進行分類,獲得分類模型,得到最后的結果。

    2. 卷積神經網絡的反向傳播過程

    當卷積神經網絡輸出的結果與我們的期望值不相符時,則進行反向傳播過程。求出結果與期望值的誤差,再將誤差一層一層的返回,計算出每一層的誤差,然后進行權值更新。

    3. 卷積神經網絡的權值更新

    卷積層的誤差更新過程為:將誤差矩陣當做卷積核,卷積輸入的特征圖,并得到了權值的偏差矩陣,然后與原先的卷積核的權值相加,并得到了更新后的卷積核。

    卷積神經網絡的訓練過程流程圖:

    就像這張流程圖一樣,不斷循環這個過程。最后得到一個穩定的權值和閾值。

    目前主流框架是pytorch(facebook)和tensorflow(google)。舉個例子(一個手寫數字識別網絡,其代碼量也就100多行):

    import sysimport tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data from tinyenv.flags import flagsFLAGS = Nonedef train():mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True, fake_data=FLAGS.fake_data,)sess = tf.InteractiveSession()with tf.name_scope('input'):x = tf.placeholder(tf.float32, [None, 784], name='x-input')y_ = tf.placeholder(tf.float32, [None, 10], name='y-input')with tf.name_scope('input_reshape'):image_shaped_input = tf.reshape(x, [-1, 28, 28, 1])tf.summary.image('input', image_shaped_input, 10)def weight_variable(shape):"""Create a weight variable with appropriate initialization."""initial = tf.truncated_normal(shape, stddev=0.1)return tf.Variable(initial)def bias_variable(shape):"""Create a bias variable with appropriate initialization."""initial = tf.constant(0.1, shape=shape)return tf.Variable(initial)def variable_summaries(var):with tf.name_scope('summaries'):mean = tf.reduce_mean(var)tf.summary.scalar('mean', mean)with tf.name_scope('stddev'):stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))tf.summary.scalar('stddev', stddev)tf.summary.scalar('max', tf.reduce_max(var))tf.summary.scalar('min', tf.reduce_min(var))tf.summary.histogram('histogram', var)def nn_layer(input_tensor, input_dim, output_dim, layer_name,act=tf.nn.relu):with tf.name_scope(layer_name):with tf.name_scope('weights'):weights = weight_variable([input_dim, output_dim])variable_summaries(weights)with tf.name_scope('biases'):biases = bias_variable([output_dim])variable_summaries(biases)with tf.name_scope('Wx_plus_b'):preactivate = tf.matmul(input_tensor, weights) + biasestf.summary.histogram('pre_activations', preactivate)activations = act(preactivate, name='activation')tf.summary.histogram('activations', activations)return activationshidden1 = nn_layer(x, 784, 500, 'layer1')with tf.name_scope('dropout'):keep_prob = tf.placeholder(tf.float32)tf.summary.scalar('dropout_keep_probability', keep_prob)dropped = tf.nn.dropout(hidden1, keep_prob)y = nn_layer(dropped, 500, 10, 'layer2', act=tf.identity)with tf.name_scope('cross_entropy'):diff = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)with tf.name_scope('total'):cross_entropy = tf.reduce_mean(diff)tf.summary.scalar('cross_entropy', cross_entropy)with tf.name_scope('train'):train_step = tf.train.AdamOptimizer(FLAGS.learning_rate).minimize(cross_entropy)with tf.name_scope('accuracy'):with tf.name_scope('correct_prediction'):correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))with tf.name_scope('accuracy'):accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))tf.summary.scalar('accuracy', accuracy)merged = tf.summary.merge_all()train_writer = tf.summary.FileWriter(FLAGS.log_dir + '/train', sess.graph)test_writer = tf.summary.FileWriter(FLAGS.log_dir + '/test')tf.global_variables_initializer().run()def feed_dict(train):if train or FLAGS.fake_data:xs, ys = mnist.train.next_batch(100, fake_data=FLAGS.fake_data)k = FLAGS.dropoutelse:xs, ys = mnist.test.images, mnist.test.labelsk = 1.0return {x: xs, y_: ys, keep_prob: k}for i in range(FLAGS.iterations):if i % 10 == 0: # Record summaries and test-set accuracysummary, acc = sess.run([merged, accuracy], feed_dict=feed_dict(False))test_writer.add_summary(summary, i)print('Accuracy at step %s: %s' % (i, acc))else:if i % 100 == 99:run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)run_metadata = tf.RunMetadata()summary, _ = sess.run([merged, train_step],feed_dict=feed_dict(True),options=run_options,run_metadata=run_metadata)train_writer.add_run_metadata(run_metadata, 'step%03d' % i)train_writer.add_summary(summary, i)else:summary, _ = sess.run([merged, train_step], feed_dict=feed_dict(True))train_writer.add_summary(summary, i)train_writer.close()test_writer.close()def main(_):if tf.gfile.Exists(FLAGS.log_dir):tf.gfile.DeleteRecursively(FLAGS.log_dir)tf.gfile.MakeDirs(FLAGS.log_dir)train()if __name__ == '__main__':FLAGS = flags()tf.app.run(main=main, argv=[sys.argv[0]])

    訓練之后,其識別準確度已達到96.7%:

    三、 應用

    1. 圖片分類

    假設每張圖片最后獲得了6維特征向量v: [-0.24754368, -0.19974484, 0.45622883, 0.01130153, 0.08802839, -0.0419769]。 我們要把圖片分為3類, 那么分類矩陣就應該是6 x 3維的矩陣。 因為根據矩陣乘法:m,n維的矩陣乘以n,l維的矩陣,會得到一個m,l維的矩陣。 所以1 x 6維的矩陣乘以6 x 3維的矩陣最后會得到一個1 x 3的向量。 如上述6維向量乘以分類矩陣之后得到:[-0.7777777, -0.9999999, 1.02222222],那么很明顯這張圖片會被分到第三類。

    2. 相似圖搜索

    廣泛應用的人臉識別其實就是相似圖搜索,比對兩張照片是不是同一個人,當兩張照片是同一個人時,他的歐氏距離會非常接近,反之。

    余弦距離:

    3.對抗樣本

    對抗樣本和神經網絡訓練過程不同的是,他是固定權重,更新輸入數據。比如輸入一張貓的圖片,人為的修改一點圖片數據,肉眼上看還是一只貓,但是你告訴神經網絡這是狗。最后大量數據訓練這后,神經網絡會把這些圖片錯誤的分類到狗這一類。

    四、 新技術

    1. 批歸一化(Batch Normalization)

    相當于把數據縮放到了合適的位置,所以應該放在卷積之后,激活函數之前。能加快網絡收斂速度。一堆公式,腦殼痛:

    2. Dropout(還沒有合適的中文翻譯)

    應用廣泛。在標準 Dropout 的每輪迭代中,網絡中的每個神經元以 p 的概率被丟棄。Dropout能夠有效的改善過擬合的情況,提升泛化能力。前幾天google申請的Dropout專利生效了。

    Dropout實現要點:

    • 一般是實施在分類器之前(論文是放在最后一層分類器之后);
    • Dropout以概率p置零神經元,這種情況下,保留的神經元的輸出要除以1-p (論文是在inference時把所有權重乘以p);
    • 通常p初始值0.5。
    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的cnn卷积神经网络_卷积神经网络(CNN)原理及应用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。