コンボリューション層の細胞層

免責事項:この記事は従って、ブロガーオリジナル記事です。CC BY-SA 4.0再現著作権の契約を、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/weixin_41417982/article/details/81412076

構築最も簡単なネットワーク、それは時間の畳み込みであるとと一緒にプールしました。私はアイデアを開始していないが、私は知っているが、これは、それは非常に長い記事でなければなりません。

畳み込みニューラルネットワーク(コンボリューショナルニューラル層CNN)、(なぜなら出現グローバル平均プーリングの時々も全て接続層、)完全接続層に加えて、さらに、畳み込み層の細胞層を含みます。畳み込み層は、特徴を抽出するために使用され、細胞層パラメータの数を減らすことができます。

コンボリューション層

畳み込み層の原則について話をします。

私たちは、コンボリューションカーネル行列であると言うことができる、特徴を抽出する畳み込みカーネルを使用しています。私たちはコンボリューションカーネル行列を設定した場合は3 * 3、および私たちの絵は* 5の画像解像度です。そして、畳み込みカーネルタスクは次のように:

 

 

左上から、畳み込みカーネル行列は3×3データの範囲に対応し、その後加算した値を乗算します。このためには、1我々はすべての操作上の9つの画素の値を取得することができます。この行列は、我々は、活性化マップ(アクティベーション・マップ)を呼び出し9つの値によって形成されます。これが私たちの畳み込み層の原理です。GIF、以下も参照してください:
ここで、畳み込みカーネル用

1 0 1 0 1 0 1 0 1 101010101

 

 

実際には、我々は通常の例の畳み込みカーネルは、主に演算処理の、一度に180度回転されています。詳細は分かりませんが、原則は同じです。

実際に、我々は、入力された画像は、一般的に三次元である、すなわちR、G、Bの三つのチャネルを含みます。しかし、実際には、コンボリューションカーネルの後、3人は1次元となります。摺動する際、実際には、値が3つのチャネルのすべて、単に一次元行列の最終的な出力を追加する画面全体です。畳み込みカーネル(コンボリューションカーネルの畳み込み層の数は、独自で決定される)活性化マップを積層摺動後に形成され、その後、出力活性化機能を介して、複数の層の畳み込みです。

 

ステップサイズとパディング:コンボリューション層2つの重要なパラメータがあります。

いわゆるステップは、畳み込みカーネルからの動きを制御することです。我々が見る上記の例では、コンボリューションカーネルは、1つの画素マッピングによって分離され、その後、我々は2つ、3つ、それを介して行うことができ、この距離は、我々がステップと呼ぶものです。

パディングは、我々はデータの操作を行うものです。1をそのまま畳み込み寸法後0補体活性化マップであるように、2つがありますが、一つは、動作していません。上記のデータは、我々は、5 * 5 * 3の形状の3×3のコンボリューションカーネルのコンボリューション後のマップで見ることができる3×3、すなわち、開始から異なる形状のデータ。時には、この変更を避けるために、私たちは「0を埋める」を使用 - データ0の外側の層を構成しています。

ここでは図は次のとおりです。

ステップ2
ステップ2(から画像マシンの心臓部
0アップ
(からのイメージチェンジ0の補数マシンの心臓部

 

すべての人々の発展の歴史は、畳み込みニューラルネットワークが出現し始めたことを知っている必要があり畳み込み理解することは手書き数字の認識で作成された最もLeNet-5 LeCun(本当に中国の人々のような名前)です。

 

LeNet-5

 

AlexNetが勃発後ろレースImageNetに上に出てくる予定です、突然エラーが昨年の半分になります。それ以来、ネットワークは、論文やネットワークの多くは、その可能性を果たし続ける、AI話題の畳み込みとなっており、そのブラックボックスは、常に人々に解釈されています。

能否对卷积神经网络工作原理做一个直观的解释? - Owl of Minerva的回答 - 知乎里面通过我们对图像进行平滑的操作进而解释了卷积核如何读取特征的。

我们需要先明确一点,实验告诉我们人类视觉是先对图像边缘开始敏感的。在我的理解中,它就是说我们对现有事物的印象是我们先通过提取边界的特征,然后逐渐的完善再进行组装而成的。而我们的卷积层很好的做到了这一点。

 

 

这是两个不同的卷积核滑动整个图像后出来的效果,可以看出,经过卷积之后图像的边界变得更加直观。我们也可以来看下VGG-16网络第一层卷积提取到的特征:

VGG-16

 

由此来看,我们也知道为什么我们不能只要一个卷积核。在我的理解下,假使我们只有一个卷积核,那我们或许只能提取到一个边界。但假如我们有许多的卷积核检测不同的边界,不同的边界又构成不同的物体,这就是我们怎么从视觉图像检测物体的凭据了。所以,深度学习的“深”不仅仅是代表网络,也代表我们能检测的物体的深度。即越深,提取的特征也就越多。

Google提出了一个项目叫Deepdream,里面通过梯度上升、反卷积形象的告诉我们一个网络究竟想要识别什么。之前权重更新我们讲过梯度下降,而梯度上升便是计算卷积核对输入的噪声的梯度,然后沿着上升的方向调整我们的输入。详细的以后再讲,但得出的图像能够使得这个卷积核被激活,也就是说得到一个较好的值。所以这个图像也就是我们卷积核所认为的最规范的图像(有点吓人):

Deepdream
其实这鹅看着还不错,有点像孔雀。

 

池化层 (pooling layer)

前面说到池化层是降低参数,而降低参数的方法当然也只有删除参数了。

一般我们有最大池化和平均池化,而最大池化就我认识来说是相对多的。需要注意的是,池化层一般放在卷积层后面。所以池化层池化的是卷积层的输出!

 

 

扫描的顺序跟卷积一样,都是从左上角开始然后根据你设置的步长逐步扫描全局。有些人会很好奇最大池化的时候你怎么知道哪个是最大值,emmm,其实我也考虑过这个问题。CS2131n里面我记得是说会提前记录最大值保存在一个矩阵中,然后根据那个矩阵来提取最大值。

至于要深入到计算过程与否,应该是没有必要的。所以我也没去查证过程。而且给的都是示例图,其实具体的计算过程应该也是不同的,但效果我们可以知道就好了。

至于为什么选择最大池化,应该是为了提取最明显的特征,所以选用的最大池化。平均池化呢,就是顾及每一个像素,所以选择将所有的像素值都相加然后再平均。

池化层也有padding的选项。但都是跟卷积层一样的,在外围补0,然后再池化。

代码解析
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
summary_dir = './summary'
#批次
batch_size = 100

n_batch = mnist.train.num_examples // batch_size

x = tf.placeholder(tf.float32, [None, 784], name='input')
y = tf.placeholder(tf.float32, [None, 10], name='label')

def net(input_tensor):
    conv_weights = tf.get_variable('weight', [3, 3, 1, 32],
                                    initializer=tf.truncated_normal_initializer(stddev=0.1))
    conv_biases = tf.get_variable('biase', [32], initializer=tf.constant_initializer(0.0))

    conv = tf.nn.conv2d(input_tensor, conv_weights, strides=[1, 1, 1, 1], padding='SAME')
    relu = tf.nn.relu(tf.nn.bias_add(conv, conv_biases))

    pool = tf.nn.max_pool(relu, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')

    pool_shape = pool.get_shape().as_list()
    nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]
    pool_reshaped = tf.reshape(pool, [-1, nodes])

    W = tf.Variable(tf.zeros([nodes, 10]), name='weight')
    b = tf.Variable(tf.zeros([10]), name='bias')
    fc = tf.nn.softmax(tf.matmul(pool_reshaped, W) + b)

    return fc

reshaped = tf.reshape(x, (-1, 28, 28, 1))
prediction = net(reshaped)
loss_ = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(y, 1), logits=prediction, name='loss')
loss = tf.reduce_mean(loss_)

train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name='accuracy')

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    for epoch in range(31):
        for batch in range(n_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            sess.run(train_step, feed_dict={x: batch_xs, y: batch_ys})
        acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels})
        print('Iter' + str(epoch) + ",Testing Accuracy" + str(acc))

这相对于我第一个只用全连接的网络只多了一个net函数,还有因为卷积层的关系进来的数据x需要改变形状。只讲这两部分:

reshaped = tf.reshape(x, (-1, 28, 28, 1))
prediction = net(reshaped)

由于我们feedict上面是,feed_dict={x: mnist.test.images, y: mnist.test.labels},而这样子调用tensorflow的句子我们得到的x固定的形状。因此我们应用tf.reshape(x_need_reshaped,object_shape)来得到需要的形状。

其中的1−1 表示拉平,不能用None,是固定的。

conv_weights = tf.get_variable('weight', [3, 3, 1, 32],
                                    initializer=tf.truncated_normal_initializer(stddev=0.1))
conv_biases = tf.get_variable('biase', [32], initializer=tf.constant_initializer(0.0))

conv = tf.nn.conv2d(input_tensor, conv_weights, strides=[1, 1, 1, 1], padding='SAME')
relu = tf.nn.relu(tf.nn.bias_add(conv, conv_biases))

pool = tf.nn.max_pool(relu, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')

ほとんどのアプリケーションは、内蔵されている初期化する機能重みを(つまり、コンボリューションカーネル)とのバイアス(バイアス項)。私たちは、用語をオフセットが、実際に制御するためのパラメータの詳細ですので、我々はコンボリューション層を話す言及しなかった、それはまた、どのように言いませんでした。コードの後に従っており、次いで、活性化マッププラスバイアスの外でした。プールも最大のプールを使用していました。

reluに注意してください。これは、役割がソフトマックス前の話のように言うことができ、また、アクティブな機能ですが、それはコンボリューション層でより使用されているが、また良い活性化関数として認識されています。それは多くのバリエーションがあります。私たちは、あなたが情報へのアクセスを行くことができます興味を持っています。後にのみその点で記事を書きます。

    pool_shape = pool.get_shape().as_list()
    nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]
    pool_reshaped = tf.reshape(pool, [-1, nodes])

    W = tf.Variable(tf.zeros([nodes, 10]), name='weight')

我々はそれが形だか分からない出力プーリング層(もちろん、あなたも手カウントすることができます)。したがって、細胞層は、一次元マトリクスに引っ張ったとしても、私たちはどのようにW形状を知る必要はありません。したがって、我々は(すなわち、層をプールした出力)形状をプールを表示し、私は密かに[なし、14、14、32]、したがってプールフレアへのモーメントを印刷、[なし]、* 14 * 32 14、10]ではありません。次の層が完全に接続されている計算するために、我々はまた、W [14 * 14 * 32、10]を形成すべきです。このコードの原則は、ケースです。

15後に採取した同一の精度:

結果

 

emmm、ないと以前よりも、以前よりも明らかに多くの良いです。次の章では、最適化手法より良い、まとめることにしました。

参考
https://mlnotebook.github.io/post/CNN1/は(残念ながら、それは英国だった)
あなたは私たちに畳み込みニューラルネットワークの作品の視覚的な解釈を与えることはできますか?-ミネルバの答えのフクロウ-知っているほとんど
CS231n

 

おすすめ

転載: www.cnblogs.com/mfryf/p/11373069.html