当前位置:   article > 正文

10月26日,AlexNet学习汇总_for i, img in enumerate(data): if i == num_samples

for i, img in enumerate(data): if i == num_samples: break plt.subplot(in

AlexNet网络的实现

关于AlexNet的一些介绍,https://www.cnblogs.com/gongxijun/p/6027747.html

里面有一些关于维度的计算,我还是没弄太清楚

这里还有一些更加详细了,可以深入的理解看一下。

https://www.cnblogs.com/alexanderkun/p/6917984.html

https://www.cnblogs.com/alexanderkun/p/6917985.html

https://www.cnblogs.com/alexanderkun/p/6918045.html

 

这是一个实践的框架,https://blog.csdn.net/MargretWG/article/details/70491745?locationNum=1&fps=1

是基于这个外国人的文章写的https://kratzert.github.io/2017/02/24/finetuning-alexnet-with-tensorflow.html

 

这里还有这样的一篇文章https://blog.csdn.net/btbujhj/article/details/73302970

里面讲述的内容也很详细,还有一些算法案例

 

 

 

 

1,__init__的用法

(知乎搬运)

定义类的时候,若是添加__init__方法,那么在创建类的实例的时候,实例会自动调用这个方法,一般用来对实例的属性进行初使化。比如:
class testClass:
def __init__(self, name, gender): //定义 __init__方法,这里有三个参数,这个self指的是一会创建类的实例的时候这个被创建的实例本身(例中的testman),你也可以写成其他的东西,比如写成me也是可以的,这样的话下面的self.Name就要写成me.Name。
self.Name=name //通常会写成self.name=name,这里为了区分前后两个是不同的东东,把前面那个大写了,等号左边的那个Name(或name)是实例的属性,后面那个是方法__init__的参数,两个是不同的)
self.Gender=gender //通常会写成self.gender=gender
print('hello') //这个print('hello')是为了说明在创建类的实例的时候,__init__方法就立马被调用了。

testman = testClass('neo,'male') //这里创建了类testClass的一个实例 testman, 类中有__init__这个方法,在创建类的实例的时候,就必须要有和方法__init__匹配的参数了,由于self指的就是创建的实例本身,self是不用传入的,所以这里传入两个参数。这条语句一出来,实例testman的两个属性Name,Gender就被赋值初使化了,其中Name是 neo,Gender 是male。

1.5  lambda函数的用法

re, 看懂代码应该就明白是什么意思了

  1. # -*- coding: utf-8 -*-
  2. # 匿名函数lambda
  3. def sum(x,y):
  4. return x+y
  5. print('common use',sum(3,5))
  6. p = lambda x,y:x+y
  7. # 匿名函数没有返回值,自己本身就是返回值
  8. print('lambda uses',p(7,8))
  1. common use 8
  2. lambda uses 15

2,dropout & dropout rate

ropout是hintion最近2年提出的;为了防止模型过拟合,Dropout可以作为一种trikc供选择。在hinton的论文摘要中指出,在每个训练批次中,通过忽略一半的特征检测器(让一半的隐层节点值为0),可以明显地减少过拟合现象。这种方式可以减少特征检测器间的相互作用,检测器相互作用是指某些检测器依赖其他检测器才能发挥作用。

https://www.jianshu.com/p/b5e93fa01385

https://blog.csdn.net/stdcoutzyx/article/details/49022443

https://www.cnblogs.com/zyber/p/6824980.html

 

3. input_channels = int(x.get_shape()[-1])

get_shape函数()

              函数主要用于获取一个张量的维度,并且输出张量 每个维度上面的值,如果是二维矩阵,也就是输出行和列的值,使用非常方便。

  1. import tensorflow as tf;
  2. with tf.Session() as sess:
  3. A = tf.random_normal(shape=[3,4])
  4. print A.get_shape()
  5. print A.get_shape
  1. 输出:
  2. (3, 4)
  3. <bound method Tensor.get_shape of <tf.Tensor 'random_normal:0' shape=(3, 4) dtype=float32>>

 

注意:第一个输出是一个元祖,就是数值,而第二输出就是一个张量的对象,里面包含更多的东西,在不同的情况下,使用不同的方式。如果你需要输出某一个维度上面的值那就用下面的这种方式就好了。

A.get_shape()[0]

这就表示第一个维度。

 

4,  lambda函数

( 也就是匿名函数 !!! )

在python中有一个匿名函数lambda,匿名函数顾名思义就是指:是指一类无需定义标识符(函数名)的函数或子程序。

   

  1. # -*- coding: UTF-8 -*-
  2. f = lambda x,y,z:x + y + z
  3. print f(1,2,3)
  4. print f(4,5,6)
  5. 输出:
  6. 6
  7. 15

  

使用lambda函数应该注意的几点:

  • lambda定义的是单行函数,如果需要复杂的函数,应该定义普通函数
  • lambda参数列表可以包含多个参数,如 lambda x, y: x + y
  • lambda中的表达式不能含有命令,而且只限一条表达式

 

5, with tf.variable_scope(name) as scope:  的用法

 

tf.variable_scope() 主要结合 tf.get_variable() 来使用,实现 变量共享。

'''
Signature: tf.name_scope(*args, **kwds)
Docstring:
Returns a context manager for use when defining a Python op.
'''

这两篇博客说的已经非常详细了

https://www.cnblogs.com/adong7639/p/8136273.html

6,  weights = tf.get_variable

就是一个变量创建的函数:

tf.get_variable(name,  shape, initializer): name就是变量的名称,shape是变量的维度,initializer是变量初始化的方式

 

使用tf.Variable时,如果检测到命名冲突,系统会自己处理。使用tf.get_variable()时,系统不会处理冲突,而会报错

基于这两个函数的特性,当我们需要共享变量的时候,需要使用tf.get_variable()。在其他情况下,这两个的用法是一样的

 

tensorflow中有两个关于variable的op,tf.Variable()tf.get_variable()下面介绍这两个的区别

https://blog.csdn.net/u012436149/article/details/53696970

 

7,  tf.split & tf.concat

tf.split( value, num_or_size_splits, axis=0, num=None, name='split' )

这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。 
value传入的就是需要切割的张量。 
这个函数有两种切割的方式:

以三个维度的张量为例,比如说一个20 * 30 * 40的张量my_tensor,就如同一个长20厘米宽30厘米高40厘米的蛋糕,每立方厘米都是一个分量。

有两种切割方式: 
1. 如果num_or_size_splits传入的是一个整数,这个整数代表这个张量最后会被切成几个小张量。此时,传入axis的数值就代表切割哪个维度(从0开始计数)。调用tf.split(my_tensor, 2,0)返回两个10 * 30 * 40的小张量。 
2. 如果num_or_size_splits传入的是一个向量,那么向量有几个分量就分成几份,切割的维度还是由axis决定。比如调用tf.split(my_tensor, [10, 5, 25], 2),则返回三个张量分别大小为 20 * 30 * 10、20 * 30 * 5、20 * 30 * 25。很显然,传入的这个向量各个分量加和必须等于axis所指示原张量维度的大小 (10 + 5 + 25 = 40)。

 

 

tf.concat( )和tf.stack( )

https://www.cnblogs.com/mdumpling/p/8053474.html

 

8,  tf.nn.xw_plus_b

tf.nn.xw_plus_b((x, weights) + biases)

相当于tf.matmul(x, weights) + biases

  1. #-*-coding:utf8-*-
  2. import tensorflow as tf
  3. x=[[1, 2, 3],[4, 5, 6]]
  4. w=[[ 7, 8],[ 9, 10],[11, 12]]
  5. b=[[3,3],[3,3]]
  6. result1=tf.nn.xw_plus_b(x,w,[3,3])
  7. result2=tf.matmul(x, w) + b
  8. init_op = tf.initialize_all_variables()
  9. with tf.Session() as sess:
  10. # Run the init operation.
  11. sess.run(init_op)
  12. print(sess.run(result1))
  13. print(sess.run(result2))

结果为

  1. [[ 61 67]
  2. [142 157]]
  3. [[ 61 67]
  4. [142 157]]

 

 

********************调试部分的一些函数***************************

Part 1 

  1. import os
  2. import cv2
  3. import numpy as np
  4. import tensorflow as tf
  5. import matplotlib.pyplot as plt
  6. # mean of imagenet dataset in BGR
  7. imagenet_mean = np.array([104., 117., 124.], dtype=np.float32)
  8. # add path of testImages
  9. current_dir = os.getcwd()
  10. image_dir = os.path.join(current_dir, 'images')
  11. # 通过这部分代码便可以找到我们数据集的位置了 #

#  这里opencv的输入时BGR格式,并不是我们所熟悉的RGB格式,所以要注意在最后进行转换

os.getcwd()

在Python中可以使用os.getcwd()函数获得当前的路径。

其原型如下所示:

os.getcwd()

该函数不需要传递参数,它返回当前的目录。需要说明的是,当前目录并不是指脚本所在的目录,而是所运行脚本的目录。

os.path.join () 

os.path.join(os.getcwd(),'data')就是获取当前目录,并组合成新目录

以下部分摘自https://www.cnblogs.com/donfaquir/p/9042673.html

在使用的过程中,我使用如下代码:

import os
path = "F:/gts/gtsdate/"
b = os.path.join(path,"/abc")

输出结果是:

'F:/abc'

并不是我期望的:

"F:/gts/gtsdate/abc"

原因是在os.path.join()第二个参数"/abc"起始字符是/
删除该字符即可,也就是

b = os.path.join(path,"abc")

os.path常用方法介绍http://www.cnblogs.com/wuxie1989/p/5623435.html

Part 2

  1. #get list of all images
  2. img_files = [os.path.join(image_dir, f) for f in os.listdir(image_dir) if f.endswith('.jpeg')]
  3. #load all images
  4. imgs = []
  5. for f in img_files:
  6. imgs.append(cv2.imread(f))
  7. #plot images
  8. fig = plt.figure(figsize=(15,6))
  9. for i, img in enumerate(imgs):
  10. fig.add_subplot(1,3,i+1)
  11. plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
  12. plt.axis('off')
  13. # 到这里我们就将我们dataset中的图片读取了进来 #

img_files = [os.path.join(image_dir, f) for f in os.listdir(image_dir) if f.endswith('.jpeg')]

熟悉一下这种写法

首先是路径的添加,使用os,path.join()函数,将f 添加到路径 image_dir的后面构成我们的 img_files 

而 f 的生成则依赖一个for循环和一个if判断语句

f 是image_dir 这个文件夹中,以.jpeg为结尾的文件,也就是图像文件。(这里要注意,如果你强行将文件名更改为.jpeg是不能够读取到的,必须要详细的查看文件的属性才可以)

os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。

这个列表以字母顺序。 它不包括 '.' 和'..' 即使它在文件夹中。listdir()方法语法格式如下:

os.listdir(path)--------(path -- 需要列出的目录路径)

返回为指定路径下的文件和文件夹列表。

for i, img in enumerate(imgs):

i 保存图像的编号,img则保存图像信息

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

  1. seq = ['one', 'two', 'three']
  2. for i, element in enumerate(seq):
  3. print i, element
  4. 结果:
  5. 0 one
  6. 1 two
  7. 2 three

plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

我们生活中大多数看到的彩色图片都是RGB类型,但是在进行图像处理时,需要用到灰度图、二值图、HSV、HSI等颜色制式,opencv提供了cvtColor()函数来实现这些功能。首先看一下cvtColor函数定义:

cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 );

具体内容参见https://blog.csdn.net/keith_bb/article/details/53470170

 

 

Part 3

 

  1. from alexnet import AlexNet
  2. from caffe_classes import class_names
  3. #placeholder for input and dropout rate
  4. x = tf.placeholder(tf.float32, [1, 227, 227, 3])
  5. keep_prob = tf.placeholder(tf.float32)
  6. #create model with default config ( == no skip_layer and 1000 units in the last layer)
  7. # 哈哈, 这最关键的一部居然如此的轻描淡写
  8. model = AlexNet(x, keep_prob, 1000, [])
  9. #define activation of last layer as score
  10. score = model.fc8
  11. #create op to calculate softmax
  12. softmax = tf.nn.softmax(score)
def __init__(self, x, keep_prob, num_classes, skip_layer, weights_path = 'DEFAULT'):

   model = AlexNet (  x, keep_prob, 1000, [  ]  )

我们根据__init__函数来看这个 model 

self.X = x
self.KEEP_PROB = keep_prob
self.NUM_CLASSES = 1000
self.SKIP_LAYER = 空
weights_path == 'DEFAULT'

 

score = model.fc8   ###  将最后一层的activation 作为score

同样的,我们还是对比来看:

def  fc ( x, num_in, num_out, name, relu = True ) :

self.fc8 = fc ( dropout7, 4096, self.NUM_CLASSES, relu = False, name='fc8' )

 

Part 4

  1. with tf.Session() as sess:
  2. # Initialize all variables
  3. sess.run(tf.global_variables_initializer())
  4. # Load the pretrained weights into the model
  5. model.load_initial_weights(sess)
  6. # Create figure handle
  7. fig2 = plt.figure(figsize=(15,6))
  8. # Loop over all images
  9. for i, image in enumerate(imgs):
  10. # Convert image to float32 and resize to (227x227)
  11. img = cv2.resize(image.astype(np.float32), (227,227))
  12. # Subtract the ImageNet mean
  13. img -= imagenet_mean
  14. # Reshape as needed to feed into model
  15. img = img.reshape((1,227,227,3))
  16. # Run the session and calculate the class probability
  17. probs = sess.run(softmax, feed_dict={x: img, keep_prob: 1})
  18. # Get the class name of the class with the highest probability
  19. class_name = class_names[np.argmax(probs)]
  20. # Plot image with class name and prob in the title
  21. fig2.add_subplot(1,3,i+1)
  22. plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
  23. plt.title("Class: " + class_name + ", probability: %.4f" %probs[0,np.argmax(probs)])
  24. plt.axis('off')

 

model.load_initial_weights(sess)

这里调用了实例model中的 load_initial_weights 函数,我们看一下他的原型

def load_initial_weights(self, session):

************************

# Convert image to float32 and resize to (227x227)
        img = cv2.resize(image.astype(np.float32), (227,227))

astype()的作用:

  1. 很多时候我们用numpy从文本文件读取数据作为numpy的数组,默认的dtype是float64
  2. 但是有些场合我们希望有些数据列作为整数, 如果直接改dtype='int'的话,就会出错!原因如上,数组长度翻倍了!!!

怎么办? 用astype!

  1. >>> b = np.array([1.23,12.201,123.1])
  2. >>>
  3. >>> b
  4. array([ 1.23 , 12.201, 123.1 ])
  5. >>> b.dtype
  6. dtype('float64')
  7. >>> c = b.astype(int)
  8. >>> c
  9. array([ 1, 12, 123])
  10. >>> c.dtype
  11. dtype('int32')

 

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

闽ICP备14008679号