CS20si 第7課: TensorFlow中的卷積

第7課: TensorFlow中的卷積

CS20si課程資料和代碼Github地址

沒有訓(xùn)練的卷積

你有可能已經(jīng)熟悉數(shù)學(xué)或物理中的“卷積”,牛津詞典對“卷積”在數(shù)學(xué)領(lǐng)域的定義如下:

一個(gè)由兩個(gè)給定的函數(shù)集成的函數(shù),表達(dá)一個(gè)函數(shù)的形狀是如何被另一個(gè)函數(shù)修改的个唧。

這就是卷積在機(jī)器學(xué)習(xí)中的含義,卷積是一個(gè)原始輸入Input被一個(gè)核Kernel(或者叫濾波器Filter/特征圖Feature Map)修改。更多的細(xì)節(jié)參照CS231n課程。

事實(shí)上吓揪,我們可以不用訓(xùn)練而直接使用卷積胆萧。比如我們可以用一個(gè)3x3的卷積來模糊一張圖片。

image

在TensorFlow中去做卷積贸人,我們有很多內(nèi)建的層可以使用。你可以輸入2維數(shù)據(jù)做1維卷積佃声,輸入3維數(shù)據(jù)做2維卷積艺智,輸入4維數(shù)據(jù)做3維卷積,最常用的是2維卷積圾亏。

tf.nn.conv2d(
    input,
    filter,
    strides,
    padding,
    use_cudnn_on_gpu=True,
    data_format='NHWC',
    dilations=[1, 1, 1, 1],
    name=None
)

Input: Batch size (N) x Height (H) x Width (W) x Channels (C)
Filter: Height x Width x Input Channels x Output Channels
(e.g. [5, 5, 3, 64])
Strides: 4 element 1-D tensor, strides in each direction
(often [1, 1, 1, 1] or [1, 2, 2, 1])
Padding: 'SAME' or 'VALID'
Dilations: The dilation factor. If set to k > 1, there will be k-1 skipped cells between each filter element on that dimension.
Data_format: default to NHWC

這兒還有一些其它的內(nèi)建卷積:

depthwise_conv2d: 單獨(dú)處理每個(gè)channel的數(shù)據(jù)十拣。
separable_conv2d: 一個(gè)depthwise的空間濾波器后面跟一個(gè)逐點(diǎn)濾波器。

作為一個(gè)有趣的練習(xí)志鹃,你可以在課程的GitHub中的kernes.py文件中看到一些著名的核的值夭问,在07_basic_kernels.py中看到它們的用法。

image

在練習(xí)中弄跌,我們硬編碼這些核的值甲喝,但是在訓(xùn)練一個(gè)CNN時(shí),我們不知道核的最優(yōu)值而是學(xué)習(xí)出它們铛只。我們會用老朋友MNIST來做學(xué)習(xí)核的練習(xí)埠胖。

用CNN處理MNIST

我們曾經(jīng)用含有一個(gè)全連接層的邏輯回歸處理MNIST,結(jié)果是糟糕的〈就妫現(xiàn)在讓我們看看用局部連接的CNN是否會好一些直撤。

我們將會用兩個(gè)步長為1的卷積層,每個(gè)跟隨一個(gè)relu激活和最大池化層maxpool蜕着,最后加上兩個(gè)全連接層谋竖。

image

卷積層

def conv_relu(inputs, filters, k_size, stride, padding, scope_name):
    with tf.variable_scope(scope_name, reuse=tf.AUTO_REUSE) as scope:
        in_channels = inputs.shape[-1]
        kernel = tf.get_variable('kernel', [k_size, k_size, in_channels, filters], 
                                initializer=tf.truncated_normal_initializer())
        biases = tf.get_variable('biases', [filters],
                            initializer=tf.random_normal_initializer())
        conv = tf.nn.conv2d(inputs, kernel, strides=[1, stride, stride, 1], padding=padding)
    return tf.nn.relu(conv + biases, name=scope.name)

池化層

def maxpool(inputs, ksize, stride, padding='VALID', scope_name='pool'):
    with tf.variable_scope(scope_name, reuse=tf.AUTO_REUSE) as scope:
        pool = tf.nn.max_pool(inputs, 
                            ksize=[1, ksize, ksize, 1], 
                            strides=[1, stride, stride, 1],
                            padding=padding)
    return pool

全連接層

def fully_connected(inputs, out_dim, scope_name='fc'):
    with tf.variable_scope(scope_name, reuse=tf.AUTO_REUSE) as scope:
        in_dim = inputs.shape[-1]
        w = tf.get_variable('weights', [in_dim, out_dim],
                            initializer=tf.truncated_normal_initializer())
        b = tf.get_variable('biases', [out_dim],
                            initializer=tf.constant_initializer(0.0))
        out = tf.matmul(inputs, w) + b
    return out

放在一起

有了上面這些層,我們可以簡單地建立我們的模型

def inference(self):
        conv1 = conv_relu(inputs=self.img,
                        filters=32,
                        k_size=5,
                        stride=1,
                        padding='SAME',
                        scope_name='conv1')
        pool1 = maxpool(conv1, 2, 2, 'VALID', 'pool1')
        conv2 = conv_relu(inputs=pool1,
                        filters=64,
                        k_size=5,
                        stride=1,
                        padding='SAME',
                        scope_name='conv2')
        pool2 = maxpool(conv2, 2, 2, 'VALID', 'pool2')
        feature_dim = pool2.shape[1] * pool2.shape[2] * pool2.shape[3]
        pool2 = tf.reshape(pool2, [-1, feature_dim])
        fc = tf.nn.relu(fully_connected(pool2, 1024, 'fc'))
        dropout = tf.layers.dropout(fc, self.keep_prob, training=self.training, name='dropout')
        
        self.logits = fully_connected(dropout, self.n_classes, 'logits')

在訓(xùn)練時(shí)承匣,需要評估每個(gè)epoch的準(zhǔn)確率蓖乘。

def eval(self):
        '''
        Count the number of right predictions in a batch
        '''
        with tf.name_scope('predict'):
            preds = tf.nn.softmax(self.logits)
            correct_preds = tf.equal(tf.argmax(preds, 1), tf.argmax(self.label, 1))
            self.accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32))

可以在課程Github的07_convnet_mnist.py中查看完整代碼。

譯者注:這篇略過了很多和CS231n重復(fù)的東西韧骗,CS20si中的CNN相關(guān)課程主要看看Tensorflow的代碼組織嘉抒,CNN的知識還是推薦看CS231n系列課程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末袍暴,一起剝皮案震驚了整個(gè)濱河市些侍,隨后出現(xiàn)的幾起案子隶症,更是在濱河造成了極大的恐慌,老刑警劉巖岗宣,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚂会,死亡現(xiàn)場離奇詭異,居然都是意外死亡耗式,警方通過查閱死者的電腦和手機(jī)胁住,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刊咳,“玉大人措嵌,你說我怎么就攤上這事÷郑” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵枫慷,是天一觀的道長让蕾。 經(jīng)常有香客問我,道長或听,這世上最難降的妖魔是什么探孝? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮誉裆,結(jié)果婚禮上顿颅,老公的妹妹穿的比我還像新娘。我一直安慰自己足丢,他們只是感情好粱腻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著斩跌,像睡著了一般绍些。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耀鸦,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天柬批,我揣著相機(jī)與錄音,去河邊找鬼袖订。 笑死氮帐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洛姑。 我是一名探鬼主播上沐,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吏口!你這毒婦竟也來了奄容?” 一聲冷哼從身側(cè)響起冰更,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昂勒,沒想到半個(gè)月后蜀细,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡戈盈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年奠衔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塘娶。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡归斤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刁岸,到底是詐尸還是另有隱情脏里,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布虹曙,位于F島的核電站迫横,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏酝碳。R本人自食惡果不足惜矾踱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疏哗。 院中可真熱鬧呛讲,春花似錦、人聲如沸返奉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芽偏。三九已至徘公,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哮针,已是汗流浹背关面。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留十厢,地道東北人等太。 一個(gè)月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像蛮放,于是被迫代替她去往敵國和親缩抡。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容