tensorflow库用法

tensorflow库用法(以下简称tf):
Tensorflow使用的是静态计算图, 需要先建立起计算图(此时不需要进行计算), 再进行前向传播和反向传播. Pytorch使用的是动态计算图, 不需要事先建立计算图,随前向传播逐步建立起来, 但这有一个缺点就是每次迭代都要生成一遍同样的计算图, 花费了更多的时间.
tf的reshape跟np的, torch的无异,不过tf使用的图片数据格式稍有不同, torch是N×C×H×W, 而tf是N×H×W×C.

tf.reset_default_graph() 重置(清除)当前的计算图, 在网络训练开始之前通常都会加上这一句.
在构建计算图时, 我们常常并不能事先知道输入数据的尺度, 为了在这种情况下仍能顺利建立计算图, 我们需要使用placeholder(占位符), 先为它在图中预留一个位置: x = tf.placeholder(tf.float32)
with tf.device(device): 先打开某个设备, 再建立计算图. 这个操作是为了告诉tf, 把计算图中的变量放置在CPU上还是GPU上. device的格式为:'/device:GPU:0''/cpu:0'. 设备打开后设置的变量(如tf.zeros())不会在这时进行实例化, 需要我们使用sess.run(tf.global_variables_initializer())来进行实例化.
运行计算图进行计算时需要在一个Session对象中操作: with tf.Session() as sess:
运行计算图: x_out = sess.run(x_want_out, feed_dict={x: x_in}) 其中x_want_out指明了我们想要tf输出的计算图中的变量名(也就是说可以输出中间变量), feed_dict变量指明我们的数据要注入到哪个位置, 比如这里就是把数据x_in注入到计算图中名字x的位置. x_out将接收到x_want_out的位置对应的值, 是一个np.array. 计算图一旦建立起来, 就可以通过重复run来多次使用. feed_dict中必须包含计算图中所有的placeholder. 非placeholder变量则不需要传值.

常用网络单元如ReLU, FC, Conv都放在tf.nn库里面.
tf的卷积核的尺寸格式是[H, W, in_channels, out_channels], 图片输入是[N, H, W, in_channels].

计算损失函数:
交叉熵: losses = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=scores) 此时得到的losses是整个batch的loss求和得到的结果, 如果我们想要取其均值(一般是要取均值的) 应多一句loss = tf.reduce_mean(losses)

求解梯度:
grad_params = tf.gradients(loss, params) params是一个保存了各个网络参数的list.
梯度更新: tf.assign_sub(w, dw) 函数可以用于梯度更新, 原参数w将变成w-dw.
听说直接返回loss还更新不了梯度, 要用下面这段代码才行, 原因尚未搞清楚:

with tf.control_dependencies(new_weights):
        return tf.identity(loss)

tf.Variable()函数定义变量(或将其他类型转换成Variable类型), 变量在计算图中一直存在且可以被修改, 可学习的参数都应该定义成这种类型(只有Variable有assign_sub属性, 可以被修改, tf.zeros, tf.random_normal 等都没有).

除了最简单的使用tf来搭建网络, 对付大型网络我们还可以考虑另外两种方法:

  1. tf.keras + tf.layers;
  2. tf.keras.Sequential + tf.layers.
tf.keras + tf.layers

定义一个 tf.keras.Model的子类作为我们的模型的类:

class TwoLayerFC(tf.keras.Model):
    def __init__(self, hidden_size, num_classes):
        super().__init__()        #记得不要漏掉这句!
        initializer = tf.variance_scaling_initializer(scale=2.0) #2.0相当于是kaiming he初始化方法
        self.fc1 = tf.layers.Dense(hidden_size, activation=tf.nn.relu, 
                                   kernel_initializer=initializer) #Dense层就全连接层. relu层不需要另起一层了, 可以直接跟fc层放一起
        self.fc2 = tf.layers.Dense(num_classes,
                                   kernel_initializer=initializer) #很神奇,不需要给出输入的维度, 只给出输出维度就能正常工作

前向传播的都差不多:

def call(self,x, training=None):
    x = tf.layers.flatten(x)
    x = self.fc1(x)
    x = self.fc2(x)
return x

优化器optimizer们放在了tf.train库下,常用的SGD和momentum SGD分别对应tf.train.GradientDescentOptimizertf.train.MomentumOptimizer.

tf.keras.Sequential + tf.layers

与第一种方法的一个区别是,这里需要事先定义好输入的尺寸, 然后以关键字参数input_shape的形式传给第一层网络.(如果除了N只剩下一个维度, 那么input_shape应写为(D, )而不是(D)或D.

def model_init_fn(inputs, is_training):
    input_shape = (32, 32, 3)
    hidden_layer_size, num_classes = 4000, 10
    initializer = tf.variance_scaling_initializer(scale=2.0)
    # 一次性把所有的网络都堆进layers里, 然后tf.keras.Sequential一下就能得到模型了
    layers = [
        tf.layers.Conv2D(channel_1, 5, padding='same', kernel_initializer=initializer, activation=tf.nn.relu, input_shape=input_shape), #这里多加了个input_shape
        tf.layers.Conv2D(channel_2, 3, padding='same', kernel_initializer=initializer, activation=tf.nn.relu),
        tf.layers.Flatten(),
        tf.layers.Dense(num_classes, kernel_initializer=initializer)
    ]
    model = tf.keras.Sequential(layers)
    return model(inputs)

TensorFlow 模型保存/载入的两种方法

常用操作:
tf.matmul()函数实现两个矩阵的相乘, 用法与np.dot()类似.
tf.cast()函数用于转换数据格式.
tf.shape()返回的对象可用于tf.reshape等操作,这个返回值也有个shape(如(4,0)),但那是表示张量的维度数,不是每个维度的值,相当于是len(x.shape),这个需要注意一下不要弄错。一个非张量的变量(如python中的int类型),它的tf.shape()值是(0,)。
tf.split函数用于对张量进行切分, 用法是split(value, num_or_size_splits, axis=0) 第二个参数可以是整数,表示分成几块; 也可以是个list, 表示每块有多大.
tf.add_n(a)函数可以将list类型的变量a里面的各个张量元素全部加起来

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值