使用tensorflow实现AlexNet
作者:triplebee 发布时间:2023-08-10 08:29:30
AlexNet是2012年ImageNet比赛的冠军,虽然过去了很长时间,但是作为深度学习中的经典模型,AlexNet不但有助于我们理解其中所使用的很多技巧,而且非常有助于提升我们使用深度学习工具箱的熟练度。尤其是我刚入门深度学习,迫切需要一个能让自己熟悉tensorflow的小练习,于是就有了这个小玩意儿......
先放上我的代码:https://github.com/hjptriplebee/AlexNet_with_tensorflow
如果想运行代码,详细的配置要求都在上面链接的readme文件中了。本文建立在一定的tensorflow基础上,不会对太细的点进行说明。
模型结构
关于模型结构网上的文献很多,我这里不赘述,一会儿都在代码里解释。
有一点需要注意,AlexNet将网络分成了上下两个部分,在论文中两部分结构完全相同,唯一不同的是他们放在不同GPU上训练,因为每一层的feature map之间都是独立的(除了全连接层),所以这相当于是提升训练速度的一种方法。很多AlexNet的复现都将上下两部分合并了,因为他们都是在单个GPU上运行的。虽然我也是在单个GPU上运行,但是我还是很想将最原始的网络结构还原出来,所以我的代码里也是分开的。
模型定义
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时等于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)#定义卷积的匿名函数
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)#划分后的输入和权重
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后的结果
定义了卷积、pooling、LRN、dropout、全连接五个模块,其中卷积模块因为将网络的上下两部分分开了,所以比较复杂。接下来定义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函数完全按照alexnet的结构搭建网络。
loadModel函数从模型文件中读取参数,采用的模型文件见github上的readme说明。
至此,我们定义了完整的模型,下面开始测试模型。
模型测试
ImageNet训练的AlexNet有很多类,几乎包含所有常见的物体,因此我们随便从网上找几张图片测试。比如我直接用了之前做项目的渣土车图片:
然后编写测试代码:
#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成网络输入大小
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] #取概率最大类的下标
#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)#绘制类的名字
cv2.imshow("demo", img)
cv2.waitKey(5000) #显示5秒
如上代码所示,首先需要设置一些参数,然后读取指定路径下的测试图像,再对模型做一个初始化,最后是真正测试代码。测试结果如下:
来源:http://blog.csdn.net/accepthjp/article/details/69999309


猜你喜欢
- (一)问题遗传算法求解正方形拼图游戏(二)代码#!/usr/bin/env python# -*- coding: utf-8 -*-fro
- 本文实例为大家分享了JS HTML5拖拽上传图片预览的具体代码,供大家参考,具体内容如下1.文件API:(File API)file类型的的
- 很多人喜欢把一个网站中相同的部分象是统一的页面logo,版权声明等做成一个过程,然后放到一个include文件中,这样所有的页面就都可以使用
- 1、Tkinter是什么Tkinter 是使用 python 进行窗口视窗设计的模块。Tkinter模块(“Tk 接口&
- 代码如下: EXEC sp_rename '表名.[原列名]', '新列名', 'column
- 本文实例讲述了Python自定义scrapy中间模块避免重复采集的方法。分享给大家供大家参考。具体如下:from scrapy import
- 在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定
- 在产品开发中,由UED发起的项目越来越多,但是现在的问题是很难为其设定商业价值的目标。如果没有明确的商业价值目标,很多公司根本没办法花大成本
- 1、准备工作准备数据:生成随机数并写入文件,之后在把数据读取出来//新生成整数随机数,并存储在txt文件中,func NewIntRandm
- python标准库OS模块简介os就是“operating system”的缩写,顾名思义,os模块提供的就是各种 Python 程序与操作
- 忽然想起一个CSS的特性,写一段代码玩玩:<style type="text/css">body {font
- 学习https://matplotlib.org/gallery/index.html 记录,描述不一定准确,具体请参考官网Matplotl
- 本文实例讲述了Python实现爬取马云的微博功能。分享给大家供大家参考,具体如下:分析请求我们打开 Ajax 的 XHR 过滤器,然后一直滑
- 本期我们将展示一种对路面类型和质量进行分类的方法及其步骤。为了测试这种方法,我们使用了我们制作的RTK数据集。路面分类该数据集[1]包含用低
- 开篇这段时间把主要精力都放在了K8S上,差点把Golang给忘了。那本篇就分享一下并发相关的内容(Goroutine和通道)。 本篇给出4个
- 12-24小时制编写一个程序,要求用户输入24小时制的时间,然后显示12小时制的时间。输入格式:输入在一行中给出带有中间的:符号(半角的冒号
- 区块链区块链是在计算机网络的节点之间共享数据的分类账(分布式数据库)。作为数据库,区块链以电子格式储存信息。区块链的创新之处在于它保证了数据
- 本文实例讲述了mysql 数据库备份的多种实现方式。分享给大家供大家参考,具体如下:一、使用mysqldump进行备份1、完整备份所有数据库
- 这篇文章主要介绍了IOS苹果AppStore内购付款的服务器端php验证方法(使用thinkphp)。AppStore内购在app中支付的过
- 废话不多说了,直接给大家贴代码了,具体代码如下所示:<!DOCTYPE html> <html> <head&