使用tensorflow實(shí)現(xiàn)AlexNet
AlexNet是2012年ImageNet比賽的冠軍,雖然過(guò)去了很長(zhǎng)時(shí)間,但是作為深度學(xué)習(xí)中的經(jīng)典模型,AlexNet不但有助于我們理解其中所使用的很多技巧,而且非常有助于提升我們使用深度學(xué)習(xí)工具箱的熟練度。尤其是我剛?cè)腴T(mén)深度學(xué)習(xí),迫切需要一個(gè)能讓自己熟悉tensorflow的小練習(xí),于是就有了這個(gè)小玩意兒......
先放上我的代碼:https://github.com/hjptriplebee/AlexNet_with_tensorflow
如果想運(yùn)行代碼,詳細(xì)的配置要求都在上面鏈接的readme文件中了。本文建立在一定的tensorflow基礎(chǔ)上,不會(huì)對(duì)太細(xì)的點(diǎn)進(jìn)行說(shuō)明。
模型結(jié)構(gòu)
關(guān)于模型結(jié)構(gòu)網(wǎng)上的文獻(xiàn)很多,我這里不贅述,一會(huì)兒都在代碼里解釋。
有一點(diǎn)需要注意,AlexNet將網(wǎng)絡(luò)分成了上下兩個(gè)部分,在論文中兩部分結(jié)構(gòu)完全相同,唯一不同的是他們放在不同GPU上訓(xùn)練,因?yàn)槊恳粚拥膄eature map之間都是獨(dú)立的(除了全連接層),所以這相當(dāng)于是提升訓(xùn)練速度的一種方法。很多AlexNet的復(fù)現(xiàn)都將上下兩部分合并了,因?yàn)樗麄兌际窃趩蝹€(gè)GPU上運(yùn)行的。雖然我也是在單個(gè)GPU上運(yùn)行,但是我還是很想將最原始的網(wǎng)絡(luò)結(jié)構(gòu)還原出來(lái),所以我的代碼里也是分開(kāi)的。
模型定義
def maxPoolLayer(x, kHeight, kWidth, strideX, strideY, name, padding = "SAME"): """max-pooling""" return tf.nn.max_pool(x, ksize = [1, kHeight, kWidth, 1], strides = [1, strideX, strideY, 1], padding = padding, name = name) def dropout(x, keepPro, name = None): """dropout""" return tf.nn.dropout(x, keepPro, name) def LRN(x, R, alpha, beta, name = None, bias = 1.0): """LRN""" return tf.nn.local_response_normalization(x, depth_radius = R, alpha = alpha, beta = beta, bias = bias, name = name) def fcLayer(x, inputD, outputD, reluFlag, name): """fully-connect""" with tf.variable_scope(name) as scope: w = tf.get_variable("w", shape = [inputD, outputD], dtype = "float") b = tf.get_variable("b", [outputD], dtype = "float") out = tf.nn.xw_plus_b(x, w, b, name = scope.name) if reluFlag: return tf.nn.relu(out) else: return out def convLayer(x, kHeight, kWidth, strideX, strideY, featureNum, name, padding = "SAME", groups = 1):#group為2時(shí)等于AlexNet中分上下兩部分 """convlutional""" channel = int(x.get_shape()[-1])#獲取channel conv = lambda a, b: tf.nn.conv2d(a, b, strides = [1, strideY, strideX, 1], padding = padding)#定義卷積的匿名函數(shù) with tf.variable_scope(name) as scope: w = tf.get_variable("w", shape = [kHeight, kWidth, channel/groups, featureNum]) b = tf.get_variable("b", shape = [featureNum]) xNew = tf.split(value = x, num_or_size_splits = groups, axis = 3)#劃分后的輸入和權(quán)重 wNew = tf.split(value = w, num_or_size_splits = groups, axis = 3) featureMap = [conv(t1, t2) for t1, t2 in zip(xNew, wNew)] #分別提取feature map mergeFeatureMap = tf.concat(axis = 3, values = featureMap) #feature map整合 # print mergeFeatureMap.shape out = tf.nn.bias_add(mergeFeatureMap, b) return tf.nn.relu(tf.reshape(out, mergeFeatureMap.get_shape().as_list()), name = scope.name) #relu后的結(jié)果
定義了卷積、pooling、LRN、dropout、全連接五個(gè)模塊,其中卷積模塊因?yàn)閷⒕W(wǎng)絡(luò)的上下兩部分分開(kāi)了,所以比較復(fù)雜。接下來(lái)定義AlexNet。
class alexNet(object): """alexNet model""" def __init__(self, x, keepPro, classNum, skip, modelPath = "bvlc_alexnet.npy"): self.X = x self.KEEPPRO = keepPro self.CLASSNUM = classNum self.SKIP = skip self.MODELPATH = modelPath #build CNN self.buildCNN() def buildCNN(self): """build model""" conv1 = convLayer(self.X, 11, 11, 4, 4, 96, "conv1", "VALID") pool1 = maxPoolLayer(conv1, 3, 3, 2, 2, "pool1", "VALID") lrn1 = LRN(pool1, 2, 2e-05, 0.75, "norm1") conv2 = convLayer(lrn1, 5, 5, 1, 1, 256, "conv2", groups = 2) pool2 = maxPoolLayer(conv2, 3, 3, 2, 2, "pool2", "VALID") lrn2 = LRN(pool2, 2, 2e-05, 0.75, "lrn2") conv3 = convLayer(lrn2, 3, 3, 1, 1, 384, "conv3") conv4 = convLayer(conv3, 3, 3, 1, 1, 384, "conv4", groups = 2) conv5 = convLayer(conv4, 3, 3, 1, 1, 256, "conv5", groups = 2) pool5 = maxPoolLayer(conv5, 3, 3, 2, 2, "pool5", "VALID") fcIn = tf.reshape(pool5, [-1, 256 * 6 * 6]) fc1 = fcLayer(fcIn, 256 * 6 * 6, 4096, True, "fc6") dropout1 = dropout(fc1, self.KEEPPRO) fc2 = fcLayer(dropout1, 4096, 4096, True, "fc7") dropout2 = dropout(fc2, self.KEEPPRO) self.fc3 = fcLayer(dropout2, 4096, self.CLASSNUM, True, "fc8") def loadModel(self, sess): """load model""" wDict = np.load(self.MODELPATH, encoding = "bytes").item() #for layers in model for name in wDict: if name not in self.SKIP: with tf.variable_scope(name, reuse = True): for p in wDict[name]: if len(p.shape) == 1: #bias 只有一維 sess.run(tf.get_variable('b', trainable = False).assign(p)) else: #weights sess.run(tf.get_variable('w', trainable = False).assign(p))
buildCNN函數(shù)完全按照alexnet的結(jié)構(gòu)搭建網(wǎng)絡(luò)。
loadModel函數(shù)從模型文件中讀取參數(shù),采用的模型文件見(jiàn)github上的readme說(shuō)明。
至此,我們定義了完整的模型,下面開(kāi)始測(cè)試模型。
模型測(cè)試
ImageNet訓(xùn)練的AlexNet有很多類(lèi),幾乎包含所有常見(jiàn)的物體,因此我們隨便從網(wǎng)上找?guī)讖垐D片測(cè)試。比如我直接用了之前做項(xiàng)目的渣土車(chē)圖片:
然后編寫(xiě)測(cè)試代碼:
#some params dropoutPro = 1 classNum = 1000 skip = [] #get testImage testPath = "testModel" testImg = [] for f in os.listdir(testPath): testImg.append(cv2.imread(testPath + "/" + f)) imgMean = np.array([104, 117, 124], np.float) x = tf.placeholder("float", [1, 227, 227, 3]) model = alexnet.alexNet(x, dropoutPro, classNum, skip) score = model.fc3 softmax = tf.nn.softmax(score) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) model.loadModel(sess) #加載模型 for i, img in enumerate(testImg): #img preprocess test = cv2.resize(img.astype(np.float), (227, 227)) #resize成網(wǎng)絡(luò)輸入大小 test -= imgMean #去均值 test = test.reshape((1, 227, 227, 3)) #拉成tensor maxx = np.argmax(sess.run(softmax, feed_dict = {x: test})) res = caffe_classes.class_names[maxx] #取概率最大類(lèi)的下標(biāo) #print(res) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(img, res, (int(img.shape[0]/3), int(img.shape[1]/3)), font, 1, (0, 255, 0), 2)#繪制類(lèi)的名字 cv2.imshow("demo", img) cv2.waitKey(5000) #顯示5秒
如上代碼所示,首先需要設(shè)置一些參數(shù),然后讀取指定路徑下的測(cè)試圖像,再對(duì)模型做一個(gè)初始化,最后是真正測(cè)試代碼。測(cè)試結(jié)果如下:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Tensorflow卷積神經(jīng)網(wǎng)絡(luò)實(shí)例進(jìn)階
- Tensorflow卷積神經(jīng)網(wǎng)絡(luò)實(shí)例
- TensorFlow實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)
- tensorflow實(shí)現(xiàn)簡(jiǎn)單的卷積神經(jīng)網(wǎng)絡(luò)
- TensorFlow實(shí)現(xiàn)簡(jiǎn)單卷積神經(jīng)網(wǎng)絡(luò)
- tensorflow學(xué)習(xí)筆記之mnist的卷積神經(jīng)網(wǎng)絡(luò)實(shí)例
- TensorFlow深度學(xué)習(xí)之卷積神經(jīng)網(wǎng)絡(luò)CNN
- TensorFlow實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)CNN
- Tensorflow實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)用于人臉關(guān)鍵點(diǎn)識(shí)別
- TensorFlow 實(shí)戰(zhàn)之實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)的實(shí)例講解
- Tensorflow實(shí)現(xiàn)AlexNet卷積神經(jīng)網(wǎng)絡(luò)及運(yùn)算時(shí)間評(píng)測(cè)
相關(guān)文章
python virtualenv虛擬環(huán)境配置與使用教程詳解
這篇文章主要介紹了python virtualenv虛擬環(huán)境配置與使用教程詳解,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07Python操作SQLite/MySQL/LMDB數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了Python操作SQLite/MySQL/LMDB數(shù)據(jù)庫(kù)的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11簡(jiǎn)單的Python的curses庫(kù)使用教程
這篇文章主要介紹了簡(jiǎn)單的Python的curses庫(kù)使用教程,來(lái)自IBM官方開(kāi)發(fā)者技術(shù)文檔,需要的朋友可以參考下2015-04-04淺談keras 的抽象后端(from keras import backend as K)
這篇文章主要介紹了淺談keras 的抽象后端(from keras import backend as K),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06基于Python實(shí)現(xiàn)新聞爬取系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了如何基于Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的新聞爬取系統(tǒng),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下2023-06-06caffe的python接口deploy生成caffemodel分類(lèi)新的圖片
這篇文章主要為大家介紹了caffe的python接口生成deploy文件學(xué)習(xí)以及用訓(xùn)練好的模型(caffemodel)來(lái)分類(lèi)新的圖片示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06Django之使用celery和NGINX生成靜態(tài)頁(yè)面實(shí)現(xiàn)性能優(yōu)化
這篇文章主要介紹了Django之使用celery和NGINX生成靜態(tài)頁(yè)面實(shí)現(xiàn)性能優(yōu)化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10python中ThreadPoolExecutor線程池和ProcessPoolExecutor進(jìn)程池
這篇文章主要介紹了python中ThreadPoolExecutor線程池和ProcessPoolExecutor進(jìn)程池,文章圍繞主題相關(guān)資料展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-06-06