TensorFlow基础——深入理解AlexNet代码中的每一个TF函数

TensorFlow基础——深入理解AlexNet代码中的每一个TF函数

本文关注如何使用TensorFlow中的函数来构建AlexNet,详细介绍每一个TF函数的应用方法,适合基础入门。

一. AlexNet的TensowFlow代码

首先给出AlexNet的代码,但是此处不会对AlexNet的原理做详细解析,而是将重点关注TensorFlow的函数使用

# 加载模块
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 导入数据
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
 
# 相关子函数定义 ###################################################
def compute_accuracy(v_xs,v_ys):
    global prediction
    y_pre = sess.run(prediction, feed_dict={xs:v_xs, keep_prob:1})
    correct_prediction = tf.equal(tf.argmax(y_pre, 1),tf.argmax(v_ys,1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    result = sess.run(accuracy, feed_dict={xs:v_xs,ys:v_ys,keep_prob:1})
    return result
 
def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)
 
def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)
 
def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding="SAME")  # padding="SAME"用零填充边界

 
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding="SAME")
 
#处理图片 ###################################################
xs = tf.placeholder(tf.float32, [None,784])   # 训练x
ys = tf.placeholder(tf.float32, [None,10])    # 训练y
keep_prob = tf.placeholder(tf.float32)    # dropout的保留率

x_image = tf.reshape(xs, [-1, 28, 28, 1])  # 向量转矩阵:将1*784的向量reshape为28*28-1表示不关注这一维度

#构建网络 ###################################################
## convl layer ##
W_conv1 = weight_variable([5,5,1,32])    # kernel 5*5, channel is 1, out size 32
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1) + b_conv1)  # output size 28*28*32
h_pool1 = max_pool_2x2(h_conv1)                          # output size 14*14*32
 
## conv2 layer ##
W_conv2 = weight_variable([5,5,32,64]) # kernel 5*5, in size 32, out size 64
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1,W_conv2) + b_conv2)  # output size 14*14*64
h_pool2 = max_pool_2x2(h_conv2)                          # output size 7*7*64
 
## funcl layer ##
W_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])
 
# [n_samples,7,7,64]->>[n_samples, 7*7*64]
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
 
## func2 layer ##
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2)
 
#优化神经网络###################################################
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1])) #定义损失函数
train_step = tf.train.GradientDescentOptimizer(1e-4).minimize(cross_entropy)   # 定义求解器
 
sess =tf.Session()    # 创建会话前台Python与后台C++之间的会话
sess.run(tf.initialize_all_variables())    # 计算图的初始化

# 主函数开始##################################################
if __name__ == '__main__':
    for i in range(1000):
        batch_xs,batch_ys = mnist.train.next_batch(100)
        sess.run(train_step, feed_dict={xs:batch_xs,ys:batch_ys, keep_prob:0.5})
        if i % 1 ==0:
            # print(sess.run(prediction,feed_dict={xs:batch_xs}))
            print(compute_accuracy(mnist.test.images,mnist.test.labels))

二. AlexNet的TensowFlow函数解析

此处将从头到尾,依次解析以上代码中用到的TF函数。

1. tf.nn、tf.layer、tf.contrib的区别

三者都是TF中定义的函数模块,但是使用有所不同。

  1. Tf.nn:提供每一层的底层实现的API,比如编辑一个myConv2d需要自行调用基础接口进行操作
  2. Tf.layer:是基于tf.nn封装的高级函数,比如定义conv2d可以直接调用tf.layers.conv2d
  3. Tf.contrib:也是封装完好的高级函数,但是tf.contrib包含不稳定和实验代码,有可能以后API会改变,比如tf.contrib**.layers.conv2d

2. tf.placeholder创建占位符

  1. 作用:Placeholder用于占位,等待计算过程中持续馈入的输入数据
  2. 格式:tf.placeholder(dtype, shape=None, name=None)
    举例:x_train = tf.placeholder(tf.float32,shape=(None,28,28,1),name=“x_train”)
    其中: None用于表示batchsize;
    28*28表示图片的高宽;
    1表示图片的channel数,黑白图片为1,RGB图片为3

PS为什么已经通过函数左值给定变量名了,还需要通过函数的name属性再次定义变量名。 例如x_train = tf.placeholder(tf.float32,shape=(None,28,28,1),name=“x_train1”)。
原因是
函数左值x_train是Python语言中的变量名空间,这个变量名只是在tensorflow图的Python脚本运行过程中指向tensorflow图中的变量的临时指针,这个命名空间在脚本运行完毕之后就会自动删除。
而函数中定义的name="x_train1"是tensorflow命名空间中属于这个图变量的真实属性,这个属性不会随着Python代码运行结束而消除,并且在tensorboard中显示的是name="x_train1"这个属性。

3. tf.reshape 修改tensor的形状

  1. 格式:tf.reshape(tensor,shape,name=None)

4. tf.truncated_normal 创建截断式正态分布

  1. 作用:tf.truncated_normal作用是利用截断式(truncated截断式的)正态分布输出随机数
    PS:截断式:如果生成的某个随机数大于了2倍标准差,就会重新生成,也就是保证生成的随机数处于【-2σ,2σ】区间内。
    PS:正态分布中处于【-3σ,3σ】的概率为99.7%;正态分布中处于【-2σ,2σ】的概率为95.6%;正态分布中处于【-2σ,2σ】的概率为68.2%

  2. 格式:tf.random.truncated_normal(shape,mean=0.0, stddev=1.0, dtype=tf.dtypes.float32, seed=None, name=None)
    举例:w1_conv = tf.random.truncated_normal([5,5,1,32],mean=0.2,stddev=0.5,dtype=tf.flaot32,seed=1,name=‘w1_conv’)
    说明
    (1)mean和stddev分别定义正态分布的均值和标准差,
    (2)seed用于定义随机数的种子,对于正态分布而言,只要定义了相同的随机数种子,则每次输出的结果都是一样的。如下面的代码实验:只要两者有相同的随机数种子,则生成的随机数的前半部分都是相同的。
    PS:这个shape对应着卷积核的shape,分别是【width,height,in_chinnels,out_chinnels】

  3. 补充:tf.random_normal()函数是生成普通正态分布的函数,tf.random_normal与tf.truncated_normal的参数格式相同,区别是前者不截断,后者阶段

  4. 实验代码

# 加载模块
a = tf.Variable(tf.random_normal([2,2],seed=1))  # 普通的正态分布
b = tf.Variable(tf.truncated_normal([2,3],seed=1))   # 截断式正态分布
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    print(sess.run(a))
    print(sess.run(b))
# 分别输出:
a:
[[-0.8113182   1.4845988 ]
 [ 0.06532937 -2.4427042 ]]
 b:
[[-0.8113182   1.4845988   0.06532937]
 [ 0.0992484   0.6396971   1.6108712 ]]
 # 可见只要随机数种子相同,就会生成相同的随机数。

5. tf.constant() 创建常量形式的张量

  1. 作用:tf.constant()基于给定的常数创建张量

  2. 格式:tb1 = tf.constant(value, dtype=None, shape=None, name=‘Const’,verify_shape=False )
    其中value是给定的常量值或者常量的list。
    举例:tensor = tf.constant([1, 2, 3, 4, 5, 6, 7]) 得到[1 2 3 4 5 6 7]
    tensor = tf.constant(-1.0, shape=[2, 3])得到 [[-1. -1. -1.],[-1. -1. -1.]]

  3. 实验代码

# 加载模块
a = tf.Variable(tf.constant(1.2,shape=[3,3]))   # 生成一个3*3的常量矩阵,所有值都是1.2
b = tf.Variable(tf.constant([1.2,1.3,1.4],shape=[7]))   # 生成一个1*7的常量矩阵,前三个值是1.2,1.3,1.4,后续的值用1.4 填补
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    print(sess.run(a))
    print(sess.run(b))
# 分别输出:
a:
[[1.2 1.2 1.2]
 [1.2 1.2 1.2]
 [1.2 1.2 1.2]]
 b:
[1.2 1.3 1.4 1.4 1.4 1.4 1.4]

6. tf.Varible() 创建TF变量的方式

  1. 作用:tf.Varible() 创建TF变量的方式。
    tensorflow中的图变量需要先定义、然后初始化(tf.global_variables_initializer。),然后在赋值计算(tf.Session的run)
    常用的变量定义函数有tf.Varible()或者tf.get_varible(),这两个函数非常重要,并且两者在变量域方面有较大差别,因此我么将在后续的文章中详细讲解。

7. tf.nn.relu() relu激活函数

  1. 作用:tf.nn.relu(features,name=None) 就是最普通的relu函数 relu = max(feature,0)
  2. PS:tf中还有另外几个relu系列函数
    (1)tf.nn.relu6(features,name=None) 算法是:relu6 = min(max(feature,0),6),可以避免正方向激活后的值过大
    (2)tf.nn.leaky_relu(features,alpha=0.2,name=None) 算法是 lrelu = max(feature,alpha*feature)alpha用于定义负区间的斜率
    (3)tf.nn.crelu(features,name=None,axis=-1) 算法是CReLU(x)=[ReLU(x),ReLU(−x)],用于补足relu所抹去的负响应

8. f.nn.dropout() dropout方法

  1. 作用
    tf.nn.dropout用于在训练过程中随机屏蔽1-keep_prob的比例的神经元,将这部分神经元的前馈值变成0,在本次训练中不参与更新与计算。
    而剩下的keep_prob比例的神经元的值被乘以一个1/keep_prob的系数,这样保证 变换以后,最终的输出值相当于没变化。
    说白了,tensorflow中的dropout就是:使输入tensor中某些元素变为0,其它没变0的元素变为原来的1/keep_prob大小!
  2. 格式:tf.nn.dropout(x,keep_prob=None,noise_shape=None,seed=None,name=None,rate=None)
    其中value是给定的常量值或者常量的list。
  3. PS:dropout在大型网络中比较实用,在小型网络中用不好就是累赘

9. tf.reduce_sum() 压缩求和函数

  1. 作用:tf.reduce_sum()用于压缩求和

  2. 格式:tf.reduce_sum(input_tensor,axis=None,keepdims=None,name=None,reduction_indices=None,keep_dims=None)
    axis 用于指明压缩方向,如果没有指明,就会直接压缩为1个常数
    keepdims表示按照某一维数就行压缩契合

  3. 实验代码

import tensorflow as tf
import numpy as np
 
x = tf.constant([[1,1,1],[2,2,2]])
with tf.Session() as sess:
    print(sess.run(tf.reduce_sum(x))) #所有求和   #输出 9
    print(sess.run(tf.reduce_sum(x,0))) #按 列 求和   # 输出 [3 3 3]
    print(sess.run(tf.reduce_sum(x,1))) #按 行 求和    # 输出  [3 6]
    print(sess.run(tf.reduce_sum(x,1,keepdims=True))) #按维度 行 求和  #输出[[3],[6]]
    print(sess.run(tf.reduce_sum(x,[0,1])))  #行列求和    # 输出9
    print(sess.run(tf.reduce_sum(x,reduction_indices=[1])))   # 输出[3,6]

10. tf.reduce_mean() 压缩求均值函数

  1. 作用:tf.reduce_mean()用于压缩求均值
  2. 格式:其参数类似于reduce_sum
    tf.reduce_mean(input_tensor,axis=None,keepdims=None,name=None,reduction_indices=None,keep_dims=None)
    axis 用于指明压缩方向,如果没有指明,就会直接压缩为1个常数
    keepdims表示按照某一维数就行压缩契合

11. f.train.GradientDescentOptimizer(1e-4).minimize(cross_entropy) # 求解器

  1. 作用:tf.train包含许多求解器,GradientDescentOptimizer(lr).minimize(loss)是一种基于梯度下降法的优化求解算法。
    这是一种个比较大的模块,将在后面开辟新的章节专门讲解

12. tf.session 定义会话

  1. 作用
    tensorflow的内核使用更加高效的C++作为后台,以支撑它的密集计算。
    tensorflow把前台(即python程序)与后台程序之间的连接称为"会话(Session)"
    tensorflow的世界里,变量的定义与计算时分开的,比如之前的tf.constant,tf.nn.relu的函数都只是定义了一个变量,而真正要开始幅值和计算还需要对其进行初始化
    sess=tf.session表示创建python与c++之间的会话,也就是启动之前定义好的图,并将这个会话命名为sess

  2. 格式:tf.Session作为会话,主要功能是指定操作对象的执行环境,Session类构造函数有3个可选参数。
    target(可选):指定连接的执行引擎,多用于分布式场景。
    graph(可选):指定要在Session对象中参与计算的图(graph)。
    config(可选):辅助配置Session对象所需的参数(限制CPU或GPU使用数目,设置优化参数以及设置日志选项等)。
    以上参数都是可选,一般一句sess=tf.session()就可以启动了

  3. PS
    除了tf.session外,还可以使用tf.InteractiveSession()来创建会话,后者将当前会话设置为默认会话,这样在进行eval和run等操作的时候就不用指定名称了
    对于tf.Session()
    sess=tf.Session()
    sess.run(op1,feed_dict(x:x1,y:y1))
    对于tf.InteractiveSession()
    sess=tf.InteractiveSession()
    op1.eval(feed_dict(x:x1,y:y1))

也就是说:tf.InteractiveSession()相当于
sess=tf.Session()
with sess.as_default():

13. tf.session.run 用于运算

  1. 作用:tf.session.run 会话创建完成后,使用run方法来进行图中的op计算
  2. 格式:run(fetches,feed_dict=Noneoptions=None,run_metadata=None)
    fetches表示数据流图中能接收的任意数据流图元素,包括各类Op/Tensor对象
    feed_dict可选项,给数据流图中的placeholder提供运行时数据。feed_dict的数据结构为python中的字典,其元素为各种键值对。
    "key"为各种Tensor对象的句柄;"value"很广泛,但必须和“键”的类型相匹配,或能转换为同一类型
  3. 举例
    sess.run(tf.initialize_all_variables()) 启动对所有算子的初始化,tf.session只是创建图,tf.initialize_all_variables()用于初始化所有op,等待输入;这个函数在新版本中将逐步被tf.global_variables_initializer()取代。
    sess.run(train_step, feed_dict={xs:batch_xs,ys:batch_ys, keep_prob:0.5}) # feed进计算图中的参数都是python的字典格式

参考

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 下面是一个使用 TensorFlow 实现 AlexNet代码示例: ```python import tensorflow as tf model = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(96, (11, 11), strides=(4, 4), input_shape=(224, 224, 3), padding="valid", activation="relu"), tf.keras.layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2), padding="valid"), tf.keras.layers.Conv2D(256, (5, 5), strides=(1, 1), padding="same", activation="relu"), tf.keras.layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2), padding="valid"), tf.keras.layers.Conv2D(384, (3, 3), strides=(1, 1), padding="same", activation="relu"), tf.keras.layers.Conv2D(384, (3, 3), strides=(1, 1), padding="same", activation="relu"), tf.keras.layers.Conv2D(256, (3, 3), strides=(1, 1), padding="same", activation="relu"), tf.keras.layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2), padding="valid"), tf.keras.layers.Flatten(), tf.keras.layers.Dense(4096, activation="relu"), tf.keras.layers.Dropout(0.5), tf.keras.layers.Dense(4096, activation="relu"), tf.keras.layers.Dropout(0.5), tf.keras.layers.Dense(1000, activation="softmax") ]) model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.01, momentum=0.9), loss="categorical_crossentropy", metrics=["accuracy"]) ``` 在这段代码,我们使用了 `tf.keras.models.Sequential` 来定义模型的结构,模型包括卷积层(`Conv2D`)、池化层(`MaxPool2D`)、全连接层(`Dense`)和 dropout 层(`Dropout`)。我们使用了 `compile` 方法来编译模型,并指定了损失函数和优化器。 ### 回答2: 使用TensorFlow实现AlexNet,可以按照以下步骤进行: 1. 导入相关库: ```python import tensorflow as tf from tensorflow.keras import layers ``` 2. 构建AlexNet模型的网络结构: ```python model = tf.keras.Sequential() model.add(layers.Conv2D(filters=96, kernel_size=(11,11), strides=(4,4), padding='valid', activation='relu', input_shape=(227,227,3))) model.add(layers.BatchNormalization()) model.add(layers.MaxPooling2D(pool_size=(3,3), strides=(2,2), padding='valid')) model.add(layers.Conv2D(filters=256, kernel_size=(5,5), strides=(1,1), padding='same', activation='relu')) model.add(layers.BatchNormalization()) model.add(layers.MaxPooling2D(pool_size=(3,3), strides=(2,2), padding='valid')) model.add(layers.Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='same', activation='relu')) model.add(layers.BatchNormalization()) model.add(layers.Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='same', activation='relu')) model.add(layers.BatchNormalization()) model.add(layers.Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='same', activation='relu')) model.add(layers.BatchNormalization()) model.add(layers.MaxPooling2D(pool_size=(3,3), strides=(2,2), padding='valid')) model.add(layers.Flatten()) model.add(layers.Dense(4096, activation='relu')) model.add(layers.Dropout(0.5)) model.add(layers.Dense(4096, activation='relu')) model.add(layers.Dropout(0.5)) model.add(layers.Dense(1000, activation='softmax')) ``` 3. 编译模型: ```python model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) ``` 4. 训练模型: ```python model.fit(x_train, y_train, batch_size=64, epochs=10, validation_data=(x_val, y_val)) ``` 注意,上述代码的`x_train`、`y_train`、`x_val`和`y_val`是训练集和验证集的输入和标签数据。 以上就是使用TensorFlow实现AlexNet的简要步骤,希望可以帮助到你! ### 回答3: AlexNet是深度学习领域非常经典的卷积神经网络模型,使用Python的TensorFlow库可以相对简单地实现这个模型。 首先,我们需要导入tensorflow库和其他一些必要的库。 ```python import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout ``` 然后,我们可以定义一个函数来创建AlexNet模型。 ```python def create_alexnet(): model = Sequential() # 第一层卷积 model.add(Conv2D(96, kernel_size=(11, 11), strides=4, activation='relu', input_shape=(227, 227, 3))) model.add(MaxPooling2D(pool_size=(3, 3), strides=2)) # 第二层卷积 model.add(Conv2D(256, kernel_size=(5, 5), activation='relu')) model.add(MaxPooling2D(pool_size=(3, 3), strides=2)) # 第三、四、五层卷积 model.add(Conv2D(384, kernel_size=(3, 3), activation='relu')) model.add(Conv2D(384, kernel_size=(3, 3), activation='relu')) model.add(Conv2D(256, kernel_size=(3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(3, 3), strides=2)) # 全连接层 model.add(Flatten()) model.add(Dense(4096, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(4096, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(1000, activation='softmax')) return model ``` 在该代码,我们使用了`Sequential`模型来构建AlexNet,然后按照论文的架构添加了一系列卷积层、池化层和全连接层。 最后,我们可以使用以下代码来创建并编译模型。 ```python model = create_alexnet() model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) ``` 这样就成功地使用tensorflow实现了AlexNet神经网络模型。可以使用该模型进行图像分类、目标识别等任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值