參考部落格
# -*- coding:utf8 -*-
import numpy as np
import time
import timeit
#手動實現卷積操作 假設輸入,核均為正方形,通道數為1,核數量為3,步幅為1,填充為0
x = np.array([[1,2,0],[1,1,3],[0,2,2]])
k = np.array([[[1,1,],[2,2]],[[1,1],[1,1]],[[0,1],[1,0]]])
number =3
kernel_size = 2
# 普通卷積,對應項相乘再求和
def conv_op(bottom,b_size,kernel,kernel_size,number,stride,padding):
top_size = (b_size + 2*padding - kernel_size)/stride+1
top = np.zeros(shape=(number,top_size,top_size))
for c in range(number):#第c個核
for h in range(top_size):#豎直方向第h次擷取圖的部分
for w in range(top_size):#水平方向第w次
# 先滑動視窗取部分圖 依次乘第c個kernel並求和 賦給特徵圖對應位置
這是簡單的方法,將和核轉化為矩陣,進行點積運算。
這裡是3通道3x3的,卷積核有2個,通道數為3,尺寸為2,步幅為1,無填充。
#另一種簡便的方法把卷積操作變成兩個大矩陣的點積
#將輸出圖變成乙個矩陣 每一行表示乙個待卷積的部分圖拉伸後的結果
def conv_op2(bottom,b_size,kernel_size,stride,padding):
top_size = (b_size + 2*padding - kernel_size)/stride+1 #單維度上應該滑動的次數 即特徵圖的尺寸
top = np.zeros(shape=(top_size*top_size,kernel_size*kernel_size))
for h in range(top_size):#豎直方向第h次
for w in range(top_size):#水平方向第w次
#print bottom[h*stride:h*stride+kernel_size,w*stride:w*stride+kernel_size]
t=bottom[h*stride:h*stride+kernel_size,w*stride:w*stride+kernel_size]
top[h*top_size+w]=t.reshape(1,4)
return top
time3 = time.clock()
x = conv_op2(x,3,kernel_size,1,0)
time4 = time.clock()
print '****** convop time:',time4-time3
# 轉化核為乙個矩陣
z=np.zeros(shape=(kernel_size*kernel_size,number))
for i in range(number):
#將第i個核拉伸成(kernel_size*kernel_size,1)形狀 並放入z的第i+1列
z[:,i:i+1] = k[i].reshape(4,1)
#k = np.reshape(k,()
# 點乘
q=np.dot(x,z)
print q.t.reshape(3,2,2) #還原成特徵圖
#輸出執行時間能看出 後者比前者快了10倍
卷積操作的matlab實現
工作之餘,腦海中突然蹦出 影象的卷積操作怎麼實現呢?然後仔細考慮了以下實現細節,並記錄下來,以備日後檢視。為了便於敘述和驗證程式的有效性,這裡貼出一張原圖 圖1 和它相應地經過均值核卷積以後的效果圖 圖2 圖1.castle原始 圖2.castle經過均值核卷積後的結果 matlab functio...
pytorch實現Sep conv卷積操作
這個卷積名字起得花裡胡哨的,其實總結起來就是輸入通道每個通道乙個卷積得到和輸入通道數相同的特徵圖,然後再使用若干個1 1的卷積聚合每個特徵圖的值得到輸出特徵圖。假設我們輸入通道是16,輸出特徵圖是32,並且使用3 3的卷積提取特徵,那麼第一步一共需要16 3 3個引數,第二步需要32 16 1 1個...
深度學習之卷積操作的實現
影象的卷積概述 一般,通過對進行卷積操作,可以對進行某種效果的增強或者是減弱,比如模糊 銳化 浮雕效果等,當然也可以發現中的某些特徵,如查詢物體的邊緣資訊。什麼是卷積核 一張卷積後的效果,絕大部分取決於它的卷積核。卷積核就是乙個2維的陣列,行列數相等而且為奇數 因為每個卷積核都是對於它中心的那個畫素...