当前位置:   article > 正文

基于TensorFlow实现AlexNet网络的构建、测试、微调过程_alexnet的权重参数bvlc_alexnet.npy文件下载

alexnet的权重参数bvlc_alexnet.npy文件下载

本文主要参照博客中内容实现AlexNet网络的构建、测试过程,利用自己的方法制作训练集来进行微调过程。本文主要介绍在TensorFlow框架下AlexNet网络的实现程序。下图是AlexNet网络的网络结构:

1. AlexNet网络的构建过程:下面程序(注释)创建了一个类来定义AlexNet模型图,并带有加载预训练参数的函数

  1. #定义AlexNet神经网络结构模型
  2. import tensorflow as tf
  3. import numpy as np
  4. #建立模型图
  5. class AlexNet(object):
  6. #keep_prob:dropout概率,num_classes:数据类别数,skip_layer
  7. def __init__(self,x,keep_prob,num_classes,skip_layer,weights_path='DEFAULT'):
  8. self.X=x
  9. self.NUM_CLASSES=num_classes
  10. self.KEEP_PROB=keep_prob
  11. self.SKIP_LAYER=skip_layer
  12. if weights_path=='DEFAULT':
  13. self.WEIGHTS_PATH='f:\\python程序\\AlexNet_Protect\\bvlc_alexnet.npy'
  14. else:
  15. self.WEIGHTS_PATH=weights_path
  16. self.create()
  17. def create(self):
  18. #第一层:卷积层-->最大池化层-->LRN
  19. conv1=conv_layer(self.X,11,11,96,4,4,padding='VALID',name='conv1')
  20. self.conv1=conv1
  21. pool1=max_pool(conv1,3,3,2,2,padding='VALID',name='pool1')
  22. norm1=lrn(pool1,2,2e-05,0.75,name='norml')
  23. #第二层:卷积层-->最大池化层-->LRN
  24. conv2=conv_layer(norm1,5,5,256,1,1,groups=2,name='conv2')
  25. self.conv2=conv2
  26. pool2=max_pool(conv2,3,3,2,2,padding='VALID',name='pool2')
  27. norm2=lrn(pool2,2,2e-05,0.75,name='norm2')
  28. #第三层:卷积层
  29. conv3=conv_layer(norm2,3,3,384,1,1,name='conv3')
  30. self.conv3=conv3
  31. #第四层:卷积层
  32. conv4=conv_layer(conv3,3,3,384,1,1,groups=2,name='conv4')
  33. self.conv4=conv4
  34. #第五层:卷积层-->最大池化层
  35. conv5=conv_layer(conv4,3,3,256,1,1,groups=2,name='conv5')
  36. self.conv5=conv5
  37. pool5=max_pool(conv5,3,3,2,2,padding='VALID',name='pool5')
  38. #第六层:全连接层
  39. flattened=tf.reshape(pool5,[-1,6*6*256])
  40. fc6=fc_layer(flattened,6*6*256,4096,name='fc6')
  41. dropout6=dropout(fc6,self.KEEP_PROB)
  42. #第七层:全连接层
  43. fc7=fc_layer(dropout6,4096,4096,name='fc7')
  44. dropout7=dropout(fc7,self.KEEP_PROB)
  45. #第八层:全连接层,不带激活函数
  46. self.fc8=fc_layer(dropout7,4096,self.NUM_CLASSES,relu=False,name='fc8')
  47. #加载神经网络预训练参数,将存储于self.WEIGHTS_PATH的预训练参数赋值给那些没有在self.SKIP_LAYER中指定的网络层的参数
  48. def load_initial_weights(self,session):
  49. #下载权重文件
  50. weights_dict=np.load(self.WEIGHTS_PATH,encoding='bytes').item()
  51. for op_name in weights_dict:
  52. if op_name not in self.SKIP_LAYER:
  53. with tf.variable_scope(op_name,reuse=True):
  54. for data in weights_dict[op_name]:
  55. #偏置项
  56. if len(data.shape)==1:
  57. var=tf.get_variable('biases',trainable=False)
  58. session.run(var.assign(data))
  59. #权重
  60. else:
  61. var=tf.get_variable('weights',trainable=False)
  62. session.run(var.assign(data))
  63. #定义卷积层,当groups=1时,AlexNet网络不拆分;当groups=2时,AlexNet网络拆分成上下两个部分。
  64. def conv_layer(x,filter_height,filter_width,num_filters,stride_y,stride_x,name,padding='SAME',groups=1):
  65. #获得输入图像的通道数
  66. input_channels=int(x.get_shape()[-1])
  67. #创建lambda表达式
  68. convovle=lambda i,k:tf.nn.conv2d(i,k,strides=[1,stride_y,stride_x,1],padding=padding)
  69. with tf.variable_scope(name) as scope:
  70. #创建卷积层所需的权重参数和偏置项参数
  71. weights=tf.get_variable("weights",shape=[filter_height,filter_width,input_channels/groups,num_filters])
  72. biases=tf.get_variable("biases",shape=[num_filters])
  73. if groups==1:
  74. conv=convovle(x,weights)
  75. #当groups不等于1时,拆分输入和权重
  76. else:
  77. input_groups=tf.split(axis=3,num_or_size_splits=groups,value=x)
  78. weight_groups=tf.split(axis=3,num_or_size_splits=groups,value=weights)
  79. output_groups=[convovle(i,k) for i,k in zip(input_groups,weight_groups)]
  80. #单独计算完后,再次根据深度连接两个网络
  81. conv=tf.concat(axis=3,values=output_groups)
  82. #加上偏置项
  83. bias=tf.reshape(tf.nn.bias_add(conv,biases),conv.get_shape().as_list())
  84. #激活函数
  85. relu=tf.nn.relu(bias,name=scope.name)
  86. return relu
  87. #定义全连接层
  88. def fc_layer(x,num_in,num_out,name,relu=True):
  89. with tf.variable_scope(name) as scope:
  90. #创建权重参数和偏置项
  91. weights=tf.get_variable("weights",shape=[num_in,num_out],trainable=True)
  92. biases=tf.get_variable("biases",[num_out],trainable=True)
  93. #计算
  94. act=tf.nn.xw_plus_b(x,weights,biases,name=scope.name)
  95. if relu==True:
  96. relu=tf.nn.relu(act)
  97. return relu
  98. else:
  99. return act
  100. #定义最大池化层
  101. def max_pool(x,filter_height,filter_width,stride_y,stride_x,name,padding='SAME'):
  102. return tf.nn.max_pool(x,ksize=[1,filter_height,filter_width,1],strides=[1,stride_y,stride_x,1],padding=padding,name=name)
  103. #定义局部响应归一化LPN
  104. def lrn(x,radius,alpha,beta,name,bias=1.0):
  105. return tf.nn.local_response_normalization(x,depth_radius=radius,alpha=alpha,beta=beta,bias=bias,name=name)
  106. #定义dropout
  107. def dropout(x,keep_prob):
  108. return tf.nn.dropout(x,keep_prob)

2. 输入一张图片对AlexNet网络进行测试,可以查看卷积层提取的特征图

  1. import tensorflow as tf
  2. import AlexNet_model
  3. import numpy as np
  4. import cv2
  5. import caffe_classes
  6. import matplotlib.pyplot as plt
  7. keep_prob=0.5
  8. num_classes=1000
  9. skip_layer=[]
  10. #测试图片读取路径
  11. image = cv2.imread("f:\\tmp\\data\\zebra.jpeg")
  12. img_resized = cv2.resize(image, (227, 227))
  13. x=tf.placeholder(tf.float32,[1,227,227,3],name='x-input')
  14. #定义神经网络结构,初始化模型
  15. model=AlexNet_model.AlexNet(x,keep_prob,num_classes,skip_layer)
  16. conv1=model.conv1
  17. conv5=model.conv5
  18. score=model.fc8
  19. #获得神经网络前向传播的softmax层输出
  20. softmax=tf.nn.softmax(score)
  21. with tf.Session() as sess:
  22. sess.run(tf.global_variables_initializer())
  23. model.load_initial_weights(sess)
  24. test=np.reshape(img_resized,(1,227,227,3))
  25. #sess.run()函数运行张量返回的是就是对应的数组
  26. soft,con1,con5=sess.run([softmax,conv1,conv5],feed_dict={x:test})
  27. #显示第五层卷积层提取的前6个特征图
  28. for i in range(6):
  29. plt.matshow(con5[0,:,:,0],cmap=plt.cm.gray)
  30. plt.show()
  31. #获取其中最大值所在的索引
  32. maxx=np.argmax(soft)
  33. #找到目标所属的类别
  34. ress=caffe_classes.class_names[maxx]
  35. text='Predicted class:'+str(maxx)+'('+ress+')'
  36. #显示测试类别
  37. cv2.putText(image,text, (20,20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
  38. #显示属于该类别的概率
  39. cv2.putText(image,'with probability:'+str(soft[0][maxx]), (20,50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
  40. cv2.imshow('test_image', image)
  41. #显示10秒
  42. cv2.waitKey(10000)

测试结果如图所示:


3. 直接读取本地图片制作自己的数据集,用的是猫狗大战图片,链接:http://pan.baidu.com/s/1dFd8kmt 密码:psor

  1. import tensorflow as tf
  2. import os
  3. import numpy as np
  4. #生成训练图片的路径
  5. train_dir='f:\\cat_dog_image\\train\\'
  6. #获取图片,存放到对应的列表中,同时贴上标签,存放到label列表中
  7. def get_files(file_dir):
  8. cats =[]
  9. label_cats =[]
  10. dogs =[]
  11. label_dogs =[]
  12. for file in os.listdir(file_dir):
  13. name = file.split(sep='.')
  14. if name[0]=='cat':
  15. cats.append(file_dir + file)
  16. label_cats.append(0)
  17. else:
  18. dogs.append(file_dir + file)
  19. label_dogs.append(1)
  20. #合并数据
  21. image_list = np.hstack((cats, dogs))
  22. label_list = np.hstack((label_cats, label_dogs))
  23. #利用shuffle打乱数据
  24. temp = np.array([image_list, label_list])
  25. temp = temp.transpose() # 转置
  26. np.random.shuffle(temp)
  27. #将所有的image和label转换成list
  28. image_list = list(temp[:, 0])
  29. label_list = list(temp[:, 1])
  30. label_list = [int(i) for i in label_list]
  31. return image_list, label_list
  32. #将上面生成的List传入get_batch() ,转换类型,产生一个输入队列queue,因为img和lab
  33. #是分开的,所以使用tf.train.slice_input_producer(),然后用tf.read_file()从队列中读取图像
  34. def get_batch(image,label,image_W,image_H,batch_size,capacity):
  35. #将python.list类型转换成tf能够识别的格式
  36. image=tf.cast(image,tf.string)
  37. label=tf.cast(label,tf.int32)
  38. #产生一个输入队列queue
  39. input_queue=tf.train.slice_input_producer([image,label])
  40. label=input_queue[1]
  41. image_contents=tf.read_file(input_queue[0])
  42. #将图像解码,不同类型的图像不能混在一起,要么只用jpeg,要么只用png等。
  43. image=tf.image.decode_jpeg(image_contents,channels=3)
  44. #将数据预处理,对图像进行旋转、缩放、裁剪、归一化等操作,让计算出的模型更健壮。
  45. image=tf.image.resize_image_with_crop_or_pad(image,image_W,image_H)
  46. image=tf.image.per_image_standardization(image)
  47. #生成batch
  48. image_batch,label_batch=tf.train.batch([image,label],batch_size=batch_size,num_threads=64,capacity=capacity)
  49. #重新排列标签,行数为[batch_size]
  50. #label_batch=tf.reshape(label_batch,[batch_size])
  51. image_batch=tf.cast(image_batch,tf.float32)
  52. return image_batch,label_batch

4. 利用自己的训练集对AlexNet网络进行微调,这里对AlexNet网络中第六、七、八全连接层进行重新训练

  1. #利用Tensorflow对预训练的AlexNet网络进行微调
  2. import tensorflow as tf
  3. import numpy as np
  4. import os
  5. from AlexNet_model import AlexNet
  6. #from datagenerator import ImageDataGenerator
  7. #from datetime import datetime
  8. #from tensorflow.contrib.data import Iterator
  9. import input_selfdata
  10. #模型保存的路径和文件名。
  11. MODEL_SAVE_PATH="/model/"
  12. MODEL_NAME="alexnet_model.ckpt"
  13. #训练集图片所在路径
  14. train_dir='f:\\cat_dog_image\\train\\'
  15. #训练图片的尺寸
  16. image_size=227
  17. #训练集中图片总数
  18. total_size=250000
  19. #学习率
  20. learning_rate=0.001
  21. #训练完整数据集迭代轮数
  22. num_epochs=10
  23. #数据块大小
  24. batch_size=128
  25. #执行Dropout操作所需的概率值
  26. dropout_rate=0.5
  27. #类别数目
  28. num_classes=2
  29. #需要重新训练的层
  30. train_layers=['fc8','fc7','fc6']
  31. #读取本地图片,制作自己的训练集,返回image_batch,label_batch
  32. train, train_label = input_selfdata.get_files(train_dir)
  33. x,y=input_selfdata.get_batch(train,train_label,image_size,image_size,batch_size,2000)
  34. #用于计算图输入和输出的TF占位符,每次读取一小部分数据作为当前的训练数据来执行反向传播算法
  35. #x =tf.placeholder(tf.float32,[batch_size,227,227,3],name='x-input')
  36. #y =tf.placeholder(tf.float32,[batch_size,num_classes])
  37. keep_prob=tf.placeholder(tf.float32)
  38. #定义神经网络结构,初始化模型
  39. model =AlexNet(x,keep_prob,num_classes,train_layers)
  40. #获得神经网络前向传播的输出
  41. score=model.fc8
  42. #获得想要训练的层的可训练变量列表
  43. var_list = [v for v in tf.trainable_variables() if v.name.split('/')[0] in train_layers]
  44. #定义损失函数,获得loss
  45. with tf.name_scope("cross_ent"):
  46. loss=tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=score,labels=y))
  47. #定义反向传播算法(优化算法)
  48. with tf.name_scope("train"):
  49. # 获得所有可训练变量的梯度
  50. gradients = tf.gradients(loss, var_list)
  51. gradients = list(zip(gradients, var_list))
  52. # 选择优化算法,对可训练变量应用梯度下降算法更新变量
  53. optimizer = tf.train.GradientDescentOptimizer(learning_rate)
  54. train_op = optimizer.apply_gradients(grads_and_vars=gradients)
  55. #使用前向传播的结果计算正确率
  56. with tf.name_scope("accuracy"):
  57. correct_pred=tf.equal(tf.cast(tf.argmax(score,1),tf.int32),y)
  58. accuracy=tf.reduce_mean(tf.cast(correct_pred,tf.float32))
  59. #Initialize an saver for store model checkpoints 加载模型
  60. saver=tf.train.Saver()
  61. # 每个epoch中验证集/测试集需要训练迭代的轮数
  62. train_batches_per_epoch = int(np.floor(total_size/batch_size))
  63. with tf.Session() as sess:
  64. #变量初始化
  65. tf.global_variables_initializer().run()
  66. coord = tf.train.Coordinator()
  67. threads = tf.train.start_queue_runners(coord=coord)
  68. try:
  69. for epoch in range(num_epochs):
  70. for step in range(train_batches_per_epoch):
  71. #while not coord.should_stop():
  72. if coord.should_stop():
  73. break
  74. _,loss_value,accu=sess.run([train_op,loss,accuracy],feed_dict={keep_prob: 1.})
  75. if step%50==0:
  76. print("Afetr %d training step(s),loss on training batch is %g,accuracy is %g." % (step,loss_value,accu))
  77. saver.save(sess,os.path.join(MODEL_SAVE_PATH,MODEL_NAME))
  78. except tf.errors.OutOfRangeError:
  79. print('done!')
  80. finally:
  81. coord.request_stop()
  82. coord.join(threads)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/123940
推荐阅读
相关标签
  

闽ICP备14008679号